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