1/* Test that stack protection is done on chosen functions. */ 2 3/* { dg-do compile { target i?86-*-* x86_64-*-* rs6000-*-* s390x-*-* } } */ 4/* { dg-options "-O2 -fstack-protector-strong" } */ 5 6/* This test checks the presence of __stack_chk_fail function in assembler. 7 * Compiler generates _stack_chk_fail_local (wrapper) calls instead for PIC. 8 */ 9/* { dg-require-effective-target nonpic } */ 10 11#include<string.h> 12 13extern int g0; 14extern int* pg0; 15int 16goo (int *); 17int 18hoo (int); 19 20/* Function frame address escaped function call. */ 21int 22foo1 () 23{ 24 int i; 25 return goo (&i); 26} 27 28struct ArrayStruct 29{ 30 int a; 31 int array[10]; 32}; 33 34struct AA 35{ 36 int b; 37 struct ArrayStruct as; 38}; 39 40/* Function frame contains array. */ 41int 42foo2 () 43{ 44 struct AA aa; 45 int i; 46 for (i = 0; i < 10; ++i) 47 { 48 aa.as.array[i] = i * (i-1) + i / 2; 49 } 50 return aa.as.array[5]; 51} 52 53/* Address computation based on a function frame address. */ 54int 55foo3 () 56{ 57 int a; 58 int *p; 59 p = &a + 5; 60 return goo (p); 61} 62 63/* Address cast based on a function frame address. */ 64int 65foo4 () 66{ 67 int a; 68 return goo (g0 << 2 ? (int *)(3 * (long)(void *)(&a)) : 0); 69} 70 71/* Address cast based on a local array. */ 72int 73foo5 () 74{ 75 short array[10]; 76 return goo ((int *)(array + 5)); 77} 78 79struct BB 80{ 81 int one; 82 int two; 83 int three; 84}; 85 86/* Address computaton based on a function frame address.*/ 87int 88foo6 () 89{ 90 struct BB bb; 91 return goo (&bb.one + sizeof(int)); 92} 93 94/* Function frame address escaped via global variable. */ 95int 96foo7 () 97{ 98 int a; 99 pg0 = &a; 100 goo (pg0); 101 return *pg0; 102} 103 104/* Check that this covers -fstack-protector. */ 105int 106foo8 () 107{ 108 char base[100]; 109 memcpy ((void *)base, (const void *)pg0, 105); 110 return (int)(base[32]); 111} 112 113/* Check that this covers -fstack-protector. */ 114int 115foo9 () 116{ 117 char* p = __builtin_alloca (100); 118 return goo ((int *)(p + 50)); 119} 120 121int 122global2 (struct BB* pbb); 123 124/* Address taken on struct. */ 125int 126foo10 () 127{ 128 struct BB bb; 129 int i; 130 bb.one = global2 (&bb); 131 for (i = 0; i < 10; ++i) 132 { 133 bb.two = bb.one + bb.two; 134 bb.three = bb.one + bb.two + bb.three; 135 } 136 return bb.three; 137} 138 139struct B 140{ 141 /* Discourage passing this struct in registers. */ 142 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; 143}; 144 145struct B global3 (void); 146 147int foo11 () 148{ 149 return global3 ().a1; 150} 151 152void foo12 () 153{ 154 global3 (); 155} 156 157/* { dg-final { scan-assembler-times "stack_chk_fail" 12 } } */ 158