[clang] [llvm] [MC] Flush PendingErrors on early return in MCAssembler::layout() (PR #225769)

Demetrios Chiuratto Agourakis via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 06:41:50 PDT 2026


https://github.com/agourakis82 created https://github.com/llvm/llvm-project/pull/225769

Fixes #225036.

### Summary
When inline assembly contains both an early parse-time error (such as a non-absolute subsection in `.text`) and an expression that can only be evaluated at layout time (such as a non-absolute fill count in `.zero`), the layout-time error is recorded in `MCAssembler::PendingErrors` during `layoutSection()`.

If `getContext().hadError()` is already true from the prior parse-time error, the relaxation loop in `MCAssembler::layout()` returned early without calling `flushPendingErrors()`. When `MCAssembler::Finish()` was subsequently called, `assert(PendingErrors.empty())` failed.

Calling `flushPendingErrors()` before returning early ensures that all pending errors are drained and reported cleanly, satisfying the assertion in `Finish()`.

### Changes
- `llvm/lib/MC/MCAssembler.cpp`: Call `flushPendingErrors()` on early return when `getContext().hadError()` in `layout()`.
- `clang/test/CodeGen/inline-asm-pending-errors.c`: Regression test verifying that inline assembly with both parse-time and layout-time directive errors reports all errors cleanly without assertion failure.

>From 0b700d915d2d9c6ab378a66a01ebc2601b79b545 Mon Sep 17 00:00:00 2001
From: Demetrios Chiuratto Agourakis <agourakis82 at gmail.com>
Date: Wed, 23 Sep 2026 13:41:21 +0000
Subject: [PATCH] [MC] Flush PendingErrors on early return in
 MCAssembler::layout()

Fixes #225036.

When inline assembly contains both an early parse-time error (such as a
non-absolute subsection in .text) and an expression that can only be
evaluated at layout time (such as a non-absolute fill count in .zero),
the layout-time error is recorded in MCAssembler::PendingErrors during
layoutSection().

If getContext().hadError() is already true from the prior parse-time error,
the relaxation loop in MCAssembler::layout() returned early before reaching
the normal flushPendingErrors() call. When Finish() was subsequently called,
assert(PendingErrors.empty()) failed.

Ensure flushPendingErrors() is called before early return in layout().
---
 clang/test/CodeGen/inline-asm-pending-errors.c | 12 ++++++++++++
 llvm/lib/MC/MCAssembler.cpp                    |  4 +++-
 2 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGen/inline-asm-pending-errors.c

diff --git a/clang/test/CodeGen/inline-asm-pending-errors.c b/clang/test/CodeGen/inline-asm-pending-errors.c
new file mode 100644
index 00000000000000..6b367d2a1868e8
--- /dev/null
+++ b/clang/test/CodeGen/inline-asm-pending-errors.c
@@ -0,0 +1,12 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O0 %s 2>&1 | FileCheck %s
+
+// PR225036: When inline assembly contains both a parse-time directive error
+// (e.g., non-absolute subsection number in .text) and a layout-time directive error
+// (e.g., non-absolute fill expression in .zero), MCAssembler must flush pending
+// errors rather than asserting PendingErrors.empty() in Finish().
+
+void test_pending_errors(int b) {
+  // CHECK: error: cannot evaluate subsection number
+  // CHECK: error: expected assembly-time absolute expression
+  asm(".text a\n.zero %0" : : "r"(b));
+}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index fcdcdbc96426ff..bf22b60cedaf36 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -702,8 +702,10 @@ void MCAssembler::layout() {
     layoutSection(Sec);
   unsigned FirstStable = Sections.size();
   while ((FirstStable = relaxOnce(FirstStable)) > 0)
-    if (getContext().hadError())
+    if (getContext().hadError()) {
+      flushPendingErrors();
       return;
+    }
 
   // Some targets might want to adjust fragment offsets. If so, perform another
   // layout iteration.



More information about the llvm-commits mailing list