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 
13 extern int g0;
14 extern int* pg0;
15 int
16 goo (int *);
17 int
18 hoo (int);
19 
20 /* Function frame address escaped function call. */
21 int
foo1()22 foo1 ()
23 {
24   int i;
25   return goo (&i);
26 }
27 
28 struct ArrayStruct
29 {
30   int a;
31   int array[10];
32 };
33 
34 struct AA
35 {
36   int b;
37   struct ArrayStruct as;
38 };
39 
40 /* Function frame contains array. */
41 int
foo2()42 foo2 ()
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. */
54 int
foo3()55 foo3 ()
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. */
64 int
foo4()65 foo4 ()
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. */
72 int
foo5()73 foo5 ()
74 {
75   short array[10];
76   return goo ((int *)(array + 5));
77 }
78 
79 struct BB
80 {
81   int one;
82   int two;
83   int three;
84 };
85 
86 /* Address computaton based on a function frame address.*/
87 int
foo6()88 foo6 ()
89 {
90   struct BB bb;
91   return goo (&bb.one + sizeof(int));
92 }
93 
94 /* Function frame address escaped via global variable. */
95 int
foo7()96 foo7 ()
97 {
98   int a;
99   pg0 = &a;
100   goo (pg0);
101   return *pg0;
102 }
103 
104 /* Check that this covers -fstack-protector. */
105 int
foo8()106 foo8 ()
107 {
108   char base[100];
109   memcpy ((void *)base, (const void *)pg0, 105);   /* { dg-warning "writing 105 bytes into a region of size 100" } */
110   return (int)(base[32]);
111 }
112 
113 /* Check that this covers -fstack-protector. */
114 int
foo9()115 foo9 ()
116 {
117   char* p = __builtin_alloca (100);
118   return goo ((int *)(p + 50));
119 }
120 
121 int
122 global2 (struct BB* pbb);
123 
124 /* Address taken on struct. */
125 int
foo10()126 foo10 ()
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 
139 struct B
140 {
141   /* Discourage passing this struct in registers. */
142   int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
143 };
144 
145 struct B global3 (void);
146 
foo11()147 int foo11 ()
148 {
149   return global3 ().a1;
150 }
151 
foo12()152 void foo12 ()
153 {
154   global3 ();
155 }
156 
157 /* { dg-final { scan-assembler-times "stack_chk_fail" 12 } } */
158