[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