624 lines · c
1// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s2// RUN: %clang_cc1 -no-enable-noundef-analysis -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s3 4#ifndef DYNAMIC5#define OBJECT_SIZE_BUILTIN __builtin_object_size6#else7#define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size8#endif9 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 15static char *__inline_strcpy_chk (char *dest, const char *src) {16 return __builtin___strcpy_chk(dest, src, OBJECT_SIZE_BUILTIN(dest, 1));17}18 19char gbuf[63];20char *gp;21int gi, gj;22 23// CHECK-LABEL: define{{.*}} void @test124void test1(void) {25 // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 4), ptr @.str, i64 59)26 strcpy(&gbuf[4], "Hi there");27}28 29// CHECK-LABEL: define{{.*}} void @test230void test2(void) {31 // CHECK: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63)32 strcpy(gbuf, "Hi there");33}34 35// CHECK-LABEL: define{{.*}} void @test336void test3(void) {37 // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 100), ptr @.str, i64 0)38 strcpy(&gbuf[100], "Hi there");39}40 41// CHECK-LABEL: define{{.*}} void @test442void test4(void) {43 // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 -1), ptr @.str, i64 0)44 strcpy((char*)(void*)&gbuf[-1], "Hi there");45}46 47// CHECK-LABEL: define{{.*}} void @test548void test5(void) {49 // CHECK: = load ptr, ptr @gp50 // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i151 strcpy(gp, "Hi there");52}53 54// CHECK-LABEL: define{{.*}} void @test655void test6(void) {56 char buf[57];57 58 // CHECK: = call ptr @__strcpy_chk(ptr %{{.*}}, ptr @.str, i64 53)59 strcpy(&buf[4], "Hi there");60}61 62// CHECK-LABEL: define{{.*}} void @test763void test7(void) {64 int i;65 // Ensure we only evaluate the side-effect once.66 // CHECK: = add67 // CHECK-NOT: = add68 // CHECK: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63)69 strcpy((++i, gbuf), "Hi there");70}71 72// CHECK-LABEL: define{{.*}} void @test873void test8(void) {74 char *buf[50];75 // CHECK-NOT: __strcpy_chk76 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)77 strcpy(buf[++gi], "Hi there");78}79 80// CHECK-LABEL: define{{.*}} void @test981void test9(void) {82 // CHECK-NOT: __strcpy_chk83 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)84 strcpy((char *)((++gi) + gj), "Hi there");85}86 87// CHECK-LABEL: define{{.*}} void @test1088char **p;89void test10(void) {90 // CHECK-NOT: __strcpy_chk91 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)92 strcpy(*(++p), "Hi there");93}94 95// CHECK-LABEL: define{{.*}} void @test1196void test11(void) {97 // CHECK-NOT: __strcpy_chk98 // CHECK: = call ptr @__inline_strcpy_chk(ptr @gbuf, ptr @.str)99 strcpy(gp = gbuf, "Hi there");100}101 102// CHECK-LABEL: define{{.*}} void @test12103void test12(void) {104 // CHECK-NOT: __strcpy_chk105 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)106 strcpy(++gp, "Hi there");107}108 109// CHECK-LABEL: define{{.*}} void @test13110void test13(void) {111 // CHECK-NOT: __strcpy_chk112 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)113 strcpy(gp++, "Hi there");114}115 116// CHECK-LABEL: define{{.*}} void @test14117void test14(void) {118 // CHECK-NOT: __strcpy_chk119 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)120 strcpy(--gp, "Hi there");121}122 123// CHECK-LABEL: define{{.*}} void @test15124void test15(void) {125 // CHECK-NOT: __strcpy_chk126 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{..*}}, ptr @.str)127 strcpy(gp--, "Hi there");128}129 130// CHECK-LABEL: define{{.*}} void @test16131void test16(void) {132 // CHECK-NOT: __strcpy_chk133 // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str)134 strcpy(gp += 1, "Hi there");135}136 137// CHECK-LABEL: @test17138void test17(void) {139 // CHECK: store i32 -1140 gi = OBJECT_SIZE_BUILTIN(gp++, 0);141 // CHECK: store i32 -1142 gi = OBJECT_SIZE_BUILTIN(gp++, 1);143 // CHECK: store i32 0144 gi = OBJECT_SIZE_BUILTIN(gp++, 2);145 // CHECK: store i32 0146 gi = OBJECT_SIZE_BUILTIN(gp++, 3);147}148 149// CHECK-LABEL: @test18150unsigned test18(int cond) {151 int a[4], b[4];152 // CHECK: phi ptr153 // CHECK: call i64 @llvm.objectsize.i64154 return OBJECT_SIZE_BUILTIN(cond ? a : b, 0);155}156 157// CHECK-LABEL: @test19158void test19(void) {159 struct {160 int a, b;161 } foo;162 163 // CHECK: store i32 8164 gi = OBJECT_SIZE_BUILTIN(&foo.a, 0);165 // CHECK: store i32 4166 gi = OBJECT_SIZE_BUILTIN(&foo.a, 1);167 // CHECK: store i32 8168 gi = OBJECT_SIZE_BUILTIN(&foo.a, 2);169 // CHECK: store i32 4170 gi = OBJECT_SIZE_BUILTIN(&foo.a, 3);171 172 // CHECK: store i32 4173 gi = OBJECT_SIZE_BUILTIN(&foo.b, 0);174 // CHECK: store i32 4175 gi = OBJECT_SIZE_BUILTIN(&foo.b, 1);176 // CHECK: store i32 4177 gi = OBJECT_SIZE_BUILTIN(&foo.b, 2);178 // CHECK: store i32 4179 gi = OBJECT_SIZE_BUILTIN(&foo.b, 3);180}181 182// CHECK-LABEL: @test20183void test20(void) {184 struct { int t[10]; } t[10];185 186 // CHECK: store i32 380187 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 0);188 // CHECK: store i32 20189 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 1);190 // CHECK: store i32 380191 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 2);192 // CHECK: store i32 20193 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 3);194}195 196// CHECK-LABEL: @test21197void test21(void) {198 struct { int t; } t;199 200 // CHECK: store i32 0201 gi = OBJECT_SIZE_BUILTIN(&t + 1, 0);202 // CHECK: store i32 0203 gi = OBJECT_SIZE_BUILTIN(&t + 1, 1);204 // CHECK: store i32 0205 gi = OBJECT_SIZE_BUILTIN(&t + 1, 2);206 // CHECK: store i32 0207 gi = OBJECT_SIZE_BUILTIN(&t + 1, 3);208 209 // CHECK: store i32 0210 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 0);211 // CHECK: store i32 0212 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 1);213 // CHECK: store i32 0214 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 2);215 // CHECK: store i32 0216 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 3);217}218 219// CHECK-LABEL: @test22220void test22(void) {221 struct { int t[10]; } t[10];222 223 // CHECK: store i32 0224 gi = OBJECT_SIZE_BUILTIN(&t[10], 0);225 // CHECK: store i32 0226 gi = OBJECT_SIZE_BUILTIN(&t[10], 1);227 // CHECK: store i32 0228 gi = OBJECT_SIZE_BUILTIN(&t[10], 2);229 // CHECK: store i32 0230 gi = OBJECT_SIZE_BUILTIN(&t[10], 3);231 232 // CHECK: store i32 0233 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 0);234 // CHECK: store i32 0235 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 1);236 // CHECK: store i32 0237 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 2);238 // CHECK: store i32 0239 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 3);240 241 // CHECK: store i32 0242 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 0);243 // CHECK: store i32 0244 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 1);245 // CHECK: store i32 0246 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 2);247 // CHECK: store i32 0248 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 3);249 250 // CHECK: store i32 0251 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0);252 // CHECK: store i32 0253 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1);254 // CHECK: store i32 0255 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2);256 // CHECK: store i32 0257 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3);258}259 260struct Test23Ty { int a; int t[10]; };261 262// CHECK-LABEL: @test23263void test23(struct Test23Ty *p) {264 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1265 gi = OBJECT_SIZE_BUILTIN(p, 0);266 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1267 gi = OBJECT_SIZE_BUILTIN(p, 1);268 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1269 gi = OBJECT_SIZE_BUILTIN(p, 2);270 // Note: this is currently fixed at 0 because LLVM doesn't have sufficient271 // data to correctly handle type=3272 // CHECK: store i32 0273 gi = OBJECT_SIZE_BUILTIN(p, 3);274 275 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1276 gi = OBJECT_SIZE_BUILTIN(&p->a, 0);277 // CHECK: store i32 4278 gi = OBJECT_SIZE_BUILTIN(&p->a, 1);279 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1280 gi = OBJECT_SIZE_BUILTIN(&p->a, 2);281 // CHECK: store i32 4282 gi = OBJECT_SIZE_BUILTIN(&p->a, 3);283 284 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1285 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 0);286 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1287 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 1);288 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1289 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 2);290 // CHECK: store i32 20291 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 3);292}293 294// PR24493 -- ICE if OBJECT_SIZE_BUILTIN called with NULL and (Type & 1) != 0295// CHECK-LABEL: @test24296void test24(void) {297 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1298 gi = OBJECT_SIZE_BUILTIN((void*)0, 0);299 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1300 gi = OBJECT_SIZE_BUILTIN((void*)0, 1);301 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1302 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 0306 gi = OBJECT_SIZE_BUILTIN((void*)0, 3);307}308 309// CHECK-LABEL: @test25310void test25(void) {311 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1312 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 0);313 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1314 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 1);315 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1316 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 0320 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 3);321 322 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1323 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 0);324 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1325 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 1);326 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1327 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 0331 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 3);332}333 334// CHECK-LABEL: @test26335void test26(void) {336 struct { int v[10]; } t[10];337 338 // CHECK: store i32 316339 gi = OBJECT_SIZE_BUILTIN(&t[1].v[11], 0);340 // CHECK: store i32 312341 gi = OBJECT_SIZE_BUILTIN(&t[1].v[12], 1);342 // CHECK: store i32 308343 gi = OBJECT_SIZE_BUILTIN(&t[1].v[13], 2);344 // CHECK: store i32 0345 gi = OBJECT_SIZE_BUILTIN(&t[1].v[14], 3);346}347 348struct Test27IncompleteTy;349 350// CHECK-LABEL: @test27351void test27(struct Test27IncompleteTy *t) {352 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1353 gi = OBJECT_SIZE_BUILTIN(t, 0);354 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1355 gi = OBJECT_SIZE_BUILTIN(t, 1);356 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1357 gi = OBJECT_SIZE_BUILTIN(t, 2);358 // Note: this is currently fixed at 0 because LLVM doesn't have sufficient359 // data to correctly handle type=3360 // CHECK: store i32 0361 gi = OBJECT_SIZE_BUILTIN(t, 3);362 363 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1364 gi = OBJECT_SIZE_BUILTIN(&test27, 0);365 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1366 gi = OBJECT_SIZE_BUILTIN(&test27, 1);367 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1368 gi = OBJECT_SIZE_BUILTIN(&test27, 2);369 // Note: this is currently fixed at 0 because LLVM doesn't have sufficient370 // data to correctly handle type=3371 // CHECK: store i32 0372 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: @test28378void test28(void) {379 struct { int v[10]; } t[10];380 381#define addCasts(s) ((char*)((short*)(s)))382 // CHECK: store i32 360383 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 0);384 // CHECK: store i32 360385 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 1);386 // CHECK: store i32 360387 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 2);388 // CHECK: store i32 360389 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 3);390 391 // CHECK: store i32 356392 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 0);393 // CHECK: store i32 36394 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 1);395 // CHECK: store i32 356396 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 2);397 // CHECK: store i32 36398 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 3);399#undef addCasts400}401 402struct DynStructVar {403 char fst[16];404 char snd[];405};406 407struct DynStruct0 {408 char fst[16];409 char snd[0];410};411 412struct DynStruct1 {413 char fst[16];414 char snd[1];415};416 417struct StaticStruct {418 char fst[16];419 char snd[2];420};421 422// CHECK-LABEL: @test29423void test29(struct DynStructVar *dv, struct DynStruct0 *d0,424 struct DynStruct1 *d1, struct StaticStruct *ss) {425 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1426 gi = OBJECT_SIZE_BUILTIN(dv->snd, 0);427 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1428 gi = OBJECT_SIZE_BUILTIN(dv->snd, 1);429 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1430 gi = OBJECT_SIZE_BUILTIN(dv->snd, 2);431 // CHECK: store i32 0432 gi = OBJECT_SIZE_BUILTIN(dv->snd, 3);433 434 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1435 gi = OBJECT_SIZE_BUILTIN(d0->snd, 0);436 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1437 gi = OBJECT_SIZE_BUILTIN(d0->snd, 1);438 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1439 gi = OBJECT_SIZE_BUILTIN(d0->snd, 2);440 // CHECK: store i32 0441 gi = OBJECT_SIZE_BUILTIN(d0->snd, 3);442 443 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1444 gi = OBJECT_SIZE_BUILTIN(d1->snd, 0);445 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1446 gi = OBJECT_SIZE_BUILTIN(d1->snd, 1);447 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1448 gi = OBJECT_SIZE_BUILTIN(d1->snd, 2);449 // CHECK: store i32 1450 gi = OBJECT_SIZE_BUILTIN(d1->snd, 3);451 452 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1453 gi = OBJECT_SIZE_BUILTIN(ss->snd, 0);454 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1455 gi = OBJECT_SIZE_BUILTIN(ss->snd, 1);456 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1457 gi = OBJECT_SIZE_BUILTIN(ss->snd, 2);458 // CHECK: store i32 2459 gi = OBJECT_SIZE_BUILTIN(ss->snd, 3);460}461 462// CHECK-LABEL: @test30463void test30(void) {464 struct { struct DynStruct1 fst, snd; } *nested;465 466 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1467 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 0);468 // CHECK: store i32 1469 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 1);470 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1471 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 2);472 // CHECK: store i32 1473 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 3);474 475 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1476 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 0);477 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1478 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 1);479 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1480 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 2);481 // CHECK: store i32 1482 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.p0(ptr %{{.*}}, i1 false, i1 true, i1486 gi = OBJECT_SIZE_BUILTIN(u->c, 0);487 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1488 gi = OBJECT_SIZE_BUILTIN(u->c, 1);489 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1490 gi = OBJECT_SIZE_BUILTIN(u->c, 2);491 // CHECK: store i32 1492 gi = OBJECT_SIZE_BUILTIN(u->c, 3);493 494 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1495 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 0);496 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1497 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 1);498 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1499 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 2);500 // CHECK: store i32 1501 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 3);502}503 504// CHECK-LABEL: @test31505void test31(void) {506 // Miscellaneous 'writing off the end' detection tests507 struct DynStructVar *dsv;508 struct DynStruct0 *ds0;509 struct DynStruct1 *ds1;510 struct StaticStruct *ss;511 512 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1513 gi = OBJECT_SIZE_BUILTIN(ds1[9].snd, 1);514 515 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1516 gi = OBJECT_SIZE_BUILTIN(&ss[9].snd[0], 1);517 518 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1519 gi = OBJECT_SIZE_BUILTIN(&ds1[9].snd[0], 1);520 521 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1522 gi = OBJECT_SIZE_BUILTIN(&ds0[9].snd[0], 1);523 524 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1525 gi = OBJECT_SIZE_BUILTIN(&dsv[9].snd[0], 1);526}527 528// CHECK-LABEL: @test32529static struct DynStructVar D32 = {530 .fst = {},531 .snd = { 0, 1, 2, },532};533unsigned long test32(void) {534 // CHECK: ret i64 19535 return OBJECT_SIZE_BUILTIN(&D32, 1);536}537// CHECK-LABEL: @test33538static struct DynStructVar D33 = {539 .fst = {},540 .snd = {},541};542unsigned long test33(void) {543 // CHECK: ret i64 16544 return OBJECT_SIZE_BUILTIN(&D33, 1);545}546// CHECK-LABEL: @test34547static struct DynStructVar D34 = {548 .fst = {},549};550unsigned long test34(void) {551 // CHECK: ret i64 16552 return OBJECT_SIZE_BUILTIN(&D34, 1);553}554// CHECK-LABEL: @test35555unsigned long test35(void) {556 // CHECK: ret i64 16557 return OBJECT_SIZE_BUILTIN(&(struct DynStructVar){}, 1);558}559extern void *memset (void *s, int c, unsigned long n);560void test36(void) {561 struct DynStructVar D;562 // FORTIFY will check the object size of D. Test this doesn't assert when563 // given a struct with a flexible array member that lacks an initializer.564 memset(&D, 0, sizeof(D));565}566// CHECK-LABEL: @test37567struct Z { struct A { int x, y[]; } z; int a; int b[]; };568static struct Z my_z = { .b = {1,2,3} };569unsigned long test37 (void) {570 // CHECK: ret i64 4571 return OBJECT_SIZE_BUILTIN(&my_z.z, 1);572}573 574// CHECK-LABEL: @PR30346575void PR30346(void) {576 struct sa_family_t {};577 struct sockaddr {578 struct sa_family_t sa_family;579 char sa_data[14];580 };581 582 struct sockaddr *sa;583 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1584 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 0);585 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1586 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 1);587 // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1588 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 2);589 // CHECK: store i32 14590 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 3);591}592 593extern char incomplete_char_array[];594// CHECK-LABEL: @incomplete_and_function_types595void incomplete_and_function_types(void) {596 // CHECK: call i64 @llvm.objectsize.i64.p0597 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 0);598 // CHECK: call i64 @llvm.objectsize.i64.p0599 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 1);600 // CHECK: call i64 @llvm.objectsize.i64.p0601 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 2);602 // CHECK: store i32 0603 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 3);604}605 606// Flips between the pointer and lvalue evaluator a lot.607void deeply_nested(void) {608 struct {609 struct {610 struct {611 struct {612 int e[2];613 char f; // Inhibit our writing-off-the-end check614 } d[2];615 } c[2];616 } b[2];617 } *a;618 619 // CHECK: store i32 4620 gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 1);621 // CHECK: store i32 4622 gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 3);623}624