vsk created this revision. vsk added reviewers: ygao, rsmith. vsk added a subscriber: cfe-commits.
When partially initializing a global, exception-handling code in the frontend emits a placeholder `%invoke.cont` block with no terminator. This commit adds a suitable BranchInst to the block to prevent "malformed BasicBlock" errors. A test case is included. Note: I have been struggling to understand why throwing an error in a destructor causes exception-handling code to be generated when invoking the constructor [esp. when the constructor does not throw anything]. This patch is meant as a workaround until the 'real' issue can be addressed. http://reviews.llvm.org/D12412 Files: lib/CodeGen/CGExprAgg.cpp test/CodeGenCXX/partial-init.cpp Index: test/CodeGenCXX/partial-init.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/partial-init.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-obj -std=c++11 -x c++ \ +// RUN: -fcxx-exceptions -fexceptions -S -emit-llvm -o - %s | FileCheck %s + +namespace std { + struct string { + const char *p; + string(const char *s) : p(s) {} + ~string() { throw 0; } + }; +} + +struct Bar { + int a; +}; + +struct Foo { + int b; + std::string c; + Bar d[32]; +}; + +static Foo table[] = { + { 0, "blerg" }, +}; + +// CHECK-NOT: does not have terminator +// CHECK-NOT: Broken function found, compilation aborted Index: lib/CodeGen/CGExprAgg.cpp =================================================================== --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -493,6 +493,12 @@ llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body"); + // The exception-handling code in VisitInitListExpr may mark entryBB as + // a placeholder with an UnreachableInst. Branch to bodyBB as intended. + if (dyn_cast_or_null<llvm::UnreachableInst>(entryBB->getTerminator())) { + llvm::BranchInst::Create(bodyBB, entryBB); + } + // Jump into the body. CGF.EmitBlock(bodyBB); llvm::PHINode *currentElement =
Index: test/CodeGenCXX/partial-init.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/partial-init.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-obj -std=c++11 -x c++ \ +// RUN: -fcxx-exceptions -fexceptions -S -emit-llvm -o - %s | FileCheck %s + +namespace std { + struct string { + const char *p; + string(const char *s) : p(s) {} + ~string() { throw 0; } + }; +} + +struct Bar { + int a; +}; + +struct Foo { + int b; + std::string c; + Bar d[32]; +}; + +static Foo table[] = { + { 0, "blerg" }, +}; + +// CHECK-NOT: does not have terminator +// CHECK-NOT: Broken function found, compilation aborted Index: lib/CodeGen/CGExprAgg.cpp =================================================================== --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -493,6 +493,12 @@ llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body"); + // The exception-handling code in VisitInitListExpr may mark entryBB as + // a placeholder with an UnreachableInst. Branch to bodyBB as intended. + if (dyn_cast_or_null<llvm::UnreachableInst>(entryBB->getTerminator())) { + llvm::BranchInst::Create(bodyBB, entryBB); + } + // Jump into the body. CGF.EmitBlock(bodyBB); llvm::PHINode *currentElement =
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits