1 /* { dg-do run } */ 2 /* { dg-require-effective-target hwaddress_exec } */ 3 4 /* 5 Tests of nested funtions are: 6 0) Accessing closed over variables works. 7 1) Accesses outside of variables is caught. 8 2) Accessing variable out of scope is caught. 9 10 Here we test that accessing closed over variables works. 11 */ 12 13 /* We need a second layer of indirection so that GCC doesn't notice we're 14 returning the address of a local variable and put 0 in it's place. */ 15 __attribute__((noinline)) Ident(void * x)16int *Ident(void *x) { 17 return x; 18 } 19 20 int __attribute__ ((noinline)) intermediate(void (* f)(int,char),char num)21intermediate (void (*f) (int, char), 22 char num) 23 { 24 if (num == 1) 25 /* NOTE: We need to overrun by an amount greater than the "extra data" in a 26 nonlocal goto structure. The entire structure is allocated on the stack 27 with a single tag, which means hwasan can't tell if a closed-over buffer 28 was overrun by an amount small enough that the access was still to some 29 data in that nonlocal goto structure. */ 30 f (100, 100); 31 else 32 f (3, 100); 33 /* Just return something ... */ 34 return num % 3; 35 } 36 37 int* __attribute__ ((noinline)) nested_function(char num)38nested_function (char num) 39 { 40 int big_array[16]; 41 int other_array[16]; 42 void store (int index, char value) 43 { big_array[index] = value; } 44 return Ident(&other_array[intermediate (store, num)]); 45 } 46 47 #ifndef MAIN main()48int main () 49 { 50 nested_function (0); 51 return 0; 52 } 53 #endif 54