1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 | FileCheck %s
3 typedef unsigned long size_t;
9 #define PS(N) __attribute__((pass_object_size(N)))
10 #define PDS(N) __attribute__((pass_dynamic_object_size(N)))
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);
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);
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);
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);
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);
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);
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);
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);
62 void *malloc(unsigned long) __attribute__((alloc_size(1)));
64 // CHECK-LABEL: define{{.*}} void @test1
65 void test1(unsigned long sz
) {
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]);
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]);
86 char *ptr
= (char *)malloc(sz
);
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
);
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);
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
);
102 // CHECK-LABEL: define{{.*}} void @test2
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]);
111 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize0Pv
112 int NoViableOverloadObjectSize0(void *const p
) __attribute__((overloadable
)) {
113 // CHECK: @llvm.objectsize
114 return __builtin_object_size(p
, 0);
117 // CHECK-LABEL: define{{.*}} i32 @_Z34NoViableOverloadDynamicObjectSize0Pv
118 int NoViableOverloadDynamicObjectSize0(void *const p
)
119 __attribute__((overloadable
)) {
120 // CHECK: @llvm.objectsize
121 return __builtin_object_size(p
, 0);
124 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize1Pv
125 int NoViableOverloadObjectSize1(void *const p
) __attribute__((overloadable
)) {
126 // CHECK: @llvm.objectsize
127 return __builtin_object_size(p
, 1);
130 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize2Pv
131 int NoViableOverloadObjectSize2(void *const p
) __attribute__((overloadable
)) {
132 // CHECK: @llvm.objectsize
133 return __builtin_object_size(p
, 2);
136 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize3Pv
137 int NoViableOverloadObjectSize3(void *const p
) __attribute__((overloadable
)) {
138 // CHECK-NOT: @llvm.objectsize
139 return __builtin_object_size(p
, 3);
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);
149 int NoViableOverloadDynamicObjectSize0(void *const p
PDS(0))
150 __attribute__((overloadable
)) {
151 return __builtin_dynamic_object_size(p
, 0);
154 int NoViableOverloadObjectSize1(void *const p
PS(1))
155 __attribute__((overloadable
)) {
156 return __builtin_object_size(p
, 1);
159 int NoViableOverloadObjectSize2(void *const p
PS(2))
160 __attribute__((overloadable
)) {
161 return __builtin_object_size(p
, 2);
164 int NoViableOverloadObjectSize3(void *const p
PS(3))
165 __attribute__((overloadable
)) {
166 return __builtin_object_size(p
, 3);
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
;
175 int NoViableOverloadObjectSize1(void *const p
PS(1))
176 __attribute__((overloadable
, enable_if(p
== 0, "never selected"))) {
177 return SHOULDNT_BE_CALLED
;
180 int NoViableOverloadObjectSize2(void *const p
PS(2))
181 __attribute__((overloadable
, enable_if(p
== 0, "never selected"))) {
182 return SHOULDNT_BE_CALLED
;
185 int NoViableOverloadObjectSize3(void *const p
PS(3))
186 __attribute__((overloadable
, enable_if(p
== 0, "never selected"))) {
187 return SHOULDNT_BE_CALLED
;
190 // CHECK-LABEL: define{{.*}} void @test3
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]);
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]);
212 // CHECK: call i32 @_Z34NoViableOverloadDynamicObjectSize0PvU25pass_dynamic_object_size0(ptr noundef %{{.*}}, i64 noundef 360)
213 gi
= NoViableOverloadDynamicObjectSize0(&t
[1]);
216 // CHECK-LABEL: define{{.*}} void @test4
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]);
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]);
241 int (*f
)(void *) = &NoViableOverloadObjectSize0
;
244 int (*g
)(void *) = &NoViableOverloadDynamicObjectSize0
;
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
);
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
);
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
);
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
);
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
);
282 int Overload0(void *, size_t, void *, size_t);
283 int OverloadNoSize(void *, void *);
285 int OverloadedObjectSize(void *const p
PS(0),
287 __attribute__((overloadable
)) __asm__("Overload0");
289 int OverloadedObjectSize(void *const p
, void *const c
)
290 __attribute__((overloadable
)) __asm__("OverloadNoSize");
292 // CHECK-LABEL: define{{.*}} void @test6
294 int known
[10], *opaque
;
296 // CHECK: call i32 @"\01Overload0"
297 gi
= OverloadedObjectSize(&known
[0], &known
[0]);
299 // CHECK: call i32 @"\01Overload0"
300 gi
= OverloadedObjectSize(&known
[0], opaque
);
302 // CHECK: call i32 @"\01Overload0"
303 gi
= OverloadedObjectSize(opaque
, &known
[0]);
305 // CHECK: call i32 @"\01Overload0"
306 gi
= OverloadedObjectSize(opaque
, opaque
);
309 int Identity(void *p
, size_t i
) { return i
; }
311 // CHECK-NOT: define{{.*}} void @AsmObjectSize
312 int AsmObjectSize0(void *const p
PS(0)) __asm__("Identity");
314 int AsmObjectSize1(void *const p
PS(1)) __asm__("Identity");
316 int AsmObjectSize2(void *const p
PS(2)) __asm__("Identity");
318 int AsmObjectSize3(void *const p
PS(3)) __asm__("Identity");
320 // CHECK-LABEL: define{{.*}} void @test7
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]);
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]);
343 // CHECK-LABEL: define{{.*}} void @test8
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]);
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))));
357 // CHECK-LABEL: define{{.*}} void @test9
358 void test9(void *const p
__attribute__((pass_object_size(0)))) {
359 // CHECK: @llvm.objectsize
360 DifferingObjectSize2(p
);
362 // CHECK-NOT: @llvm.objectsize
363 DifferingObjectSize0(p
);
364 DifferingObjectSize1(p
);
366 // CHECK: call void @DifferingObjectSize3(ptr noundef %{{.*}}, i64 noundef 0)
367 DifferingObjectSize3(p
);
370 // CHECK-LABEL: define{{.*}} void @test10
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
);
377 // CHECK-NOT: @llvm.objectsize
378 DifferingObjectSize1(p
);
380 // CHECK: call void @DifferingObjectSize3(ptr noundef %{{.*}}, i64 noundef 0)
381 DifferingObjectSize3(p
);
384 // CHECK-LABEL: define{{.*}} void @test11
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
);
391 // CHECK-NOT: @llvm.objectsize
392 DifferingObjectSize2(p
);
394 // CHECK: call void @DifferingObjectSize3(ptr noundef %{{.*}}, i64 noundef 0)
395 DifferingObjectSize3(p
);
398 // CHECK-LABEL: define{{.*}} void @test12
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
);
405 // CHECK-NOT: @llvm.objectsize
406 DifferingObjectSize2(p
);
407 DifferingObjectSize3(p
);
410 // CHECK-LABEL: define{{.*}} void @test13
416 // CHECK: @llvm.objectsize
419 // Allow side-effects, since they always need to happen anyway. Just make sure
420 // we don't perform them twice.
423 // CHECK: @llvm.objectsize
424 // CHECK: call i32 @ObjectSize0
425 ObjectSize0(p
+ ++i
);
428 // CHECK: @llvm.objectsize
430 // CHECK: call i32 @ObjectSize0
431 ObjectSize0(p
+ i
++);
434 // There was a bug where variadic functions with pass_object_size would cause
435 // problems in the form of failed assertions.
436 void my_sprintf(char *const c
__attribute__((pass_object_size(0))), ...) {}
438 // CHECK-LABEL: define{{.*}} void @test14
439 void test14(char *c
) {
440 // CHECK: @llvm.objectsize
441 // CHECK: call void (ptr, i64, ...) @my_sprintf
444 // CHECK: @llvm.objectsize
445 // CHECK: call void (ptr, i64, ...) @my_sprintf
446 my_sprintf(c
, 1, 2, 3);
449 void pass_size_unsigned(unsigned *const PS(0));
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
454 void test15(unsigned *I
) {
455 // CHECK: @llvm.objectsize.i64.p0
456 // CHECK: call void @pass_size_unsigned
457 pass_size_unsigned(I
);
460 void pass_size_as1(__attribute__((address_space(1))) void *const PS(0));
462 void pass_size_unsigned_as1(
463 __attribute__((address_space(1))) unsigned *const PS(0));
465 // CHECK-LABEL: define{{.*}} void @test16
466 void test16(__attribute__((address_space(1))) unsigned *I
) {
467 // CHECK: call i64 @llvm.objectsize.i64.p1
468 // CHECK: call void @pass_size_as1
470 // CHECK: call i64 @llvm.objectsize.i64.p1
471 // CHECK: call void @pass_size_unsigned_as1
472 pass_size_unsigned_as1(I
);
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
478 void test17(char *C
) {
479 // Check for 65535 to see if we're emitting this pointer twice.
482 // CHECK: @llvm.objectsize.i64.p0(ptr [[PTR:%[^,]+]],
484 // CHECK: call i32 @ObjectSize0(ptr noundef [[PTR]]
485 ObjectSize0(C
+ ({ int a
= 65535; a
; }));
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);