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