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(i8* %{{.*}}, i64) |
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(i8* %{{.*}}, i64) |
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(i8* %{{.*}}, i64) |
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(i8* %{{.*}}, i64) |
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(i8* %{{.*}}, i64) |
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(i8* %{{.*}}, i64) |
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(i8* %{{.*}}, i64) |
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(i8* %{{.*}}, i64) |
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 |
65 | void test1(unsigned long sz) { |
66 | struct Foo t[10]; |
67 | |
68 | // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 360) |
69 | gi = ObjectSize0(&t[1]); |
70 | // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 360) |
71 | gi = ObjectSize1(&t[1]); |
72 | // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 360) |
73 | gi = ObjectSize2(&t[1]); |
74 | // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 360) |
75 | gi = ObjectSize3(&t[1]); |
76 | |
77 | // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 356) |
78 | gi = ObjectSize0(&t[1].t[1]); |
79 | // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 36) |
80 | gi = ObjectSize1(&t[1].t[1]); |
81 | // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 356) |
82 | gi = ObjectSize2(&t[1].t[1]); |
83 | // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36) |
84 | gi = ObjectSize3(&t[1].t[1]); |
85 | |
86 | char *ptr = (char *)malloc(sz); |
87 | |
88 | // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8({{.*}}, i1 false, i1 true, i1 true) |
89 | // CHECK: call i32 @DynamicObjectSize0(i8* %{{.*}}, i64 [[REG]]) |
90 | gi = DynamicObjectSize0(ptr); |
91 | |
92 | // CHECK: [[WITH_OFFSET:%.*]] = getelementptr |
93 | // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[WITH_OFFSET]], i1 false, i1 true, i1 true) |
94 | // CHECK: call i32 @DynamicObjectSize0(i8* {{.*}}, i64 [[REG]]) |
95 | gi = DynamicObjectSize0(ptr+10); |
96 | |
97 | // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8({{.*}}, i1 true, i1 true, i1 true) |
98 | // CHECK: call i32 @DynamicObjectSize2(i8* {{.*}}, i64 [[REG]]) |
99 | gi = DynamicObjectSize2(ptr); |
100 | } |
101 | |
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(i8* %{{.*}}, i64 [[VAR]]) |
106 | gi = ObjectSize1(&t->t[1]); |
107 | // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36) |
108 | gi = ObjectSize3(&t->t[1]); |
109 | } |
110 | |
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); |
115 | } |
116 | |
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); |
122 | } |
123 | |
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); |
128 | } |
129 | |
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); |
134 | } |
135 | |
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); |
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 |
191 | void test3() { |
192 | struct Foo t[10]; |
193 | |
194 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 360) |
195 | gi = NoViableOverloadObjectSize0(&t[1]); |
196 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 360) |
197 | gi = NoViableOverloadObjectSize1(&t[1]); |
198 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 360) |
199 | gi = NoViableOverloadObjectSize2(&t[1]); |
200 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 360) |
201 | gi = NoViableOverloadObjectSize3(&t[1]); |
202 | |
203 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 356) |
204 | gi = NoViableOverloadObjectSize0(&t[1].t[1]); |
205 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 36) |
206 | gi = NoViableOverloadObjectSize1(&t[1].t[1]); |
207 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 356) |
208 | gi = NoViableOverloadObjectSize2(&t[1].t[1]); |
209 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36) |
210 | gi = NoViableOverloadObjectSize3(&t[1].t[1]); |
211 | |
212 | // CHECK: call i32 @_Z34NoViableOverloadDynamicObjectSize0PvU25pass_dynamic_object_size0(i8* %{{.*}}, i64 360) |
213 | gi = NoViableOverloadDynamicObjectSize0(&t[1]); |
214 | } |
215 | |
216 | // CHECK-LABEL: define void @test4 |
217 | void test4(struct Foo *t) { |
218 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}}) |
219 | gi = NoViableOverloadObjectSize0(&t[1]); |
220 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 %{{.*}}) |
221 | gi = NoViableOverloadObjectSize1(&t[1]); |
222 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}}) |
223 | gi = NoViableOverloadObjectSize2(&t[1]); |
224 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 0) |
225 | gi = NoViableOverloadObjectSize3(&t[1]); |
226 | |
227 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}}) |
228 | gi = NoViableOverloadObjectSize0(&t[1].t[1]); |
229 | // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize |
230 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 [[VAR]]) |
231 | gi = NoViableOverloadObjectSize1(&t[1].t[1]); |
232 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}}) |
233 | gi = NoViableOverloadObjectSize2(&t[1].t[1]); |
234 | // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36) |
235 | gi = NoViableOverloadObjectSize3(&t[1].t[1]); |
236 | } |
237 | |
238 | void test5() { |
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(i8* %{{.*}}, i64 %{{.*}}) |
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(i8* %{{.*}}, i64 %{{.*}}) |
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(i8* %{{.*}}, i64 %{{.*}}) |
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(i8* %{{.*}}, i64 %{{.*}}) |
272 | // CHECK-NOT: @llvm.objectsize |
273 | return ObjectSize3(p); |
274 | } |
275 | |
276 | int IndirectDynamicObjectSize0(void *const p PDS(0)) { |
277 | // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 %{{.*}}) |
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 |
293 | void test6() { |
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 | |
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 |
321 | void test7() { |
322 | struct Foo t[10]; |
323 | |
324 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) |
325 | gi = AsmObjectSize0(&t[1]); |
326 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) |
327 | gi = AsmObjectSize1(&t[1]); |
328 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) |
329 | gi = AsmObjectSize2(&t[1]); |
330 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) |
331 | gi = AsmObjectSize3(&t[1]); |
332 | |
333 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356) |
334 | gi = AsmObjectSize0(&t[1].t[1]); |
335 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) |
336 | gi = AsmObjectSize1(&t[1].t[1]); |
337 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356) |
338 | gi = AsmObjectSize2(&t[1].t[1]); |
339 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) |
340 | gi = AsmObjectSize3(&t[1].t[1]); |
341 | } |
342 | |
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"(i8* %{{.*}}, i64 [[VAR]]) |
347 | gi = AsmObjectSize1(&t[1].t[1]); |
348 | // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 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 |
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(i8* %{{.*}}, i64 0) |
367 | DifferingObjectSize3(p); |
368 | } |
369 | |
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); |
376 | |
377 | // CHECK-NOT: @llvm.objectsize |
378 | DifferingObjectSize1(p); |
379 | |
380 | // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0) |
381 | DifferingObjectSize3(p); |
382 | } |
383 | |
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); |
390 | |
391 | // CHECK-NOT: @llvm.objectsize |
392 | DifferingObjectSize2(p); |
393 | |
394 | // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0) |
395 | DifferingObjectSize3(p); |
396 | } |
397 | |
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); |
404 | |
405 | // CHECK-NOT: @llvm.objectsize |
406 | DifferingObjectSize2(p); |
407 | DifferingObjectSize3(p); |
408 | } |
409 | |
410 | // CHECK-LABEL: define void @test13 |
411 | void test13() { |
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. |
436 | void my_sprintf(char *const c __attribute__((pass_object_size(0))), ...) {} |
437 | |
438 | // CHECK-LABEL: define void @test14 |
439 | void test14(char *c) { |
440 | // CHECK: @llvm.objectsize |
441 | // CHECK: call void (i8*, i64, ...) @my_sprintf |
442 | my_sprintf(c); |
443 | |
444 | // CHECK: @llvm.objectsize |
445 | // CHECK: call void (i8*, 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 i8*s, which caused crashes. |
453 | // CHECK-LABEL: define void @test15 |
454 | void test15(unsigned *I) { |
455 | // CHECK: @llvm.objectsize.i64.p0i32 |
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 |
466 | void test16(__attribute__((address_space(1))) unsigned *I) { |
467 | // CHECK: call i64 @llvm.objectsize.i64.p1i8 |
468 | // CHECK: call void @pass_size_as1 |
469 | pass_size_as1(I); |
470 | // CHECK: call i64 @llvm.objectsize.i64.p1i32 |
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 |
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.p0i8(i8* [[PTR:%[^,]+]], |
483 | // CHECK-NOT: 65535 |
484 | // CHECK: call i32 @ObjectSize0(i8* [[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 | |