Skip to content

Commit b72309c

Browse files
committed
[DebugInfo] Give functions with no source locations a scope-line
In degenerate but legal inputs, we can have functions that have no source locations at all -- all the DebugLocs attached to instructions are empty. LLVM didn't produce any source location for the function; with this patch it will at least emit the function-scope source location. Demonstrated by empty-line-info.ll The XCOFF test modified has similar symptoms -- with this patch, the size of the ".dwline" section grows a bit, thus shifting some of the file internal offsets, which I've updated.
1 parent dca325e commit b72309c

File tree

3 files changed

+65
-19
lines changed

3 files changed

+65
-19
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,23 +2192,23 @@ DwarfDebug::emitInitialLocDirective(const MachineFunction &MF, unsigned CUID) {
21922192
const MachineInstr *PrologEndLoc = PrologEnd.first;
21932193
bool IsEmptyPrologue = PrologEnd.second;
21942194

2195-
// Get beginning of function.
2196-
if (PrologEndLoc) {
2197-
// If the prolog is empty, no need to generate scope line for the proc.
2198-
if (IsEmptyPrologue)
2195+
// If the prolog is empty, no need to generate scope line for the proc.
2196+
if (IsEmptyPrologue)
2197+
// In degenerate cases, we can have functions with no source locations
2198+
// at all. These want a scope line, to avoid a totally empty function.
2199+
// Thus, only skip scope line if there's location to place prologue_end.
2200+
if (PrologEndLoc)
21992201
return PrologEndLoc;
22002202

2201-
// Ensure the compile unit is created if the function is called before
2202-
// beginFunction().
2203-
DISubprogram *SP = MF.getFunction().getSubprogram();
2204-
(void)getOrCreateDwarfCompileUnit(SP->getUnit());
2205-
// We'd like to list the prologue as "not statements" but GDB behaves
2206-
// poorly if we do that. Revisit this with caution/GDB (7.5+) testing.
2207-
::recordSourceLine(*Asm, SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT,
2208-
CUID, getDwarfVersion(), getUnits());
2209-
return PrologEndLoc;
2210-
}
2211-
return nullptr;
2203+
// Ensure the compile unit is created if the function is called before
2204+
// beginFunction().
2205+
DISubprogram *SP = MF.getFunction().getSubprogram();
2206+
(void)getOrCreateDwarfCompileUnit(SP->getUnit());
2207+
// We'd like to list the prologue as "not statements" but GDB behaves
2208+
// poorly if we do that. Revisit this with caution/GDB (7.5+) testing.
2209+
::recordSourceLine(*Asm, SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT,
2210+
CUID, getDwarfVersion(), getUnits());
2211+
return PrologEndLoc;
22122212
}
22132213

22142214
// Gather pre-function debug information. Assumes being called immediately

llvm/test/CodeGen/PowerPC/aix-xcoff-exception-section-debug.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ define dso_local void @test__trap_annotation_debug(i32 %a) !dbg !4 {
4040
; SYMS32-NEXT: NumberOfAuxEntries: 2
4141
; SYMS32-NEXT: Function Auxiliary Entry {
4242
; SYMS32-NEXT: Index: [[#IND+1]]
43-
; SYMS32-NEXT: OffsetToExceptionTable: 0x2A8
43+
; SYMS32-NEXT: OffsetToExceptionTable: 0x2B8
4444
; SYMS32-NEXT: SizeOfFunction: 0xC
4545
; SYMS32-NEXT: PointerToLineNum: 0x0
4646
; SYMS32-NEXT: SymbolIndexOfNextBeyond: [[#IND+3]]
@@ -67,7 +67,7 @@ define dso_local void @test__trap_annotation_debug(i32 %a) !dbg !4 {
6767
; SYMS32-NEXT: NumberOfAuxEntries: 2
6868
; SYMS32-NEXT: Function Auxiliary Entry {
6969
; SYMS32-NEXT: Index: [[#IND+4]]
70-
; SYMS32-NEXT: OffsetToExceptionTable: 0x2B4
70+
; SYMS32-NEXT: OffsetToExceptionTable: 0x2C4
7171
; SYMS32-NEXT: SizeOfFunction: 0x34
7272
; SYMS32-NEXT: PointerToLineNum: 0x0
7373
; SYMS32-NEXT: SymbolIndexOfNextBeyond: [[#IND+6]]
@@ -93,7 +93,7 @@ define dso_local void @test__trap_annotation_debug(i32 %a) !dbg !4 {
9393
; SYMS64-NEXT: NumberOfAuxEntries: 3
9494
; SYMS64-NEXT: Exception Auxiliary Entry {
9595
; SYMS64-NEXT: Index: [[#IND+1]]
96-
; SYMS64-NEXT: OffsetToExceptionTable: 0x398
96+
; SYMS64-NEXT: OffsetToExceptionTable: 0x3AC
9797
; SYMS64-NEXT: SizeOfFunction: 0x18
9898
; SYMS64-NEXT: SymbolIndexOfNextBeyond: [[#IND+4]]
9999
; SYMS64-NEXT: Auxiliary Type: AUX_EXCEPT (0xFF)
@@ -126,7 +126,7 @@ define dso_local void @test__trap_annotation_debug(i32 %a) !dbg !4 {
126126
; SYMS64-NEXT: NumberOfAuxEntries: 3
127127
; SYMS64-NEXT: Exception Auxiliary Entry {
128128
; SYMS64-NEXT: Index: [[#IND+5]]
129-
; SYMS64-NEXT: OffsetToExceptionTable: 0x3AC
129+
; SYMS64-NEXT: OffsetToExceptionTable: 0x3C0
130130
; SYMS64-NEXT: SizeOfFunction: 0x68
131131
; SYMS64-NEXT: SymbolIndexOfNextBeyond: [[#IND+8]]
132132
; SYMS64-NEXT: Auxiliary Type: AUX_EXCEPT (0xFF)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; RUN: llc %s -o - -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
2+
3+
;; Test that, even though there are no source locations attached to the foo
4+
;; function, we still give it the start-of-function source location of the
5+
;; definition line. Otherwise, this function would have no entry in the
6+
;; line table at all.
7+
8+
; CHECK-LABEL: foo:
9+
; CHECK-NEXT: .Lfunc_begin0:
10+
; CHECK-NEXT: .file 0 "." "foobar.c"
11+
; CHECK-NEXT: .loc 0 1 0
12+
13+
define dso_local noundef i32 @foo(ptr nocapture noundef writeonly %bar) local_unnamed_addr !dbg !10 {
14+
entry:
15+
store i32 0, ptr %bar, align 4
16+
ret i32 0
17+
}
18+
19+
!llvm.dbg.cu = !{!0}
20+
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
21+
!llvm.ident = !{!9}
22+
23+
!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
24+
!1 = !DIFile(filename: "foobar.c", directory: ".")
25+
!2 = !{i32 7, !"Dwarf Version", i32 5}
26+
!3 = !{i32 2, !"Debug Info Version", i32 3}
27+
!4 = !{i32 1, !"wchar_size", i32 4}
28+
!5 = !{i32 8, !"PIC Level", i32 2}
29+
!6 = !{i32 7, !"PIE Level", i32 2}
30+
!7 = !{i32 7, !"uwtable", i32 2}
31+
!8 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
32+
!9 = !{!"clang"}
33+
!10 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !15)
34+
!11 = !DISubroutineType(types: !12)
35+
!12 = !{!13, !14}
36+
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
37+
!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
38+
!15 = !{!16}
39+
!16 = !DILocalVariable(name: "bar", arg: 1, scope: !10, file: !1, line: 1, type: !14)
40+
!17 = !DILocation(line: 0, scope: !10)
41+
!18 = !DILocation(line: 2, column: 8, scope: !10)
42+
!19 = !{!20, !20, i64 0}
43+
!20 = !{!"int", !21, i64 0}
44+
!21 = !{!"omnipotent char", !22, i64 0}
45+
!22 = !{!"Simple C/C++ TBAA"}
46+
!23 = !DILocation(line: 3, column: 3, scope: !10)

0 commit comments

Comments
 (0)