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