[llvm] [MC] Diagnose unfinished CFI frame from an earlier section (PR #196775)
via llvm-commits
llvm-commits at lists.llvm.org
Sat May 9 20:59:33 PDT 2026
https://github.com/1wos created https://github.com/llvm/llvm-project/pull/196775
Fixes #177852.
**Problem.** The reproducer has two `.cfi_startproc` directives separated by a `.popsection`. The first is never closed; the second is properly paired with `.cfi_endproc`. `MCStreamer::finish()` only inspects the last entry of `DwarfFrameInfos`, so the unfinished earlier frame slips through and crashes `finishImpl()` when it emits frame data with a null End label.
**Fix.** Use `hasUnfinishedDwarfFrameInfo()` instead, which walks the full `FrameInfoStack` and catches every unfinished frame.
**Test.** Added `llvm/test/MC/ELF/cfi-startproc-no-endproc.s`. The reproducer now emits `error: Unfinished frame!` instead of crashing, and `check-llvm-mc` still passes.
>From 02fb1007ff52a26a18a2f62b6c94eebeeff10ee4 Mon Sep 17 00:00:00 2001
From: 1wos <79901950+1wos at users.noreply.github.com>
Date: Sun, 10 May 2026 12:39:28 +0900
Subject: [PATCH] [MC] Diagnose unfinished CFI frame from an earlier section
MCStreamer::finish() inspected only DwarfFrameInfos.back().End, so
a .cfi_startproc left open in one section followed by a properly
closed frame in another section passed the check and crashed in
finishImpl().
Use hasUnfinishedDwarfFrameInfo() to check FrameInfoStack instead.
Fixes #177852.
---
llvm/lib/MC/MCStreamer.cpp | 2 +-
llvm/test/MC/ELF/cfi-startproc-no-endproc.s | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/MC/ELF/cfi-startproc-no-endproc.s
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 6325eee91c57e..f9f4138916cfe 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -1117,7 +1117,7 @@ void MCStreamer::emitWindowsUnwindTables() {}
void MCStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {}
void MCStreamer::finish(SMLoc EndLoc) {
- if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
+ if (hasUnfinishedDwarfFrameInfo() ||
(!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
getContext().reportError(EndLoc, "Unfinished frame!");
return;
diff --git a/llvm/test/MC/ELF/cfi-startproc-no-endproc.s b/llvm/test/MC/ELF/cfi-startproc-no-endproc.s
new file mode 100644
index 0000000000000..76682bfc78f46
--- /dev/null
+++ b/llvm/test/MC/ELF/cfi-startproc-no-endproc.s
@@ -0,0 +1,20 @@
+# RUN: not llvm-mc %s -triple x86_64-linux -o /dev/null 2>&1 | FileCheck %s
+# RUN: not llvm-mc %s -triple x86_64-linux -filetype=obj -o /dev/null 2>&1 | FileCheck %s
+
+## https://github.com/llvm/llvm-project/issues/177852
+## Check we don't crash when an inner .cfi_startproc in one section
+## is left unfinished while a later frame in another section is
+## properly closed (so the last DwarfFrameInfo entry has a valid End).
+
+.pushsection .text.qux, "ax", @progbits
+.type qux, @function
+qux:
+.cfi_startproc
+.popsection
+
+.type quux, @function
+quux:
+.cfi_startproc
+.cfi_endproc
+
+# CHECK: error: Unfinished frame!
More information about the llvm-commits
mailing list