brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.1 KiB · 2a3dfc8 Raw
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