]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/pass-object-size.c
Vendor import of clang trunk r300422:
[FreeBSD/FreeBSD.git] / test / CodeGen / pass-object-size.c
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
11 int gi = 0;
12
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);
17 }
18
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);
23 }
24
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);
29 }
30
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);
35 }
36
37 // CHECK-LABEL: define void @test1
38 void test1() {
39   struct Foo t[10];
40
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]);
49
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]);
58 }
59
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]);
67 }
68
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);
73 }
74
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);
79 }
80
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);
85 }
86
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);
91 }
92
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);
98 }
99
100 int NoViableOverloadObjectSize1(void *const p PS(1))
101     __attribute__((overloadable)) {
102   return __builtin_object_size(p, 1);
103 }
104
105 int NoViableOverloadObjectSize2(void *const p PS(2))
106     __attribute__((overloadable)) {
107   return __builtin_object_size(p, 2);
108 }
109
110 int NoViableOverloadObjectSize3(void *const p PS(3))
111     __attribute__((overloadable)) {
112   return __builtin_object_size(p, 3);
113 }
114
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;
119 }
120
121 int NoViableOverloadObjectSize1(void *const p PS(1))
122     __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
123   return SHOULDNT_BE_CALLED;
124 }
125
126 int NoViableOverloadObjectSize2(void *const p PS(2))
127     __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
128   return SHOULDNT_BE_CALLED;
129 }
130
131 int NoViableOverloadObjectSize3(void *const p PS(3))
132     __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
133   return SHOULDNT_BE_CALLED;
134 }
135
136 // CHECK-LABEL: define void @test3
137 void test3() {
138   struct Foo t[10];
139
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]);
148
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]);
157 }
158
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]);
169
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]);
179 }
180
181 void test5() {
182   struct Foo t[10];
183
184   int (*f)(void *) = &NoViableOverloadObjectSize0;
185   gi = f(&t[1]);
186 }
187
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);
193 }
194
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);
200 }
201
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);
207 }
208
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);
214 }
215
216 int Overload0(void *, size_t, void *, size_t);
217 int OverloadNoSize(void *, void *);
218
219 int OverloadedObjectSize(void *const p PS(0),
220                          void *const c PS(0))
221     __attribute__((overloadable)) __asm__("Overload0");
222
223 int OverloadedObjectSize(void *const p, void *const c)
224     __attribute__((overloadable)) __asm__("OverloadNoSize");
225
226 // CHECK-LABEL: define void @test6
227 void test6() {
228   int known[10], *opaque;
229
230   // CHECK: call i32 @"\01Overload0"
231   gi = OverloadedObjectSize(&known[0], &known[0]);
232
233   // CHECK: call i32 @"\01Overload0"
234   gi = OverloadedObjectSize(&known[0], opaque);
235
236   // CHECK: call i32 @"\01Overload0"
237   gi = OverloadedObjectSize(opaque, &known[0]);
238
239   // CHECK: call i32 @"\01Overload0"
240   gi = OverloadedObjectSize(opaque, opaque);
241 }
242
243 int Identity(void *p, size_t i) { return i; }
244
245 // CHECK-NOT: define void @AsmObjectSize
246 int AsmObjectSize0(void *const p PS(0)) __asm__("Identity");
247
248 int AsmObjectSize1(void *const p PS(1)) __asm__("Identity");
249
250 int AsmObjectSize2(void *const p PS(2)) __asm__("Identity");
251
252 int AsmObjectSize3(void *const p PS(3)) __asm__("Identity");
253
254 // CHECK-LABEL: define void @test7
255 void test7() {
256   struct Foo t[10];
257
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]);
266
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]);
275 }
276
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]);
284 }
285
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))));
290
291 // CHECK-LABEL: define void @test9
292 void test9(void *const p __attribute__((pass_object_size(0)))) {
293   // CHECK: @llvm.objectsize
294   DifferingObjectSize2(p);
295
296   // CHECK-NOT: @llvm.objectsize
297   DifferingObjectSize0(p);
298   DifferingObjectSize1(p);
299
300   // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
301   DifferingObjectSize3(p);
302 }
303
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);
310
311   // CHECK-NOT: @llvm.objectsize
312   DifferingObjectSize1(p);
313
314   // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
315   DifferingObjectSize3(p);
316 }
317
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);
324
325   // CHECK-NOT: @llvm.objectsize
326   DifferingObjectSize2(p);
327
328   // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
329   DifferingObjectSize3(p);
330 }
331
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);
338
339   // CHECK-NOT: @llvm.objectsize
340   DifferingObjectSize2(p);
341   DifferingObjectSize3(p);
342 }
343
344 // CHECK-LABEL: define void @test13
345 void test13() {
346   char c[10];
347   unsigned i = 0;
348   char *p = c;
349
350   // CHECK: @llvm.objectsize
351   ObjectSize0(p);
352
353   // Allow side-effects, since they always need to happen anyway. Just make sure
354   // we don't perform them twice.
355   // CHECK: = add
356   // CHECK-NOT: = add
357   // CHECK: @llvm.objectsize
358   // CHECK: call i32 @ObjectSize0
359   ObjectSize0(p + ++i);
360
361   // CHECK: = add
362   // CHECK: @llvm.objectsize
363   // CHECK-NOT: = add
364   // CHECK: call i32 @ObjectSize0
365   ObjectSize0(p + i++);
366 }
367
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))), ...) {}
371
372 // CHECK-LABEL: define void @test14
373 void test14(char *c) {
374   // CHECK: @llvm.objectsize
375   // CHECK: call void (i8*, i64, ...) @my_sprintf
376   my_sprintf(c);
377
378   // CHECK: @llvm.objectsize
379   // CHECK: call void (i8*, i64, ...) @my_sprintf
380   my_sprintf(c, 1, 2, 3);
381 }
382
383 void pass_size_unsigned(unsigned *const PS(0));
384
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);
392 }
393
394 void pass_size_as1(__attribute__((address_space(1))) void *const PS(0));
395
396 void pass_size_unsigned_as1(
397     __attribute__((address_space(1))) unsigned *const PS(0));
398
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
403   pass_size_as1(I);
404   // CHECK: call i64 @llvm.objectsize.i64.p1i32
405   // CHECK: call void @pass_size_unsigned_as1
406   pass_size_unsigned_as1(I);
407 }
408
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.
414   // CHECK: 65535
415   // CHECK-NOT: 65535
416   // CHECK: @llvm.objectsize.i64.p0i8(i8* [[PTR:%[^,]+]],
417   // CHECK-NOT: 65535
418   // CHECK: call i32 @ObjectSize0(i8* [[PTR]]
419   ObjectSize0(C + ({ int a = 65535; a; }));
420 }