Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit e45c75d

Browse files
JDevliegherealexcrichton
authored andcommitted
[DebugInfo] Fix potential CU mismatch for SubprogramScopeDIEs.
In constructAbstractSubprogramScopeDIE there can be a potential mismatch between `this` and the CU of ContextDIE when a scope is shared between two DISubprograms belonging to a different CU. In that case, `this` is the CU that was specified in the IR, but the CU of ContextDIE is that of the first subprogram that was emitted. This patch fixes the mismatch by looking up the CU of ContextDIE, and switching to use that. This fixes PR35212 (https://bugs.llvm.org/show_bug.cgi?id=35212) Patch by Philip Craig! Differential revision: https://reviews.llvm.org/D39981 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318289 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 896fb22 commit e45c75d

File tree

3 files changed

+67
-8
lines changed

3 files changed

+67
-8
lines changed

lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

+13-7
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
616616
auto *SP = cast<DISubprogram>(Scope->getScopeNode());
617617

618618
DIE *ContextDIE;
619+
DwarfCompileUnit *ContextCU = this;
619620

620621
if (includeMinimalInlineScopes())
621622
ContextDIE = &getUnitDie();
@@ -626,18 +627,23 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
626627
else if (auto *SPDecl = SP->getDeclaration()) {
627628
ContextDIE = &getUnitDie();
628629
getOrCreateSubprogramDIE(SPDecl);
629-
} else
630+
} else {
630631
ContextDIE = getOrCreateContextDIE(resolve(SP->getScope()));
632+
// The scope may be shared with a subprogram that has already been
633+
// constructed in another CU, in which case we need to construct this
634+
// subprogram in the same CU.
635+
ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
636+
}
631637

632638
// Passing null as the associated node because the abstract definition
633639
// shouldn't be found by lookup.
634-
AbsDef = &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
635-
applySubprogramAttributesToDefinition(SP, *AbsDef);
640+
AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
641+
ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
636642

637-
if (!includeMinimalInlineScopes())
638-
addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
639-
if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef))
640-
addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
643+
if (!ContextCU->includeMinimalInlineScopes())
644+
ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
645+
if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
646+
ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
641647
}
642648

643649
DIE *DwarfCompileUnit::constructImportedEntityDIE(

lib/CodeGen/AsmPrinter/DwarfDebug.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ class DwarfDebug : public DebugHandlerBase {
264264
// 0, referencing the comp_dir of all the type units that use it.
265265
MCDwarfDwoLineTable SplitTypeUnitFileTable;
266266
/// @}
267-
267+
268268
/// True iff there are multiple CUs in this module.
269269
bool SingleCU;
270270
bool IsDarwin;
@@ -539,6 +539,9 @@ class DwarfDebug : public DebugHandlerBase {
539539
/// A helper function to check whether the DIE for a given Scope is
540540
/// going to be null.
541541
bool isLexicalScopeDIENull(LexicalScope *Scope);
542+
543+
/// Find the matching DwarfCompileUnit for the given CU DIE.
544+
DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Die); }
542545
};
543546
} // End of namespace llvm
544547

test/DebugInfo/cross-cu-scope.ll

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; RUN: %llc_dwarf %s -filetype=obj -o %t
2+
; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s
3+
4+
; Reduced test case from PR35212. Two DISubprogram belong to a different CU but
5+
; share a scope. Both are declarations and end up in the scope's CU. We want to
6+
; check that the CU from the context DIE is used (rather than from the IR).
7+
; This manifests itself by the DW_base_type ending up in the second CU, rather
8+
; than in the first one as specified in the IR.
9+
10+
; CHECK: DW_TAG_compile_unit
11+
; CHECK-NEXT: discriminator 0
12+
; CHECK: DW_TAG_compile_unit
13+
; CHECK-NEXT: discriminator 1
14+
; CHECK: DW_TAG_structure_type
15+
; CHECK-NOT: NULL
16+
; CHECK: DW_TAG_subprogram
17+
; CHECK-NOT: NULL
18+
; CHECK: DW_TAG_formal_parameter
19+
; CHECK-NOT: NULL
20+
; CHECK: DW_AT_type{{.*}}"usize"
21+
; CHECK: NULL
22+
; CHECK: DW_TAG_base_type
23+
; CHECK-NOT: NULL
24+
; CHECK: DW_AT_name{{.*}}"usize"
25+
26+
define hidden void @foo() !dbg !4 {
27+
ret void, !dbg !7
28+
}
29+
30+
!llvm.dbg.cu = !{!0, !2}
31+
!llvm.module.flags = !{!3}
32+
33+
!0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !1, producer: "clang LLVM (rustc version 1.23.0-nightly (discriminator 0))", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
34+
!1 = !DIFile(filename: "../lib.rs", directory: "/home/alex/code/rust4/lol")
35+
!2 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !1, producer: "clang LLVM (rustc version 1.23.0-nightly (discriminator 1))", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
36+
!3 = !{i32 2, !"Debug Info Version", i32 3}
37+
!4 = distinct !DISubprogram(name: "clone<alloc::string::String>", linkageName: "_ZN5alloc3vec8{{impl}}28clone<alloc::string::String>E", scope: null, file: !1, line: 1519, type: !5, isLocal: false, isDefinition: true, scopeLine: 1519, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !6, variables: !6)
38+
!5 = !DISubroutineType(types: !6)
39+
!6 = !{}
40+
!7 = !DILocation(line: 1612, scope: !8, inlinedAt: !11)
41+
!8 = distinct !DILexicalBlock(scope: !9, file: !1, line: 86, column: 12)
42+
!9 = distinct !DISubprogram(name: "allocate_in<alloc::string::String,alloc::heap::Heap>", linkageName: "_ZN5alloc7raw_vec8{{impl}}52allocate_in<alloc::string::String,alloc::heap::Heap>E", scope: !10, file: !1, line: 82, type: !5, isLocal: false, isDefinition: true, scopeLine: 82, flags: DIFlagPrototyped, isOptimized: true, unit: !2, templateParams: !6, variables: !6)
43+
!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "RawVec<alloc::string::String, alloc::heap::Heap>", file: !1, size: 128, align: 64, elements: !6, identifier: "5c6e4db16d2c64555e40661d70c4d81e")
44+
!11 = distinct !DILocation(line: 86, scope: !8, inlinedAt: !12)
45+
!12 = distinct !DILocation(line: 141, scope: !13, inlinedAt: !17)
46+
!13 = distinct !DISubprogram(name: "with_capacity<alloc::string::String>", linkageName: "_ZN5alloc7raw_vec8{{impl}}36with_capacity<alloc::string::String>E", scope: !10, file: !1, line: 140, type: !5, isLocal: false, isDefinition: true, scopeLine: 140, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !6, variables: !14)
47+
!14 = !{!15}
48+
!15 = !DILocalVariable(name: "cap", arg: 1, scope: !13, file: !1, line: 1, type: !16)
49+
!16 = !DIBasicType(name: "usize", size: 64, encoding: DW_ATE_unsigned)
50+
!17 = !DILocation(line: 1521, scope: !4)

0 commit comments

Comments
 (0)