1 // PR middle-end/59470
2 // { dg-do run }
3 // { dg-options "-O2 -fstack-protector" }
4 // { dg-additional-options "-fPIC" { target fpic } }
5 // { dg-require-effective-target fstack_protector }
6 
7 struct A
8 {
9   int a1;
throwA10   A () throw () : a1 (0) {}
11 };
12 
13 struct B
14 {
15   unsigned int b1 () throw ();
16 };
17 
18 __attribute__((noinline, noclone)) unsigned int
b1()19 B::b1 () throw ()
20 {
21   asm volatile ("" : : : "memory");
22   return 0;
23 }
24 
25 struct C
26 {
27   const A **c1;
28   void c2 (const A *, unsigned int);
29 };
30 
31 __attribute__((noinline, noclone)) void
c2(const A *,unsigned int)32 C::c2 (const A *, unsigned int)
33 {
34   asm volatile ("" : : : "memory");
35 }
36 
37 struct D
38 {
39   C *d1;
40 };
41 
42 struct E
43 {
44   int e1;
45   int e2;
46   D e3;
47 };
48 
49 struct F
50 {
51   virtual int f1 (const char * s, int n);
52 };
53 
54 struct G
55 {
56   F *g1;
57   bool g2;
g3G58   G & g3 (const char * ws, int len)
59   {
60     if (__builtin_expect (!g2, true)
61 	&& __builtin_expect (this->g1->f1 (ws, len) != len, false))
62       g2 = true;
63     return *this;
64   }
65 };
66 
67 struct H : public A
68 {
69   const char *h1;
70   unsigned int h2;
71   bool h3;
72   const char *h4;
73   char h5;
74   char h6;
75   char h7[31];
76   bool h8;
HH77   H () : h1 (0), h2 (0), h4 (0), h5 (0), h6 (0), h8 (false) {}
78   void h9 (const D &) __attribute__((noinline, noclone));
79 };
80 
81 void
h9(const D &)82 H::h9 (const D &)
83 {
84   h3 = true;
85   __builtin_memset (h7, 0, sizeof (h7));
86   asm volatile ("" : : : "memory");
87 };
88 
89 B b;
90 
91 inline const H *
foo(const D & x)92 foo (const D &x)
93 {
94   const unsigned int i = b.b1 ();
95   const A **j = x.d1->c1;
96   if (!j[i])
97     {
98       H *k = 0;
99       try
100 	{
101 	  k = new H;
102 	  k->h9 (x);
103 	}
104       catch (...)
105 	{
106 	}
107       x.d1->c2 (k, i);
108     }
109     return static_cast <const H *>(j[i]);
110 }
111 
112 __attribute__((noinline, noclone)) int
bar(char * x,unsigned long v,const char * y,int z,bool w)113 bar (char *x, unsigned long v, const char *y, int z, bool w)
114 {
115   asm volatile ("" : : "r" (x), "r" (v), "r" (y) : "memory");
116   asm volatile ("" : : "r" (z), "r" (w) : "memory");
117   return 8;
118 }
119 
120 __attribute__((noinline, noclone)) void
baz(void * z,const char * g,unsigned int h,char s,E & e,char * n,char * c,int & l)121 baz (void *z, const char *g, unsigned int h, char s, E &e, char *n, char *c, int &l)
122 {
123   asm volatile ("" : : "r" (z), "r" (g), "r" (h) : "memory");
124   asm volatile ("" : : "r" (s), "r" (&e), "r" (n) : "memory");
125   asm volatile ("" : : "r" (c), "r" (&l) : "memory");
126   if (n == c)
127     __builtin_abort ();
128   int i = 0;
129   asm ("" : "+r" (i));
130   if (i == 0)
131     __builtin_exit (0);
132 }
133 
134 __attribute__((noinline, noclone)) G
test(void * z,G s,E & x,char,long v)135 test (void *z, G s, E &x, char, long v)
136 {
137   const D &d = x.e3;
138   const H *h = foo (d);
139   const char *q = h->h7;
140   const int f = x.e2;
141   const int i = 5 * sizeof (long);
142   char *c = static_cast <char *>(__builtin_alloca (i));
143   const int b = f & 74;
144   const bool e = (b != 64 && b != 8);
145   const unsigned long u = ((v > 0 || !e) ? (unsigned long) v : -(unsigned long) v);
146   int l = bar (c + i, u, q, f, e);
147   c += i - l;
148   if (h->h3)
149     {
150       char *c2 = static_cast <char *>(__builtin_alloca ((l + 1) * 2));
151       baz (z, h->h1, h->h2, h->h6, x, c2 + 2, c, l);
152       c = c2 + 2;
153     }
154   if (__builtin_expect (e, true))
155     {
156     }
157   else if ((f & 4096) && v)
158     {
159       {
160 	const bool m = f & 176;
161 	*--c = q[m];
162 	*--c = q[1];
163       }
164     }
165   const int w = x.e1;
166   if (w > l)
167     {
168       char * c3 = static_cast <char *>(__builtin_alloca (w));
169       c = c3;
170     }
171   return s.g3 (c, l);
172 }
173 
174 int
main()175 main ()
176 {
177   H h;
178   const A *j[1];
179   C c;
180   G g;
181   E e;
182   h.h9 (e.e3);
183   j[0] = &h;
184   c.c1 = j;
185   e.e3.d1 = &c;
186   test (0, g, e, 0, 0);
187   __builtin_abort ();
188 }
189