1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 | FileCheck %s
2
3 typedef unsigned long size_t;
4
5 struct Foo {
6 int t[10];
7 };
8
9 #define PS(N) __attribute__((pass_object_size(N)))
10 #define PDS(N) __attribute__((pass_dynamic_object_size(N)))
11
12 int gi = 0;
13
14 // CHECK-LABEL: define{{.*}} i32 @ObjectSize0(ptr noundef %{{.*}}, i64 noundef %0)
15 int ObjectSize0(void *const p PS(0)) {
16 // CHECK-NOT: @llvm.objectsize
17 return __builtin_object_size(p, 0);
18 }
19
20 // CHECK-LABEL: define{{.*}} i32 @DynamicObjectSize0(ptr noundef %{{.*}}, i64 noundef %0)
21 int DynamicObjectSize0(void *const p PDS(0)) {
22 // CHECK-NOT: @llvm.objectsize
23 return __builtin_dynamic_object_size(p, 0);
24 }
25
26 // CHECK-LABEL: define{{.*}} i32 @ObjectSize1(ptr noundef %{{.*}}, i64 noundef %0)
27 int ObjectSize1(void *const p PS(1)) {
28 // CHECK-NOT: @llvm.objectsize
29 return __builtin_object_size(p, 1);
30 }
31
32 // CHECK-LABEL: define{{.*}} i32 @DynamicObjectSize1(ptr noundef %{{.*}}, i64 noundef %0)
33 int DynamicObjectSize1(void *const p PDS(1)) {
34 // CHECK-NOT: @llvm.objectsize
35 return __builtin_dynamic_object_size(p, 1);
36 }
37
38 // CHECK-LABEL: define{{.*}} i32 @ObjectSize2(ptr noundef %{{.*}}, i64 noundef %0)
39 int ObjectSize2(void *const p PS(2)) {
40 // CHECK-NOT: @llvm.objectsize
41 return __builtin_object_size(p, 2);
42 }
43
44 // CHECK-LABEL: define{{.*}} i32 @DynamicObjectSize2(ptr noundef %{{.*}}, i64 noundef %0)
45 int DynamicObjectSize2(void *const p PDS(2)) {
46 // CHECK-NOT: @llvm.objectsize
47 return __builtin_object_size(p, 2);
48 }
49
50 // CHECK-LABEL: define{{.*}} i32 @ObjectSize3(ptr noundef %{{.*}}, i64 noundef %0)
51 int ObjectSize3(void *const p PS(3)) {
52 // CHECK-NOT: @llvm.objectsize
53 return __builtin_object_size(p, 3);
54 }
55
56 // CHECK-LABEL: define{{.*}} i32 @DynamicObjectSize3(ptr noundef %{{.*}}, i64 noundef %0)
57 int DynamicObjectSize3(void *const p PDS(3)) {
58 // CHECK-NOT: @llvm.objectsize
59 return __builtin_object_size(p, 3);
60 }
61
62 void *malloc(unsigned long) __attribute__((alloc_size(1)));
63
64 // CHECK-LABEL: define{{.*}} void @test1
test1(unsigned long sz)65 void test1(unsigned long sz) {
66 struct Foo t[10];
67
68 // CHECK: call i32 @ObjectSize0(ptr noundef %{{.*}}, i64 noundef 360)
69 gi = ObjectSize0(&t[1]);
70 // CHECK: call i32 @ObjectSize1(ptr noundef %{{.*}}, i64 noundef 360)
71 gi = ObjectSize1(&t[1]);
72 // CHECK: call i32 @ObjectSize2(ptr noundef %{{.*}}, i64 noundef 360)
73 gi = ObjectSize2(&t[1]);
74 // CHECK: call i32 @ObjectSize3(ptr noundef %{{.*}}, i64 noundef 360)
75 gi = ObjectSize3(&t[1]);
76
77 // CHECK: call i32 @ObjectSize0(ptr noundef %{{.*}}, i64 noundef 356)
78 gi = ObjectSize0(&t[1].t[1]);
79 // CHECK: call i32 @ObjectSize1(ptr noundef %{{.*}}, i64 noundef 36)
80 gi = ObjectSize1(&t[1].t[1]);
81 // CHECK: call i32 @ObjectSize2(ptr noundef %{{.*}}, i64 noundef 356)
82 gi = ObjectSize2(&t[1].t[1]);
83 // CHECK: call i32 @ObjectSize3(ptr noundef %{{.*}}, i64 noundef 36)
84 gi = ObjectSize3(&t[1].t[1]);
85
86 char *ptr = (char *)malloc(sz);
87
88 // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 false, i1 true, i1 true)
89 // CHECK: call i32 @DynamicObjectSize0(ptr noundef %{{.*}}, i64 noundef [[REG]])
90 gi = DynamicObjectSize0(ptr);
91
92 // CHECK: [[WITH_OFFSET:%.*]] = getelementptr
93 // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[WITH_OFFSET]], i1 false, i1 true, i1 true)
94 // CHECK: call i32 @DynamicObjectSize0(ptr noundef {{.*}}, i64 noundef [[REG]])
95 gi = DynamicObjectSize0(ptr+10);
96
97 // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 true, i1 true, i1 true)
98 // CHECK: call i32 @DynamicObjectSize2(ptr noundef {{.*}}, i64 noundef [[REG]])
99 gi = DynamicObjectSize2(ptr);
100 }
101
102 // CHECK-LABEL: define{{.*}} void @test2
test2(struct Foo * t)103 void test2(struct Foo *t) {
104 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize
105 // CHECK: call i32 @ObjectSize1(ptr noundef %{{.*}}, i64 noundef [[VAR]])
106 gi = ObjectSize1(&t->t[1]);
107 // CHECK: call i32 @ObjectSize3(ptr noundef %{{.*}}, i64 noundef 36)
108 gi = ObjectSize3(&t->t[1]);
109 }
110
111 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize0Pv
NoViableOverloadObjectSize0(void * const p)112 int NoViableOverloadObjectSize0(void *const p) __attribute__((overloadable)) {
113 // CHECK: @llvm.objectsize
114 return __builtin_object_size(p, 0);
115 }
116
117 // CHECK-LABEL: define{{.*}} i32 @_Z34NoViableOverloadDynamicObjectSize0Pv
NoViableOverloadDynamicObjectSize0(void * const p)118 int NoViableOverloadDynamicObjectSize0(void *const p)
119 __attribute__((overloadable)) {
120 // CHECK: @llvm.objectsize
121 return __builtin_object_size(p, 0);
122 }
123
124 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize1Pv
NoViableOverloadObjectSize1(void * const p)125 int NoViableOverloadObjectSize1(void *const p) __attribute__((overloadable)) {
126 // CHECK: @llvm.objectsize
127 return __builtin_object_size(p, 1);
128 }
129
130 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize2Pv
NoViableOverloadObjectSize2(void * const p)131 int NoViableOverloadObjectSize2(void *const p) __attribute__((overloadable)) {
132 // CHECK: @llvm.objectsize
133 return __builtin_object_size(p, 2);
134 }
135
136 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize3Pv
NoViableOverloadObjectSize3(void * const p)137 int NoViableOverloadObjectSize3(void *const p) __attribute__((overloadable)) {
138 // CHECK-NOT: @llvm.objectsize
139 return __builtin_object_size(p, 3);
140 }
141
142 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize0Pv
143 // CHECK-NOT: @llvm.objectsize
144 int NoViableOverloadObjectSize0(void *const p PS(0))
145 __attribute__((overloadable)) {
146 return __builtin_object_size(p, 0);
147 }
148
149 int NoViableOverloadDynamicObjectSize0(void *const p PDS(0))
150 __attribute__((overloadable)) {
151 return __builtin_dynamic_object_size(p, 0);
152 }
153
154 int NoViableOverloadObjectSize1(void *const p PS(1))
155 __attribute__((overloadable)) {
156 return __builtin_object_size(p, 1);
157 }
158
159 int NoViableOverloadObjectSize2(void *const p PS(2))
160 __attribute__((overloadable)) {
161 return __builtin_object_size(p, 2);
162 }
163
164 int NoViableOverloadObjectSize3(void *const p PS(3))
165 __attribute__((overloadable)) {
166 return __builtin_object_size(p, 3);
167 }
168
169 const static int SHOULDNT_BE_CALLED = -100;
170 int NoViableOverloadObjectSize0(void *const p PS(0))
171 __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
172 return SHOULDNT_BE_CALLED;
173 }
174
175 int NoViableOverloadObjectSize1(void *const p PS(1))
176 __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
177 return SHOULDNT_BE_CALLED;
178 }
179
180 int NoViableOverloadObjectSize2(void *const p PS(2))
181 __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
182 return SHOULDNT_BE_CALLED;
183 }
184
185 int NoViableOverloadObjectSize3(void *const p PS(3))
186 __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
187 return SHOULDNT_BE_CALLED;
188 }
189
190 // CHECK-LABEL: define{{.*}} void @test3
test3(void)191 void test3(void) {
192 struct Foo t[10];
193
194 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(ptr noundef %{{.*}}, i64 noundef 360)
195 gi = NoViableOverloadObjectSize0(&t[1]);
196 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(ptr noundef %{{.*}}, i64 noundef 360)
197 gi = NoViableOverloadObjectSize1(&t[1]);
198 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(ptr noundef %{{.*}}, i64 noundef 360)
199 gi = NoViableOverloadObjectSize2(&t[1]);
200 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(ptr noundef %{{.*}}, i64 noundef 360)
201 gi = NoViableOverloadObjectSize3(&t[1]);
202
203 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(ptr noundef %{{.*}}, i64 noundef 356)
204 gi = NoViableOverloadObjectSize0(&t[1].t[1]);
205 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(ptr noundef %{{.*}}, i64 noundef 36)
206 gi = NoViableOverloadObjectSize1(&t[1].t[1]);
207 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(ptr noundef %{{.*}}, i64 noundef 356)
208 gi = NoViableOverloadObjectSize2(&t[1].t[1]);
209 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(ptr noundef %{{.*}}, i64 noundef 36)
210 gi = NoViableOverloadObjectSize3(&t[1].t[1]);
211
212 // CHECK: call i32 @_Z34NoViableOverloadDynamicObjectSize0PvU25pass_dynamic_object_size0(ptr noundef %{{.*}}, i64 noundef 360)
213 gi = NoViableOverloadDynamicObjectSize0(&t[1]);
214 }
215
216 // CHECK-LABEL: define{{.*}} void @test4
test4(struct Foo * t)217 void test4(struct Foo *t) {
218 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(ptr noundef %{{.*}}, i64 noundef %{{.*}})
219 gi = NoViableOverloadObjectSize0(&t[1]);
220 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(ptr noundef %{{.*}}, i64 noundef %{{.*}})
221 gi = NoViableOverloadObjectSize1(&t[1]);
222 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(ptr noundef %{{.*}}, i64 noundef %{{.*}})
223 gi = NoViableOverloadObjectSize2(&t[1]);
224 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(ptr noundef %{{.*}}, i64 noundef 0)
225 gi = NoViableOverloadObjectSize3(&t[1]);
226
227 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(ptr noundef %{{.*}}, i64 noundef %{{.*}})
228 gi = NoViableOverloadObjectSize0(&t[1].t[1]);
229 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize
230 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(ptr noundef %{{.*}}, i64 noundef [[VAR]])
231 gi = NoViableOverloadObjectSize1(&t[1].t[1]);
232 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(ptr noundef %{{.*}}, i64 noundef %{{.*}})
233 gi = NoViableOverloadObjectSize2(&t[1].t[1]);
234 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(ptr noundef %{{.*}}, i64 noundef 36)
235 gi = NoViableOverloadObjectSize3(&t[1].t[1]);
236 }
237
test5(void)238 void test5(void) {
239 struct Foo t[10];
240
241 int (*f)(void *) = &NoViableOverloadObjectSize0;
242 gi = f(&t[1]);
243
244 int (*g)(void *) = &NoViableOverloadDynamicObjectSize0;
245 gi = g(&t[1]);
246 }
247
248 // CHECK-LABEL: define{{.*}} i32 @IndirectObjectSize0
249 int IndirectObjectSize0(void *const p PS(0)) {
250 // CHECK: call i32 @ObjectSize0(ptr noundef %{{.*}}, i64 noundef %{{.*}})
251 // CHECK-NOT: @llvm.objectsize
252 return ObjectSize0(p);
253 }
254
255 // CHECK-LABEL: define{{.*}} i32 @IndirectObjectSize1
256 int IndirectObjectSize1(void *const p PS(1)) {
257 // CHECK: call i32 @ObjectSize1(ptr noundef %{{.*}}, i64 noundef %{{.*}})
258 // CHECK-NOT: @llvm.objectsize
259 return ObjectSize1(p);
260 }
261
262 // CHECK-LABEL: define{{.*}} i32 @IndirectObjectSize2
263 int IndirectObjectSize2(void *const p PS(2)) {
264 // CHECK: call i32 @ObjectSize2(ptr noundef %{{.*}}, i64 noundef %{{.*}})
265 // CHECK-NOT: @llvm.objectsize
266 return ObjectSize2(p);
267 }
268
269 // CHECK-LABEL: define{{.*}} i32 @IndirectObjectSize3
270 int IndirectObjectSize3(void *const p PS(3)) {
271 // CHECK: call i32 @ObjectSize3(ptr noundef %{{.*}}, i64 noundef %{{.*}})
272 // CHECK-NOT: @llvm.objectsize
273 return ObjectSize3(p);
274 }
275
276 int IndirectDynamicObjectSize0(void *const p PDS(0)) {
277 // CHECK: call i32 @ObjectSize0(ptr noundef %{{.*}}, i64 noundef %{{.*}})
278 // CHECK-NOT: @llvm.objectsize
279 return ObjectSize0(p);
280 }
281
282 int Overload0(void *, size_t, void *, size_t);
283 int OverloadNoSize(void *, void *);
284
285 int OverloadedObjectSize(void *const p PS(0),
286 void *const c PS(0))
287 __attribute__((overloadable)) __asm__("Overload0");
288
289 int OverloadedObjectSize(void *const p, void *const c)
290 __attribute__((overloadable)) __asm__("OverloadNoSize");
291
292 // CHECK-LABEL: define{{.*}} void @test6
test6(void)293 void test6(void) {
294 int known[10], *opaque;
295
296 // CHECK: call i32 @"\01Overload0"
297 gi = OverloadedObjectSize(&known[0], &known[0]);
298
299 // CHECK: call i32 @"\01Overload0"
300 gi = OverloadedObjectSize(&known[0], opaque);
301
302 // CHECK: call i32 @"\01Overload0"
303 gi = OverloadedObjectSize(opaque, &known[0]);
304
305 // CHECK: call i32 @"\01Overload0"
306 gi = OverloadedObjectSize(opaque, opaque);
307 }
308
Identity(void * p,size_t i)309 int Identity(void *p, size_t i) { return i; }
310
311 // CHECK-NOT: define{{.*}} void @AsmObjectSize
312 int AsmObjectSize0(void *const p PS(0)) __asm__("Identity");
313
314 int AsmObjectSize1(void *const p PS(1)) __asm__("Identity");
315
316 int AsmObjectSize2(void *const p PS(2)) __asm__("Identity");
317
318 int AsmObjectSize3(void *const p PS(3)) __asm__("Identity");
319
320 // CHECK-LABEL: define{{.*}} void @test7
test7(void)321 void test7(void) {
322 struct Foo t[10];
323
324 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 360)
325 gi = AsmObjectSize0(&t[1]);
326 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 360)
327 gi = AsmObjectSize1(&t[1]);
328 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 360)
329 gi = AsmObjectSize2(&t[1]);
330 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 360)
331 gi = AsmObjectSize3(&t[1]);
332
333 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 356)
334 gi = AsmObjectSize0(&t[1].t[1]);
335 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 36)
336 gi = AsmObjectSize1(&t[1].t[1]);
337 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 356)
338 gi = AsmObjectSize2(&t[1].t[1]);
339 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 36)
340 gi = AsmObjectSize3(&t[1].t[1]);
341 }
342
343 // CHECK-LABEL: define{{.*}} void @test8
test8(struct Foo * t)344 void test8(struct Foo *t) {
345 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize
346 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef [[VAR]])
347 gi = AsmObjectSize1(&t[1].t[1]);
348 // CHECK: call i32 @"\01Identity"(ptr noundef %{{.*}}, i64 noundef 36)
349 gi = AsmObjectSize3(&t[1].t[1]);
350 }
351
352 void DifferingObjectSize0(void *const p __attribute__((pass_object_size(0))));
353 void DifferingObjectSize1(void *const p __attribute__((pass_object_size(1))));
354 void DifferingObjectSize2(void *const p __attribute__((pass_object_size(2))));
355 void DifferingObjectSize3(void *const p __attribute__((pass_object_size(3))));
356
357 // CHECK-LABEL: define{{.*}} void @test9
test9(void * const p)358 void test9(void *const p __attribute__((pass_object_size(0)))) {
359 // CHECK: @llvm.objectsize
360 DifferingObjectSize2(p);
361
362 // CHECK-NOT: @llvm.objectsize
363 DifferingObjectSize0(p);
364 DifferingObjectSize1(p);
365
366 // CHECK: call void @DifferingObjectSize3(ptr noundef %{{.*}}, i64 noundef 0)
367 DifferingObjectSize3(p);
368 }
369
370 // CHECK-LABEL: define{{.*}} void @test10
test10(void * const p)371 void test10(void *const p __attribute__((pass_object_size(1)))) {
372 // CHECK: @llvm.objectsize
373 DifferingObjectSize2(p);
374 // CHECK: @llvm.objectsize
375 DifferingObjectSize0(p);
376
377 // CHECK-NOT: @llvm.objectsize
378 DifferingObjectSize1(p);
379
380 // CHECK: call void @DifferingObjectSize3(ptr noundef %{{.*}}, i64 noundef 0)
381 DifferingObjectSize3(p);
382 }
383
384 // CHECK-LABEL: define{{.*}} void @test11
test11(void * const p)385 void test11(void *const p __attribute__((pass_object_size(2)))) {
386 // CHECK: @llvm.objectsize
387 DifferingObjectSize0(p);
388 // CHECK: @llvm.objectsize
389 DifferingObjectSize1(p);
390
391 // CHECK-NOT: @llvm.objectsize
392 DifferingObjectSize2(p);
393
394 // CHECK: call void @DifferingObjectSize3(ptr noundef %{{.*}}, i64 noundef 0)
395 DifferingObjectSize3(p);
396 }
397
398 // CHECK-LABEL: define{{.*}} void @test12
test12(void * const p)399 void test12(void *const p __attribute__((pass_object_size(3)))) {
400 // CHECK: @llvm.objectsize
401 DifferingObjectSize0(p);
402 // CHECK: @llvm.objectsize
403 DifferingObjectSize1(p);
404
405 // CHECK-NOT: @llvm.objectsize
406 DifferingObjectSize2(p);
407 DifferingObjectSize3(p);
408 }
409
410 // CHECK-LABEL: define{{.*}} void @test13
test13(void)411 void test13(void) {
412 char c[10];
413 unsigned i = 0;
414 char *p = c;
415
416 // CHECK: @llvm.objectsize
417 ObjectSize0(p);
418
419 // Allow side-effects, since they always need to happen anyway. Just make sure
420 // we don't perform them twice.
421 // CHECK: = add
422 // CHECK-NOT: = add
423 // CHECK: @llvm.objectsize
424 // CHECK: call i32 @ObjectSize0
425 ObjectSize0(p + ++i);
426
427 // CHECK: = add
428 // CHECK: @llvm.objectsize
429 // CHECK-NOT: = add
430 // CHECK: call i32 @ObjectSize0
431 ObjectSize0(p + i++);
432 }
433
434 // There was a bug where variadic functions with pass_object_size would cause
435 // problems in the form of failed assertions.
my_sprintf(char * const c,...)436 void my_sprintf(char *const c __attribute__((pass_object_size(0))), ...) {}
437
438 // CHECK-LABEL: define{{.*}} void @test14
test14(char * c)439 void test14(char *c) {
440 // CHECK: @llvm.objectsize
441 // CHECK: call void (ptr, i64, ...) @my_sprintf
442 my_sprintf(c);
443
444 // CHECK: @llvm.objectsize
445 // CHECK: call void (ptr, i64, ...) @my_sprintf
446 my_sprintf(c, 1, 2, 3);
447 }
448
449 void pass_size_unsigned(unsigned *const PS(0));
450
451 // Bug: we weren't lowering to the proper @llvm.objectsize for pointers that
452 // don't turn into ptr s, which caused crashes.
453 // CHECK-LABEL: define{{.*}} void @test15
test15(unsigned * I)454 void test15(unsigned *I) {
455 // CHECK: @llvm.objectsize.i64.p0
456 // CHECK: call void @pass_size_unsigned
457 pass_size_unsigned(I);
458 }
459
460 void pass_size_as1(__attribute__((address_space(1))) void *const PS(0));
461
462 void pass_size_unsigned_as1(
463 __attribute__((address_space(1))) unsigned *const PS(0));
464
465 // CHECK-LABEL: define{{.*}} void @test16
test16(unsigned * I)466 void test16(__attribute__((address_space(1))) unsigned *I) {
467 // CHECK: call i64 @llvm.objectsize.i64.p1
468 // CHECK: call void @pass_size_as1
469 pass_size_as1(I);
470 // CHECK: call i64 @llvm.objectsize.i64.p1
471 // CHECK: call void @pass_size_unsigned_as1
472 pass_size_unsigned_as1(I);
473 }
474
475 // This used to cause assertion failures, since we'd try to emit the statement
476 // expression (and definitions for `a`) twice.
477 // CHECK-LABEL: define{{.*}} void @test17
test17(char * C)478 void test17(char *C) {
479 // Check for 65535 to see if we're emitting this pointer twice.
480 // CHECK: 65535
481 // CHECK-NOT: 65535
482 // CHECK: @llvm.objectsize.i64.p0(ptr [[PTR:%[^,]+]],
483 // CHECK-NOT: 65535
484 // CHECK: call i32 @ObjectSize0(ptr noundef [[PTR]]
485 ObjectSize0(C + ({ int a = 65535; a; }));
486 }
487
488 // CHECK-LABEL: define{{.*}} void @test18
489 void test18(char *const p PDS(0)) {
490 // CHECK-NOT: llvm.objectsize
491 gi = __builtin_dynamic_object_size(p, 0);
492 gi = __builtin_object_size(p, 0);
493 }
494