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
__inline_strcpy_chk(char * dest,const char * src)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
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
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
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
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
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
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
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
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
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;
test10()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
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
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
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
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
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
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
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
test18(int cond)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
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
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
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
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
test23(struct Test23Ty * p)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
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
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
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
test27(struct Test27IncompleteTy * t)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
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
test29(struct DynStructVar * dv,struct DynStruct0 * d0,struct DynStruct1 * d1,struct StaticStruct * ss)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
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
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 }
520