[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / clang / test / CodeGen / object-size.c
blob58561a5470f72c133b9f4200e40ea7d7ebdff61e
1 // RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
2 // RUN: %clang_cc1 -no-enable-noundef-analysis -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
4 #ifndef DYNAMIC
5 #define OBJECT_SIZE_BUILTIN __builtin_object_size
6 #else
7 #define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
8 #endif
10 #define strcpy(dest, src) \
11 ((OBJECT_SIZE_BUILTIN(dest, 0) != -1ULL) \
12 ? __builtin___strcpy_chk (dest, src, OBJECT_SIZE_BUILTIN(dest, 1)) \
13 : __inline_strcpy_chk(dest, src))
15 static char *__inline_strcpy_chk (char *dest, const char *src) {
16 return __builtin___strcpy_chk(dest, src, OBJECT_SIZE_BUILTIN(dest, 1));
19 char gbuf[63];
20 char *gp;
21 int gi, gj;
23 // CHECK-LABEL: define{{.*}} void @test1
24 void test1(void) {
25 // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 4), ptr @.str, i64 59)
26 strcpy(&gbuf[4], "Hi there");
29 // CHECK-LABEL: define{{.*}} void @test2
30 void test2(void) {
31 // CHECK: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63)
32 strcpy(gbuf, "Hi there");
35 // CHECK-LABEL: define{{.*}} void @test3
36 void test3(void) {
37 // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 100), ptr @.str, i64 0)
38 strcpy(&gbuf[100], "Hi there");
41 // CHECK-LABEL: define{{.*}} void @test4
42 void test4(void) {
43 // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 -1), ptr @.str, i64 0)
44 strcpy((char*)(void*)&gbuf[-1], "Hi there");
47 // CHECK-LABEL: define{{.*}} void @test5
48 void test5(void) {
49 // CHECK: = load ptr, ptr @gp
50 // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
51 strcpy(gp, "Hi there");
54 // CHECK-LABEL: define{{.*}} void @test6
55 void test6(void) {
56 char buf[57];
58 // CHECK: = call ptr @__strcpy_chk(ptr %{{.*}}, ptr @.str, i64 53)
59 strcpy(&buf[4], "Hi there");
62 // CHECK-LABEL: define{{.*}} void @test7
63 void test7(void) {
64 int i;
65 // Ensure we only evaluate the side-effect once.
66 // CHECK: = add
67 // CHECK-NOT: = add
68 // CHECK: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63)
69 strcpy((++i, gbuf), "Hi there");
72 // CHECK-LABEL: define{{.*}} void @test8
73 void test8(void) {
74 char *buf[50];
75 // CHECK-NOT: __strcpy_chk
76 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)
77 strcpy(buf[++gi], "Hi there");
80 // CHECK-LABEL: define{{.*}} void @test9
81 void test9(void) {
82 // CHECK-NOT: __strcpy_chk
83 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)
84 strcpy((char *)((++gi) + gj), "Hi there");
87 // CHECK-LABEL: define{{.*}} void @test10
88 char **p;
89 void test10(void) {
90 // CHECK-NOT: __strcpy_chk
91 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)
92 strcpy(*(++p), "Hi there");
95 // CHECK-LABEL: define{{.*}} void @test11
96 void test11(void) {
97 // CHECK-NOT: __strcpy_chk
98 // CHECK: = call ptr @__inline_strcpy_chk(ptr @gbuf, ptr @.str)
99 strcpy(gp = gbuf, "Hi there");
102 // CHECK-LABEL: define{{.*}} void @test12
103 void test12(void) {
104 // CHECK-NOT: __strcpy_chk
105 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)
106 strcpy(++gp, "Hi there");
109 // CHECK-LABEL: define{{.*}} void @test13
110 void test13(void) {
111 // CHECK-NOT: __strcpy_chk
112 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)
113 strcpy(gp++, "Hi there");
116 // CHECK-LABEL: define{{.*}} void @test14
117 void test14(void) {
118 // CHECK-NOT: __strcpy_chk
119 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)
120 strcpy(--gp, "Hi there");
123 // CHECK-LABEL: define{{.*}} void @test15
124 void test15(void) {
125 // CHECK-NOT: __strcpy_chk
126 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{..*}}, ptr @.str)
127 strcpy(gp--, "Hi there");
130 // CHECK-LABEL: define{{.*}} void @test16
131 void test16(void) {
132 // CHECK-NOT: __strcpy_chk
133 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)
134 strcpy(gp += 1, "Hi there");
137 // CHECK-LABEL: @test17
138 void test17(void) {
139 // CHECK: store i32 -1
140 gi = OBJECT_SIZE_BUILTIN(gp++, 0);
141 // CHECK: store i32 -1
142 gi = OBJECT_SIZE_BUILTIN(gp++, 1);
143 // CHECK: store i32 0
144 gi = OBJECT_SIZE_BUILTIN(gp++, 2);
145 // CHECK: store i32 0
146 gi = OBJECT_SIZE_BUILTIN(gp++, 3);
149 // CHECK-LABEL: @test18
150 unsigned test18(int cond) {
151 int a[4], b[4];
152 // CHECK: phi ptr
153 // CHECK: call i64 @llvm.objectsize.i64
154 return OBJECT_SIZE_BUILTIN(cond ? a : b, 0);
157 // CHECK-LABEL: @test19
158 void test19(void) {
159 struct {
160 int a, b;
161 } foo;
163 // CHECK: store i32 8
164 gi = OBJECT_SIZE_BUILTIN(&foo.a, 0);
165 // CHECK: store i32 4
166 gi = OBJECT_SIZE_BUILTIN(&foo.a, 1);
167 // CHECK: store i32 8
168 gi = OBJECT_SIZE_BUILTIN(&foo.a, 2);
169 // CHECK: store i32 4
170 gi = OBJECT_SIZE_BUILTIN(&foo.a, 3);
172 // CHECK: store i32 4
173 gi = OBJECT_SIZE_BUILTIN(&foo.b, 0);
174 // CHECK: store i32 4
175 gi = OBJECT_SIZE_BUILTIN(&foo.b, 1);
176 // CHECK: store i32 4
177 gi = OBJECT_SIZE_BUILTIN(&foo.b, 2);
178 // CHECK: store i32 4
179 gi = OBJECT_SIZE_BUILTIN(&foo.b, 3);
182 // CHECK-LABEL: @test20
183 void test20(void) {
184 struct { int t[10]; } t[10];
186 // CHECK: store i32 380
187 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 0);
188 // CHECK: store i32 20
189 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 1);
190 // CHECK: store i32 380
191 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 2);
192 // CHECK: store i32 20
193 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 3);
196 // CHECK-LABEL: @test21
197 void test21(void) {
198 struct { int t; } t;
200 // CHECK: store i32 0
201 gi = OBJECT_SIZE_BUILTIN(&t + 1, 0);
202 // CHECK: store i32 0
203 gi = OBJECT_SIZE_BUILTIN(&t + 1, 1);
204 // CHECK: store i32 0
205 gi = OBJECT_SIZE_BUILTIN(&t + 1, 2);
206 // CHECK: store i32 0
207 gi = OBJECT_SIZE_BUILTIN(&t + 1, 3);
209 // CHECK: store i32 0
210 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 0);
211 // CHECK: store i32 0
212 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 1);
213 // CHECK: store i32 0
214 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 2);
215 // CHECK: store i32 0
216 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 3);
219 // CHECK-LABEL: @test22
220 void test22(void) {
221 struct { int t[10]; } t[10];
223 // CHECK: store i32 0
224 gi = OBJECT_SIZE_BUILTIN(&t[10], 0);
225 // CHECK: store i32 0
226 gi = OBJECT_SIZE_BUILTIN(&t[10], 1);
227 // CHECK: store i32 0
228 gi = OBJECT_SIZE_BUILTIN(&t[10], 2);
229 // CHECK: store i32 0
230 gi = OBJECT_SIZE_BUILTIN(&t[10], 3);
232 // CHECK: store i32 0
233 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 0);
234 // CHECK: store i32 0
235 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 1);
236 // CHECK: store i32 0
237 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 2);
238 // CHECK: store i32 0
239 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 3);
241 // CHECK: store i32 0
242 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 0);
243 // CHECK: store i32 0
244 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 1);
245 // CHECK: store i32 0
246 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 2);
247 // CHECK: store i32 0
248 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 3);
250 // CHECK: store i32 0
251 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0);
252 // CHECK: store i32 0
253 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1);
254 // CHECK: store i32 0
255 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2);
256 // CHECK: store i32 0
257 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3);
260 struct Test23Ty { int a; int t[10]; };
262 // CHECK-LABEL: @test23
263 void test23(struct Test23Ty *p) {
264 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
265 gi = OBJECT_SIZE_BUILTIN(p, 0);
266 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
267 gi = OBJECT_SIZE_BUILTIN(p, 1);
268 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
269 gi = OBJECT_SIZE_BUILTIN(p, 2);
270 // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
271 // data to correctly handle type=3
272 // CHECK: store i32 0
273 gi = OBJECT_SIZE_BUILTIN(p, 3);
275 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
276 gi = OBJECT_SIZE_BUILTIN(&p->a, 0);
277 // CHECK: store i32 4
278 gi = OBJECT_SIZE_BUILTIN(&p->a, 1);
279 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
280 gi = OBJECT_SIZE_BUILTIN(&p->a, 2);
281 // CHECK: store i32 4
282 gi = OBJECT_SIZE_BUILTIN(&p->a, 3);
284 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
285 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 0);
286 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
287 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 1);
288 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
289 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 2);
290 // CHECK: store i32 20
291 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 3);
294 // PR24493 -- ICE if OBJECT_SIZE_BUILTIN called with NULL and (Type & 1) != 0
295 // CHECK-LABEL: @test24
296 void test24(void) {
297 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
298 gi = OBJECT_SIZE_BUILTIN((void*)0, 0);
299 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
300 gi = OBJECT_SIZE_BUILTIN((void*)0, 1);
301 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
302 gi = OBJECT_SIZE_BUILTIN((void*)0, 2);
303 // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
304 // Hopefully will be lowered properly in the future.
305 // CHECK: store i32 0
306 gi = OBJECT_SIZE_BUILTIN((void*)0, 3);
309 // CHECK-LABEL: @test25
310 void test25(void) {
311 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
312 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 0);
313 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
314 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 1);
315 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
316 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 2);
317 // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
318 // Hopefully will be lowered properly in the future.
319 // CHECK: store i32 0
320 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 3);
322 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
323 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 0);
324 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
325 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 1);
326 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
327 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 2);
328 // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
329 // Hopefully will be lowered properly in the future.
330 // CHECK: store i32 0
331 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 3);
334 // CHECK-LABEL: @test26
335 void test26(void) {
336 struct { int v[10]; } t[10];
338 // CHECK: store i32 316
339 gi = OBJECT_SIZE_BUILTIN(&t[1].v[11], 0);
340 // CHECK: store i32 312
341 gi = OBJECT_SIZE_BUILTIN(&t[1].v[12], 1);
342 // CHECK: store i32 308
343 gi = OBJECT_SIZE_BUILTIN(&t[1].v[13], 2);
344 // CHECK: store i32 0
345 gi = OBJECT_SIZE_BUILTIN(&t[1].v[14], 3);
348 struct Test27IncompleteTy;
350 // CHECK-LABEL: @test27
351 void test27(struct Test27IncompleteTy *t) {
352 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
353 gi = OBJECT_SIZE_BUILTIN(t, 0);
354 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
355 gi = OBJECT_SIZE_BUILTIN(t, 1);
356 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
357 gi = OBJECT_SIZE_BUILTIN(t, 2);
358 // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
359 // data to correctly handle type=3
360 // CHECK: store i32 0
361 gi = OBJECT_SIZE_BUILTIN(t, 3);
363 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
364 gi = OBJECT_SIZE_BUILTIN(&test27, 0);
365 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1
366 gi = OBJECT_SIZE_BUILTIN(&test27, 1);
367 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1
368 gi = OBJECT_SIZE_BUILTIN(&test27, 2);
369 // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
370 // data to correctly handle type=3
371 // CHECK: store i32 0
372 gi = OBJECT_SIZE_BUILTIN(&test27, 3);
375 // The intent of this test is to ensure that OBJECT_SIZE_BUILTIN treats `&foo`
376 // and `(T*)&foo` identically, when used as the pointer argument.
377 // CHECK-LABEL: @test28
378 void test28(void) {
379 struct { int v[10]; } t[10];
381 #define addCasts(s) ((char*)((short*)(s)))
382 // CHECK: store i32 360
383 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 0);
384 // CHECK: store i32 360
385 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 1);
386 // CHECK: store i32 360
387 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 2);
388 // CHECK: store i32 360
389 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 3);
391 // CHECK: store i32 356
392 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 0);
393 // CHECK: store i32 36
394 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 1);
395 // CHECK: store i32 356
396 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 2);
397 // CHECK: store i32 36
398 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 3);
399 #undef addCasts
402 struct DynStructVar {
403 char fst[16];
404 char snd[];
407 struct DynStruct0 {
408 char fst[16];
409 char snd[0];
412 struct DynStruct1 {
413 char fst[16];
414 char snd[1];
417 struct StaticStruct {
418 char fst[16];
419 char snd[2];
422 // CHECK-LABEL: @test29
423 void test29(struct DynStructVar *dv, struct DynStruct0 *d0,
424 struct DynStruct1 *d1, struct StaticStruct *ss) {
425 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
426 gi = OBJECT_SIZE_BUILTIN(dv->snd, 0);
427 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
428 gi = OBJECT_SIZE_BUILTIN(dv->snd, 1);
429 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
430 gi = OBJECT_SIZE_BUILTIN(dv->snd, 2);
431 // CHECK: store i32 0
432 gi = OBJECT_SIZE_BUILTIN(dv->snd, 3);
434 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
435 gi = OBJECT_SIZE_BUILTIN(d0->snd, 0);
436 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
437 gi = OBJECT_SIZE_BUILTIN(d0->snd, 1);
438 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
439 gi = OBJECT_SIZE_BUILTIN(d0->snd, 2);
440 // CHECK: store i32 0
441 gi = OBJECT_SIZE_BUILTIN(d0->snd, 3);
443 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
444 gi = OBJECT_SIZE_BUILTIN(d1->snd, 0);
445 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
446 gi = OBJECT_SIZE_BUILTIN(d1->snd, 1);
447 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
448 gi = OBJECT_SIZE_BUILTIN(d1->snd, 2);
449 // CHECK: store i32 1
450 gi = OBJECT_SIZE_BUILTIN(d1->snd, 3);
452 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
453 gi = OBJECT_SIZE_BUILTIN(ss->snd, 0);
454 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
455 gi = OBJECT_SIZE_BUILTIN(ss->snd, 1);
456 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
457 gi = OBJECT_SIZE_BUILTIN(ss->snd, 2);
458 // CHECK: store i32 2
459 gi = OBJECT_SIZE_BUILTIN(ss->snd, 3);
462 // CHECK-LABEL: @test30
463 void test30(void) {
464 struct { struct DynStruct1 fst, snd; } *nested;
466 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
467 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 0);
468 // CHECK: store i32 1
469 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 1);
470 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
471 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 2);
472 // CHECK: store i32 1
473 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 3);
475 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
476 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 0);
477 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
478 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 1);
479 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
480 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 2);
481 // CHECK: store i32 1
482 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 3);
484 union { struct DynStruct1 d1; char c[1]; } *u;
485 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
486 gi = OBJECT_SIZE_BUILTIN(u->c, 0);
487 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
488 gi = OBJECT_SIZE_BUILTIN(u->c, 1);
489 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
490 gi = OBJECT_SIZE_BUILTIN(u->c, 2);
491 // CHECK: store i32 1
492 gi = OBJECT_SIZE_BUILTIN(u->c, 3);
494 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
495 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 0);
496 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
497 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 1);
498 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
499 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 2);
500 // CHECK: store i32 1
501 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 3);
504 // CHECK-LABEL: @test31
505 void test31(void) {
506 // Miscellaneous 'writing off the end' detection tests
507 struct DynStructVar *dsv;
508 struct DynStruct0 *ds0;
509 struct DynStruct1 *ds1;
510 struct StaticStruct *ss;
512 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
513 gi = OBJECT_SIZE_BUILTIN(ds1[9].snd, 1);
515 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
516 gi = OBJECT_SIZE_BUILTIN(&ss[9].snd[0], 1);
518 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
519 gi = OBJECT_SIZE_BUILTIN(&ds1[9].snd[0], 1);
521 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
522 gi = OBJECT_SIZE_BUILTIN(&ds0[9].snd[0], 1);
524 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
525 gi = OBJECT_SIZE_BUILTIN(&dsv[9].snd[0], 1);
528 // CHECK-LABEL: @test32
529 static struct DynStructVar D32 = {
530 .fst = {},
531 .snd = { 0, 1, 2, },
533 unsigned long test32(void) {
534 // CHECK: ret i64 19
535 return OBJECT_SIZE_BUILTIN(&D32, 1);
537 // CHECK-LABEL: @test33
538 static struct DynStructVar D33 = {
539 .fst = {},
540 .snd = {},
542 unsigned long test33(void) {
543 // CHECK: ret i64 16
544 return OBJECT_SIZE_BUILTIN(&D33, 1);
546 // CHECK-LABEL: @test34
547 static struct DynStructVar D34 = {
548 .fst = {},
550 unsigned long test34(void) {
551 // CHECK: ret i64 16
552 return OBJECT_SIZE_BUILTIN(&D34, 1);
554 // CHECK-LABEL: @test35
555 unsigned long test35(void) {
556 // CHECK: ret i64 16
557 return OBJECT_SIZE_BUILTIN(&(struct DynStructVar){}, 1);
559 extern void *memset (void *s, int c, unsigned long n);
560 void test36(void) {
561 struct DynStructVar D;
562 // FORTIFY will check the object size of D. Test this doesn't assert when
563 // given a struct with a flexible array member that lacks an initializer.
564 memset(&D, 0, sizeof(D));
566 // CHECK-LABEL: @test37
567 struct Z { struct A { int x, y[]; } z; int a; int b[]; };
568 static struct Z my_z = { .b = {1,2,3} };
569 unsigned long test37 (void) {
570 // CHECK: ret i64 4
571 return OBJECT_SIZE_BUILTIN(&my_z.z, 1);
574 // CHECK-LABEL: @PR30346
575 void PR30346(void) {
576 struct sa_family_t {};
577 struct sockaddr {
578 struct sa_family_t sa_family;
579 char sa_data[14];
582 struct sockaddr *sa;
583 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
584 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 0);
585 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1
586 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 1);
587 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1
588 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 2);
589 // CHECK: store i32 14
590 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 3);
593 extern char incomplete_char_array[];
594 // CHECK-LABEL: @incomplete_and_function_types
595 int incomplete_and_function_types(void) {
596 // CHECK: call i64 @llvm.objectsize.i64.p0
597 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 0);
598 // CHECK: call i64 @llvm.objectsize.i64.p0
599 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 1);
600 // CHECK: call i64 @llvm.objectsize.i64.p0
601 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 2);
602 // CHECK: store i32 0
603 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 3);
606 // Flips between the pointer and lvalue evaluator a lot.
607 void deeply_nested(void) {
608 struct {
609 struct {
610 struct {
611 struct {
612 int e[2];
613 char f; // Inhibit our writing-off-the-end check
614 } d[2];
615 } c[2];
616 } b[2];
617 } *a;
619 // CHECK: store i32 4
620 gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 1);
621 // CHECK: store i32 4
622 gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 3);