1 // RUN: %clang_cc1 -no-opaque-pointers %s -I%S -triple=x86_64-apple-darwin10 -fstrict-vtable-pointers -std=c++11 -disable-llvm-passes -O2 -emit-llvm -o %t.ll 2 // RUN: FileCheck --check-prefix=CHECK-CTORS %s < %t.ll 3 // RUN: FileCheck --check-prefix=CHECK-NEW %s < %t.ll 4 // RUN: FileCheck --check-prefix=CHECK-DTORS %s < %t.ll 5 // RUN: FileCheck --check-prefix=CHECK-LINK-REQ %s < %t.ll 6 7 typedef __typeof__(sizeof(0)) size_t; 8 void *operator new(size_t, void *) throw(); 9 using uintptr_t = unsigned long long; 10 11 struct NotTrivialDtor { 12 ~NotTrivialDtor(); 13 }; 14 15 struct DynamicBase1 { 16 NotTrivialDtor obj; 17 virtual void foo(); 18 }; 19 20 struct DynamicDerived : DynamicBase1 { 21 void foo() override; 22 }; 23 24 struct DynamicBase2 { 25 virtual void bar(); 26 ~DynamicBase2() { 27 bar(); 28 } 29 }; 30 31 struct DynamicDerivedMultiple : DynamicBase1, DynamicBase2 { 32 void foo() override; 33 void bar() override; 34 }; 35 36 struct StaticBase { 37 NotTrivialDtor obj; 38 void bar(); 39 }; 40 41 struct DynamicFromStatic : StaticBase { 42 virtual void bar(); 43 }; 44 45 struct DynamicFromVirtualStatic1 : virtual StaticBase { 46 }; 47 48 struct DynamicFromVirtualStatic2 : virtual StaticBase { 49 }; 50 51 struct DynamicFrom2Virtuals : DynamicFromVirtualStatic1, 52 DynamicFromVirtualStatic2 { 53 }; 54 55 // CHECK-NEW-LABEL: define{{.*}} void @_Z12LocalObjectsv() 56 // CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8( 57 // CHECK-NEW-LABEL: {{^}}} 58 void LocalObjects() { 59 DynamicBase1 DB; 60 DB.foo(); 61 DynamicDerived DD; 62 DD.foo(); 63 64 DynamicBase2 DB2; 65 DB2.bar(); 66 67 StaticBase SB; 68 SB.bar(); 69 70 DynamicDerivedMultiple DDM; 71 DDM.foo(); 72 DDM.bar(); 73 74 DynamicFromStatic DFS; 75 DFS.bar(); 76 DynamicFromVirtualStatic1 DFVS1; 77 DFVS1.bar(); 78 DynamicFrom2Virtuals DF2V; 79 DF2V.bar(); 80 } 81 82 struct DynamicFromVirtualStatic1; 83 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic1C1Ev 84 // CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8( 85 // CHECK-CTORS-LABEL: {{^}}} 86 87 struct DynamicFrom2Virtuals; 88 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev 89 // CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8( 90 // CHECK-CTORS-LABEL: {{^}}} 91 92 // CHECK-NEW-LABEL: define{{.*}} void @_Z9Pointers1v() 93 // CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8( 94 // CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev( 95 96 // CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS2:.*]]) 97 // CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]* 98 // CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* {{[^,]*}} %[[THIS4]]) 99 // CHECK-NEW-LABEL: {{^}}} 100 void Pointers1() { 101 DynamicBase1 *DB = new DynamicBase1; 102 DB->foo(); 103 104 DynamicDerived *DD = new (DB) DynamicDerived; 105 DD->foo(); 106 DD->~DynamicDerived(); 107 } 108 109 // CHECK-NEW-LABEL: define{{.*}} void @_Z14HackingObjectsv() 110 // CHECK-NEW: call void @_ZN12DynamicBase1C1Ev 111 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8( 112 // CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev( 113 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8( 114 // CHECK-NEW: call void @_ZN12DynamicBase1C1Ev( 115 // CHECK-NEW-LABEL: {{^}}} 116 void HackingObjects() { 117 DynamicBase1 DB; 118 DB.foo(); 119 120 DynamicDerived *DB2 = new (&DB) DynamicDerived; 121 // Using DB now is prohibited. 122 DB2->foo(); 123 DB2->~DynamicDerived(); 124 125 // We have to get back to the previous type to avoid calling wrong destructor 126 new (&DB) DynamicBase1; 127 DB.foo(); 128 } 129 130 /*** Testing Constructors ***/ 131 struct DynamicBase1; 132 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev( 133 // CHECK-CTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8( 134 // CHECK-CTORS-LABEL: {{^}}} 135 136 struct DynamicDerived; 137 138 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev( 139 // CHECK-CTORS: %[[THIS0:.*]] = load %[[DynamicDerived:.*]]*, %[[DynamicDerived]]** {{.*}} 140 // CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0]] to i8* 141 // CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS1:.*]]) 142 // CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[DynamicDerived]]* 143 // CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[DynamicDerived]]* %[[THIS3]] to %[[DynamicBase:.*]]* 144 // CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[DynamicBase]]* {{[^,]*}} %[[THIS4]]) 145 146 // CHECK-CTORS: %[[THIS5:.*]] = bitcast %struct.DynamicDerived* %[[THIS0]] to i32 (...)*** 147 // CHECK-CTORS: store {{.*}} %[[THIS5]] 148 // CHECK-CTORS-LABEL: {{^}}} 149 150 struct DynamicDerivedMultiple; 151 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleC2Ev( 152 153 // CHECK-CTORS: %[[THIS0:.*]] = load %[[CLASS:.*]]*, %[[CLASS]]** {{.*}} 154 // CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0]] to i8* 155 // CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS1]]) 156 // CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[CLASS]]* 157 // CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[CLASS]]* %[[THIS3]] to %[[BASE_CLASS:.*]]* 158 // CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[BASE_CLASS]]* {{[^,]*}} %[[THIS4]]) 159 160 // CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8( 161 162 // CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev( 163 // CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8 164 165 // CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)*** 166 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 0, i32 2) {{.*}} %[[THIS10]] 167 // CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8* 168 // CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16 169 // CHECK-CTORS: %[[THIS12:.*]] = bitcast i8* %[[THIS_ADD]] to i32 (...)*** 170 171 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 1, i32 2) {{.*}} %[[THIS12]] 172 // CHECK-CTORS-LABEL: {{^}}} 173 174 struct DynamicFromStatic; 175 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev( 176 // CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8( 177 // CHECK-CTORS-LABEL: {{^}}} 178 179 struct A { 180 virtual void foo(); 181 int m; 182 }; 183 struct B : A { 184 void foo() override; 185 }; 186 187 union U { 188 A a; 189 B b; 190 }; 191 192 void changeToB(U *u); 193 void changeToA(U *u); 194 195 void g2(A *a) { 196 a->foo(); 197 } 198 // We have to guard access to union fields with invariant.group, because 199 // it is very easy to skip the barrier with unions. In this example the inlined 200 // g2 will produce loads with the same !invariant.group metadata, and 201 // u->a and u->b would use the same pointer. 202 // CHECK-NEW-LABEL: define{{.*}} void @_Z14UnionsBarriersP1U 203 void UnionsBarriers(U *u) { 204 // CHECK-NEW: call void @_Z9changeToBP1U( 205 changeToB(u); 206 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8* 207 // CHECK-NEW: call void @_Z2g2P1A(%struct.A* 208 g2(&u->b); 209 // CHECK-NEW: call void @_Z9changeToAP1U(%union.U* 210 changeToA(u); 211 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8* 212 // call void @_Z2g2P1A(%struct.A* %a) 213 g2(&u->a); 214 // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8* 215 } 216 217 struct HoldingVirtuals { 218 A a; 219 }; 220 221 struct Empty {}; 222 struct AnotherEmpty { 223 Empty e; 224 }; 225 union NoVptrs { 226 int a; 227 AnotherEmpty empty; 228 }; 229 void take(AnotherEmpty &); 230 231 // CHECK-NEW-LABEL: noBarriers 232 void noBarriers(NoVptrs &noVptrs) { 233 // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8* 234 // CHECK-NEW: 42 235 noVptrs.a += 42; 236 // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8* 237 // CHECK-NEW: call void @_Z4takeR12AnotherEmpty( 238 take(noVptrs.empty); 239 } 240 241 union U2 { 242 HoldingVirtuals h; 243 int z; 244 }; 245 void take(HoldingVirtuals &); 246 247 // CHECK-NEW-LABEL: define{{.*}} void @_Z15UnionsBarriers2R2U2 248 void UnionsBarriers2(U2 &u) { 249 // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8* 250 // CHECK-NEW: 42 251 u.z += 42; 252 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8* 253 // CHECK-NEW: call void @_Z4takeR15HoldingVirtuals( 254 take(u.h); 255 } 256 257 struct VirtualInBase : HoldingVirtuals, Empty { 258 }; 259 260 struct VirtualInVBase : virtual Empty, virtual HoldingVirtuals { 261 }; 262 263 // It has vtable by virtual inheritance. 264 struct VirtualInheritance : virtual Empty { 265 }; 266 267 union U3 { 268 VirtualInBase v1; 269 VirtualInBase v2; 270 VirtualInheritance v3; 271 int z; 272 }; 273 274 void take(VirtualInBase &); 275 void take(VirtualInVBase &); 276 void take(VirtualInheritance &); 277 278 void UnionsBarrier3(U3 &u) { 279 // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8* 280 // CHECK-NEW: 42 281 u.z += 42; 282 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8* 283 // CHECK-NEW: call void @_Z4takeR13VirtualInBase( 284 take(u.v1); 285 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8* 286 // CHECK-NEW: call void @_Z4takeR13VirtualInBase( 287 take(u.v2); 288 289 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8* 290 // CHECK-NEW: call void @_Z4takeR18VirtualInheritance( 291 take(u.v3); 292 } 293 294 // CHECK-NEW-LABEL: define{{.*}} void @_Z7comparev() 295 void compare() { 296 A *a = new A; 297 a->foo(); 298 // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8* 299 A *b = new (a) B; 300 301 // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* 302 // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A* 303 // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* 304 // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A* 305 // CHECK-NEW: %cmp = icmp eq %struct.A* %[[a2]], %[[b2]] 306 if (a == b) 307 b->foo(); 308 } 309 310 // CHECK-NEW-LABEL: compare2 311 bool compare2(A *a, A *a2) { 312 // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* 313 // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A* 314 // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* 315 // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A* 316 // CHECK-NEW: %cmp = icmp ult %struct.A* %[[a2]], %[[b2]] 317 return a < a2; 318 } 319 // CHECK-NEW-LABEL: compareIntPointers 320 bool compareIntPointers(int *a, int *b) { 321 // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group 322 return a == b; 323 } 324 325 struct HoldingOtherVirtuals { 326 B b; 327 }; 328 329 // There is no need to add barriers for comparision of pointer to classes 330 // that are not dynamic. 331 // CHECK-NEW-LABEL: compare5 332 bool compare5(HoldingOtherVirtuals *a, HoldingOtherVirtuals *b) { 333 // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group 334 return a == b; 335 } 336 // CHECK-NEW-LABEL: compareNull 337 bool compareNull(A *a) { 338 // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group 339 340 if (a != nullptr) 341 return false; 342 if (!a) 343 return false; 344 return a == nullptr; 345 } 346 347 struct X; 348 // We have to also introduce the barriers if comparing pointers to incomplete 349 // objects 350 // CHECK-NEW-LABEL: define{{.*}} zeroext i1 @_Z8compare4P1XS0_ 351 bool compare4(X *x, X *x2) { 352 // CHECK-NEW: %[[x:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* 353 // CHECK-NEW: %[[xp:.*]] = bitcast i8* %[[x]] to %struct.X* 354 // CHECK-NEW: %[[x2:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* 355 // CHECK-NEW: %[[x2p:.*]] = bitcast i8* %[[x2]] to %struct.X* 356 // CHECK-NEW: %cmp = icmp eq %struct.X* %[[xp]], %[[x2p]] 357 return x == x2; 358 } 359 360 // CHECK-NEW-LABEL: define{{.*}} void @_Z7member1P20HoldingOtherVirtuals( 361 void member1(HoldingOtherVirtuals *p) { 362 363 // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group.p0i8( 364 (void)p->b; 365 } 366 367 // CHECK-NEW-LABEL: member2 368 void member2(A *a) { 369 // CHECK-NEW: call i8* @llvm.strip.invariant.group.p0i8 370 (void)a->m; 371 } 372 373 // Check if from comparison of addresses of member we can't infer the equality 374 // of ap and bp. 375 // CHECK-NEW-LABEL: @_Z18testCompareMembersv( 376 void testCompareMembers() { 377 // CHECK-NEW: [[AP:%.*]] = alloca %struct.A* 378 // CHECK-NEW: [[APM:%.*]] = alloca i32* 379 // CHECK-NEW: [[BP:%.*]] = alloca %struct.B* 380 // CHECK-NEW: [[BPM:%.*]] = alloca i32* 381 382 A *ap = new A; 383 // CHECK-NEW: call void %{{.*}}(%struct.A* {{[^,]*}} %{{.*}}) 384 ap->foo(); 385 // CHECK-NEW: [[TMP7:%.*]] = load %struct.A*, %struct.A** [[AP]] 386 // CHECK-NEW: [[TMP8:%.*]] = bitcast %struct.A* [[TMP7]] to i8* 387 // CHECK-NEW: [[TMP9:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[TMP8]]) 388 // CHECK-NEW: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to %struct.A* 389 // CHECK-NEW: [[M:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[TMP10]], i32 0, i32 1 390 // CHECK-NEW: store i32* [[M]], i32** [[APM]] 391 int *const apm = &ap->m; 392 393 B *bp = new (ap) B; 394 395 // CHECK-NEW: [[TMP20:%.*]] = load %struct.B*, %struct.B** [[BP]] 396 // CHECK-NEW: [[TMP21:%.*]] = bitcast %struct.B* [[TMP20]] to %struct.A* 397 // CHECK-NEW: [[TMP22:%.*]] = bitcast %struct.A* [[TMP21]] to i8* 398 // CHECK-NEW: [[TMP23:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[TMP22]]) 399 // CHECK-NEW: [[TMP24:%.*]] = bitcast i8* [[TMP23]] to %struct.A* 400 // CHECK-NEW: [[M4:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP24]], i32 0, i32 1 401 // CHECK-NEW: store i32* [[M4]], i32** [[BPM]] 402 int *const bpm = &bp->m; 403 404 // CHECK-NEW: [[TMP25:%.*]] = load i32*, i32** [[APM]] 405 // CHECK-NEW: [[TMP26:%.*]] = load i32*, i32** [[BPM]] 406 // CHECK-NEW-NOT: strip.invariant.group 407 // CHECK-NEW-NOT: launder.invariant.group 408 // CHECK-NEW: [[CMP:%.*]] = icmp eq i32* [[TMP25]], [[TMP26]] 409 if (apm == bpm) { 410 bp->foo(); 411 } 412 } 413 414 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast1P1A(%struct.A* 415 void testCast1(A *a) { 416 // Here we get rid of dynamic info 417 // CHECK-NEW: call i8* @llvm.strip.invariant.group 418 auto *v = (void *)a; 419 420 // CHECK-NEW: call i8* @llvm.strip.invariant.group 421 auto i2 = (uintptr_t)a; 422 (void)i2; 423 424 // CHECK-NEW-NOT: @llvm.strip.invariant.group 425 // CHECK-NEW-NOT: @llvm.launder.invariant.group 426 427 // The information is already stripped 428 auto i = (uintptr_t)v; 429 } 430 431 struct Incomplete; 432 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast2P10Incomplete(%struct.Incomplete* 433 void testCast2(Incomplete *I) { 434 // Here we get rid of potential dynamic info 435 // CHECK-NEW: call i8* @llvm.strip.invariant.group 436 auto *v = (void *)I; 437 438 // CHECK-NEW: call i8* @llvm.strip.invariant.group 439 auto i2 = (uintptr_t)I; 440 (void)i2; 441 442 // CHECK-NEW-NOT: @llvm.strip.invariant.group 443 // CHECK-NEW-NOT: @llvm.launder.invariant.group 444 445 // The information is already stripped 446 auto i = (uintptr_t)v; 447 } 448 449 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast3y( 450 void testCast3(uintptr_t i) { 451 // CHECK-NEW-NOT: @llvm.strip.invariant.group 452 // CHECK-NEW: @llvm.launder.invariant.group 453 A *a3 = (A *)i; 454 (void)a3; 455 456 auto *v2 = (void *)i; 457 458 // CHECK-NEW: @llvm.launder.invariant.group 459 A *a2 = (A *)v2; 460 (void)a2; 461 462 // CHECK-NEW-NOT: @llvm.launder.invariant.group 463 auto *v3 = (void *)i; 464 (void)v3; 465 } 466 467 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast4y( 468 void testCast4(uintptr_t i) { 469 // CHECK-NEW-NOT: @llvm.strip.invariant.group 470 // CHECK-NEW: @llvm.launder.invariant.group 471 auto *a3 = (Incomplete *)i; 472 (void)a3; 473 474 // CHECK-NEW: @llvm.launder.invariant.group 475 auto *v2 = (void *)i; 476 // CHECK-NEW-NOT: @llvm.launder.invariant.group 477 auto *a2 = (Incomplete *)v2; 478 (void)a2; 479 } 480 481 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast5P1B( 482 void testCast5(B *b) { 483 // CHECK-NEW-NOT: @llvm.strip.invariant.group 484 // CHECK-NEW-NOT: @llvm.launder.invariant.group 485 A *a = b; 486 (void)a; 487 488 auto *b2 = (B *)a; 489 (void)b2; 490 } 491 492 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast6P1A( 493 void testCast6(A *a) { 494 495 // CHECK-NEW: @llvm.strip.invariant.group 496 auto *I = (Incomplete *)a; 497 (void)I; 498 // CHECK-NEW: @llvm.launder.invariant.group 499 auto *a2 = (A *)I; 500 (void)a2; 501 502 // CHECK-NEW: @llvm.strip.invariant.group 503 auto *E = (Empty *)a; 504 (void)E; 505 506 // CHECK-NEW: @llvm.launder.invariant.group 507 auto *a3 = (A *)E; 508 (void)a3; 509 510 // CHECK-NEW-NOT: @llvm.strip.invariant.group 511 auto i = (uintptr_t)E; 512 (void)i; 513 } 514 515 class Incomplete2; 516 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast7P10Incomplete( 517 void testCast7(Incomplete *I) { 518 // CHECK-NEW-NOT: @llvm.strip.invariant.group 519 520 // Incomplete2 could be dynamic where Incomplete may not be dynamic, thus 521 // launder is needed. We don't strip firstly because launder is sufficient. 522 523 // CHECK-NEW: @llvm.launder.invariant.group 524 auto *I2 = (Incomplete2 *)I; 525 (void)I2; 526 // CHECK-NEW-LABEL: ret void 527 } 528 529 template <typename Base> 530 struct PossiblyDerivingFromDynamicBase : Base { 531 }; 532 533 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast8P10Incomplete( 534 void testCast8(Incomplete *I) { 535 // CHECK-NEW-NOT: @llvm.strip.invariant.group 536 // CHECK-NEW: @llvm.launder.invariant.group 537 auto *P = (PossiblyDerivingFromDynamicBase<Incomplete> *)I; 538 (void)P; 539 540 // CHECK-NEW: @llvm.launder.invariant.group 541 auto *P2 = (PossiblyDerivingFromDynamicBase<Empty> *)I; 542 (void)P2; 543 544 // CHECK-NEW: @llvm.launder.invariant.group 545 auto *P3 = (PossiblyDerivingFromDynamicBase<A> *)I; 546 (void)P3; 547 548 // CHECK-NEW-NOT: @llvm.launder.invariant.group 549 auto *a3 = (A *)P3; 550 551 // CHECK-NEW-LABEL: ret void 552 } 553 554 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast9 555 void testCast9(PossiblyDerivingFromDynamicBase<Incomplete> *P) { 556 // CHECK-NEW: @llvm.strip.invariant.group 557 auto *V = (void *)P; 558 559 // CHECK-NEW-LABEL: ret void 560 } 561 562 /** DTORS **/ 563 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev( 564 // CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8( 565 // CHECK-DTORS-LABEL: {{^}}} 566 567 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic2D2Ev( 568 // CHECK-DTORS-NOT: invariant.barrier 569 // CHECK-DTORS-LABEL: {{^}}} 570 571 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev 572 // CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8( 573 // CHECK-DTORS-LABEL: {{^}}} 574 575 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev( 576 577 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev( 578 // CHECK-DTORS: call i8* @llvm.launder.invariant.group.p0i8( 579 // CHECK-DTORS-LABEL: {{^}}} 580 581 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev 582 // CHECK-DTORS: call i8* @llvm.launder.invariant.group.p0i8( 583 // CHECK-DTORS-LABEL: {{^}}} 584 585 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev 586 // CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8( 587 // CHECK-DTORS-LABEL: {{^}}} 588 589 // CHECK-LINK-REQ: !llvm.module.flags = !{![[FIRST:[0-9]+]], ![[SEC:[0-9]+]]{{.*}}} 590 591 // CHECK-LINK-REQ: ![[FIRST]] = !{i32 1, !"StrictVTablePointers", i32 1} 592 // CHECK-LINK-REQ: ![[SEC]] = !{i32 3, !"StrictVTablePointersRequirement", ![[META:.*]]} 593 // CHECK-LINK-REQ: ![[META]] = !{!"StrictVTablePointers", i32 1} 594