[llvm] [CodeView] Generate debug info for artificial subprograms (PR #196327)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 07:32:23 PDT 2026
https://github.com/serge-sans-paille created https://github.com/llvm/llvm-project/pull/196327
Based on https://clang.llvm.org/docs/AttributeReference.html#artificial, Artificial subprograms are not required to have a non-zero line number location, so don't ignore them.
Fix #195768
>From 5a32d0ea4f109ea13451159eef3000974701d78e Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Thu, 7 May 2026 16:14:23 +0200
Subject: [PATCH] [CodeView] Generate debug info for artificial subprograms
Based on https://clang.llvm.org/docs/AttributeReference.html#artificial,
Artificial subprograms are not required to have a non-zero line number
location, so don't ignore them.
Fix #195768
---
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 17 ++++-
.../DebugInfo/COFF/builtin-verbose-trap.ll | 64 +++++++++++++++++++
2 files changed, 78 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/DebugInfo/COFF/builtin-verbose-trap.ll
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 61d1db5608878..ccec0b5910658 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -3123,12 +3123,23 @@ void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) {
CurFn = nullptr;
}
-// Usable locations are valid with non-zero line numbers. A line number of zero
-// corresponds to optimized code that doesn't have a distinct source location.
+// Usable locations are valid with non-zero line numbers, or artificial
+// subprograms because they are associated to the corresponding line within the
+// inlined callee.
+//
+// A line number of zero corresponds to optimized code that doesn't have a
+// distinct source location.
+//
// In this case, we try to use the previous or next source location depending on
// the context.
static bool isUsableDebugLoc(DebugLoc DL) {
- return DL && DL.getLine() != 0;
+ if (!DL)
+ return false;
+ if (DL.getLine() != 0)
+ return true;
+ if (const DILocalScope *Scope = DL->getScope())
+ return Scope->getSubprogram()->isArtificial();
+ return false;
}
void CodeViewDebug::beginInstruction(const MachineInstr *MI) {
diff --git a/llvm/test/DebugInfo/COFF/builtin-verbose-trap.ll b/llvm/test/DebugInfo/COFF/builtin-verbose-trap.ll
new file mode 100644
index 0000000000000..879328938fe8a
--- /dev/null
+++ b/llvm/test/DebugInfo/COFF/builtin-verbose-trap.ll
@@ -0,0 +1,64 @@
+; RUN: llc < %s -filetype=obj | llvm-readobj - --codeview | FileCheck %s
+
+; Original C++ source:
+; int done() {
+; __builtin_verbose_trap("STL_FOO", "broken stuff");
+; }
+
+; Make sure the call to clang-trap is annotated, even though the associated
+; debug location as a line number of 0.
+
+; CHECK: InlineesSym {
+; CHECK-NEXT: Kind: S_INLINEES (0x1168)
+; CHECK-NEXT: Inlinees [
+; CHECK-NEXT: FuncID: __clang_trap_msg$STL_FOO$broken stuff (0x1002)
+; CHECK-NEXT: ]
+; CHECK-NEXT: }
+; CHECK-NEXT: InlineSiteSym {
+; CHECK-NEXT: Kind: S_INLINESITE (0x114D)
+; CHECK-NEXT: PtrParent: 0x0
+; CHECK-NEXT: PtrEnd: 0x0
+; CHECK-NEXT: Inlinee: __clang_trap_msg$STL_FOO$broken stuff (0x1002)
+; CHECK-NEXT: BinaryAnnotations [
+; CHECK-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x1, LineOffset: 0}
+; CHECK-NEXT: ChangeCodeLength: 0x7
+; CHECK-NEXT: ]
+; CHECK-NEXT: }
+
+
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i686-pc-windows-msvc18.0.0"
+
+define dso_local i32 @done() !dbg !10 {
+ %1 = alloca i32
+ call void @llvm.trap(), !dbg !14
+ %2 = load i32, ptr %1, align 4
+ ret i32 %2
+}
+
+declare void @llvm.trap()
+
+
+!llvm.dbg.cu = !{!0}
+!llvm.linker.options = !{!2, !3}
+!llvm.module.flags = !{!4, !5, !6, !7, !8}
+!llvm.ident = !{!9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 20.1.8 (taskcluster-cBNpsXlaTmqEnu_aiQ0ElA)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.c", directory: "/Users/jrmuizel/bugs/inline", checksumkind: CSK_MD5, checksum: "ebf5ba4ead45cede7df7db37b24dc58d")
+!2 = !{!"/DEFAULTLIB:libcmt.lib"}
+!3 = !{!"/DEFAULTLIB:oldnames.lib"}
+!4 = !{i32 2, !"CodeView", i32 1}
+!5 = !{i32 2, !"Debug Info Version", i32 3}
+!6 = !{i32 1, !"wchar_size", i32 2}
+!7 = !{i32 8, !"PIC Level", i32 2}
+!8 = !{i32 7, !"uwtable", i32 2}
+!9 = !{!"clang version 20.1.8 (taskcluster-cBNpsXlaTmqEnu_aiQ0ElA)"}
+!10 = distinct !DISubprogram(name: "done", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0)
+!11 = !DISubroutineType(types: !12)
+!12 = !{!13}
+!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!14 = !DILocation(line: 0, scope: !15, inlinedAt: !17)
+!15 = distinct !DISubprogram(name: "__clang_trap_msg$STL_FOO$broken stuff", scope: !1, file: !1, type: !16, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: !0)
+!16 = !DISubroutineType(types: null)
+!17 = !DILocation(line: 2, scope: !10)
More information about the llvm-commits
mailing list