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)))
13 // CHECK-LABEL: define i32 @ObjectSize0(i8* %{{.*}}, i64)
14 int ObjectSize0(void *const p PS(0)) {
15 // CHECK-NOT: @llvm.objectsize
16 return __builtin_object_size(p, 0);
19 // CHECK-LABEL: define i32 @ObjectSize1(i8* %{{.*}}, i64)
20 int ObjectSize1(void *const p PS(1)) {
21 // CHECK-NOT: @llvm.objectsize
22 return __builtin_object_size(p, 1);
25 // CHECK-LABEL: define i32 @ObjectSize2(i8* %{{.*}}, i64)
26 int ObjectSize2(void *const p PS(2)) {
27 // CHECK-NOT: @llvm.objectsize
28 return __builtin_object_size(p, 2);
31 // CHECK-LABEL: define i32 @ObjectSize3(i8* %{{.*}}, i64)
32 int ObjectSize3(void *const p PS(3)) {
33 // CHECK-NOT: @llvm.objectsize
34 return __builtin_object_size(p, 3);
37 // CHECK-LABEL: define void @test1
41 // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 360)
42 gi = ObjectSize0(&t[1]);
43 // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 360)
44 gi = ObjectSize1(&t[1]);
45 // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 360)
46 gi = ObjectSize2(&t[1]);
47 // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 360)
48 gi = ObjectSize3(&t[1]);
50 // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 356)
51 gi = ObjectSize0(&t[1].t[1]);
52 // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 36)
53 gi = ObjectSize1(&t[1].t[1]);
54 // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 356)
55 gi = ObjectSize2(&t[1].t[1]);
56 // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36)
57 gi = ObjectSize3(&t[1].t[1]);
60 // CHECK-LABEL: define void @test2
61 void test2(struct Foo *t) {
62 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize
63 // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 [[VAR]])
64 gi = ObjectSize1(&t->t[1]);
65 // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36)
66 gi = ObjectSize3(&t->t[1]);
69 // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize0Pv
70 int NoViableOverloadObjectSize0(void *const p) __attribute__((overloadable)) {
71 // CHECK: @llvm.objectsize
72 return __builtin_object_size(p, 0);
75 // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize1Pv
76 int NoViableOverloadObjectSize1(void *const p) __attribute__((overloadable)) {
77 // CHECK: @llvm.objectsize
78 return __builtin_object_size(p, 1);
81 // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize2Pv
82 int NoViableOverloadObjectSize2(void *const p) __attribute__((overloadable)) {
83 // CHECK: @llvm.objectsize
84 return __builtin_object_size(p, 2);
87 // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize3Pv
88 int NoViableOverloadObjectSize3(void *const p) __attribute__((overloadable)) {
89 // CHECK-NOT: @llvm.objectsize
90 return __builtin_object_size(p, 3);
93 // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize0Pv
94 // CHECK-NOT: @llvm.objectsize
95 int NoViableOverloadObjectSize0(void *const p PS(0))
96 __attribute__((overloadable)) {
97 return __builtin_object_size(p, 0);
100 int NoViableOverloadObjectSize1(void *const p PS(1))
101 __attribute__((overloadable)) {
102 return __builtin_object_size(p, 1);
105 int NoViableOverloadObjectSize2(void *const p PS(2))
106 __attribute__((overloadable)) {
107 return __builtin_object_size(p, 2);
110 int NoViableOverloadObjectSize3(void *const p PS(3))
111 __attribute__((overloadable)) {
112 return __builtin_object_size(p, 3);
115 const static int SHOULDNT_BE_CALLED = -100;
116 int NoViableOverloadObjectSize0(void *const p PS(0))
117 __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
118 return SHOULDNT_BE_CALLED;
121 int NoViableOverloadObjectSize1(void *const p PS(1))
122 __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
123 return SHOULDNT_BE_CALLED;
126 int NoViableOverloadObjectSize2(void *const p PS(2))
127 __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
128 return SHOULDNT_BE_CALLED;
131 int NoViableOverloadObjectSize3(void *const p PS(3))
132 __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
133 return SHOULDNT_BE_CALLED;
136 // CHECK-LABEL: define void @test3
140 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 360)
141 gi = NoViableOverloadObjectSize0(&t[1]);
142 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 360)
143 gi = NoViableOverloadObjectSize1(&t[1]);
144 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 360)
145 gi = NoViableOverloadObjectSize2(&t[1]);
146 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 360)
147 gi = NoViableOverloadObjectSize3(&t[1]);
149 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 356)
150 gi = NoViableOverloadObjectSize0(&t[1].t[1]);
151 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 36)
152 gi = NoViableOverloadObjectSize1(&t[1].t[1]);
153 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 356)
154 gi = NoViableOverloadObjectSize2(&t[1].t[1]);
155 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36)
156 gi = NoViableOverloadObjectSize3(&t[1].t[1]);
159 // CHECK-LABEL: define void @test4
160 void test4(struct Foo *t) {
161 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}})
162 gi = NoViableOverloadObjectSize0(&t[1]);
163 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 %{{.*}})
164 gi = NoViableOverloadObjectSize1(&t[1]);
165 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}})
166 gi = NoViableOverloadObjectSize2(&t[1]);
167 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 0)
168 gi = NoViableOverloadObjectSize3(&t[1]);
170 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}})
171 gi = NoViableOverloadObjectSize0(&t[1].t[1]);
172 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize
173 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 [[VAR]])
174 gi = NoViableOverloadObjectSize1(&t[1].t[1]);
175 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}})
176 gi = NoViableOverloadObjectSize2(&t[1].t[1]);
177 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36)
178 gi = NoViableOverloadObjectSize3(&t[1].t[1]);
184 int (*f)(void *) = &NoViableOverloadObjectSize0;
188 // CHECK-LABEL: define i32 @IndirectObjectSize0
189 int IndirectObjectSize0(void *const p PS(0)) {
190 // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 %{{.*}})
191 // CHECK-NOT: @llvm.objectsize
192 return ObjectSize0(p);
195 // CHECK-LABEL: define i32 @IndirectObjectSize1
196 int IndirectObjectSize1(void *const p PS(1)) {
197 // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 %{{.*}})
198 // CHECK-NOT: @llvm.objectsize
199 return ObjectSize1(p);
202 // CHECK-LABEL: define i32 @IndirectObjectSize2
203 int IndirectObjectSize2(void *const p PS(2)) {
204 // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 %{{.*}})
205 // CHECK-NOT: @llvm.objectsize
206 return ObjectSize2(p);
209 // CHECK-LABEL: define i32 @IndirectObjectSize3
210 int IndirectObjectSize3(void *const p PS(3)) {
211 // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 %{{.*}})
212 // CHECK-NOT: @llvm.objectsize
213 return ObjectSize3(p);
216 int Overload0(void *, size_t, void *, size_t);
217 int OverloadNoSize(void *, void *);
219 int OverloadedObjectSize(void *const p PS(0),
221 __attribute__((overloadable)) __asm__("Overload0");
223 int OverloadedObjectSize(void *const p, void *const c)
224 __attribute__((overloadable)) __asm__("OverloadNoSize");
226 // CHECK-LABEL: define void @test6
228 int known[10], *opaque;
230 // CHECK: call i32 @"\01Overload0"
231 gi = OverloadedObjectSize(&known[0], &known[0]);
233 // CHECK: call i32 @"\01Overload0"
234 gi = OverloadedObjectSize(&known[0], opaque);
236 // CHECK: call i32 @"\01Overload0"
237 gi = OverloadedObjectSize(opaque, &known[0]);
239 // CHECK: call i32 @"\01Overload0"
240 gi = OverloadedObjectSize(opaque, opaque);
243 int Identity(void *p, size_t i) { return i; }
245 // CHECK-NOT: define void @AsmObjectSize
246 int AsmObjectSize0(void *const p PS(0)) __asm__("Identity");
248 int AsmObjectSize1(void *const p PS(1)) __asm__("Identity");
250 int AsmObjectSize2(void *const p PS(2)) __asm__("Identity");
252 int AsmObjectSize3(void *const p PS(3)) __asm__("Identity");
254 // CHECK-LABEL: define void @test7
258 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360)
259 gi = AsmObjectSize0(&t[1]);
260 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360)
261 gi = AsmObjectSize1(&t[1]);
262 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360)
263 gi = AsmObjectSize2(&t[1]);
264 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360)
265 gi = AsmObjectSize3(&t[1]);
267 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356)
268 gi = AsmObjectSize0(&t[1].t[1]);
269 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36)
270 gi = AsmObjectSize1(&t[1].t[1]);
271 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356)
272 gi = AsmObjectSize2(&t[1].t[1]);
273 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36)
274 gi = AsmObjectSize3(&t[1].t[1]);
277 // CHECK-LABEL: define void @test8
278 void test8(struct Foo *t) {
279 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize
280 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 [[VAR]])
281 gi = AsmObjectSize1(&t[1].t[1]);
282 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36)
283 gi = AsmObjectSize3(&t[1].t[1]);
286 void DifferingObjectSize0(void *const p __attribute__((pass_object_size(0))));
287 void DifferingObjectSize1(void *const p __attribute__((pass_object_size(1))));
288 void DifferingObjectSize2(void *const p __attribute__((pass_object_size(2))));
289 void DifferingObjectSize3(void *const p __attribute__((pass_object_size(3))));
291 // CHECK-LABEL: define void @test9
292 void test9(void *const p __attribute__((pass_object_size(0)))) {
293 // CHECK: @llvm.objectsize
294 DifferingObjectSize2(p);
296 // CHECK-NOT: @llvm.objectsize
297 DifferingObjectSize0(p);
298 DifferingObjectSize1(p);
300 // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
301 DifferingObjectSize3(p);
304 // CHECK-LABEL: define void @test10
305 void test10(void *const p __attribute__((pass_object_size(1)))) {
306 // CHECK: @llvm.objectsize
307 DifferingObjectSize2(p);
308 // CHECK: @llvm.objectsize
309 DifferingObjectSize0(p);
311 // CHECK-NOT: @llvm.objectsize
312 DifferingObjectSize1(p);
314 // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
315 DifferingObjectSize3(p);
318 // CHECK-LABEL: define void @test11
319 void test11(void *const p __attribute__((pass_object_size(2)))) {
320 // CHECK: @llvm.objectsize
321 DifferingObjectSize0(p);
322 // CHECK: @llvm.objectsize
323 DifferingObjectSize1(p);
325 // CHECK-NOT: @llvm.objectsize
326 DifferingObjectSize2(p);
328 // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
329 DifferingObjectSize3(p);
332 // CHECK-LABEL: define void @test12
333 void test12(void *const p __attribute__((pass_object_size(3)))) {
334 // CHECK: @llvm.objectsize
335 DifferingObjectSize0(p);
336 // CHECK: @llvm.objectsize
337 DifferingObjectSize1(p);
339 // CHECK-NOT: @llvm.objectsize
340 DifferingObjectSize2(p);
341 DifferingObjectSize3(p);
344 // CHECK-LABEL: define void @test13
350 // CHECK: @llvm.objectsize
353 // Allow side-effects, since they always need to happen anyway. Just make sure
354 // we don't perform them twice.
357 // CHECK: @llvm.objectsize
358 // CHECK: call i32 @ObjectSize0
359 ObjectSize0(p + ++i);
362 // CHECK: @llvm.objectsize
364 // CHECK: call i32 @ObjectSize0
365 ObjectSize0(p + i++);
368 // There was a bug where variadic functions with pass_object_size would cause
369 // problems in the form of failed assertions.
370 void my_sprintf(char *const c __attribute__((pass_object_size(0))), ...) {}
372 // CHECK-LABEL: define void @test14
373 void test14(char *c) {
374 // CHECK: @llvm.objectsize
375 // CHECK: call void (i8*, i64, ...) @my_sprintf
378 // CHECK: @llvm.objectsize
379 // CHECK: call void (i8*, i64, ...) @my_sprintf
380 my_sprintf(c, 1, 2, 3);
383 void pass_size_unsigned(unsigned *const PS(0));
385 // Bug: we weren't lowering to the proper @llvm.objectsize for pointers that
386 // don't turn into i8*s, which caused crashes.
387 // CHECK-LABEL: define void @test15
388 void test15(unsigned *I) {
389 // CHECK: @llvm.objectsize.i64.p0i32
390 // CHECK: call void @pass_size_unsigned
391 pass_size_unsigned(I);
394 void pass_size_as1(__attribute__((address_space(1))) void *const PS(0));
396 void pass_size_unsigned_as1(
397 __attribute__((address_space(1))) unsigned *const PS(0));
399 // CHECK-LABEL: define void @test16
400 void test16(__attribute__((address_space(1))) unsigned *I) {
401 // CHECK: call i64 @llvm.objectsize.i64.p1i8
402 // CHECK: call void @pass_size_as1
404 // CHECK: call i64 @llvm.objectsize.i64.p1i32
405 // CHECK: call void @pass_size_unsigned_as1
406 pass_size_unsigned_as1(I);
409 // This used to cause assertion failures, since we'd try to emit the statement
410 // expression (and definitions for `a`) twice.
411 // CHECK-LABEL: define void @test17
412 void test17(char *C) {
413 // Check for 65535 to see if we're emitting this pointer twice.
416 // CHECK: @llvm.objectsize.i64.p0i8(i8* [[PTR:%[^,]+]],
418 // CHECK: call i32 @ObjectSize0(i8* [[PTR]]
419 ObjectSize0(C + ({ int a = 65535; a; }));