diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index b2ae9ad36da..73496b0c382 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1175,7 +1175,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSet &Processed) { Processed.insert(DV); const MachineInstr *MInsn = Ranges.front().first; assert(MInsn->isDebugValue() && "History must begin with debug value"); - DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc()); + DbgVariable *AbsVar = findAbstractVariable(DV, Scope->getScopeNode()); DbgVariable *RegVar = new DbgVariable(MInsn, AbsVar, this); if (!addCurrentFnArgument(RegVar, Scope)) addScopeVariable(Scope, RegVar); diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 29ebad40256..fddc7fa137f 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1781,8 +1781,7 @@ std::unique_ptr DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV, // Define variable debug information entry. auto VariableDie = make_unique(DV.getTag()); - DbgVariable *AbsVar = DV.getAbstractVariable(); - if (AbsVar && AbsVar->getDIE()) + if (DbgVariable *AbsVar = DV.getAbstractVariable()) addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin, *AbsVar->getDIE()); else { if (!Name.empty()) diff --git a/test/DebugInfo/incorrect-variable-debugloc.ll b/test/DebugInfo/incorrect-variable-debugloc.ll new file mode 100644 index 00000000000..284704c54a9 --- /dev/null +++ b/test/DebugInfo/incorrect-variable-debugloc.ll @@ -0,0 +1,391 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O2 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; This is a test case that's as reduced as I can get it, though I haven't fully +; understood the mechanisms by which this bug occurs, so perhaps there's further +; simplification to be had (it's certainly a bit non-obvious what's going on). I +; hesitate to hand-craft or otherwise simplify the IR compared to what Clang +; generates as this is a particular tickling of optimizations and debug location +; propagation I want a realistic example of. + +; Generated with clang-tot -cc1 -g -O2 -w -std=c++11 -fsanitize=address,use-after-return -fcxx-exceptions -fexceptions -x c++ incorrect-variable-debug-loc.cpp -emit-llvm + +; struct A { +; int m_fn1(); +; }; +; +; struct B { +; void __attribute__((always_inline)) m_fn2() { i = 0; } +; int i; +; }; +; +; struct C { +; void m_fn3(); +; int j; +; B b; +; }; +; +; int fn1() { +; C A; +; A.b.m_fn2(); +; A.m_fn3(); +; } +; void C::m_fn3() { +; A().m_fn1(); +; b.m_fn2(); +; } + +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}} "C" +; CHECK: [[FN3_DECL:.*]]: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "m_fn3" + +; CHECK: DW_AT_specification {{.*}} {[[FN3_DECL]]} +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "this" + +%struct.C = type { i32, %struct.B } +%struct.B = type { i32 } +%struct.A = type { i8 } + +@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 1, void ()* @asan.module_ctor }] +@__asan_option_detect_stack_use_after_return = external global i32 +@__asan_gen_ = private unnamed_addr constant [11 x i8] c"1 32 8 1 A\00", align 1 +@__asan_gen_1 = private unnamed_addr constant [13 x i8] c"1 32 1 3 tmp\00", align 1 + +; Function Attrs: noreturn sanitize_address +define i32 @_Z3fn1v() #0 { +entry: + %MyAlloca = alloca [64 x i8], align 32, !dbg !39 + %0 = ptrtoint [64 x i8]* %MyAlloca to i64, !dbg !39 + %1 = load i32* @__asan_option_detect_stack_use_after_return, !dbg !39 + %2 = icmp ne i32 %1, 0, !dbg !39 + br i1 %2, label %3, label %5 + +;