1/* { dg-do run } */
2/* { dg-options "-O2" } */
3
4typedef __SIZE_TYPE__ size_t;
5extern void abort (void);
6extern void exit (int);
7extern void *malloc (size_t);
8extern void *calloc (size_t, size_t);
9extern void *alloca (size_t);
10extern void *memcpy (void *, const void *, size_t);
11extern void *memset (void *, int, size_t);
12extern char *strcpy (char *, const char *);
13
14struct A
15{
16  char a[10];
17  int b;
18  char c[10];
19} y, w[4];
20
21extern char exta[];
22extern char extb[30];
23extern struct A zerol[0];
24
25void
26__attribute__ ((noinline))
27test1 (void *q, int x)
28{
29  struct A a;
30  void *p = &a.a[3], *r;
31  char var[x + 10];
32  if (x < 0)
33    r = &a.a[9];
34  else
35    r = &a.c[1];
36  if (__builtin_object_size (p, 2)
37      != sizeof (a) - __builtin_offsetof (struct A, a) - 3)
38    abort ();
39  if (__builtin_object_size (&a.c[9], 2)
40      != sizeof (a) - __builtin_offsetof (struct A, c) - 9)
41    abort ();
42  if (__builtin_object_size (q, 2) != 0)
43    abort ();
44  if (__builtin_object_size (r, 2)
45      != sizeof (a) - __builtin_offsetof (struct A, c) - 1)
46    abort ();
47  if (x < 6)
48    r = &w[2].a[1];
49  else
50    r = &a.a[6];
51  if (__builtin_object_size (&y, 2)
52      != sizeof (y))
53    abort ();
54  if (__builtin_object_size (w, 2)
55      != sizeof (w))
56    abort ();
57  if (__builtin_object_size (&y.b, 2)
58      != sizeof (a) - __builtin_offsetof (struct A, b))
59    abort ();
60  if (__builtin_object_size (r, 2)
61      != sizeof (a) - __builtin_offsetof (struct A, a) - 6)
62    abort ();
63  if (x < 20)
64    r = malloc (30);
65  else
66    r = calloc (2, 16);
67  if (__builtin_object_size (r, 2) != 30)
68    abort ();
69  if (x < 20)
70    r = malloc (30);
71  else
72    r = calloc (2, 14);
73  if (__builtin_object_size (r, 2) != 2 * 14)
74    abort ();
75  if (x < 30)
76    r = malloc (sizeof (a));
77  else
78    r = &a.a[3];
79  if (__builtin_object_size (r, 2)
80      != sizeof (a) - __builtin_offsetof (struct A, a) - 3)
81    abort ();
82  r = memcpy (r, "a", 2);
83  if (__builtin_object_size (r, 2)
84      != sizeof (a) - __builtin_offsetof (struct A, a) - 3)
85    abort ();
86  r = memcpy (r + 2, "b", 2) + 2;
87  if (__builtin_object_size (r, 2)
88      != sizeof (a) - __builtin_offsetof (struct A, a) - 3 - 4)
89    abort ();
90  r = &a.a[4];
91  r = memset (r, 'a', 2);
92  if (__builtin_object_size (r, 2)
93      != sizeof (a) - __builtin_offsetof (struct A, a) - 4)
94    abort ();
95  r = memset (r + 2, 'b', 2) + 2;
96  if (__builtin_object_size (r, 2)
97      != sizeof (a) - __builtin_offsetof (struct A, a) - 8)
98    abort ();
99  r = &a.a[1];
100  r = strcpy (r, "ab");
101  if (__builtin_object_size (r, 2)
102      != sizeof (a) - __builtin_offsetof (struct A, a) - 1)
103    abort ();
104  r = strcpy (r + 2, "cd") + 2;
105  if (__builtin_object_size (r, 2)
106      != sizeof (a) - __builtin_offsetof (struct A, a) - 5)
107    abort ();
108  if (__builtin_object_size (exta, 2) != 0)
109    abort ();
110  if (__builtin_object_size (exta + 10, 2) != 0)
111    abort ();
112  if (__builtin_object_size (&exta[5], 2) != 0)
113    abort ();
114  if (__builtin_object_size (extb, 2) != sizeof (extb))
115    abort ();
116  if (__builtin_object_size (extb + 10, 2) != sizeof (extb) - 10)
117    abort ();
118  if (__builtin_object_size (&extb[5], 2) != sizeof (extb) - 5)
119    abort ();
120  if (__builtin_object_size (var, 2) != 0)
121    abort ();
122  if (__builtin_object_size (var + 10, 2) != 0)
123    abort ();
124  if (__builtin_object_size (&var[5], 2) != 0)
125    abort ();
126  if (__builtin_object_size (zerol, 2) != 0)
127    abort ();
128  if (__builtin_object_size (&zerol, 2) != 0)
129    abort ();
130  if (__builtin_object_size (&zerol[0], 2) != 0)
131    abort ();
132  if (__builtin_object_size (zerol[0].a, 2) != 0)
133    abort ();
134  if (__builtin_object_size (&zerol[0].a[0], 2) != 0)
135    abort ();
136  if (__builtin_object_size (&zerol[0].b, 2) != 0)
137    abort ();
138  if (__builtin_object_size ("abcdefg", 2) != sizeof ("abcdefg"))
139    abort ();
140  if (__builtin_object_size ("abcd\0efg", 2) != sizeof ("abcd\0efg"))
141    abort ();
142  if (__builtin_object_size (&"abcd\0efg", 2) != sizeof ("abcd\0efg"))
143    abort ();
144  if (__builtin_object_size (&"abcd\0efg"[0], 2) != sizeof ("abcd\0efg"))
145    abort ();
146  if (__builtin_object_size (&"abcd\0efg"[4], 2) != sizeof ("abcd\0efg") - 4)
147    abort ();
148  if (__builtin_object_size ("abcd\0efg" + 5, 2) != sizeof ("abcd\0efg") - 5)
149    abort ();
150  if (__builtin_object_size (L"abcdefg", 2) != sizeof (L"abcdefg"))
151    abort ();
152  r = (char *) L"abcd\0efg";
153  if (__builtin_object_size (r + 2, 2) != sizeof (L"abcd\0efg") - 2)
154    abort ();
155}
156
157size_t l1 = 1;
158
159void
160__attribute__ ((noinline))
161test2 (void)
162{
163  struct B { char buf1[10]; char buf2[10]; } a;
164  char *r, buf3[20];
165  int i;
166
167  if (sizeof (a) != 20)
168    return;
169
170  r = buf3;
171  for (i = 0; i < 4; ++i)
172    {
173      if (i == l1 - 1)
174	r = &a.buf1[1];
175      else if (i == l1)
176	r = &a.buf2[7];
177      else if (i == l1 + 1)
178	r = &buf3[5];
179      else if (i == l1 + 2)
180	r = &a.buf1[9];
181    }
182  if (__builtin_object_size (r, 2) != 3)
183    abort ();
184  r = &buf3[20];
185  for (i = 0; i < 4; ++i)
186    {
187      if (i == l1 - 1)
188	r = &a.buf1[7];
189      else if (i == l1)
190	r = &a.buf2[7];
191      else if (i == l1 + 1)
192	r = &buf3[5];
193      else if (i == l1 + 2)
194	r = &a.buf1[9];
195    }
196  if (__builtin_object_size (r, 2) != 0)
197    abort ();
198  r = &buf3[2];
199  for (i = 0; i < 4; ++i)
200    {
201      if (i == l1 - 1)
202	r = &a.buf1[1];
203      else if (i == l1)
204	r = &a.buf1[2];
205      else if (i == l1 + 1)
206	r = &buf3[5];
207      else if (i == l1 + 2)
208	r = &a.buf1[4];
209    }
210  if (__builtin_object_size (r, 2) != 15)
211    abort ();
212  r += 8;
213  if (__builtin_object_size (r, 2) != 7)
214    abort ();
215  if (__builtin_object_size (r + 6, 2) != 1)
216    abort ();
217  r = &buf3[18];
218  for (i = 0; i < 4; ++i)
219    {
220      if (i == l1 - 1)
221	r = &a.buf1[9];
222      else if (i == l1)
223	r = &a.buf2[9];
224      else if (i == l1 + 1)
225	r = &buf3[5];
226      else if (i == l1 + 2)
227	r = &a.buf1[4];
228    }
229  if (__builtin_object_size (r + 12, 2) != 0)
230    abort ();
231}
232
233void
234__attribute__ ((noinline))
235test3 (void)
236{
237  char buf4[10];
238  struct B { struct A a[2]; struct A b; char c[4]; char d; double e;
239	     _Complex double f; } x;
240  double y;
241  _Complex double z;
242  double *dp;
243
244  if (__builtin_object_size (buf4, 2) != sizeof (buf4))
245    abort ();
246  if (__builtin_object_size (&buf4, 2) != sizeof (buf4))
247    abort ();
248  if (__builtin_object_size (&buf4[0], 2) != sizeof (buf4))
249    abort ();
250  if (__builtin_object_size (&buf4[1], 2) != sizeof (buf4) - 1)
251    abort ();
252  if (__builtin_object_size (&x, 2) != sizeof (x))
253    abort ();
254  if (__builtin_object_size (&x.a, 2) != sizeof (x))
255    abort ();
256  if (__builtin_object_size (&x.a[0], 2) != sizeof (x))
257    abort ();
258  if (__builtin_object_size (&x.a[0].a, 2) != sizeof (x))
259    abort ();
260  if (__builtin_object_size (&x.a[0].a[0], 2) != sizeof (x))
261    abort ();
262  if (__builtin_object_size (&x.a[0].a[3], 2) != sizeof (x) - 3)
263    abort ();
264  if (__builtin_object_size (&x.a[0].b, 2)
265      != sizeof (x) - __builtin_offsetof (struct A, b))
266    abort ();
267  if (__builtin_object_size (&x.a[1].c, 2)
268      != sizeof (x) - sizeof (struct A) - __builtin_offsetof (struct A, c))
269    abort ();
270  if (__builtin_object_size (&x.a[1].c[0], 2)
271      != sizeof (x) - sizeof (struct A) - __builtin_offsetof (struct A, c))
272    abort ();
273  if (__builtin_object_size (&x.a[1].c[3], 2)
274      != sizeof (x) - sizeof (struct A) - __builtin_offsetof (struct A, c) - 3)
275    abort ();
276  if (__builtin_object_size (&x.b, 2)
277      != sizeof (x) - __builtin_offsetof (struct B, b))
278    abort ();
279  if (__builtin_object_size (&x.b.a, 2)
280      != sizeof (x) - __builtin_offsetof (struct B, b))
281    abort ();
282  if (__builtin_object_size (&x.b.a[0], 2)
283      != sizeof (x) - __builtin_offsetof (struct B, b))
284    abort ();
285  if (__builtin_object_size (&x.b.a[3], 2)
286      != sizeof (x) - __builtin_offsetof (struct B, b) - 3)
287    abort ();
288  if (__builtin_object_size (&x.b.b, 2)
289      != sizeof (x) - __builtin_offsetof (struct B, b)
290	 - __builtin_offsetof (struct A, b))
291    abort ();
292  if (__builtin_object_size (&x.b.c, 2)
293      != sizeof (x) - __builtin_offsetof (struct B, b)
294	 - __builtin_offsetof (struct A, c))
295    abort ();
296  if (__builtin_object_size (&x.b.c[0], 2)
297      != sizeof (x) - __builtin_offsetof (struct B, b)
298	 - __builtin_offsetof (struct A, c))
299    abort ();
300  if (__builtin_object_size (&x.b.c[3], 2)
301      != sizeof (x) - __builtin_offsetof (struct B, b)
302	 - __builtin_offsetof (struct A, c) - 3)
303    abort ();
304  if (__builtin_object_size (&x.c, 2)
305      != sizeof (x) - __builtin_offsetof (struct B, c))
306    abort ();
307  if (__builtin_object_size (&x.c[0], 2)
308      != sizeof (x) - __builtin_offsetof (struct B, c))
309    abort ();
310  if (__builtin_object_size (&x.c[1], 2)
311      != sizeof (x) - __builtin_offsetof (struct B, c) - 1)
312    abort ();
313  if (__builtin_object_size (&x.d, 2)
314      != sizeof (x) - __builtin_offsetof (struct B, d))
315    abort ();
316  if (__builtin_object_size (&x.e, 2)
317      != sizeof (x) - __builtin_offsetof (struct B, e))
318    abort ();
319  if (__builtin_object_size (&x.f, 2)
320      != sizeof (x) - __builtin_offsetof (struct B, f))
321    abort ();
322  dp = &__real__ x.f;
323  if (__builtin_object_size (dp, 2)
324      != sizeof (x) - __builtin_offsetof (struct B, f))
325    abort ();
326  dp = &__imag__ x.f;
327  if (__builtin_object_size (dp, 2)
328      != sizeof (x) - __builtin_offsetof (struct B, f)
329	 - sizeof (x.f) / 2)
330    abort ();
331  dp = &y;
332  if (__builtin_object_size (dp, 2) != sizeof (y))
333    abort ();
334  if (__builtin_object_size (&z, 2) != sizeof (z))
335    abort ();
336  dp = &__real__ z;
337  if (__builtin_object_size (dp, 2) != sizeof (z))
338    abort ();
339  dp = &__imag__ z;
340  if (__builtin_object_size (dp, 2) != sizeof (z) / 2)
341    abort ();
342}
343
344struct S { unsigned int a; };
345
346char *
347__attribute__ ((noinline))
348test4 (char *x, int y)
349{
350  register int i;
351  struct A *p;
352
353  for (i = 0; i < y; i++)
354    {
355      p = (struct A *) x;
356      x = (char *) &p[1];
357      if (__builtin_object_size (p, 2) != 0)
358	abort ();
359    }
360  return x;
361}
362
363void
364__attribute__ ((noinline))
365test5 (size_t x)
366{
367  char buf[64];
368  char *p = &buf[8];
369  size_t i;
370
371  for (i = 0; i < x; ++i)
372    p = p + 4;
373  if (__builtin_object_size (p, 2) != 0)
374    abort ();
375  memset (p, ' ', sizeof (buf) - 8 - 4 * 4);
376}
377
378void
379__attribute__ ((noinline))
380test6 (size_t x)
381{
382  struct T { char buf[64]; char buf2[64]; } t;
383  char *p = &t.buf[8];
384  size_t i;
385
386  for (i = 0; i < x; ++i)
387    p = p + 4;
388  if (__builtin_object_size (p, 2) != 0)
389    abort ();
390  memset (p, ' ', sizeof (t) - 8 - 4 * 4);
391}
392
393void
394__attribute__ ((noinline))
395test7 (void)
396{
397  char buf[64];
398  struct T { char buf[64]; char buf2[64]; } t;
399  char *p = &buf[64], *q = &t.buf[64];
400
401  if (__builtin_object_size (p + 64, 2) != 0)
402    abort ();
403  if (__builtin_object_size (q + 63, 2) != sizeof (t) - 64 - 63)
404    abort ();
405  if (__builtin_object_size (q + 64, 2) != sizeof (t) - 64 - 64)
406    abort ();
407  if (__builtin_object_size (q + 256, 2) != 0)
408    abort ();
409}
410
411void
412__attribute__ ((noinline))
413test8 (void)
414{
415  struct T { char buf[10]; char buf2[10]; } t;
416  char *p = &t.buf2[-4];
417  char *q = &t.buf2[0];
418  if (__builtin_object_size (p, 2) != sizeof (t) - 10 + 4)
419    abort ();
420  if (__builtin_object_size (q, 2) != sizeof (t) - 10)
421    abort ();
422  /* GCC only handles additions, not subtractions.  */
423  q = q - 8;
424  if (__builtin_object_size (q, 2) != 0
425      && __builtin_object_size (q, 2) != sizeof (t) - 10 + 8)
426    abort ();
427  p = &t.buf[-4];
428  if (__builtin_object_size (p, 2) != 0)
429    abort ();
430}
431
432int
433main (void)
434{
435  struct S s[10];
436  __asm ("" : "=r" (l1) : "0" (l1));
437  test1 (main, 6);
438  test2 ();
439  test3 ();
440  test4 ((char *) s, 10);
441  test5 (4);
442  test6 (4);
443  test7 ();
444  test8 ();
445  exit (0);
446}
447