Skip to content

Commit 2c45677

Browse files
[DebugInfo] Fix line 0 records incorrectly having is_stmt set
Fixes issue #33870 (Bugzilla #34522) Line 0 debug records should not have the is_stmt flag set in DWARF. This change ensures is_stmt is only set for non-zero line numbers. Changes made in DwarfDebug.cpp: - beginInstruction: Only set is_stmt for prologue_end if line != 0 - beginInstruction: Only set is_stmt for key instructions if line != 0 - emitInitialLocDirective: Set is_stmt=0 if scopeLine == 0 Added two test cases to verify the behavior: - llvm/test/DebugInfo/X86/line-0-no-is-stmt.ll: Verifies line 0 does not get is_stmt - llvm/test/DebugInfo/X86/line-nonzero-has-is-stmt.ll: Verifies non-zero lines do get is_stmt
1 parent 77a194c commit 2c45677

File tree

3 files changed

+74
-4
lines changed

3 files changed

+74
-4
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,12 +2199,16 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
21992199
if (DL.getLine() == 0 && LastAsmLine == 0)
22002200
return;
22012201
if (MI == PrologEndLoc) {
2202-
Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT;
2202+
Flags |= DWARF2_FLAG_PROLOGUE_END;
2203+
// Don't set is_stmt for line 0
2204+
if (DL.getLine() != 0)
2205+
Flags |= DWARF2_FLAG_IS_STMT;
22032206
PrologEndLoc = nullptr;
22042207
}
22052208

22062209
if (ScopeUsesKeyInstructions) {
2207-
if (IsKey)
2210+
// Don't set is_stmt for line 0
2211+
if (IsKey && DL.getLine() != 0)
22082212
Flags |= DWARF2_FLAG_IS_STMT;
22092213
} else {
22102214
// If the line changed, we call that a new statement; unless we went to
@@ -2400,8 +2404,11 @@ DwarfDebug::emitInitialLocDirective(const MachineFunction &MF, unsigned CUID) {
24002404
(void)getOrCreateDwarfCompileUnit(SP->getUnit());
24012405
// We'd like to list the prologue as "not statements" but GDB behaves
24022406
// poorly if we do that. Revisit this with caution/GDB (7.5+) testing.
2403-
::recordSourceLine(*Asm, SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT,
2404-
CUID, getDwarfVersion(), getUnits());
2407+
// However, we should not set is_stmt for line 0.
2408+
unsigned ScopeLine = SP->getScopeLine();
2409+
unsigned Flags = (ScopeLine != 0) ? DWARF2_FLAG_IS_STMT : 0;
2410+
::recordSourceLine(*Asm, ScopeLine, 0, SP, Flags, CUID, getDwarfVersion(),
2411+
getUnits());
24052412
return PrologEndLoc;
24062413
}
24072414

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; Test that line 0 records don't have is_stmt set
2+
; This tests the fix for LLVM issue #33870 (Bugzilla #34522)
3+
;
4+
; When scopeLine is 0, the initial location directive should not have is_stmt set.
5+
6+
; RUN: %llc_dwarf -mtriple=x86_64-unknown-linux -O0 -filetype=obj < %s | llvm-dwarfdump --debug-line - | FileCheck %s
7+
8+
; The line table entry for line 0 should exist but not have "is_stmt" in its Flags
9+
; CHECK: Address
10+
; CHECK: 0x{{[0-9a-f]+}} 0 0
11+
; CHECK-NOT: is_stmt
12+
; CHECK: end_sequence
13+
14+
define void @foo() !dbg !6 {
15+
entry:
16+
ret void, !dbg !9
17+
}
18+
19+
!llvm.dbg.cu = !{!0}
20+
!llvm.module.flags = !{!2, !3, !4}
21+
22+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
23+
!1 = !DIFile(filename: "test.c", directory: "/tmp")
24+
!2 = !{i32 2, !"Dwarf Version", i32 4}
25+
!3 = !{i32 2, !"Debug Info Version", i32 3}
26+
!4 = !{i32 1, !"wchar_size", i32 4}
27+
!5 = !{}
28+
; scopeLine is 0 (line 0 should not have is_stmt)
29+
!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !7, scopeLine: 0, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !5)
30+
!7 = !DISubroutineType(types: !8)
31+
!8 = !{null}
32+
; Line 0 location (should not have is_stmt)
33+
!9 = !DILocation(line: 0, column: 0, scope: !6)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; Test that non-zero line records DO have is_stmt set
2+
; This is for comparison with line 0 behavior (issue #33870 / Bugzilla #34522)
3+
;
4+
; When scopeLine is non-zero, the initial location directive should have is_stmt set.
5+
6+
; RUN: %llc_dwarf -mtriple=x86_64-unknown-linux -O0 -filetype=obj < %s | llvm-dwarfdump --debug-line - | FileCheck %s
7+
8+
; With scopeLine=10, we should see line 10 with is_stmt and prologue_end
9+
; CHECK: 0x{{[0-9a-f]+}} 10 {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} is_stmt prologue_end
10+
11+
define void @bar() !dbg !6 {
12+
entry:
13+
ret void, !dbg !9
14+
}
15+
16+
!llvm.dbg.cu = !{!0}
17+
!llvm.module.flags = !{!2, !3, !4}
18+
19+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
20+
!1 = !DIFile(filename: "test.c", directory: "/tmp")
21+
!2 = !{i32 2, !"Dwarf Version", i32 4}
22+
!3 = !{i32 2, !"Debug Info Version", i32 3}
23+
!4 = !{i32 1, !"wchar_size", i32 4}
24+
!5 = !{}
25+
; scopeLine is 10 (non-zero line should have is_stmt)
26+
!6 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 10, type: !7, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !5)
27+
!7 = !DISubroutineType(types: !8)
28+
!8 = !{null}
29+
; Line 10 location (should have is_stmt)
30+
!9 = !DILocation(line: 10, column: 5, scope: !6)

0 commit comments

Comments
 (0)