@@ -5412,13 +5412,50 @@ namespace {
5412
5412
enumAddr);
5413
5413
}
5414
5414
5415
+ llvm::Value *testResilientTag (IRGenFunction &IGF, llvm::Value *tag,
5416
+ EnumElementDecl *Case) const {
5417
+ auto &C = IGM.getLLVMContext ();
5418
+
5419
+ // If the enum case is weakly linked check the address of the case
5420
+ // first.
5421
+ llvm::BasicBlock *conditionalBlock = nullptr ;
5422
+ llvm::BasicBlock *afterConditionalBlock = nullptr ;
5423
+ llvm::BasicBlock *beforeNullPtrCheck = nullptr ;
5424
+ if (Case->isWeakImported (IGM.getSwiftModule ())) {
5425
+ beforeNullPtrCheck = IGF.Builder .GetInsertBlock ();
5426
+ auto address = IGM.getAddrOfEnumCase (Case, NotForDefinition);
5427
+ conditionalBlock = llvm::BasicBlock::Create (C);
5428
+ afterConditionalBlock = llvm::BasicBlock::Create (C);
5429
+ auto *addressVal =
5430
+ IGF.Builder .CreatePtrToInt (address.getAddress (), IGM.IntPtrTy );
5431
+ auto isNullPtr = IGF.Builder .CreateICmpEQ (
5432
+ addressVal, llvm::ConstantInt::get (IGM.IntPtrTy , 0 ));
5433
+ IGF.Builder .CreateCondBr (isNullPtr, afterConditionalBlock,
5434
+ conditionalBlock);
5435
+ }
5436
+ if (conditionalBlock)
5437
+ IGF.Builder .emitBlock (conditionalBlock);
5438
+
5439
+ // Check the tag.
5440
+ auto tagVal = loadResilientTagIndex (IGF, Case);
5441
+ auto matchesTag = IGF.Builder .CreateICmpEQ (tag, tagVal);
5442
+ if (conditionalBlock) {
5443
+ IGF.Builder .CreateBr (afterConditionalBlock);
5444
+ IGF.Builder .emitBlock (afterConditionalBlock);
5445
+ auto phi = IGF.Builder .CreatePHI (IGM.Int1Ty , 2 );
5446
+ phi->addIncoming (IGF.Builder .getInt1 (false ), beforeNullPtrCheck);
5447
+ phi->addIncoming (matchesTag, conditionalBlock);
5448
+ matchesTag = phi;
5449
+ }
5450
+ return matchesTag;
5451
+ }
5452
+
5415
5453
llvm::Value *
5416
5454
emitIndirectCaseTest (IRGenFunction &IGF, SILType T,
5417
5455
Address enumAddr,
5418
5456
EnumElementDecl *Case) const override {
5419
5457
llvm::Value *tag = emitGetEnumTagCall (IGF, T, enumAddr);
5420
- llvm::Value *expectedTag = loadResilientTagIndex (IGF, Case);
5421
- return IGF.Builder .CreateICmpEQ (tag, expectedTag);
5458
+ return testResilientTag (IGF, tag, Case);
5422
5459
}
5423
5460
5424
5461
void emitIndirectSwitch (IRGenFunction &IGF,
@@ -5453,8 +5490,8 @@ namespace {
5453
5490
if (continuationBB)
5454
5491
IGF.Builder .emitBlock (continuationBB);
5455
5492
5456
- auto tagVal = loadResilientTagIndex (IGF, elt. decl );
5457
- auto matchesTag = IGF. Builder . CreateICmpEQ ( tag, tagVal );
5493
+ // Check the tag.
5494
+ auto matchesTag = testResilientTag (IGF, tag, elt. decl );
5458
5495
5459
5496
// If we are not the last block create a continuation block.
5460
5497
if (++numCasesEmitted < dests.size ())
0 commit comments