[clang] [WinEH] Fix crash, object unwinding in the except block (PR #172287)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Dec 28 07:53:46 PST 2025
https://github.com/GkvJwa updated https://github.com/llvm/llvm-project/pull/172287
>From 98fa6cd36dcfaa61f957201943ee661c07870833 Mon Sep 17 00:00:00 2001
From: GkvJwa <gkvjwa at gmail.com>
Date: Sun, 28 Dec 2025 23:53:25 +0800
Subject: [PATCH] Test
---
clang/lib/CodeGen/CGDecl.cpp | 15 ++++++++++++++-
clang/lib/CodeGen/CGException.cpp | 2 ++
clang/lib/CodeGen/CodeGenFunction.h | 3 +++
clang/test/CodeGenCXX/exceptions-seh.cpp | 20 ++++++++++++++++++++
4 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 8b1cd83af2396..1216403eeba1a 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -2212,8 +2212,21 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
const VarDecl &D = *emission.Variable;
// Check the type for a cleanup.
- if (QualType::DestructionKind dtorKind = D.needsDestruction(getContext()))
+ if (QualType::DestructionKind dtorKind = D.needsDestruction(getContext())) {
+ // Check if we're in a SEH block and this is a C++ destructor
+ if (dtorKind == QualType::DK_cxx_destructor) {
+ if (isSEHTryScope()) {
+ // We're in a __try block
+ getContext().getDiagnostics().Report(D.getLocation(),
+ diag::err_seh_expected_handler);
+ } else if (InSEHExceptBlock) {
+ // We're in an __except block
+ getContext().getDiagnostics().Report(D.getLocation(),
+ diag::err_seh_expected_handler);
+ }
+ }
emitAutoVarTypeCleanup(emission, dtorKind);
+ }
// In GC mode, honor objc_precise_lifetime.
if (getLangOpts().getGC() != LangOptions::NonGC &&
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index e9d20672ce185..bd41343d345bf 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -2270,7 +2270,9 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {
}
// Emit the __except body.
+ InSEHExceptBlock = true;
EmitStmt(Except->getBlock());
+ InSEHExceptBlock = false;
// End the lifetime of the exception code.
SEHCodeSlotStack.pop_back();
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 855e43631f436..4ea6e9de04dae 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -589,6 +589,9 @@ class CodeGenFunction : public CodeGenTypeCache {
GlobalDecl CurSEHParent;
+ // Track if we're currently emitting __except block
+ bool InSEHExceptBlock = false;
+
/// True if the current function is an outlined SEH helper. This can be a
/// finally block or filter expression.
bool IsOutlinedSEHHelper = false;
diff --git a/clang/test/CodeGenCXX/exceptions-seh.cpp b/clang/test/CodeGenCXX/exceptions-seh.cpp
index bb374dd1f5bd5..87adde5ff1baa 100644
--- a/clang/test/CodeGenCXX/exceptions-seh.cpp
+++ b/clang/test/CodeGenCXX/exceptions-seh.cpp
@@ -4,6 +4,10 @@
// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
// RUN: -o - -mconstructor-aliases -O1 -disable-llvm-passes | \
// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX
+// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions -fexceptions \
+// RUN: -fms-extensions -x c++ -emit-llvm -verify %s -DERR1
+// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions -fexceptions \
+// RUN: -fms-extensions -x c++ -emit-llvm -verify %s -DERR2
extern "C" unsigned long _exception_code();
extern "C" void might_throw();
@@ -175,3 +179,19 @@ void use_inline() {
// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }
void seh_in_noexcept() noexcept { __try {} __finally {} }
+
+#if defined(ERR1)
+void seh_unwinding() {
+ __try {
+ HasCleanup x; // expected-error{{expected '__except' or '__finally' block}}
+ } __except (1) {
+ }
+}
+#elif defined(ERR2)
+void seh_unwinding() {
+ __try {
+ } __except (1) {
+ HasCleanup x; // expected-error{{expected '__except' or '__finally' block}}
+ }
+}
+#endif
More information about the cfe-commits
mailing list