https://gcc.gnu.org/g:b0f09b72d9e1783e8ccaf2d8c1c72b03e3973f0b
commit r17-443-gb0f09b72d9e1783e8ccaf2d8c1c72b03e3973f0b Author: Oleg Tolmatcev <[email protected]> Date: Wed May 6 19:20:31 2026 +0200 i386: Keep SEH enabled for Win64 sysv_abi functions TARGET_SEH currently depends on TARGET_64BIT_MS_ABI. For Win64 functions compiled with SysV ABI, that makes the SEH hooks drop out even though exception handling still emits .seh_handlerdata. The result is assembly with .seh_handlerdata outside any .seh_proc block. Keep TARGET_SEH enabled for all 64-bit Windows functions when unwind tables are requested so SEH prologue and handler state remains consistent across ABI variants. Add a regression test covering a SysV ABI wrapper trampoline that references a throwing callee on x86_64 mingw. gcc/ChangeLog: * config/i386/cygming.h (TARGET_SEH): Keep SEH enabled for all 64-bit Windows functions when unwind tables are requested. gcc/testsuite/ChangeLog: * g++.target/i386/seh-sysvabi-wrap1.C: New test. Signed-off-by: oltolm <[email protected]> Signed-off-by: Jonathan Yong <[email protected]> Diff: --- gcc/config/i386/cygming.h | 6 ++- gcc/testsuite/g++.target/i386/seh-sysvabi-wrap1.C | 50 +++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h index 6e5a301aee10..c32f228044ee 100644 --- a/gcc/config/i386/cygming.h +++ b/gcc/config/i386/cygming.h @@ -26,7 +26,11 @@ along with GCC; see the file COPYING3. If not see #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG #undef TARGET_SEH -#define TARGET_SEH (TARGET_64BIT_MS_ABI && flag_unwind_tables) +/* Win64 uses SEH unwind metadata regardless of whether an individual + function is compiled with the default MS ABI or with sysv_abi. Keep + SEH enabled for all 64-bit Windows functions whenever unwind tables are + requested so .seh_proc state stays consistent with EH emission. */ +#define TARGET_SEH (TARGET_64BIT && flag_unwind_tables) #undef PREFERRED_STACK_BOUNDARY_DEFAULT #define PREFERRED_STACK_BOUNDARY_DEFAULT \ diff --git a/gcc/testsuite/g++.target/i386/seh-sysvabi-wrap1.C b/gcc/testsuite/g++.target/i386/seh-sysvabi-wrap1.C new file mode 100644 index 000000000000..34241dbc471e --- /dev/null +++ b/gcc/testsuite/g++.target/i386/seh-sysvabi-wrap1.C @@ -0,0 +1,50 @@ +/* Verify that x86_64 mingw can emit SEH metadata for a sysv_abi wrapper + trampoline that references a throwing callee. */ +/* { dg-do compile { target x86_64-*-mingw* } } */ +/* { dg-options "-std=gnu++17 -fexceptions" } */ + +#define SYSV __attribute__ ((sysv_abi)) +#define NOINLINE __attribute__ ((noinline)) + +template <auto F> +struct wrapper; + +template <typename R, typename... Args, SYSV R (*Func) (Args...)> +struct wrapper<Func> +{ + static R SYSV NOINLINE + call (Args... args) noexcept + { + return Func (args...); + } +}; + +using entry_fn = int SYSV (*) (); + +volatile int throw_flag; +volatile unsigned long long sink; + +int SYSV NOINLINE +stub0 () +{ + try + { + if (throw_flag) + throw 0; + } + catch (...) + { + } + + return 1; +} + +static entry_fn wrapped[] = { wrapper<stub0>::call }; + +int +main () +{ + entry_fn fn = wrapped[0]; + sink += (unsigned long long) (void *) fn; + return fn () == 0; +}
