From d6e40fd518fe9e1317a8d3b81d387d098c162d53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
Date: Tue, 18 Apr 2023 11:03:41 +0300
Subject: [PATCH] Remove Windows setjmp redefinition hacks

Within Perl, the main PerlProc_setjmp symbol, in iperlsys.h, redirects to
Sigsetjmp in iperlsys.h, and on Windows, Sigsetjmp redirects to setjmp.
This layering works fine everywhere it is used.

However, the header XSUB.h, which seems to be meant to intercept direct
calls to system functions and redirect them to the corresponding
PerlProc names, breaks setjmp on Windows. Previously, XSUB.h would
undef setjmp and redirect it to PerlProc_setjmp, but this breaks
the regular PerlProc_setjmp -> Sigsetjmp -> setjmp expansion, since
setjmp isn't a regular function but a macro on Windows, and exactly
what it expands to is implementation defined.

This has been worked around since 2006 (since
4dcb9e53db5ab3b8d2b2f8eaba341cb2c0c5d2b8) in threads.xs by undeffing
XSUB.h's setjmp define, and redefining it to what setjmp.h would
do in e.g. MSVC headers.

For MSVC headers, this has been mostly straightforward, but on
mingw platforms, setjmp can expand to various different things;
trying to replicate the system headers in threads.xs is brittle,
as this has required numerous minor patches on mingw-w64 through
the years. This replication recently broke on mingw-w64 on i386,
when support for USE_NO_MINGW_SETJMP_TWO_ARGS was removed.

Instead of trying to mimic the system's setjmp definition, just
stop overriding the system header's setjmp/longjmp and keep them
intact.
---
 XSUB.h                  | 14 ++++++++++++++
 dist/threads/threads.xs | 17 -----------------
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/XSUB.h b/XSUB.h
index 82cd0dc777..b7f92abc5f 100644
--- a/XSUB.h
+++ b/XSUB.h
@@ -504,7 +504,14 @@ Rethrows a previously caught exception.  See L<perlguts/"Exception Handling">.
 #    undef fgetpos
 #    undef ioctl
 #    undef getlogin
+
+/* Don't undefine/redefine setjmp on Windows; PerlProc_setjmp gets redirected
+ * back to plain setjmp in the end, but then we've lost the system header's
+ * definition of it. Just keep the system headers versions of setjmp intact. */
+#ifndef _WIN32
 #    undef setjmp
+#endif
+
 #    undef getc
 #    undef ungetc
 #    undef fileno
@@ -609,8 +616,15 @@ Rethrows a previously caught exception.  See L<perlguts/"Exception Handling">.
 #    define sleep		PerlProc_sleep
 #    define times		PerlProc_times
 #    define wait		PerlProc_wait
+
+/* Don't undefine/redefine setjmp on Windows; PerlProc_setjmp gets redirected
+ * back to plain setjmp in the end, but then we've lost the system header's
+ * definition of it. Just keep the system headers versions of setjmp intact. */
+#ifndef _WIN32
 #    define setjmp		PerlProc_setjmp
 #    define longjmp		PerlProc_longjmp
+#endif
+
 #    define signal		PerlProc_signal
 #    define getpid		PerlProc_getpid
 #    define gettimeofday	PerlProc_gettimeofday
diff --git a/dist/threads/threads.xs b/dist/threads/threads.xs
index 25fec167aa..1a403af2f6 100644
--- a/dist/threads/threads.xs
+++ b/dist/threads/threads.xs
@@ -1,24 +1,7 @@
 #define PERL_NO_GET_CONTEXT
-/* Workaround for mingw 32-bit compiler by mingw-w64.sf.net - has to come before any #include.
- * It also defines USE_NO_MINGW_SETJMP_TWO_ARGS for the mingw.org 32-bit compilers ... but
- * that's ok as that compiler makes no use of that symbol anyway */
-#if defined(WIN32) && defined(__MINGW32__) && !defined(__MINGW64__)
-#  define USE_NO_MINGW_SETJMP_TWO_ARGS 1
-#endif
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
-/* Workaround for XSUB.h bug under WIN32 */
-#ifdef WIN32
-#  undef setjmp
-#  if defined(USE_NO_MINGW_SETJMP_TWO_ARGS) || (!defined(__BORLANDC__) && !defined(__MINGW64__))
-#    define setjmp(x) _setjmp(x)
-#  endif
-#  if defined(__MINGW64__)
-#    include <intrin.h>
-#    define setjmp(x) _setjmpex((x), mingw_getsp())
-#  endif
-#endif
 #define NEED_PL_signals
 #define NEED_sv_2pv_flags
 #include "ppport.h"
-- 
2.34.1

