Author: GkvJwa
Date: 2026-02-04T10:51:33+08:00
New Revision: 6b77030339c57a9758722ef5615ef93b3475ab33

URL: 
https://github.com/llvm/llvm-project/commit/6b77030339c57a9758722ef5615ef93b3475ab33
DIFF: 
https://github.com/llvm/llvm-project/commit/6b77030339c57a9758722ef5615ef93b3475ab33.diff

LOG: [WinEH] Fix crash object unwinding in seh block (#172287)

On Windows, prevent object unwinding when the current function uses SEH, 
consistent with MSVC. It also avoids EH number algorithm crashes

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticCommonKinds.td
    clang/lib/CodeGen/CGDecl.cpp
    clang/test/CodeGenCXX/exceptions-seh.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index 4aa5855bb0b94..cb267e3ee05c1 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -286,6 +286,8 @@ def err_seh___except_filter : Error<
   "%0 only allowed in __except filter expression">;
 def err_seh___finally_block : Error<
   "%0 only allowed in __finally block">;
+def err_seh_object_unwinding : Error<
+  "'__try' is not permitted in functions that require object unwinding">;
 
 // Sema && AST
 def note_invalid_subexpr_in_const_expr : Note<

diff  --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index f39e282f3d055..0cc0742c45c95 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -2227,8 +2227,13 @@ 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, prevent it
+    if (currentFunctionUsesSEHTry())
+      getContext().getDiagnostics().Report(D.getLocation(),
+                                           diag::err_seh_object_unwinding);
     emitAutoVarTypeCleanup(emission, dtorKind);
+  }
 
   // In GC mode, honor objc_precise_lifetime.
   if (getLangOpts().getGC() != LangOptions::NonGC &&

diff  --git a/clang/test/CodeGenCXX/exceptions-seh.cpp 
b/clang/test/CodeGenCXX/exceptions-seh.cpp
index bb374dd1f5bd5..22665a0c8fcc3 100644
--- a/clang/test/CodeGenCXX/exceptions-seh.cpp
+++ b/clang/test/CodeGenCXX/exceptions-seh.cpp
@@ -4,6 +4,12 @@
 // 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
+// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions 
-fexceptions \
+// RUN:         -fms-extensions -x c++ -emit-llvm -verify %s -DERR3
 
 extern "C" unsigned long _exception_code();
 extern "C" void might_throw();
@@ -175,3 +181,26 @@ 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{{'__try' is not permitted in functions 
that require object unwinding}}
+  } __except (1) {
+  }
+}
+#elif defined(ERR2)
+void seh_unwinding() {
+  __try {
+  } __except (1) {
+    HasCleanup x; // expected-error{{'__try' is not permitted in functions 
that require object unwinding}}
+  }
+}
+#elif defined(ERR3)
+void seh_unwinding() {
+  HasCleanup x; // expected-error{{'__try' is not permitted in functions that 
require object unwinding}}
+  __try {
+  } __except (1) {
+  }
+}
+#endif


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to