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