| /* 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<string.h> |
| |
| 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 } } */ |