block-6116917.c   [plain text]


/* APPLE LOCAL file radar 6116917 */
/* { dg-do run { target *-*-darwin[1-2][0-9]* } } */
/* { dg-options "-mmacosx-version-min=10.6 -ObjC -Os -Wall -Wextra" { target *-*-darwin* } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "-m64" } { "" } } */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//#include <Block_private.h>

/* APPLE LOCAL begin radar 5847213 - radar 6329245 */
struct Block_basic {
    void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
    int Block_flags;
    int reserved;
    void (*Block_invoke)(void *);

    struct Block_descriptor_1 {
        unsigned long int reserved;     // NULL
        unsigned long int Block_size;  // sizeof(struct Block_literal_1)

        // optional helper functions
        void (*Block_copy)(void *dst, void *src);
        void (*Block_dispose)(void *src);
    } *descriptor;

    // imported variables
};
/* APPLE LOCAL end radar 5847213 - radar 6329245 */

void
func(void (^b)(void))
{
	b();
}

void
func2(void (^b)(void))
{
	b();
}

extern char **environ;

int
main(int argc __attribute__((unused)), char *argv[])
{
	struct Block_basic *bb;
	long bbi_addr, bb_addr;

	void (^stage1)(void) = ^{
		void (^stage2)(void) = ^{
			/* trick the compiler into slirping argc/argv into this Block */
			if (environ == argv) {
				fprintf(stdout, "You won the lottery! argv == environ\n");
			}
		};

		func2(stage2);
	};

	bb = (void *)stage1;

	/* APPLE LOCAL radar 5847213 - radar 6329245 */
	bbi_addr = (long)bb->Block_invoke;
	bb_addr = (long)bb;

	if (labs(bbi_addr - bb_addr) > (64 * 1024)) {
		func(stage1);
		exit(EXIT_SUCCESS);
	} else {
		fprintf(stderr, "Blocks generated code on the stack! Block_copy() is not safe!\n");
		exit(EXIT_FAILURE);
	}
}