blob: 75472d26489bcf9cf6bb3042001392ebaf1a1e6a [file] [log] [blame]
/* 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);
}
}