Skip to content

Commit 8c1e62b

Browse files
authored
[DwarfDebug] Avoid generating extra DW_TAG_subprogram entries (#154636)
The test llvm/test/DebugInfo/X86/pr12831.ll was added in 4d358b5 to fix the issue with emission of empty DW_TAG_subprogram tags (https://bugs.llvm.org/show_bug.cgi?id=12831). However, the test output is not checked properly, and it contains: ``` 0x00000206: DW_TAG_subprogram 0x00000207: DW_TAG_reference_type DW_AT_type (0x00000169 "class ") ``` The reason is that the DIE for the definition DISubprogram "writeExpr" is created during the call to `getOrCreateSubprogramDIE(declaration of writeExpr)`. Therefore, when `getOrCreateSubprogramDIE(definition of writeExpr)` is first called, we get a recursive chain of calls: ``` getOrCreateSubprogramDIE(definition of writeExpr) getOrCreateSubprogramDIE(declaration of writeExpr) ... getOrCreateSubprogramDIE(definition of writeExpr) ``` The outer call doesn't expect that the DIE for the definition of writeExpr will be created during the creation of declaration DIE. So, another DIE is created for the same subprogram. In this PR, a check is added to fix that.
1 parent 75b812e commit 8c1e62b

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,13 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) {
13511351
ContextDIE = &getUnitDie();
13521352
// Build the decl now to ensure it precedes the definition.
13531353
getOrCreateSubprogramDIE(SPDecl);
1354+
// Check whether the DIE for SP has already been created after the call
1355+
// above.
1356+
// FIXME: Should the creation of definition subprogram DIE during
1357+
// the creation of declaration subprogram DIE be allowed?
1358+
// See https://github.com/llvm/llvm-project/pull/154636.
1359+
if (DIE *SPDie = getDIE(SP))
1360+
return SPDie;
13541361
}
13551362
}
13561363

llvm/test/DebugInfo/X86/pr12831.ll

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,39 @@
1-
; RUN: llc %s -mtriple=x86_64-unknown-linux-gnu -o /dev/null
1+
; RUN: llc %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s
2+
3+
; Check that there are no empty DW_TAG_subprogram tags.
4+
; CHECK: DW_TAG_subprogram
5+
; CHECK-NEXT: DW_AT
6+
; CHECK: DW_TAG_subprogram
7+
; CHECK-NEXT: DW_AT
8+
; CHECK: DW_TAG_subprogram
9+
; CHECK-NEXT: DW_AT
10+
; CHECK: DW_TAG_subprogram
11+
; CHECK-NEXT: DW_AT
12+
; CHECK: DW_TAG_subprogram
13+
; CHECK-NEXT: DW_AT
14+
; CHECK: DW_TAG_subprogram
15+
; CHECK-NEXT: DW_AT
16+
; CHECK: DW_TAG_subprogram
17+
; CHECK-NEXT: DW_AT
18+
; CHECK: DW_TAG_subprogram
19+
; CHECK-NEXT: DW_AT
20+
; CHECK: DW_TAG_subprogram
21+
; CHECK-NEXT: DW_AT
22+
; CHECK: DW_TAG_subprogram
23+
; CHECK-NEXT: DW_AT
24+
; CHECK: DW_TAG_subprogram
25+
; CHECK-NEXT: DW_AT
26+
; CHECK: DW_TAG_subprogram
27+
; CHECK-NEXT: DW_AT
28+
; CHECK: DW_TAG_subprogram
29+
; CHECK-NEXT: DW_AT
30+
; CHECK: DW_TAG_subprogram
31+
; CHECK-NEXT: DW_AT
32+
; CHECK: DW_TAG_subprogram
33+
; CHECK-NEXT: DW_AT
34+
; CHECK: DW_TAG_subprogram
35+
; CHECK-NEXT: DW_AT
36+
; CHECK-NOT: DW_TAG_subprogram
237

338
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
439
target triple = "x86_64-unknown-linux-gnu"

0 commit comments

Comments
 (0)