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