[llvm] [MC] Fix line table assertion failure after inline asm error (PR #228742)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 3 11:04:51 PDT 2026


https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/228742

>From c89b40a6fa59b5177357b4ba6294dec0e670fc74 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 3 Oct 2026 09:32:37 -0700
Subject: [PATCH] [MC] Fix line table assertion failure after inline asm error

An inline asm `.file 3 "b"` without files 1 and 2 is diagnosed as
"unassigned file number", but code generation continues, and
MCObjectStreamer::finishImpl emits the line table with empty file
entries, which asserts.

Fix #228061: Set MCContext::HadError for errors reported through
MCContext::diagnose, and skip line table emission when an error has been
reported.
---
 llvm/lib/MC/MCContext.cpp                     |  2 ++
 llvm/lib/MC/MCObjectStreamer.cpp              |  7 ++++--
 .../DebugInfo/X86/inline-asm-file-error.ll    | 23 +++++++++++++++++++
 llvm/tools/llvm-mca/CodeRegionGenerator.cpp   | 11 +++++----
 4 files changed, 36 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/DebugInfo/X86/inline-asm-file-error.ll

diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index cea521debe71a1..935b0888bf6939 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -1081,6 +1081,8 @@ CodeViewContext &MCContext::getCVContext() {
 
 void MCContext::diagnose(const SMDiagnostic &SMD) {
   assert(DiagHandler && "MCContext::DiagHandler is not set");
+  if (SMD.getKind() == SourceMgr::DK_Error)
+    HadError = true;
   bool UseInlineSrcMgr = false;
   const SourceMgr *SMP = nullptr;
   if (SrcMgr) {
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 7a64fbbd667129..8fb2d7bc90c524 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -807,8 +807,11 @@ void MCObjectStreamer::finishImpl() {
   if (getContext().getGenDwarfForAssembly())
     MCGenDwarfInfo::Emit(this);
 
-  // Dump out the dwarf file & directory tables and line tables.
-  MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
+  // Dump out the dwarf file & directory tables and line tables. Suppress in
+  // case of errors (e.g. an unassigned file number in inline asm may leave hole
+  // in the file table).
+  if (!getContext().hadError())
+    MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
 
   // Emit pseudo probes for the current module.
   MCPseudoProbeTable::emit(this);
diff --git a/llvm/test/DebugInfo/X86/inline-asm-file-error.ll b/llvm/test/DebugInfo/X86/inline-asm-file-error.ll
new file mode 100644
index 00000000000000..5e73184a9684a7
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/inline-asm-file-error.ll
@@ -0,0 +1,23 @@
+;; An unassigned file number leaves a hole in the file table. Don't emit the
+;; line table after the error.
+; RUN: not llc -mtriple=x86_64 -filetype=obj %s -o /dev/null 2>&1 | FileCheck %s
+
+; CHECK: warning: inconsistent use of MD5 checksums
+; CHECK: error: unassigned file number: 1 for .file directives
+; CHECK: error: unassigned file number: 2 for .file directives
+
+define void @f() !dbg !4 {
+  call void asm sideeffect ".file 3 \22b\22", ""(), !dbg !5
+  ret void, !dbg !5
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, emissionKind: FullDebug)
+!1 = !DIFile(filename: "a.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "00000000000000000000000000000000")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !6, spFlags: DISPFlagDefinition, unit: !0)
+!5 = !DILocation(line: 1, scope: !4)
+!6 = !DISubroutineType(types: !{})
diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
index 67b90d0ebe6ce3..46e57830c6186a 100644
--- a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
+++ b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
@@ -64,17 +64,18 @@ Expected<const CodeRegions &> AsmCodeRegionGenerator::parseCodeRegions(
   // were already shown to the user. SkipFailures implies continuing in the
   // presence of any kind of failure within the parser, in which case failing
   // input lines are not represented, but the rest of the input remains.
-  if (Parser->Run(false) && !SkipFailures) {
+  bool HadParseError = Parser->Run(false);
+  if (CCP->hadErr())
+    return make_error<StringError>("There was an error parsing comments.",
+                                   inconvertibleErrorCode());
+
+  if (HadParseError && !SkipFailures) {
     const char *Message = "Assembly input parsing had errors, use "
                           "-skip-unsupported-instructions=parse-failure "
                           "to drop failing lines from the input.";
     return make_error<StringError>(Message, inconvertibleErrorCode());
   }
 
-  if (CCP->hadErr())
-    return make_error<StringError>("There was an error parsing comments.",
-                                   inconvertibleErrorCode());
-
   // Set the assembler dialect from the input. llvm-mca will use this as the
   // default dialect when printing reports.
   AssemblerDialect = Parser->getAssemblerDialect();



More information about the llvm-commits mailing list