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
