[llvm] [AsmParser] Fixed `assembler local symbol not defined` unable to locate the exact line number. (PR #219719)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 29 13:48:24 PDT 2026
https://github.com/zhangweize9-cyber updated https://github.com/llvm/llvm-project/pull/219719
>From 670b609b1e0d077f65383c331eee148c4c8d6b9c Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Sun, 30 Aug 2026 02:06:12 +0800
Subject: [PATCH] [AsmParser] Fixed `assembler local symbol not defined` unable
to locate the exact line number.
---
llvm/include/llvm/MC/MCContext.h | 14 +++++++++++
llvm/lib/MC/MCExpr.cpp | 2 ++
llvm/lib/MC/MCParser/AsmParser.cpp | 25 ++++++++++++++-----
.../undefined-local-symbol-location.s | 13 ++++++++++
4 files changed, 48 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/MC/AsmParser/undefined-local-symbol-location.s
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 7e76abe08f56f..9eca783571898 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -162,6 +162,9 @@ class MCContext {
/// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1)
DenseMap<std::pair<unsigned, unsigned>, MCSymbol *> LocalSymbols;
+ /// Recording SymbolLocs.
+ DenseMap<const MCSymbol *, SMLoc> SymbolLocs;
+
/// Keeps track of labels that are used in inline assembly.
StringMap<MCSymbol *, BumpPtrAllocator &> InlineAsmUsedLabelNames;
@@ -481,6 +484,17 @@ class MCContext {
/// \param Name - The symbol name, which must be unique across all symbols.
LLVM_ABI MCSymbol *getOrCreateSymbol(const Twine &Name);
+ /// Set the initial source location for a symbol.
+ void setSymbolLoc(const MCSymbol *Sym, SMLoc Loc) {
+ if (Sym && Loc.isValid() && !SymbolLocs.count(Sym))
+ SymbolLocs[Sym] = Loc;
+ }
+
+ /// Get the recorded source location for a symbol.
+ SMLoc getSymbolLoc(const MCSymbol *Sym) const {
+ return SymbolLocs.lookup(Sym);
+ }
+
/// Variant of getOrCreateSymbol that handles backslash-escaped symbols.
/// For example, parse "a\"b\\" as a"\.
LLVM_ABI MCSymbol *parseSymbol(const Twine &Name);
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index c23dc3c119a01..d5ce3ad8d29f0 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -226,6 +226,8 @@ MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, Spec specifier,
const MCSymbolRefExpr *MCSymbolRefExpr::create(const MCSymbol *Sym,
uint16_t specifier,
MCContext &Ctx, SMLoc Loc) {
+ if (Sym && Loc.isValid())
+ Ctx.setSymbolLoc(Sym, Loc);
return new (Ctx) MCSymbolRefExpr(Sym, specifier, Loc);
}
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 839dbca990578..8b446c2d2684a 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1044,12 +1044,25 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// explicitly. If we know it's a variable, we have a definition for
// the purposes of this check.
if (Sym && Sym->isTemporary() && !Sym->isVariable() &&
- !Sym->isDefined())
- // FIXME: We would really like to refer back to where the symbol was
- // first referenced for a source location. We need to add something
- // to track that. Currently, we just point to the end of the file.
- printError(getTok().getLoc(), "assembler local symbol '" +
- Sym->getName() + "' not defined");
+ !Sym->isDefined()) {
+ SMLoc ErrorLoc = getContext().getSymbolLoc(Sym);
+ if (!ErrorLoc.isValid())
+ ErrorLoc = getTok().getLoc();
+
+ /// Achieve underline annotation effect.
+ SMRange SymbolRange;
+ if (ErrorLoc.isValid()) {
+ const char *StartPtr = ErrorLoc.getPointer();
+ SMLoc EndLoc =
+ SMLoc::getFromPointer(StartPtr + Sym->getName().size());
+ SymbolRange = SMRange(ErrorLoc, EndLoc);
+ }
+
+ printError(ErrorLoc,
+ "assembler local symbol '" + Sym->getName() +
+ "' not defined",
+ SymbolRange);
+ }
}
}
diff --git a/llvm/test/MC/AsmParser/undefined-local-symbol-location.s b/llvm/test/MC/AsmParser/undefined-local-symbol-location.s
new file mode 100644
index 0000000000000..52be762a868a7
--- /dev/null
+++ b/llvm/test/MC/AsmParser/undefined-local-symbol-location.s
@@ -0,0 +1,13 @@
+// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 6
+// RUN: not llvm-mc -triple=x86_64-apple-macos %s 2>&1 | FileCheck %s
+.text
+
+
+jmp L_undefined_temporary_symbol
+// CHECK: :[[@LINE-1]]:5: error: assembler local symbol 'L_undefined_temporary_symbol' not defined
+movl %eax
+// CHECK: :[[@LINE-1]]:1: error: too few operands for instruction
+movl $0x1234567890, %eax
+// CHECK: :[[@LINE-1]]:6: error: unknown token in expression
+invalid_inst_name %eax
+// CHECK: :[[@LINE-1]]:1: error: invalid instruction mnemonic 'invalid_inst_name'
More information about the llvm-commits
mailing list