Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Win32] mingw-w64 ports of gcc-13 will break 32-bit builds of perl #21039

Closed
sisyphus opened this issue Apr 19, 2023 · 1 comment · Fixed by #21142
Closed

[Win32] mingw-w64 ports of gcc-13 will break 32-bit builds of perl #21039

sisyphus opened this issue Apr 19, 2023 · 1 comment · Fixed by #21142

Comments

@sisyphus
Copy link
Contributor

sisyphus commented Apr 19, 2023

Description
With mingw-w64 ports of gcc-13, 32-bit versions of setjmp.h will no longer look at whether USE_NO_MINGW_SETJMP_TWO_ARGS is defined.
This change means that dist/threads/threads.xs won't compile using gcc-13. (No such issue with gcc-12 and earlier.)
Martin Storsjo (who is a member of the mingw-w64 development team) has generously provided me with the following patch to the perl source that (verified) will fix this problem:

---
 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"
---

Things to note:

  1. It's simple, elegant, and removes a heap of crud;
  2. It doesn't distinguish between different windows compilers;
  3. It doesn't even distinguish between different versions of gcc.

Applying this patch to perl-5.37.10, I've checked that perl still builds and tests fine for both 32-bit and 64-bit versions of both gcc-12.2.0 and gcc-13.0.1.
I've also checked that this patch (applied to 5.37.10) works fine with 32-bit and 64-bit VS-2022 compilers. (With the 32-bit VS-2022 I built both MSWin32-x86-multi-thread and MSWin32-x86-multi-thread-64int.)

To me, it looks great, and I'll be applying this patch to the perls that I build henceforth.
But I haven't (eg) tested it using any gcc versions older than 12.2.0.

Anyway .... I'm putting the patch up here as something that people might like to test and/or comment upon.

If you think there's a better way to deal with the impending issue with gcc-13, now is a good time to speak up.

Snapshots of mingw-w64 ports of the gcc-13.0.1 toolchain can be downloaded from:
https://gcc-mcf.lhmouse.com/
or
https://winlibs.com

EDIT: fixed typo

Cheers,
Rob

xenu added a commit to xenu/perl5 that referenced this issue Jun 5, 2023
Those redefinitions are in effect only when PERL_IMPLICIT_SYS is defined
(pretty much only on Windows) and they're broken (circular) when
HAS_SIGSETJMP isn't defined (e.g. on Windows). Also, even if they
weren't broken, they don't provide any value.

The workaround in thread.xs for this issue is still needed, because it's
a dual-life module and it's supposed to work on older Perls. However, it
can be simplified by defining NO_XSLOCKS to suppress the redefinitions.

Fixes Perl#21039
xenu added a commit to xenu/perl5 that referenced this issue Jun 6, 2023
Those redefinitions are in effect only when PERL_IMPLICIT_SYS is defined
(pretty much only on Windows) and they're broken (circular) when
HAS_SIGSETJMP isn't defined (e.g. on Windows). Also, even if they
weren't broken, they don't provide any value.

The workaround in threads.xs for this issue is still needed, because
it's a dual-life module and it's supposed to work on older Perls.
However, it can be simplified by defining NO_XSLOCKS to suppress the
redefinitions.

Fixes Perl#21039
@sisyphus
Copy link
Contributor Author

#21142 LGTM.
Apply those changes, in preference to the patches provided here.

Cheers,
Rob

tonycoz pushed a commit that referenced this issue Jul 10, 2023
Those redefinitions are in effect only when PERL_IMPLICIT_SYS is defined
(pretty much only on Windows) and they're broken (circular) when
HAS_SIGSETJMP isn't defined (e.g. on Windows). Also, even if they
weren't broken, they don't provide any value.

The workaround in threads.xs for this issue is still needed, because
it's a dual-life module and it's supposed to work on older Perls.
However, it can be simplified by defining NO_XSLOCKS to suppress the
redefinitions.

Fixes #21039
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants