/* Test that stack protection is done on chosen functions. */ /* { dg-do compile { target i?86-*-* x86_64-*-* rs6000-*-* s390x-*-* } } */ /* { dg-options "-O2 -fstack-protector-strong" } */ /* This test checks the presence of __stack_chk_fail function in assembler. * Compiler generates _stack_chk_fail_local (wrapper) calls instead for PIC. */ /* { dg-require-effective-target nonpic } */ #include extern int g0; extern int* pg0; int goo (int *); int hoo (int); /* Function frame address escaped function call. */ int foo1 () { int i; return goo (&i); } struct ArrayStruct { int a; int array[10]; }; struct AA { int b; struct ArrayStruct as; }; /* Function frame contains array. */ int foo2 () { struct AA aa; int i; for (i = 0; i < 10; ++i) { aa.as.array[i] = i * (i-1) + i / 2; } return aa.as.array[5]; } /* Address computation based on a function frame address. */ int foo3 () { int a; int *p; p = &a + 5; return goo (p); } /* Address cast based on a function frame address. */ int foo4 () { int a; return goo (g0 << 2 ? (int *)(3 * (long)(void *)(&a)) : 0); } /* Address cast based on a local array. */ int foo5 () { short array[10]; return goo ((int *)(array + 5)); } struct BB { int one; int two; int three; }; /* Address computaton based on a function frame address.*/ int foo6 () { struct BB bb; return goo (&bb.one + sizeof(int)); } /* Function frame address escaped via global variable. */ int foo7 () { int a; pg0 = &a; goo (pg0); return *pg0; } /* Check that this covers -fstack-protector. */ int foo8 () { char base[100]; memcpy ((void *)base, (const void *)pg0, 105); /* { dg-warning "writing 105 bytes into a region of size 100" } */ return (int)(base[32]); } /* Check that this covers -fstack-protector. */ int foo9 () { char* p = __builtin_alloca (100); return goo ((int *)(p + 50)); } int global2 (struct BB* pbb); /* Address taken on struct. */ int foo10 () { struct BB bb; int i; bb.one = global2 (&bb); for (i = 0; i < 10; ++i) { bb.two = bb.one + bb.two; bb.three = bb.one + bb.two + bb.three; } return bb.three; } struct B { /* Discourage passing this struct in registers. */ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; }; struct B global3 (void); int foo11 () { return global3 ().a1; } void foo12 () { global3 (); } /* { dg-final { scan-assembler-times "stack_chk_fail" 12 } } */