https://github.com/mstorsjo created 
https://github.com/llvm/llvm-project/pull/180513

On Windows, libunwind is normally only built in mingw mode; it's not relevant 
for MSVC targets. (Attempting to build it is entirely blocked in CMake, see 
[1]).

In mingw headers, the type EXCEPTION_DISPOSITION is defined as an int while it 
is an enum in the MSVC vcruntime headers.

However, in addition to the canonical enum members, we also use a value which 
has no assigned enum member. In older mingw-w64 headers, there was a define for 
this value, 4, with the name ExceptionExecuteHandler, but that was removed in 
[2]. The libunwind code reference this value just by the literal value 4, with 
a comment referencing it as ExceptionExecuteHandler.

This extra enum value isn't passed to the outside Microsoft runtime, but is 
only used to pass values from one part of libunwind to another; this handling 
is necessary for the forced_unwind{1-3}.pass.cpp tests to succeed.

If the mingw-w64 headers would define EXCEPTION_DISPOSITION as an enum, just 
like the MSVC vcruntime headers, then we'd run into build errors and warnings 
like this:

    llvm-project/libunwind/src/Unwind-seh.cpp:166:14: error: cannot initialize 
return object of type 'EXCEPTION_DISPOSITION' (aka 'enum 
_EXCEPTION_DISPOSITION') with an rvalue of type 'int'
      166 |       return 4 /* ExceptionExecuteHandler in mingw */;
          |              ^
    llvm-project/libunwind/src/Unwind-seh.cpp:185:14: error: cannot initialize 
return object of type 'EXCEPTION_DISPOSITION' (aka 'enum 
_EXCEPTION_DISPOSITION') with an rvalue of type 'int'
      185 |       return 4 /* ExceptionExecuteHandler in mingw */;
          |              ^
    llvm-project/libunwind/src/Unwind-seh.cpp:272:8: warning: case value not in 
enumerated type 'EXCEPTION_DISPOSITION' (aka 'enum _EXCEPTION_DISPOSITION') 
[-Wswitch]
      272 |   case 4 /*ExceptionExecuteHandler*/:
          |        ^

Fix these cases by adding explicit casts between EXCEPTION_DISPOSITION and int.

A (partial) similar change was proposed in [3], but the author never followed 
up on the discussion, and the PR was later closed.

[1] b0b546d44777eb1fa25995384876bd14a006a929
[2] 
https://github.com/mingw-w64/mingw-w64/commit/2de6703961c0d519046b841f7b392a040e1e5b55
[3] https://github.com/llvm/llvm-project/pull/159293

From 6cbc7b387127e9aea3024ca23caa7b64672e32b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <[email protected]>
Date: Mon, 9 Feb 2026 14:13:58 +0200
Subject: [PATCH] [libunwind] Fix building with EXCEPTION_DISPOSITION as enum

On Windows, libunwind is normally only built in mingw mode;
it's not relevant for MSVC targets. (Attempting to build it
is entirely blocked in CMake, see [1]).

In mingw headers, the type EXCEPTION_DISPOSITION is defined
as an int while it is an enum in the MSVC vcruntime headers.

However, in addition to the canonical enum members, we also
use a value which has no assigned enum member. In older mingw-w64
headers, there was a define for this value, 4, with the name
ExceptionExecuteHandler, but that was removed in [2]. The
libunwind code reference this value just by the literal value
4, with a comment referencing it as ExceptionExecuteHandler.

This extra enum value isn't passed to the outside Microsoft
runtime, but is only used to pass values from one part of
libunwind to another; this handling is necessary for the
forced_unwind{1-3}.pass.cpp tests to succeed.

If the mingw-w64 headers would define EXCEPTION_DISPOSITION as
an enum, just like the MSVC vcruntime headers, then we'd run
into build errors and warnings like this:

    llvm-project/libunwind/src/Unwind-seh.cpp:166:14: error: cannot initialize 
return object of type 'EXCEPTION_DISPOSITION' (aka 'enum 
_EXCEPTION_DISPOSITION') with an rvalue of type 'int'
      166 |       return 4 /* ExceptionExecuteHandler in mingw */;
          |              ^
    llvm-project/libunwind/src/Unwind-seh.cpp:185:14: error: cannot initialize 
return object of type 'EXCEPTION_DISPOSITION' (aka 'enum 
_EXCEPTION_DISPOSITION') with an rvalue of type 'int'
      185 |       return 4 /* ExceptionExecuteHandler in mingw */;
          |              ^
    llvm-project/libunwind/src/Unwind-seh.cpp:272:8: warning: case value not in 
enumerated type 'EXCEPTION_DISPOSITION' (aka 'enum _EXCEPTION_DISPOSITION') 
[-Wswitch]
      272 |   case 4 /*ExceptionExecuteHandler*/:
          |        ^

Fix these cases by adding explicit casts between EXCEPTION_DISPOSITION
and int.

A (partial) similar change was proposed in [3], but the author
never followed up on the discussion, and the PR was later closed.

[1] b0b546d44777eb1fa25995384876bd14a006a929
[2] 
https://github.com/mingw-w64/mingw-w64/commit/2de6703961c0d519046b841f7b392a040e1e5b55
[3] https://github.com/llvm/llvm-project/pull/159293
---
 libunwind/src/Unwind-seh.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libunwind/src/Unwind-seh.cpp b/libunwind/src/Unwind-seh.cpp
index 110c5987c3f1a..fe905f8765e17 100644
--- a/libunwind/src/Unwind-seh.cpp
+++ b/libunwind/src/Unwind-seh.cpp
@@ -163,7 +163,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID 
frame, PCONTEXT ms_ctx,
     // If we were called by __libunwind_seh_personality(), indicate that
     // a handler was found; otherwise, initiate phase 2 by unwinding.
     if (ours && ms_exc->NumberParameters > 1)
-      return 4 /* ExceptionExecuteHandler in mingw */;
+      return static_cast<EXCEPTION_DISPOSITION>(4);
     // This should never happen in phase 2.
     if (IS_UNWINDING(ms_exc->ExceptionFlags))
       _LIBUNWIND_ABORT("Personality indicated exception handler in phase 2!");
@@ -182,7 +182,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID 
frame, PCONTEXT ms_ctx,
     // a handler was found; otherwise, it's time to initiate a collided
     // unwind to the target.
     if (ours && !IS_UNWINDING(ms_exc->ExceptionFlags) && 
ms_exc->NumberParameters > 1)
-      return 4 /* ExceptionExecuteHandler in mingw */;
+      return static_cast<EXCEPTION_DISPOSITION>(4);
     // This should never happen in phase 1.
     if (!IS_UNWINDING(ms_exc->ExceptionFlags))
       _LIBUNWIND_ABORT("Personality installed context during phase 1!");
@@ -266,7 +266,7 @@ __libunwind_seh_personality(int version, _Unwind_Action 
state,
   _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() LanguageHandler "
                              "returned %d",
                              (int)ms_act);
-  switch (ms_act) {
+  switch (static_cast<int>(ms_act)) {
   case ExceptionContinueExecution: return _URC_END_OF_STACK;
   case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND;
   case 4 /*ExceptionExecuteHandler*/:

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

Reply via email to