1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li #define strcpy(dest, src) \
4*67e74705SXin Li ((__builtin_object_size(dest, 0) != -1ULL) \
5*67e74705SXin Li ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
6*67e74705SXin Li : __inline_strcpy_chk(dest, src))
7*67e74705SXin Li
__inline_strcpy_chk(char * dest,const char * src)8*67e74705SXin Li static char *__inline_strcpy_chk (char *dest, const char *src) {
9*67e74705SXin Li return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1));
10*67e74705SXin Li }
11*67e74705SXin Li
12*67e74705SXin Li char gbuf[63];
13*67e74705SXin Li char *gp;
14*67e74705SXin Li int gi, gj;
15*67e74705SXin Li
16*67e74705SXin Li // CHECK-LABEL: define void @test1
test1()17*67e74705SXin Li void test1() {
18*67e74705SXin Li // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 4), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 59)
19*67e74705SXin Li strcpy(&gbuf[4], "Hi there");
20*67e74705SXin Li }
21*67e74705SXin Li
22*67e74705SXin Li // CHECK-LABEL: define void @test2
test2()23*67e74705SXin Li void test2() {
24*67e74705SXin Li // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 63)
25*67e74705SXin Li strcpy(gbuf, "Hi there");
26*67e74705SXin Li }
27*67e74705SXin Li
28*67e74705SXin Li // CHECK-LABEL: define void @test3
test3()29*67e74705SXin Li void test3() {
30*67e74705SXin Li // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 0)
31*67e74705SXin Li strcpy(&gbuf[100], "Hi there");
32*67e74705SXin Li }
33*67e74705SXin Li
34*67e74705SXin Li // CHECK-LABEL: define void @test4
test4()35*67e74705SXin Li void test4() {
36*67e74705SXin Li // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 -1), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 0)
37*67e74705SXin Li strcpy((char*)(void*)&gbuf[-1], "Hi there");
38*67e74705SXin Li }
39*67e74705SXin Li
40*67e74705SXin Li // CHECK-LABEL: define void @test5
test5()41*67e74705SXin Li void test5() {
42*67e74705SXin Li // CHECK: = load i8*, i8** @gp
43*67e74705SXin Li // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
44*67e74705SXin Li strcpy(gp, "Hi there");
45*67e74705SXin Li }
46*67e74705SXin Li
47*67e74705SXin Li // CHECK-LABEL: define void @test6
test6()48*67e74705SXin Li void test6() {
49*67e74705SXin Li char buf[57];
50*67e74705SXin Li
51*67e74705SXin Li // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 53)
52*67e74705SXin Li strcpy(&buf[4], "Hi there");
53*67e74705SXin Li }
54*67e74705SXin Li
55*67e74705SXin Li // CHECK-LABEL: define void @test7
test7()56*67e74705SXin Li void test7() {
57*67e74705SXin Li int i;
58*67e74705SXin Li // Ensure we only evaluate the side-effect once.
59*67e74705SXin Li // CHECK: = add
60*67e74705SXin Li // CHECK-NOT: = add
61*67e74705SXin Li // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 63)
62*67e74705SXin Li strcpy((++i, gbuf), "Hi there");
63*67e74705SXin Li }
64*67e74705SXin Li
65*67e74705SXin Li // CHECK-LABEL: define void @test8
test8()66*67e74705SXin Li void test8() {
67*67e74705SXin Li char *buf[50];
68*67e74705SXin Li // CHECK-NOT: __strcpy_chk
69*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
70*67e74705SXin Li strcpy(buf[++gi], "Hi there");
71*67e74705SXin Li }
72*67e74705SXin Li
73*67e74705SXin Li // CHECK-LABEL: define void @test9
test9()74*67e74705SXin Li void test9() {
75*67e74705SXin Li // CHECK-NOT: __strcpy_chk
76*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
77*67e74705SXin Li strcpy((char *)((++gi) + gj), "Hi there");
78*67e74705SXin Li }
79*67e74705SXin Li
80*67e74705SXin Li // CHECK-LABEL: define void @test10
81*67e74705SXin Li char **p;
test10()82*67e74705SXin Li void test10() {
83*67e74705SXin Li // CHECK-NOT: __strcpy_chk
84*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
85*67e74705SXin Li strcpy(*(++p), "Hi there");
86*67e74705SXin Li }
87*67e74705SXin Li
88*67e74705SXin Li // CHECK-LABEL: define void @test11
test11()89*67e74705SXin Li void test11() {
90*67e74705SXin Li // CHECK-NOT: __strcpy_chk
91*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
92*67e74705SXin Li strcpy(gp = gbuf, "Hi there");
93*67e74705SXin Li }
94*67e74705SXin Li
95*67e74705SXin Li // CHECK-LABEL: define void @test12
test12()96*67e74705SXin Li void test12() {
97*67e74705SXin Li // CHECK-NOT: __strcpy_chk
98*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
99*67e74705SXin Li strcpy(++gp, "Hi there");
100*67e74705SXin Li }
101*67e74705SXin Li
102*67e74705SXin Li // CHECK-LABEL: define void @test13
test13()103*67e74705SXin Li void test13() {
104*67e74705SXin Li // CHECK-NOT: __strcpy_chk
105*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
106*67e74705SXin Li strcpy(gp++, "Hi there");
107*67e74705SXin Li }
108*67e74705SXin Li
109*67e74705SXin Li // CHECK-LABEL: define void @test14
test14()110*67e74705SXin Li void test14() {
111*67e74705SXin Li // CHECK-NOT: __strcpy_chk
112*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
113*67e74705SXin Li strcpy(--gp, "Hi there");
114*67e74705SXin Li }
115*67e74705SXin Li
116*67e74705SXin Li // CHECK-LABEL: define void @test15
test15()117*67e74705SXin Li void test15() {
118*67e74705SXin Li // CHECK-NOT: __strcpy_chk
119*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
120*67e74705SXin Li strcpy(gp--, "Hi there");
121*67e74705SXin Li }
122*67e74705SXin Li
123*67e74705SXin Li // CHECK-LABEL: define void @test16
test16()124*67e74705SXin Li void test16() {
125*67e74705SXin Li // CHECK-NOT: __strcpy_chk
126*67e74705SXin Li // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
127*67e74705SXin Li strcpy(gp += 1, "Hi there");
128*67e74705SXin Li }
129*67e74705SXin Li
130*67e74705SXin Li // CHECK-LABEL: @test17
test17()131*67e74705SXin Li void test17() {
132*67e74705SXin Li // CHECK: store i32 -1
133*67e74705SXin Li gi = __builtin_object_size(gp++, 0);
134*67e74705SXin Li // CHECK: store i32 -1
135*67e74705SXin Li gi = __builtin_object_size(gp++, 1);
136*67e74705SXin Li // CHECK: store i32 0
137*67e74705SXin Li gi = __builtin_object_size(gp++, 2);
138*67e74705SXin Li // CHECK: store i32 0
139*67e74705SXin Li gi = __builtin_object_size(gp++, 3);
140*67e74705SXin Li }
141*67e74705SXin Li
142*67e74705SXin Li // CHECK-LABEL: @test18
test18(int cond)143*67e74705SXin Li unsigned test18(int cond) {
144*67e74705SXin Li int a[4], b[4];
145*67e74705SXin Li // CHECK: phi i32*
146*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64
147*67e74705SXin Li return __builtin_object_size(cond ? a : b, 0);
148*67e74705SXin Li }
149*67e74705SXin Li
150*67e74705SXin Li // CHECK-LABEL: @test19
test19()151*67e74705SXin Li void test19() {
152*67e74705SXin Li struct {
153*67e74705SXin Li int a, b;
154*67e74705SXin Li } foo;
155*67e74705SXin Li
156*67e74705SXin Li // CHECK: store i32 8
157*67e74705SXin Li gi = __builtin_object_size(&foo.a, 0);
158*67e74705SXin Li // CHECK: store i32 4
159*67e74705SXin Li gi = __builtin_object_size(&foo.a, 1);
160*67e74705SXin Li // CHECK: store i32 8
161*67e74705SXin Li gi = __builtin_object_size(&foo.a, 2);
162*67e74705SXin Li // CHECK: store i32 4
163*67e74705SXin Li gi = __builtin_object_size(&foo.a, 3);
164*67e74705SXin Li
165*67e74705SXin Li // CHECK: store i32 4
166*67e74705SXin Li gi = __builtin_object_size(&foo.b, 0);
167*67e74705SXin Li // CHECK: store i32 4
168*67e74705SXin Li gi = __builtin_object_size(&foo.b, 1);
169*67e74705SXin Li // CHECK: store i32 4
170*67e74705SXin Li gi = __builtin_object_size(&foo.b, 2);
171*67e74705SXin Li // CHECK: store i32 4
172*67e74705SXin Li gi = __builtin_object_size(&foo.b, 3);
173*67e74705SXin Li }
174*67e74705SXin Li
175*67e74705SXin Li // CHECK-LABEL: @test20
test20()176*67e74705SXin Li void test20() {
177*67e74705SXin Li struct { int t[10]; } t[10];
178*67e74705SXin Li
179*67e74705SXin Li // CHECK: store i32 380
180*67e74705SXin Li gi = __builtin_object_size(&t[0].t[5], 0);
181*67e74705SXin Li // CHECK: store i32 20
182*67e74705SXin Li gi = __builtin_object_size(&t[0].t[5], 1);
183*67e74705SXin Li // CHECK: store i32 380
184*67e74705SXin Li gi = __builtin_object_size(&t[0].t[5], 2);
185*67e74705SXin Li // CHECK: store i32 20
186*67e74705SXin Li gi = __builtin_object_size(&t[0].t[5], 3);
187*67e74705SXin Li }
188*67e74705SXin Li
189*67e74705SXin Li // CHECK-LABEL: @test21
test21()190*67e74705SXin Li void test21() {
191*67e74705SXin Li struct { int t; } t;
192*67e74705SXin Li
193*67e74705SXin Li // CHECK: store i32 0
194*67e74705SXin Li gi = __builtin_object_size(&t + 1, 0);
195*67e74705SXin Li // CHECK: store i32 0
196*67e74705SXin Li gi = __builtin_object_size(&t + 1, 1);
197*67e74705SXin Li // CHECK: store i32 0
198*67e74705SXin Li gi = __builtin_object_size(&t + 1, 2);
199*67e74705SXin Li // CHECK: store i32 0
200*67e74705SXin Li gi = __builtin_object_size(&t + 1, 3);
201*67e74705SXin Li
202*67e74705SXin Li // CHECK: store i32 0
203*67e74705SXin Li gi = __builtin_object_size(&t.t + 1, 0);
204*67e74705SXin Li // CHECK: store i32 0
205*67e74705SXin Li gi = __builtin_object_size(&t.t + 1, 1);
206*67e74705SXin Li // CHECK: store i32 0
207*67e74705SXin Li gi = __builtin_object_size(&t.t + 1, 2);
208*67e74705SXin Li // CHECK: store i32 0
209*67e74705SXin Li gi = __builtin_object_size(&t.t + 1, 3);
210*67e74705SXin Li }
211*67e74705SXin Li
212*67e74705SXin Li // CHECK-LABEL: @test22
test22()213*67e74705SXin Li void test22() {
214*67e74705SXin Li struct { int t[10]; } t[10];
215*67e74705SXin Li
216*67e74705SXin Li // CHECK: store i32 0
217*67e74705SXin Li gi = __builtin_object_size(&t[10], 0);
218*67e74705SXin Li // CHECK: store i32 0
219*67e74705SXin Li gi = __builtin_object_size(&t[10], 1);
220*67e74705SXin Li // CHECK: store i32 0
221*67e74705SXin Li gi = __builtin_object_size(&t[10], 2);
222*67e74705SXin Li // CHECK: store i32 0
223*67e74705SXin Li gi = __builtin_object_size(&t[10], 3);
224*67e74705SXin Li
225*67e74705SXin Li // CHECK: store i32 0
226*67e74705SXin Li gi = __builtin_object_size(&t[9].t[10], 0);
227*67e74705SXin Li // CHECK: store i32 0
228*67e74705SXin Li gi = __builtin_object_size(&t[9].t[10], 1);
229*67e74705SXin Li // CHECK: store i32 0
230*67e74705SXin Li gi = __builtin_object_size(&t[9].t[10], 2);
231*67e74705SXin Li // CHECK: store i32 0
232*67e74705SXin Li gi = __builtin_object_size(&t[9].t[10], 3);
233*67e74705SXin Li
234*67e74705SXin Li // CHECK: store i32 0
235*67e74705SXin Li gi = __builtin_object_size((char*)&t[0] + sizeof(t), 0);
236*67e74705SXin Li // CHECK: store i32 0
237*67e74705SXin Li gi = __builtin_object_size((char*)&t[0] + sizeof(t), 1);
238*67e74705SXin Li // CHECK: store i32 0
239*67e74705SXin Li gi = __builtin_object_size((char*)&t[0] + sizeof(t), 2);
240*67e74705SXin Li // CHECK: store i32 0
241*67e74705SXin Li gi = __builtin_object_size((char*)&t[0] + sizeof(t), 3);
242*67e74705SXin Li
243*67e74705SXin Li // CHECK: store i32 0
244*67e74705SXin Li gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0);
245*67e74705SXin Li // CHECK: store i32 0
246*67e74705SXin Li gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1);
247*67e74705SXin Li // CHECK: store i32 0
248*67e74705SXin Li gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2);
249*67e74705SXin Li // CHECK: store i32 0
250*67e74705SXin Li gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3);
251*67e74705SXin Li }
252*67e74705SXin Li
253*67e74705SXin Li struct Test23Ty { int a; int t[10]; };
254*67e74705SXin Li
255*67e74705SXin Li // CHECK-LABEL: @test23
test23(struct Test23Ty * p)256*67e74705SXin Li void test23(struct Test23Ty *p) {
257*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
258*67e74705SXin Li gi = __builtin_object_size(p, 0);
259*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
260*67e74705SXin Li gi = __builtin_object_size(p, 1);
261*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
262*67e74705SXin Li gi = __builtin_object_size(p, 2);
263*67e74705SXin Li // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
264*67e74705SXin Li // data to correctly handle type=3
265*67e74705SXin Li // CHECK: store i32 0
266*67e74705SXin Li gi = __builtin_object_size(p, 3);
267*67e74705SXin Li
268*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
269*67e74705SXin Li gi = __builtin_object_size(&p->a, 0);
270*67e74705SXin Li // CHECK: store i32 4
271*67e74705SXin Li gi = __builtin_object_size(&p->a, 1);
272*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
273*67e74705SXin Li gi = __builtin_object_size(&p->a, 2);
274*67e74705SXin Li // CHECK: store i32 4
275*67e74705SXin Li gi = __builtin_object_size(&p->a, 3);
276*67e74705SXin Li
277*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
278*67e74705SXin Li gi = __builtin_object_size(&p->t[5], 0);
279*67e74705SXin Li // CHECK: store i32 20
280*67e74705SXin Li gi = __builtin_object_size(&p->t[5], 1);
281*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
282*67e74705SXin Li gi = __builtin_object_size(&p->t[5], 2);
283*67e74705SXin Li // CHECK: store i32 20
284*67e74705SXin Li gi = __builtin_object_size(&p->t[5], 3);
285*67e74705SXin Li }
286*67e74705SXin Li
287*67e74705SXin Li // PR24493 -- ICE if __builtin_object_size called with NULL and (Type & 1) != 0
288*67e74705SXin Li // CHECK-LABEL: @test24
test24()289*67e74705SXin Li void test24() {
290*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
291*67e74705SXin Li gi = __builtin_object_size((void*)0, 0);
292*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
293*67e74705SXin Li gi = __builtin_object_size((void*)0, 1);
294*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true)
295*67e74705SXin Li gi = __builtin_object_size((void*)0, 2);
296*67e74705SXin Li // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
297*67e74705SXin Li // Hopefully will be lowered properly in the future.
298*67e74705SXin Li // CHECK: store i32 0
299*67e74705SXin Li gi = __builtin_object_size((void*)0, 3);
300*67e74705SXin Li }
301*67e74705SXin Li
302*67e74705SXin Li // CHECK-LABEL: @test25
test25()303*67e74705SXin Li void test25() {
304*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
305*67e74705SXin Li gi = __builtin_object_size((void*)0x1000, 0);
306*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
307*67e74705SXin Li gi = __builtin_object_size((void*)0x1000, 1);
308*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true)
309*67e74705SXin Li gi = __builtin_object_size((void*)0x1000, 2);
310*67e74705SXin Li // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
311*67e74705SXin Li // Hopefully will be lowered properly in the future.
312*67e74705SXin Li // CHECK: store i32 0
313*67e74705SXin Li gi = __builtin_object_size((void*)0x1000, 3);
314*67e74705SXin Li
315*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
316*67e74705SXin Li gi = __builtin_object_size((void*)0 + 0x1000, 0);
317*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
318*67e74705SXin Li gi = __builtin_object_size((void*)0 + 0x1000, 1);
319*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true)
320*67e74705SXin Li gi = __builtin_object_size((void*)0 + 0x1000, 2);
321*67e74705SXin Li // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
322*67e74705SXin Li // Hopefully will be lowered properly in the future.
323*67e74705SXin Li // CHECK: store i32 0
324*67e74705SXin Li gi = __builtin_object_size((void*)0 + 0x1000, 3);
325*67e74705SXin Li }
326*67e74705SXin Li
327*67e74705SXin Li // CHECK-LABEL: @test26
test26()328*67e74705SXin Li void test26() {
329*67e74705SXin Li struct { int v[10]; } t[10];
330*67e74705SXin Li
331*67e74705SXin Li // CHECK: store i32 316
332*67e74705SXin Li gi = __builtin_object_size(&t[1].v[11], 0);
333*67e74705SXin Li // CHECK: store i32 312
334*67e74705SXin Li gi = __builtin_object_size(&t[1].v[12], 1);
335*67e74705SXin Li // CHECK: store i32 308
336*67e74705SXin Li gi = __builtin_object_size(&t[1].v[13], 2);
337*67e74705SXin Li // CHECK: store i32 0
338*67e74705SXin Li gi = __builtin_object_size(&t[1].v[14], 3);
339*67e74705SXin Li }
340*67e74705SXin Li
341*67e74705SXin Li struct Test27IncompleteTy;
342*67e74705SXin Li
343*67e74705SXin Li // CHECK-LABEL: @test27
test27(struct Test27IncompleteTy * t)344*67e74705SXin Li void test27(struct Test27IncompleteTy *t) {
345*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
346*67e74705SXin Li gi = __builtin_object_size(t, 0);
347*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
348*67e74705SXin Li gi = __builtin_object_size(t, 1);
349*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
350*67e74705SXin Li gi = __builtin_object_size(t, 2);
351*67e74705SXin Li // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
352*67e74705SXin Li // data to correctly handle type=3
353*67e74705SXin Li // CHECK: store i32 0
354*67e74705SXin Li gi = __builtin_object_size(t, 3);
355*67e74705SXin Li
356*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
357*67e74705SXin Li gi = __builtin_object_size(&test27, 0);
358*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
359*67e74705SXin Li gi = __builtin_object_size(&test27, 1);
360*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true)
361*67e74705SXin Li gi = __builtin_object_size(&test27, 2);
362*67e74705SXin Li // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
363*67e74705SXin Li // data to correctly handle type=3
364*67e74705SXin Li // CHECK: store i32 0
365*67e74705SXin Li gi = __builtin_object_size(&test27, 3);
366*67e74705SXin Li }
367*67e74705SXin Li
368*67e74705SXin Li // The intent of this test is to ensure that __builtin_object_size treats `&foo`
369*67e74705SXin Li // and `(T*)&foo` identically, when used as the pointer argument.
370*67e74705SXin Li // CHECK-LABEL: @test28
test28()371*67e74705SXin Li void test28() {
372*67e74705SXin Li struct { int v[10]; } t[10];
373*67e74705SXin Li
374*67e74705SXin Li #define addCasts(s) ((char*)((short*)(s)))
375*67e74705SXin Li // CHECK: store i32 360
376*67e74705SXin Li gi = __builtin_object_size(addCasts(&t[1]), 0);
377*67e74705SXin Li // CHECK: store i32 360
378*67e74705SXin Li gi = __builtin_object_size(addCasts(&t[1]), 1);
379*67e74705SXin Li // CHECK: store i32 360
380*67e74705SXin Li gi = __builtin_object_size(addCasts(&t[1]), 2);
381*67e74705SXin Li // CHECK: store i32 360
382*67e74705SXin Li gi = __builtin_object_size(addCasts(&t[1]), 3);
383*67e74705SXin Li
384*67e74705SXin Li // CHECK: store i32 356
385*67e74705SXin Li gi = __builtin_object_size(addCasts(&t[1].v[1]), 0);
386*67e74705SXin Li // CHECK: store i32 36
387*67e74705SXin Li gi = __builtin_object_size(addCasts(&t[1].v[1]), 1);
388*67e74705SXin Li // CHECK: store i32 356
389*67e74705SXin Li gi = __builtin_object_size(addCasts(&t[1].v[1]), 2);
390*67e74705SXin Li // CHECK: store i32 36
391*67e74705SXin Li gi = __builtin_object_size(addCasts(&t[1].v[1]), 3);
392*67e74705SXin Li #undef addCasts
393*67e74705SXin Li }
394*67e74705SXin Li
395*67e74705SXin Li struct DynStructVar {
396*67e74705SXin Li char fst[16];
397*67e74705SXin Li char snd[];
398*67e74705SXin Li };
399*67e74705SXin Li
400*67e74705SXin Li struct DynStruct0 {
401*67e74705SXin Li char fst[16];
402*67e74705SXin Li char snd[0];
403*67e74705SXin Li };
404*67e74705SXin Li
405*67e74705SXin Li struct DynStruct1 {
406*67e74705SXin Li char fst[16];
407*67e74705SXin Li char snd[1];
408*67e74705SXin Li };
409*67e74705SXin Li
410*67e74705SXin Li struct StaticStruct {
411*67e74705SXin Li char fst[16];
412*67e74705SXin Li char snd[2];
413*67e74705SXin Li };
414*67e74705SXin Li
415*67e74705SXin Li // CHECK-LABEL: @test29
test29(struct DynStructVar * dv,struct DynStruct0 * d0,struct DynStruct1 * d1,struct StaticStruct * ss)416*67e74705SXin Li void test29(struct DynStructVar *dv, struct DynStruct0 *d0,
417*67e74705SXin Li struct DynStruct1 *d1, struct StaticStruct *ss) {
418*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
419*67e74705SXin Li gi = __builtin_object_size(dv->snd, 0);
420*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
421*67e74705SXin Li gi = __builtin_object_size(dv->snd, 1);
422*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
423*67e74705SXin Li gi = __builtin_object_size(dv->snd, 2);
424*67e74705SXin Li // CHECK: store i32 0
425*67e74705SXin Li gi = __builtin_object_size(dv->snd, 3);
426*67e74705SXin Li
427*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
428*67e74705SXin Li gi = __builtin_object_size(d0->snd, 0);
429*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
430*67e74705SXin Li gi = __builtin_object_size(d0->snd, 1);
431*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
432*67e74705SXin Li gi = __builtin_object_size(d0->snd, 2);
433*67e74705SXin Li // CHECK: store i32 0
434*67e74705SXin Li gi = __builtin_object_size(d0->snd, 3);
435*67e74705SXin Li
436*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
437*67e74705SXin Li gi = __builtin_object_size(d1->snd, 0);
438*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
439*67e74705SXin Li gi = __builtin_object_size(d1->snd, 1);
440*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
441*67e74705SXin Li gi = __builtin_object_size(d1->snd, 2);
442*67e74705SXin Li // CHECK: store i32 1
443*67e74705SXin Li gi = __builtin_object_size(d1->snd, 3);
444*67e74705SXin Li
445*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
446*67e74705SXin Li gi = __builtin_object_size(ss->snd, 0);
447*67e74705SXin Li // CHECK: store i32 2
448*67e74705SXin Li gi = __builtin_object_size(ss->snd, 1);
449*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
450*67e74705SXin Li gi = __builtin_object_size(ss->snd, 2);
451*67e74705SXin Li // CHECK: store i32 2
452*67e74705SXin Li gi = __builtin_object_size(ss->snd, 3);
453*67e74705SXin Li }
454*67e74705SXin Li
455*67e74705SXin Li // CHECK-LABEL: @test30
test30()456*67e74705SXin Li void test30() {
457*67e74705SXin Li struct { struct DynStruct1 fst, snd; } *nested;
458*67e74705SXin Li
459*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
460*67e74705SXin Li gi = __builtin_object_size(nested->fst.snd, 0);
461*67e74705SXin Li // CHECK: store i32 1
462*67e74705SXin Li gi = __builtin_object_size(nested->fst.snd, 1);
463*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
464*67e74705SXin Li gi = __builtin_object_size(nested->fst.snd, 2);
465*67e74705SXin Li // CHECK: store i32 1
466*67e74705SXin Li gi = __builtin_object_size(nested->fst.snd, 3);
467*67e74705SXin Li
468*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
469*67e74705SXin Li gi = __builtin_object_size(nested->snd.snd, 0);
470*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
471*67e74705SXin Li gi = __builtin_object_size(nested->snd.snd, 1);
472*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
473*67e74705SXin Li gi = __builtin_object_size(nested->snd.snd, 2);
474*67e74705SXin Li // CHECK: store i32 1
475*67e74705SXin Li gi = __builtin_object_size(nested->snd.snd, 3);
476*67e74705SXin Li
477*67e74705SXin Li union { struct DynStruct1 d1; char c[1]; } *u;
478*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
479*67e74705SXin Li gi = __builtin_object_size(u->c, 0);
480*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
481*67e74705SXin Li gi = __builtin_object_size(u->c, 1);
482*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
483*67e74705SXin Li gi = __builtin_object_size(u->c, 2);
484*67e74705SXin Li // CHECK: store i32 1
485*67e74705SXin Li gi = __builtin_object_size(u->c, 3);
486*67e74705SXin Li
487*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
488*67e74705SXin Li gi = __builtin_object_size(u->d1.snd, 0);
489*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
490*67e74705SXin Li gi = __builtin_object_size(u->d1.snd, 1);
491*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
492*67e74705SXin Li gi = __builtin_object_size(u->d1.snd, 2);
493*67e74705SXin Li // CHECK: store i32 1
494*67e74705SXin Li gi = __builtin_object_size(u->d1.snd, 3);
495*67e74705SXin Li }
496*67e74705SXin Li
497*67e74705SXin Li // CHECK-LABEL: @test31
test31()498*67e74705SXin Li void test31() {
499*67e74705SXin Li // Miscellaneous 'writing off the end' detection tests
500*67e74705SXin Li struct DynStructVar *dsv;
501*67e74705SXin Li struct DynStruct0 *ds0;
502*67e74705SXin Li struct DynStruct1 *ds1;
503*67e74705SXin Li struct StaticStruct *ss;
504*67e74705SXin Li
505*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
506*67e74705SXin Li gi = __builtin_object_size(ds1[9].snd, 1);
507*67e74705SXin Li
508*67e74705SXin Li // CHECK: store i32 2
509*67e74705SXin Li gi = __builtin_object_size(&ss[9].snd[0], 1);
510*67e74705SXin Li
511*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
512*67e74705SXin Li gi = __builtin_object_size(&ds1[9].snd[0], 1);
513*67e74705SXin Li
514*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
515*67e74705SXin Li gi = __builtin_object_size(&ds0[9].snd[0], 1);
516*67e74705SXin Li
517*67e74705SXin Li // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
518*67e74705SXin Li gi = __builtin_object_size(&dsv[9].snd[0], 1);
519*67e74705SXin Li }
520