[llvm] 38b12d4 - MCAssembler: Postpone errors in layout iteration
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 1 18:27:32 PDT 2025
Author: Fangrui Song
Date: 2025-06-01T18:27:26-07:00
New Revision: 38b12d4a7c219b46d1cb52580cbacbdb931262f2
URL: https://github.com/llvm/llvm-project/commit/38b12d4a7c219b46d1cb52580cbacbdb931262f2
DIFF: https://github.com/llvm/llvm-project/commit/38b12d4a7c219b46d1cb52580cbacbdb931262f2.diff
LOG: MCAssembler: Postpone errors in layout iteration
.org and .fill errors reported in a layout iteration might go away in
the final layout. Related to #100283
Added:
Modified:
llvm/include/llvm/MC/MCAssembler.h
llvm/lib/MC/MCAssembler.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 31d4445af45d6..3e141734ceac2 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -71,6 +71,8 @@ class MCAssembler {
SmallVector<const MCSymbol *, 0> Symbols;
+ mutable SmallVector<std::pair<SMLoc, std::string>, 0> PendingErrors;
+
MCDwarfLineTableParams LTParams;
/// The set of function symbols for which a .thumb_func directive has
@@ -230,6 +232,10 @@ class MCAssembler {
uint64_t FSize) const;
void reportError(SMLoc L, const Twine &Msg) const;
+ // Record pending errors during layout iteration, as they may go away once the
+ // layout is finalized.
+ void recordError(SMLoc L, const Twine &Msg) const;
+ void flushPendingErrors() const;
void dump() const;
};
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 5fde90e6abb7e..bde126c5c1099 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -217,12 +217,12 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
auto &FF = cast<MCFillFragment>(F);
int64_t NumValues = 0;
if (!FF.getNumValues().evaluateKnownAbsolute(NumValues, *this)) {
- reportError(FF.getLoc(), "expected assembly-time absolute expression");
+ recordError(FF.getLoc(), "expected assembly-time absolute expression");
return 0;
}
int64_t Size = NumValues * FF.getValueSize();
if (Size < 0) {
- reportError(FF.getLoc(), "invalid number of bytes");
+ recordError(FF.getLoc(), "invalid number of bytes");
return 0;
}
return Size;
@@ -266,7 +266,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
const MCOrgFragment &OF = cast<MCOrgFragment>(F);
MCValue Value;
if (!OF.getOffset().evaluateAsValue(Value, *this)) {
- reportError(OF.getLoc(), "expected assembly-time absolute expression");
+ recordError(OF.getLoc(), "expected assembly-time absolute expression");
return 0;
}
@@ -275,14 +275,14 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
if (const auto *SA = Value.getAddSym()) {
uint64_t Val;
if (!getSymbolOffset(*SA, Val)) {
- reportError(OF.getLoc(), "expected absolute expression");
+ recordError(OF.getLoc(), "expected absolute expression");
return 0;
}
TargetLocation += Val;
}
int64_t Size = TargetLocation - FragmentOffset;
if (Size < 0 || Size >= 0x40000000) {
- reportError(OF.getLoc(), "invalid .org offset '" + Twine(TargetLocation) +
+ recordError(OF.getLoc(), "invalid .org offset '" + Twine(TargetLocation) +
"' (at offset '" + Twine(FragmentOffset) +
"')");
return 0;
@@ -825,6 +825,7 @@ void MCAssembler::writeSectionData(raw_ostream &OS,
for (const MCFragment &F : *Sec)
writeFragment(OS, *this, F);
+ flushPendingErrors();
assert(getContext().hadError() ||
OS.tell() - Start == getSectionAddressSize(*Sec));
}
@@ -878,6 +879,8 @@ void MCAssembler::layout() {
// Finalize the layout, including fragment lowering.
getBackend().finishLayout(*this);
+ flushPendingErrors();
+
DEBUG_WITH_TYPE("mc-dump", {
errs() << "assembler backend - final-layout\n--\n";
dump(); });
@@ -968,6 +971,7 @@ void MCAssembler::Finish() {
stats::ObjectBytes += getWriter().writeObject();
HasLayout = false;
+ assert(PendingErrors.empty());
}
bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup,
@@ -1222,6 +1226,7 @@ bool MCAssembler::relaxFragment(MCFragment &F) {
bool MCAssembler::layoutOnce() {
++stats::RelaxationSteps;
+ PendingErrors.clear();
bool Changed = false;
for (MCSection &Sec : *this)
@@ -1235,6 +1240,16 @@ void MCAssembler::reportError(SMLoc L, const Twine &Msg) const {
getContext().reportError(L, Msg);
}
+void MCAssembler::recordError(SMLoc Loc, const Twine &Msg) const {
+ PendingErrors.emplace_back(Loc, Msg.str());
+}
+
+void MCAssembler::flushPendingErrors() const {
+ for (auto &Err : PendingErrors)
+ reportError(Err.first, Err.second);
+ PendingErrors.clear();
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MCAssembler::dump() const{
raw_ostream &OS = errs();
More information about the llvm-commits
mailing list