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