xref: /aosp_15_r20/external/clang/test/CodeGen/pass-object-size.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li typedef unsigned long size_t;
4*67e74705SXin Li 
5*67e74705SXin Li struct Foo {
6*67e74705SXin Li   int t[10];
7*67e74705SXin Li };
8*67e74705SXin Li 
9*67e74705SXin Li #define PS(N) __attribute__((pass_object_size(N)))
10*67e74705SXin Li 
11*67e74705SXin Li int gi = 0;
12*67e74705SXin Li 
13*67e74705SXin Li // CHECK-LABEL: define i32 @ObjectSize0(i8* %{{.*}}, i64)
14*67e74705SXin Li int ObjectSize0(void *const p PS(0)) {
15*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
16*67e74705SXin Li   return __builtin_object_size(p, 0);
17*67e74705SXin Li }
18*67e74705SXin Li 
19*67e74705SXin Li // CHECK-LABEL: define i32 @ObjectSize1(i8* %{{.*}}, i64)
20*67e74705SXin Li int ObjectSize1(void *const p PS(1)) {
21*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
22*67e74705SXin Li   return __builtin_object_size(p, 1);
23*67e74705SXin Li }
24*67e74705SXin Li 
25*67e74705SXin Li // CHECK-LABEL: define i32 @ObjectSize2(i8* %{{.*}}, i64)
26*67e74705SXin Li int ObjectSize2(void *const p PS(2)) {
27*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
28*67e74705SXin Li   return __builtin_object_size(p, 2);
29*67e74705SXin Li }
30*67e74705SXin Li 
31*67e74705SXin Li // CHECK-LABEL: define i32 @ObjectSize3(i8* %{{.*}}, i64)
32*67e74705SXin Li int ObjectSize3(void *const p PS(3)) {
33*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
34*67e74705SXin Li   return __builtin_object_size(p, 3);
35*67e74705SXin Li }
36*67e74705SXin Li 
37*67e74705SXin Li // CHECK-LABEL: define void @test1
test1()38*67e74705SXin Li void test1() {
39*67e74705SXin Li   struct Foo t[10];
40*67e74705SXin Li 
41*67e74705SXin Li   // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 360)
42*67e74705SXin Li   gi = ObjectSize0(&t[1]);
43*67e74705SXin Li   // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 360)
44*67e74705SXin Li   gi = ObjectSize1(&t[1]);
45*67e74705SXin Li   // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 360)
46*67e74705SXin Li   gi = ObjectSize2(&t[1]);
47*67e74705SXin Li   // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 360)
48*67e74705SXin Li   gi = ObjectSize3(&t[1]);
49*67e74705SXin Li 
50*67e74705SXin Li   // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 356)
51*67e74705SXin Li   gi = ObjectSize0(&t[1].t[1]);
52*67e74705SXin Li   // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 36)
53*67e74705SXin Li   gi = ObjectSize1(&t[1].t[1]);
54*67e74705SXin Li   // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 356)
55*67e74705SXin Li   gi = ObjectSize2(&t[1].t[1]);
56*67e74705SXin Li   // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36)
57*67e74705SXin Li   gi = ObjectSize3(&t[1].t[1]);
58*67e74705SXin Li }
59*67e74705SXin Li 
60*67e74705SXin Li // CHECK-LABEL: define void @test2
test2(struct Foo * t)61*67e74705SXin Li void test2(struct Foo *t) {
62*67e74705SXin Li   // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 36)
63*67e74705SXin Li   gi = ObjectSize1(&t->t[1]);
64*67e74705SXin Li   // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36)
65*67e74705SXin Li   gi = ObjectSize3(&t->t[1]);
66*67e74705SXin Li }
67*67e74705SXin Li 
68*67e74705SXin Li // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize0Pv
NoViableOverloadObjectSize0(void * const p)69*67e74705SXin Li int NoViableOverloadObjectSize0(void *const p) __attribute__((overloadable)) {
70*67e74705SXin Li   // CHECK: @llvm.objectsize
71*67e74705SXin Li   return __builtin_object_size(p, 0);
72*67e74705SXin Li }
73*67e74705SXin Li 
74*67e74705SXin Li // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize1Pv
NoViableOverloadObjectSize1(void * const p)75*67e74705SXin Li int NoViableOverloadObjectSize1(void *const p) __attribute__((overloadable)) {
76*67e74705SXin Li   // CHECK: @llvm.objectsize
77*67e74705SXin Li   return __builtin_object_size(p, 1);
78*67e74705SXin Li }
79*67e74705SXin Li 
80*67e74705SXin Li // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize2Pv
NoViableOverloadObjectSize2(void * const p)81*67e74705SXin Li int NoViableOverloadObjectSize2(void *const p) __attribute__((overloadable)) {
82*67e74705SXin Li   // CHECK: @llvm.objectsize
83*67e74705SXin Li   return __builtin_object_size(p, 2);
84*67e74705SXin Li }
85*67e74705SXin Li 
86*67e74705SXin Li // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize3Pv
NoViableOverloadObjectSize3(void * const p)87*67e74705SXin Li int NoViableOverloadObjectSize3(void *const p) __attribute__((overloadable)) {
88*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
89*67e74705SXin Li   return __builtin_object_size(p, 3);
90*67e74705SXin Li }
91*67e74705SXin Li 
92*67e74705SXin Li // CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize0Pv
93*67e74705SXin Li // CHECK-NOT: @llvm.objectsize
94*67e74705SXin Li int NoViableOverloadObjectSize0(void *const p PS(0))
95*67e74705SXin Li     __attribute__((overloadable)) {
96*67e74705SXin Li   return __builtin_object_size(p, 0);
97*67e74705SXin Li }
98*67e74705SXin Li 
99*67e74705SXin Li int NoViableOverloadObjectSize1(void *const p PS(1))
100*67e74705SXin Li     __attribute__((overloadable)) {
101*67e74705SXin Li   return __builtin_object_size(p, 1);
102*67e74705SXin Li }
103*67e74705SXin Li 
104*67e74705SXin Li int NoViableOverloadObjectSize2(void *const p PS(2))
105*67e74705SXin Li     __attribute__((overloadable)) {
106*67e74705SXin Li   return __builtin_object_size(p, 2);
107*67e74705SXin Li }
108*67e74705SXin Li 
109*67e74705SXin Li int NoViableOverloadObjectSize3(void *const p PS(3))
110*67e74705SXin Li     __attribute__((overloadable)) {
111*67e74705SXin Li   return __builtin_object_size(p, 3);
112*67e74705SXin Li }
113*67e74705SXin Li 
114*67e74705SXin Li const static int SHOULDNT_BE_CALLED = -100;
115*67e74705SXin Li int NoViableOverloadObjectSize0(void *const p PS(0))
116*67e74705SXin Li     __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
117*67e74705SXin Li   return SHOULDNT_BE_CALLED;
118*67e74705SXin Li }
119*67e74705SXin Li 
120*67e74705SXin Li int NoViableOverloadObjectSize1(void *const p PS(1))
121*67e74705SXin Li     __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
122*67e74705SXin Li   return SHOULDNT_BE_CALLED;
123*67e74705SXin Li }
124*67e74705SXin Li 
125*67e74705SXin Li int NoViableOverloadObjectSize2(void *const p PS(2))
126*67e74705SXin Li     __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
127*67e74705SXin Li   return SHOULDNT_BE_CALLED;
128*67e74705SXin Li }
129*67e74705SXin Li 
130*67e74705SXin Li int NoViableOverloadObjectSize3(void *const p PS(3))
131*67e74705SXin Li     __attribute__((overloadable, enable_if(p == 0, "never selected"))) {
132*67e74705SXin Li   return SHOULDNT_BE_CALLED;
133*67e74705SXin Li }
134*67e74705SXin Li 
135*67e74705SXin Li // CHECK-LABEL: define void @test3
test3()136*67e74705SXin Li void test3() {
137*67e74705SXin Li   struct Foo t[10];
138*67e74705SXin Li 
139*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 360)
140*67e74705SXin Li   gi = NoViableOverloadObjectSize0(&t[1]);
141*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 360)
142*67e74705SXin Li   gi = NoViableOverloadObjectSize1(&t[1]);
143*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 360)
144*67e74705SXin Li   gi = NoViableOverloadObjectSize2(&t[1]);
145*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 360)
146*67e74705SXin Li   gi = NoViableOverloadObjectSize3(&t[1]);
147*67e74705SXin Li 
148*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 356)
149*67e74705SXin Li   gi = NoViableOverloadObjectSize0(&t[1].t[1]);
150*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 36)
151*67e74705SXin Li   gi = NoViableOverloadObjectSize1(&t[1].t[1]);
152*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 356)
153*67e74705SXin Li   gi = NoViableOverloadObjectSize2(&t[1].t[1]);
154*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36)
155*67e74705SXin Li   gi = NoViableOverloadObjectSize3(&t[1].t[1]);
156*67e74705SXin Li }
157*67e74705SXin Li 
158*67e74705SXin Li // CHECK-LABEL: define void @test4
test4(struct Foo * t)159*67e74705SXin Li void test4(struct Foo *t) {
160*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}})
161*67e74705SXin Li   gi = NoViableOverloadObjectSize0(&t[1]);
162*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 %{{.*}})
163*67e74705SXin Li   gi = NoViableOverloadObjectSize1(&t[1]);
164*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}})
165*67e74705SXin Li   gi = NoViableOverloadObjectSize2(&t[1]);
166*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 0)
167*67e74705SXin Li   gi = NoViableOverloadObjectSize3(&t[1]);
168*67e74705SXin Li 
169*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}})
170*67e74705SXin Li   gi = NoViableOverloadObjectSize0(&t[1].t[1]);
171*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 36)
172*67e74705SXin Li   gi = NoViableOverloadObjectSize1(&t[1].t[1]);
173*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}})
174*67e74705SXin Li   gi = NoViableOverloadObjectSize2(&t[1].t[1]);
175*67e74705SXin Li   // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36)
176*67e74705SXin Li   gi = NoViableOverloadObjectSize3(&t[1].t[1]);
177*67e74705SXin Li }
178*67e74705SXin Li 
test5()179*67e74705SXin Li void test5() {
180*67e74705SXin Li   struct Foo t[10];
181*67e74705SXin Li 
182*67e74705SXin Li   int (*f)(void *) = &NoViableOverloadObjectSize0;
183*67e74705SXin Li   gi = f(&t[1]);
184*67e74705SXin Li }
185*67e74705SXin Li 
186*67e74705SXin Li // CHECK-LABEL: define i32 @IndirectObjectSize0
187*67e74705SXin Li int IndirectObjectSize0(void *const p PS(0)) {
188*67e74705SXin Li   // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 %{{.*}})
189*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
190*67e74705SXin Li   return ObjectSize0(p);
191*67e74705SXin Li }
192*67e74705SXin Li 
193*67e74705SXin Li // CHECK-LABEL: define i32 @IndirectObjectSize1
194*67e74705SXin Li int IndirectObjectSize1(void *const p PS(1)) {
195*67e74705SXin Li   // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 %{{.*}})
196*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
197*67e74705SXin Li   return ObjectSize1(p);
198*67e74705SXin Li }
199*67e74705SXin Li 
200*67e74705SXin Li // CHECK-LABEL: define i32 @IndirectObjectSize2
201*67e74705SXin Li int IndirectObjectSize2(void *const p PS(2)) {
202*67e74705SXin Li   // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 %{{.*}})
203*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
204*67e74705SXin Li   return ObjectSize2(p);
205*67e74705SXin Li }
206*67e74705SXin Li 
207*67e74705SXin Li // CHECK-LABEL: define i32 @IndirectObjectSize3
208*67e74705SXin Li int IndirectObjectSize3(void *const p PS(3)) {
209*67e74705SXin Li   // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 %{{.*}})
210*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
211*67e74705SXin Li   return ObjectSize3(p);
212*67e74705SXin Li }
213*67e74705SXin Li 
214*67e74705SXin Li int Overload0(void *, size_t, void *, size_t);
215*67e74705SXin Li int OverloadNoSize(void *, void *);
216*67e74705SXin Li 
217*67e74705SXin Li int OverloadedObjectSize(void *const p PS(0),
218*67e74705SXin Li                          void *const c PS(0))
219*67e74705SXin Li     __attribute__((overloadable)) __asm__("Overload0");
220*67e74705SXin Li 
221*67e74705SXin Li int OverloadedObjectSize(void *const p, void *const c)
222*67e74705SXin Li     __attribute__((overloadable)) __asm__("OverloadNoSize");
223*67e74705SXin Li 
224*67e74705SXin Li // CHECK-LABEL: define void @test6
test6()225*67e74705SXin Li void test6() {
226*67e74705SXin Li   int known[10], *opaque;
227*67e74705SXin Li 
228*67e74705SXin Li   // CHECK: call i32 @"\01Overload0"
229*67e74705SXin Li   gi = OverloadedObjectSize(&known[0], &known[0]);
230*67e74705SXin Li 
231*67e74705SXin Li   // CHECK: call i32 @"\01Overload0"
232*67e74705SXin Li   gi = OverloadedObjectSize(&known[0], opaque);
233*67e74705SXin Li 
234*67e74705SXin Li   // CHECK: call i32 @"\01Overload0"
235*67e74705SXin Li   gi = OverloadedObjectSize(opaque, &known[0]);
236*67e74705SXin Li 
237*67e74705SXin Li   // CHECK: call i32 @"\01Overload0"
238*67e74705SXin Li   gi = OverloadedObjectSize(opaque, opaque);
239*67e74705SXin Li }
240*67e74705SXin Li 
Identity(void * p,size_t i)241*67e74705SXin Li int Identity(void *p, size_t i) { return i; }
242*67e74705SXin Li 
243*67e74705SXin Li // CHECK-NOT: define void @AsmObjectSize
244*67e74705SXin Li int AsmObjectSize0(void *const p PS(0)) __asm__("Identity");
245*67e74705SXin Li 
246*67e74705SXin Li int AsmObjectSize1(void *const p PS(1)) __asm__("Identity");
247*67e74705SXin Li 
248*67e74705SXin Li int AsmObjectSize2(void *const p PS(2)) __asm__("Identity");
249*67e74705SXin Li 
250*67e74705SXin Li int AsmObjectSize3(void *const p PS(3)) __asm__("Identity");
251*67e74705SXin Li 
252*67e74705SXin Li // CHECK-LABEL: define void @test7
test7()253*67e74705SXin Li void test7() {
254*67e74705SXin Li   struct Foo t[10];
255*67e74705SXin Li 
256*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360)
257*67e74705SXin Li   gi = AsmObjectSize0(&t[1]);
258*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360)
259*67e74705SXin Li   gi = AsmObjectSize1(&t[1]);
260*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360)
261*67e74705SXin Li   gi = AsmObjectSize2(&t[1]);
262*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360)
263*67e74705SXin Li   gi = AsmObjectSize3(&t[1]);
264*67e74705SXin Li 
265*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356)
266*67e74705SXin Li   gi = AsmObjectSize0(&t[1].t[1]);
267*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36)
268*67e74705SXin Li   gi = AsmObjectSize1(&t[1].t[1]);
269*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356)
270*67e74705SXin Li   gi = AsmObjectSize2(&t[1].t[1]);
271*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36)
272*67e74705SXin Li   gi = AsmObjectSize3(&t[1].t[1]);
273*67e74705SXin Li }
274*67e74705SXin Li 
275*67e74705SXin Li // CHECK-LABEL: define void @test8
test8(struct Foo * t)276*67e74705SXin Li void test8(struct Foo *t) {
277*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36)
278*67e74705SXin Li   gi = AsmObjectSize1(&t[1].t[1]);
279*67e74705SXin Li   // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36)
280*67e74705SXin Li   gi = AsmObjectSize3(&t[1].t[1]);
281*67e74705SXin Li }
282*67e74705SXin Li 
283*67e74705SXin Li void DifferingObjectSize0(void *const p __attribute__((pass_object_size(0))));
284*67e74705SXin Li void DifferingObjectSize1(void *const p __attribute__((pass_object_size(1))));
285*67e74705SXin Li void DifferingObjectSize2(void *const p __attribute__((pass_object_size(2))));
286*67e74705SXin Li void DifferingObjectSize3(void *const p __attribute__((pass_object_size(3))));
287*67e74705SXin Li 
288*67e74705SXin Li // CHECK-LABEL: define void @test9
test9(void * const p)289*67e74705SXin Li void test9(void *const p __attribute__((pass_object_size(0)))) {
290*67e74705SXin Li   // CHECK: @llvm.objectsize
291*67e74705SXin Li   DifferingObjectSize2(p);
292*67e74705SXin Li 
293*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
294*67e74705SXin Li   DifferingObjectSize0(p);
295*67e74705SXin Li   DifferingObjectSize1(p);
296*67e74705SXin Li 
297*67e74705SXin Li   // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
298*67e74705SXin Li   DifferingObjectSize3(p);
299*67e74705SXin Li }
300*67e74705SXin Li 
301*67e74705SXin Li // CHECK-LABEL: define void @test10
test10(void * const p)302*67e74705SXin Li void test10(void *const p __attribute__((pass_object_size(1)))) {
303*67e74705SXin Li   // CHECK: @llvm.objectsize
304*67e74705SXin Li   DifferingObjectSize2(p);
305*67e74705SXin Li   // CHECK: @llvm.objectsize
306*67e74705SXin Li   DifferingObjectSize0(p);
307*67e74705SXin Li 
308*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
309*67e74705SXin Li   DifferingObjectSize1(p);
310*67e74705SXin Li 
311*67e74705SXin Li   // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
312*67e74705SXin Li   DifferingObjectSize3(p);
313*67e74705SXin Li }
314*67e74705SXin Li 
315*67e74705SXin Li // CHECK-LABEL: define void @test11
test11(void * const p)316*67e74705SXin Li void test11(void *const p __attribute__((pass_object_size(2)))) {
317*67e74705SXin Li   // CHECK: @llvm.objectsize
318*67e74705SXin Li   DifferingObjectSize0(p);
319*67e74705SXin Li   // CHECK: @llvm.objectsize
320*67e74705SXin Li   DifferingObjectSize1(p);
321*67e74705SXin Li 
322*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
323*67e74705SXin Li   DifferingObjectSize2(p);
324*67e74705SXin Li 
325*67e74705SXin Li   // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0)
326*67e74705SXin Li   DifferingObjectSize3(p);
327*67e74705SXin Li }
328*67e74705SXin Li 
329*67e74705SXin Li // CHECK-LABEL: define void @test12
test12(void * const p)330*67e74705SXin Li void test12(void *const p __attribute__((pass_object_size(3)))) {
331*67e74705SXin Li   // CHECK: @llvm.objectsize
332*67e74705SXin Li   DifferingObjectSize0(p);
333*67e74705SXin Li   // CHECK: @llvm.objectsize
334*67e74705SXin Li   DifferingObjectSize1(p);
335*67e74705SXin Li 
336*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
337*67e74705SXin Li   DifferingObjectSize2(p);
338*67e74705SXin Li   DifferingObjectSize3(p);
339*67e74705SXin Li }
340*67e74705SXin Li 
341*67e74705SXin Li // CHECK-LABEL: define void @test13
test13()342*67e74705SXin Li void test13() {
343*67e74705SXin Li   // Ensuring that we don't lower objectsize if the expression has side-effects
344*67e74705SXin Li   char c[10];
345*67e74705SXin Li   char *p = c;
346*67e74705SXin Li 
347*67e74705SXin Li   // CHECK: @llvm.objectsize
348*67e74705SXin Li   ObjectSize0(p);
349*67e74705SXin Li 
350*67e74705SXin Li   // CHECK-NOT: @llvm.objectsize
351*67e74705SXin Li   ObjectSize0(++p);
352*67e74705SXin Li   ObjectSize0(p++);
353*67e74705SXin Li }
354*67e74705SXin Li 
355*67e74705SXin Li // There was a bug where variadic functions with pass_object_size would cause
356*67e74705SXin Li // problems in the form of failed assertions.
my_sprintf(char * const c,...)357*67e74705SXin Li void my_sprintf(char *const c __attribute__((pass_object_size(0))), ...) {}
358*67e74705SXin Li 
359*67e74705SXin Li // CHECK-LABEL: define void @test14
test14(char * c)360*67e74705SXin Li void test14(char *c) {
361*67e74705SXin Li   // CHECK: @llvm.objectsize
362*67e74705SXin Li   // CHECK: call void (i8*, i64, ...) @my_sprintf
363*67e74705SXin Li   my_sprintf(c);
364*67e74705SXin Li 
365*67e74705SXin Li   // CHECK: @llvm.objectsize
366*67e74705SXin Li   // CHECK: call void (i8*, i64, ...) @my_sprintf
367*67e74705SXin Li   my_sprintf(c, 1, 2, 3);
368*67e74705SXin Li }
369