From: David Blaikie Date: Fri, 1 Feb 2013 19:09:49 +0000 (+0000) Subject: Fix exception handling line table problems introduced by r173593 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=357aafb566cdaf5ac689d787f08db998545ce1e1;p=platform%2Fupstream%2Fllvm.git Fix exception handling line table problems introduced by r173593 r173593 made us a little too eager to associate all code at the end of a function with the user-written 'return' line. This caused problems with breakpoints as they'd be set in exception handling code preceeding the actual non-exception return handling code, leading to the breakpoint never being hit in non-exceptional execution. This change restores the pre-r173593 exception handling line information where the cleanup code is associated with the '}' not the return line. llvm-svn: 174206 --- diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index ca810e7..5e60bd8 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2205,7 +2205,9 @@ void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) { if (CurLoc == PrevLoc || SM.getExpansionLoc(CurLoc) == SM.getExpansionLoc(PrevLoc)) // New Builder may not be in sync with CGDebugInfo. - if (!Builder.getCurrentDebugLocation().isUnknown()) + if (!Builder.getCurrentDebugLocation().isUnknown() && + Builder.getCurrentDebugLocation().getScope(CGM.getLLVMContext()) == + LexicalBlockStack.back()) return; // Update last state. diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 59e38e6..729cdba 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -117,7 +117,7 @@ bool CodeGenFunction::hasAggregateLLVMType(QualType type) { llvm_unreachable("unknown type kind!"); } -bool CodeGenFunction::EmitReturnBlock() { +void CodeGenFunction::EmitReturnBlock() { // For cleanliness, we try to avoid emitting the return block for // simple cases. llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); @@ -132,7 +132,7 @@ bool CodeGenFunction::EmitReturnBlock() { delete ReturnBlock.getBlock(); } else EmitBlock(ReturnBlock.getBlock()); - return false; + return; } // Otherwise, if the return block is the target of a single direct @@ -144,11 +144,13 @@ bool CodeGenFunction::EmitReturnBlock() { if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock.getBlock()) { // Reset insertion point, including debug location, and delete the branch. + // this is really subtle & only works because the next change in location + // will hit the caching in CGDebugInfo::EmitLocation & not override this Builder.SetCurrentDebugLocation(BI->getDebugLoc()); Builder.SetInsertPoint(BI->getParent()); BI->eraseFromParent(); delete ReturnBlock.getBlock(); - return true; + return; } } @@ -157,7 +159,6 @@ bool CodeGenFunction::EmitReturnBlock() { // region.end for now. EmitBlock(ReturnBlock.getBlock()); - return false; } static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) { @@ -171,6 +172,9 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); + if (CGDebugInfo *DI = getDebugInfo()) + DI->EmitLocation(Builder, EndLoc); + // Pop any cleanups that might have been associated with the // parameters. Do this in whatever block we're currently in; it's // important to do this before we enter the return block or return @@ -179,14 +183,13 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { PopCleanupBlocks(PrologueCleanupDepth); // Emit function epilog (to return). - bool MoveEndLoc = EmitReturnBlock(); + EmitReturnBlock(); if (ShouldInstrumentFunction()) EmitFunctionInstrumentation("__cyg_profile_func_exit"); // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) { - if (!MoveEndLoc) DI->setLocation(EndLoc); DI->EmitFunctionEnd(Builder); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 15fd10c..94faac0 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1413,7 +1413,7 @@ public: /// EmitReturnBlock - Emit the unified return block, trying to avoid its /// emission when possible. - bool EmitReturnBlock(); + void EmitReturnBlock(); /// FinishFunction - Complete IR generation of the current function. It is /// legal to call this function even if there is no current insertion point. diff --git a/clang/test/CodeGenCXX/debug-info-class.cpp b/clang/test/CodeGenCXX/debug-info-class.cpp index 131693b..410b921 100644 --- a/clang/test/CodeGenCXX/debug-info-class.cpp +++ b/clang/test/CodeGenCXX/debug-info-class.cpp @@ -1,21 +1,20 @@ // RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s struct foo; -void func(foo *f) { // CHECK: DW_TAG_structure_type +void func(foo *f) { } class bar; -void func(bar *f) { // CHECK: DW_TAG_class_type +void func(bar *f) { } union baz; -void func(baz *f) { // CHECK: DW_TAG_union_type +void func(baz *f) { } -class B { // CHECK: DW_TAG_class_type +class B { public: virtual ~B(); -// CHECK: metadata !"_vptr$B", {{.*}}, i32 64, metadata !{{.*}}} ; [ DW_TAG_member ] }; -struct A { // CHECK: DW_TAG_structure_type +struct A { int one; - static const int HdrSize = 52; // CHECK: HdrSize + static const int HdrSize = 52; int two; A() { int x = 1; @@ -23,7 +22,22 @@ struct A { // CHECK: DW_TAG_structure_type }; -int main() { - A a; +int main(int argc, char **argv) { B b; + if (argc) { + A a; + } + return 0; } + +// CHECK: unwind label %terminate.lpad, !dbg ![[EXCEPTLOC:.*]] +// CHECK: store i32 0, i32* %retval, !dbg ![[RETLOC:.*]] +// CHECK: DW_TAG_structure_type ] [foo] +// CHECK: DW_TAG_class_type ] [bar] +// CHECK: DW_TAG_union_type ] [baz] +// CHECK: DW_TAG_structure_type ] [A] +// CHECK: HdrSize +// CHECK: DW_TAG_class_type ] [B] +// CHECK: metadata !"_vptr$B", {{.*}}, i32 64, metadata !{{.*}}} ; [ DW_TAG_member ] +// CHECK: ![[EXCEPTLOC]] = metadata !{i32 31, +// CHECK: ![[RETLOC]] = metadata !{i32 30,