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
5 #define OBJECT_SIZE_BUILTIN __builtin_object_size
7 #define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
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));
23 // CHECK-LABEL: define{{.*}} void @test1
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
31 // CHECK: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63)
32 strcpy(gbuf
, "Hi there");
35 // CHECK-LABEL: define{{.*}} void @test3
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
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
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
58 // CHECK: = call ptr @__strcpy_chk(ptr %{{.*}}, ptr @.str, i64 53)
59 strcpy(&buf
[4], "Hi there");
62 // CHECK-LABEL: define{{.*}} void @test7
65 // Ensure we only evaluate the side-effect once.
68 // CHECK: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63)
69 strcpy((++i
, gbuf
), "Hi there");
72 // CHECK-LABEL: define{{.*}} void @test8
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
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
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
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
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
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
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
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
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
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
) {
153 // CHECK: call i64 @llvm.objectsize.i64
154 return OBJECT_SIZE_BUILTIN(cond
? a
: b
, 0);
157 // CHECK-LABEL: @test19
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
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
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
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
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
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
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
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);
402 struct DynStructVar
{
417 struct StaticStruct
{
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
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
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
= {
533 unsigned long test32(void) {
535 return OBJECT_SIZE_BUILTIN(&D32
, 1);
537 // CHECK-LABEL: @test33
538 static struct DynStructVar D33
= {
542 unsigned long test33(void) {
544 return OBJECT_SIZE_BUILTIN(&D33
, 1);
546 // CHECK-LABEL: @test34
547 static struct DynStructVar D34
= {
550 unsigned long test34(void) {
552 return OBJECT_SIZE_BUILTIN(&D34
, 1);
554 // CHECK-LABEL: @test35
555 unsigned long test35(void) {
557 return OBJECT_SIZE_BUILTIN(&(struct DynStructVar
){}, 1);
559 extern void *memset (void *s
, int c
, unsigned long n
);
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) {
571 return OBJECT_SIZE_BUILTIN(&my_z
.z
, 1);
574 // CHECK-LABEL: @PR30346
576 struct sa_family_t
{};
578 struct sa_family_t sa_family
;
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) {
613 char f
; // Inhibit our writing-off-the-end check
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);