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