More cleanup enabling.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111070 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGException.h b/lib/CodeGen/CGException.h
index f40e3e3..f129474 100644
--- a/lib/CodeGen/CGException.h
+++ b/lib/CodeGen/CGException.h
@@ -565,6 +565,28 @@
return stable_iterator(EndOfBuffer - ir.Ptr);
}
+inline EHScopeStack::stable_iterator
+EHScopeStack::getInnermostActiveNormalCleanup() const {
+ for (EHScopeStack::stable_iterator
+ I = getInnermostNormalCleanup(), E = stable_end(); I != E; ) {
+ EHCleanupScope &S = cast<EHCleanupScope>(*find(I));
+ if (S.isActive()) return I;
+ I = S.getEnclosingNormalCleanup();
+ }
+ return stable_end();
+}
+
+inline EHScopeStack::stable_iterator
+EHScopeStack::getInnermostActiveEHCleanup() const {
+ for (EHScopeStack::stable_iterator
+ I = getInnermostEHCleanup(), E = stable_end(); I != E; ) {
+ EHCleanupScope &S = cast<EHCleanupScope>(*find(I));
+ if (S.isActive()) return I;
+ I = S.getEnclosingEHCleanup();
+ }
+ return stable_end();
+}
+
}
}
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index b3ac8f1..5bee016 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -805,6 +805,7 @@
assert(isa<EHCleanupScope>(*EHStack.begin()) && "top not a cleanup!");
EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin());
assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups());
+ assert(Scope.isActive() && "cleanup was still inactive when popped!");
// Check whether we need an EH cleanup. This is only true if we've
// generated a lazy EH cleanup block.
@@ -1100,11 +1101,15 @@
// Create the branch.
llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
- // If we're not in a cleanup scope, or if the destination scope is
- // the current normal-cleanup scope, we don't need to worry about
- // fixups.
- if (!EHStack.hasNormalCleanups() ||
- Dest.getScopeDepth() == EHStack.getInnermostNormalCleanup()) {
+ // 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.
+ if (TopCleanup == EHStack.stable_end() ||
+ TopCleanup.encloses(Dest.getScopeDepth())) { // works for invalid
Builder.ClearInsertionPoint();
return;
}
@@ -1131,12 +1136,12 @@
// Adjust BI to point to the first cleanup block.
{
EHCleanupScope &Scope =
- cast<EHCleanupScope>(*EHStack.find(EHStack.getInnermostNormalCleanup()));
+ cast<EHCleanupScope>(*EHStack.find(TopCleanup));
BI->setSuccessor(0, CreateNormalEntry(*this, Scope));
}
// Add this destination to all the scopes involved.
- EHScopeStack::stable_iterator I = EHStack.getInnermostNormalCleanup();
+ EHScopeStack::stable_iterator I = TopCleanup;
EHScopeStack::stable_iterator E = Dest.getScopeDepth();
if (E.strictlyEncloses(I)) {
while (true) {
@@ -1173,13 +1178,17 @@
// Create the branch.
llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
+ // Calculate the innermost active cleanup.
+ EHScopeStack::stable_iterator
+ InnermostCleanup = EHStack.getInnermostActiveEHCleanup();
+
// If the destination is in the same EH cleanup scope as us, we
// don't need to thread through anything.
- if (Dest.getScopeDepth() == EHStack.getInnermostEHCleanup()) {
+ if (InnermostCleanup.encloses(Dest.getScopeDepth())) {
Builder.ClearInsertionPoint();
return;
}
- assert(EHStack.hasEHCleanups());
+ assert(InnermostCleanup != EHStack.stable_end());
// Store the index at the start.
llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex());
@@ -1188,14 +1197,13 @@
// Adjust BI to point to the first cleanup block.
{
EHCleanupScope &Scope =
- cast<EHCleanupScope>(*EHStack.find(EHStack.getInnermostEHCleanup()));
+ cast<EHCleanupScope>(*EHStack.find(InnermostCleanup));
BI->setSuccessor(0, CreateEHEntry(*this, Scope));
}
// Add this destination to all the scopes involved.
for (EHScopeStack::stable_iterator
- I = EHStack.getInnermostEHCleanup(),
- E = Dest.getScopeDepth(); ; ) {
+ I = InnermostCleanup, E = Dest.getScopeDepth(); ; ) {
assert(E.strictlyEncloses(I));
EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(I));
assert(Scope.isEHCleanup());
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 3d212b5..a7c3a28 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -127,7 +127,15 @@
bool isValid() const { return Size >= 0; }
+ /// Returns true if this scope encloses I.
+ /// Returns false if I is invalid.
+ /// This scope must be valid.
bool encloses(stable_iterator I) const { return Size <= I.Size; }
+
+ /// Returns true if this scope strictly encloses I: that is,
+ /// if it encloses I and is not I.
+ /// Returns false is I is invalid.
+ /// This scope must be valid.
bool strictlyEncloses(stable_iterator I) const { return Size < I.Size; }
friend bool operator==(stable_iterator A, stable_iterator B) {
@@ -317,6 +325,7 @@
stable_iterator getInnermostNormalCleanup() const {
return InnermostNormalCleanup;
}
+ stable_iterator getInnermostActiveNormalCleanup() const; // CGException.h
/// Determines whether there are any EH cleanups on the stack.
bool hasEHCleanups() const {
@@ -328,6 +337,7 @@
stable_iterator getInnermostEHCleanup() const {
return InnermostEHCleanup;
}
+ stable_iterator getInnermostActiveEHCleanup() const; // CGException.h
/// An unstable reference to a scope-stack depth. Invalidated by
/// pushes but not pops.