blob: b7b5c3bac5dd70184a5ee10f256071bc21332a87 [file] [log] [blame]
/* APPLE LOCAL file radar 6116917 */
/* { dg-options "-mmacosx-version-min=10.6 -ObjC -Os -Wall -Wextra" { target *-*-darwin* } } */
/* { dg-do run } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "-m64" } { "" } } */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//#include <Block_private.h>
struct Block_basic {
void *isa;
int Block_flags; // int32_t
int Block_size; // XXX should be packed into Block_flags
void (*Block_invoke)(void *);
void (*Block_copy)(void *dst, void *src);
void (*Block_dispose)(void *);
//long params[0]; // generic space for const & byref hidden params, return value, variable on needs of course
};
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;
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);
}
}