diff options
Diffstat (limited to 'gnu/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp index 22055b2cb90..0a766d17620 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp @@ -281,10 +281,10 @@ void EHScopeStack::popNullFixups() { BranchFixups.pop_back(); } -void CodeGenFunction::initFullExprCleanup() { +Address CodeGenFunction::createCleanupActiveFlag() { // Create a variable to decide whether the cleanup needs to be run. - Address active = CreateTempAlloca(Builder.getInt1Ty(), CharUnits::One(), - "cleanup.cond"); + Address active = CreateTempAllocaWithoutCast( + Builder.getInt1Ty(), CharUnits::One(), "cleanup.cond"); // Initialize it to false at a site that's guaranteed to be run // before each evaluation. @@ -293,10 +293,14 @@ void CodeGenFunction::initFullExprCleanup() { // Initialize it to true at the current location. Builder.CreateStore(Builder.getTrue(), active); + return active; +} + +void CodeGenFunction::initFullExprCleanupWithFlag(Address ActiveFlag) { // Set that as the active flag in the cleanup. EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin()); assert(!cleanup.hasActiveFlag() && "cleanup already has active flag?"); - cleanup.setActiveFlag(active); + cleanup.setActiveFlag(ActiveFlag); if (cleanup.isNormalCleanup()) cleanup.setTestFlagInNormalCleanup(); if (cleanup.isEHCleanup()) cleanup.setTestFlagInEHCleanup(); @@ -315,7 +319,7 @@ static llvm::LoadInst *createLoadInstBefore(Address addr, const Twine &name, auto load = new llvm::LoadInst(addr.getPointer(), name, beforeInst); load->setAlignment(addr.getAlignment().getQuantity()); return load; -} +} /// All the branch fixups on the EH stack have propagated out past the /// outermost normal cleanup; resolve them all by adding cases to the @@ -494,6 +498,13 @@ void CodeGenFunction::PopCleanupBlocks( &LifetimeExtendedCleanupStack[I], Header.getSize()); I += Header.getSize(); + + if (Header.isConditional()) { + Address ActiveFlag = + reinterpret_cast<Address &>(LifetimeExtendedCleanupStack[I]); + initFullExprCleanupWithFlag(ActiveFlag); + I += sizeof(ActiveFlag); + } } LifetimeExtendedCleanupStack.resize(OldLifetimeExtendedSize); } @@ -610,7 +621,7 @@ static void destroyOptimisticNormalEntry(CodeGenFunction &CGF, ++i; use.set(unreachableBB); - + // The only uses should be fixup switches. llvm::SwitchInst *si = cast<llvm::SwitchInst>(use.getUser()); if (si->getNumCases() == 1 && si->getDefaultDest() == unreachableBB) { @@ -624,12 +635,12 @@ static void destroyOptimisticNormalEntry(CodeGenFunction &CGF, si->eraseFromParent(); // Destroy the load. - assert(condition->getOperand(0) == CGF.NormalCleanupDest); + assert(condition->getOperand(0) == CGF.NormalCleanupDest.getPointer()); assert(condition->use_empty()); condition->eraseFromParent(); } } - + assert(entry->use_empty()); delete entry; } @@ -648,7 +659,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { Address NormalActiveFlag = Scope.shouldTestFlagInNormalCleanup() ? Scope.getActiveFlag() : Address::invalid(); - Address EHActiveFlag = + Address EHActiveFlag = Scope.shouldTestFlagInEHCleanup() ? Scope.getActiveFlag() : Address::invalid(); @@ -697,7 +708,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // cleanup, rewrite it so that it leads to the appropriate place. if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) { llvm::BasicBlock *prebranchDest; - + // If the prebranch is semantically branching through the next // cleanup, just forward it to the next block, leaving the // insertion point in the prebranched block. @@ -833,7 +844,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (NormalCleanupDestSlot->hasOneUse()) { NormalCleanupDestSlot->user_back()->eraseFromParent(); NormalCleanupDestSlot->eraseFromParent(); - NormalCleanupDest = nullptr; + NormalCleanupDest = Address::invalid(); } llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0); @@ -911,7 +922,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { } // V. Set up the fallthrough edge out. - + // Case 1: a fallthrough source exists but doesn't branch to the // cleanup because the cleanup is inactive. if (!HasFallthrough && FallthroughSource) { @@ -971,16 +982,21 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad( CurrentFuncletPad); llvm::CleanupPadInst *CPI = nullptr; - if (!EHPersonality::get(*this).usesFuncletPads()) { - EHStack.pushTerminate(); - PushedTerminate = true; - } else { + + const EHPersonality &Personality = EHPersonality::get(*this); + if (Personality.usesFuncletPads()) { llvm::Value *ParentPad = CurrentFuncletPad; if (!ParentPad) ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext()); CurrentFuncletPad = CPI = Builder.CreateCleanupPad(ParentPad); } + // Non-MSVC personalities need to terminate when an EH cleanup throws. + if (!Personality.isMSVCPersonality()) { + EHStack.pushTerminate(); + PushedTerminate = true; + } + // We only actually emit the cleanup code if the cleanup is either // active or was used before it was deactivated. if (EHActiveFlag.isValid() || IsActive) { @@ -1009,11 +1025,11 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { bool CodeGenFunction::isObviouslyBranchWithoutCleanups(JumpDest Dest) const { assert(Dest.getScopeDepth().encloses(EHStack.stable_begin()) && "stale jump destination"); - + // Calculate the innermost active normal cleanup. EHScopeStack::stable_iterator TopCleanup = EHStack.getInnermostActiveNormalCleanup(); - + // If we're not in an active normal cleanup scope, or if the // destination scope is within the innermost active normal cleanup // scope, we don't need to worry about fixups. @@ -1103,7 +1119,7 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { break; } } - + Builder.ClearInsertionPoint(); } @@ -1233,8 +1249,10 @@ void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C, EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C)); assert(Scope.isActive() && "double deactivation"); - // If it's the top of the stack, just pop it. - if (C == EHStack.stable_begin()) { + // If it's the top of the stack, just pop it, but do so only if it belongs + // to the current RunCleanupsScope. + if (C == EHStack.stable_begin() && + CurrentCleanupScopeDepth.strictlyEncloses(C)) { // If it's a normal cleanup, we need to pretend that the // fallthrough is unreachable. CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); @@ -1250,10 +1268,10 @@ void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C, } Address CodeGenFunction::getNormalCleanupDestSlot() { - if (!NormalCleanupDest) + if (!NormalCleanupDest.isValid()) NormalCleanupDest = - CreateTempAlloca(Builder.getInt32Ty(), "cleanup.dest.slot"); - return Address(NormalCleanupDest, CharUnits::fromQuantity(4)); + CreateDefaultAlignTempAlloca(Builder.getInt32Ty(), "cleanup.dest.slot"); + return NormalCleanupDest; } /// Emits all the code to cause the given temporary to be cleaned up. |
