[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