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;
+}

Reply via email to