blob: 0afcc100508cd2a5467698e901e32fa2292a32c9 [file] [log] [blame]
/* { dg-do run } */
/* { dg-require-effective-target hwaddress_exec } */
/*
Tests of nested funtions are:
0) Accessing closed over variables works.
1) Accesses outside of variables is caught.
2) Accessing variable out of scope is caught.
Here we test that accessing closed over variables works.
*/
/* We need a second layer of indirection so that GCC doesn't notice we're
returning the address of a local variable and put 0 in it's place. */
__attribute__((noinline))
int *Ident(void *x) {
return x;
}
int __attribute__ ((noinline))
intermediate (void (*f) (int, char),
char num)
{
if (num == 1)
/* NOTE: We need to overrun by an amount greater than the "extra data" in a
nonlocal goto structure. The entire structure is allocated on the stack
with a single tag, which means hwasan can't tell if a closed-over buffer
was overrun by an amount small enough that the access was still to some
data in that nonlocal goto structure. */
f (100, 100);
else
f (3, 100);
/* Just return something ... */
return num % 3;
}
int* __attribute__ ((noinline))
nested_function (char num)
{
int big_array[16];
int other_array[16];
void store (int index, char value)
{ big_array[index] = value; }
return Ident(&other_array[intermediate (store, num)]);
}
#ifndef MAIN
int main ()
{
nested_function (0);
return 0;
}
#endif