Only 64-bit targets for now. Enabling this on 32-bit x86 requires additional work, as we need to provide exception helpers for modules that don’t link against msvcrt/ucrt. LLVM currently does not support `__try`/`__except` on 32-bit ARM.
While `__try`/`__except` is generally available on the MinGW target with `-fms-extensions`, `-fasync-exceptions` is currently supported only on the MSVC target. For that reason, I did not enable it for the MinGW target.
From: Jacek Caban jacek@codeweavers.com
Without this, the compiler may inline them into dispatch_exception. When compiler exceptions are enabled, this causes a handler to be set up for dispatch_exception, which is unintended. A side effect of this is that EXCEPTION_NESTED_CALL may be cleared when a nested exception is dispatched.
This fixes test_nested_exception test on aarch64 when compiler exceptions are used. --- dlls/ntdll/exception.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index bf4a53e1b6e..2284333668a 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -465,7 +465,7 @@ void __cdecl __wine_spec_unimplemented_stub( const char *module, const char *fun * * IsBadStringPtrA replacement for ntdll, to catch exception in debug traces. */ -BOOL WINAPI IsBadStringPtrA( LPCSTR str, UINT_PTR max ) +BOOL DECLSPEC_NOINLINE WINAPI IsBadStringPtrA( LPCSTR str, UINT_PTR max ) { if (!str) return TRUE; __TRY @@ -486,7 +486,7 @@ BOOL WINAPI IsBadStringPtrA( LPCSTR str, UINT_PTR max ) * * IsBadStringPtrW replacement for ntdll, to catch exception in debug traces. */ -BOOL WINAPI IsBadStringPtrW( LPCWSTR str, UINT_PTR max ) +BOOL DECLSPEC_NOINLINE WINAPI IsBadStringPtrW( LPCWSTR str, UINT_PTR max ) { if (!str) return TRUE; __TRY
From: Jacek Caban jacek@codeweavers.com
This affects Clang in MSVC mode. By default, Clang treats __try/__except as regular exceptions, assuming that memory access doesn’t throw. As a result, it may incorrectly move code outside the exception handler or optimize away the handler entirely. MSVC always treats __try/__except as meaningful. Work around the issue by explicitly enabling -fasync-exceptions.
See https://github.com/llvm/llvm-project/issues/62606 more context. --- configure.ac | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configure.ac b/configure.ac index 2dcf3111f49..e900ea20493 100644 --- a/configure.ac +++ b/configure.ac @@ -540,6 +540,7 @@ This is an error since --enable-archs=$wine_arch was requested.])]) WINE_TRY_PE_CFLAGS([-fno-strict-aliasing]) dnl clang needs to be told to fail on unknown options WINE_TRY_PE_CFLAGS([-Werror=unknown-warning-option],[CFLAGS="$CFLAGS -Werror=unknown-warning-option"]) + WINE_TRY_PE_CFLAGS([-Werror=unused-command-line-argument],[CFLAGS="$CFLAGS -Werror=unused-command-line-argument"]) WINE_TRY_PE_CFLAGS([-Werror=ignored-optimization-argument],[CFLAGS="$CFLAGS -Werror=ignored-optimization-argument"]) WINE_TRY_PE_CFLAGS([-Wdeclaration-after-statement]) WINE_TRY_PE_CFLAGS([-Wempty-body]) @@ -558,6 +559,7 @@ This is an error since --enable-archs=$wine_arch was requested.])]) WINE_TRY_PE_CFLAGS([-Wabsolute-value]) WINE_TRY_PE_CFLAGS([-Wenum-enum-conversion],[:],WINE_TRY_PE_CFLAGS([-Wenum-conversion])) WINE_TRY_PE_CFLAGS([-ffunction-sections]) + WINE_TRY_PE_CFLAGS([-fasync-exceptions])
dnl clang had broken -fms-hotpatch support before version 18 (https://github.com/llvm/llvm-project/pull/77245) WINE_TRY_PE_CFLAGS([-fms-hotpatch -DMIN_CLANG_VERSION=18],
From: Jacek Caban jacek@codeweavers.com
--- dlls/winecrt0/exception.c | 6 ++++++ include/excpt.h | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/winecrt0/exception.c b/dlls/winecrt0/exception.c index 58cf91172ac..ab4224cf4c2 100644 --- a/dlls/winecrt0/exception.c +++ b/dlls/winecrt0/exception.c @@ -18,6 +18,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "excpt.h" +#undef USE_COMPILER_EXCEPTIONS +#undef GetExceptionInformation +#undef GetExceptionCode +#undef AbnormalTermination + #include <stdarg.h> #include "winternl.h" #include "wine/exception.h" diff --git a/include/excpt.h b/include/excpt.h index 3369f3b1547..17c7409c636 100644 --- a/include/excpt.h +++ b/include/excpt.h @@ -38,7 +38,11 @@ typedef enum _EXCEPTION_DISPOSITION #define EXCEPTION_CONTINUE_EXECUTION -1
-#if defined(_MSC_VER) && defined(USE_COMPILER_EXCEPTIONS) +#if !defined(USE_COMPILER_EXCEPTIONS) && defined(_MSC_VER) && !defined(__i386__) && !defined(__arm__) && (!defined(__clang_major__) || __clang_major__ >= 19) +#define USE_COMPILER_EXCEPTIONS +#endif + +#ifdef USE_COMPILER_EXCEPTIONS #define GetExceptionCode _exception_code #define GetExceptionInformation (struct _EXCEPTION_POINTERS *)_exception_info #define AbnormalTermination _abnormal_termination @@ -46,6 +50,6 @@ typedef enum _EXCEPTION_DISPOSITION unsigned long __cdecl _exception_code(void); void * __cdecl _exception_info(void); int __cdecl _abnormal_termination(void); -#endif /* defined(_MSC_VER) && defined(USE_COMPILER_EXCEPTIONS) */ +#endif /* USE_COMPILER_EXCEPTIONS */
#endif /* __WINE_EXCPT_H */