forked from OSchip/llvm-project
Teach PopCleanupBlock to correctly handle the possibility of branching through
a EH-only cleanup as part of a fallthrough branch-through. That this happens for this test case is actually a separate bug. llvm-svn: 115668
This commit is contained in:
parent
44e5c1f16c
commit
e5dd32da11
|
@ -846,26 +846,31 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
|
|||
llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
|
||||
bool HasFallthrough = (FallthroughSource != 0 && IsActive);
|
||||
|
||||
// As a kindof crazy internal case, branch-through fall-throughs
|
||||
// leave the insertion point set to the end of the last cleanup.
|
||||
// Branch-through fall-throughs leave the insertion point set to the
|
||||
// end of the last cleanup, which points to the current scope. The
|
||||
// rest of IR gen doesn't need to worry about this; it only happens
|
||||
// during the execution of PopCleanupBlocks().
|
||||
bool HasPrebranchedFallthrough =
|
||||
(FallthroughSource && FallthroughSource->getTerminator());
|
||||
|
||||
// If this is a normal cleanup, then having a prebranched
|
||||
// fallthrough implies that the fallthrough source unconditionally
|
||||
// jumps here.
|
||||
assert(!Scope.isNormalCleanup() || !HasPrebranchedFallthrough ||
|
||||
(Scope.getNormalBlock() &&
|
||||
FallthroughSource->getTerminator()->getSuccessor(0)
|
||||
== Scope.getNormalBlock()));
|
||||
|
||||
bool RequiresNormalCleanup = false;
|
||||
if (Scope.isNormalCleanup() &&
|
||||
(HasFixups || HasExistingBranches || HasFallthrough)) {
|
||||
RequiresNormalCleanup = true;
|
||||
}
|
||||
|
||||
assert(!HasPrebranchedFallthrough || RequiresNormalCleanup || !IsActive);
|
||||
assert(!HasPrebranchedFallthrough ||
|
||||
(Scope.isNormalCleanup() && Scope.getNormalBlock() &&
|
||||
FallthroughSource->getTerminator()->getSuccessor(0)
|
||||
== Scope.getNormalBlock()));
|
||||
|
||||
// Even if we don't need the normal cleanup, we might still have
|
||||
// prebranched fallthrough to worry about.
|
||||
if (!RequiresNormalCleanup && HasPrebranchedFallthrough) {
|
||||
if (Scope.isNormalCleanup() && !RequiresNormalCleanup &&
|
||||
HasPrebranchedFallthrough) {
|
||||
assert(!IsActive);
|
||||
|
||||
llvm::BasicBlock *NormalEntry = Scope.getNormalBlock();
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang-cc1 %s -fexceptions
|
||||
|
||||
// Reduced from a crash on boost::interprocess's node_allocator_test.cpp.
|
||||
namespace test0 {
|
||||
struct A { A(); ~A(); };
|
||||
struct V { V(const A &a = A()); ~V(); };
|
||||
|
||||
template<int X> int vector_test()
|
||||
{
|
||||
A process_name;
|
||||
try {
|
||||
A segment;
|
||||
|
||||
V *stdvector = new V();
|
||||
|
||||
int x = 5, y = 7;
|
||||
if(x == y) return 1;
|
||||
}
|
||||
catch(int ex){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
return vector_test<0>();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue