Home | History | Annotate | Download | only in CodeGen
      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 }
    520