From b24fcc6f1c7a446c01588558eb85bf4fdd42506d Mon Sep 17 00:00:00 2001
From: Greg Burd <greg@burd.me>
Date: Sun, 26 Jul 2026 13:30:36 -0400
Subject: [PATCH v1] Don't use __builtin_setjmp on aarch64 MinGW/Windows

Commit 146cb3889c3 made the WIN32/MinGW-64 build use gcc's
__builtin_setjmp/__builtin_longjmp to work around longstanding issues
in MinGW-64's own setjmp support.  That workaround is fine on x86_64
MinGW, but it is broken on aarch64 (ARM64) MinGW toolchains:

  * clang for aarch64-w64-windows-gnu does not implement
    __builtin_setjmp at all -- it errors with
    "__builtin_setjmp is not supported for the current target"; and

  * where the builtin is accepted its first argument is a void **,
    which is incompatible with the intptr_t sigjmp_buf[5] that c.h
    declares, producing
    "incompatible pointer types passing 'sigjmp_buf' to parameter of
    type 'void **'".

The net effect is that a PostgreSQL build with a clang-based aarch64
MinGW toolchain fails to compile as early as src/common/pg_get_line.c
(the first caller of sigsetjmp()).

Restrict the __builtin_setjmp path to !defined(__aarch64__) so that
aarch64 MinGW falls back to plain setjmp()/longjmp(), the same path
already used for non-MinGW Windows toolchains.  x86_64 MinGW is
unchanged.

Reported while building for aarch64 Windows with an MSYS2 clangarm64
toolchain.
---
 src/include/c.h | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/include/c.h b/src/include/c.h
index 20cfbac54e7..981f8c42f55 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1525,18 +1525,23 @@ typedef struct pg_signal_info
  * When there is no sigsetjmp, its functionality is provided by plain
  * setjmp.  We now support the case only on Windows.  However, it seems
  * that MinGW-64 has some longstanding issues in its setjmp support,
- * so on that toolchain we cheat and use gcc's builtins.
+ * so on that toolchain we cheat and use gcc's builtins.  That workaround
+ * only applies to x86_64 MinGW: on aarch64 (ARM64) MinGW toolchains
+ * clang does not implement __builtin_setjmp/__builtin_longjmp at all
+ * ("__builtin_setjmp is not supported for the current target"), and its
+ * prototype takes a void ** rather than PostgreSQL's sigjmp_buf, so fall
+ * back to plain setjmp there.
  */
 #ifdef WIN32
-#ifdef __MINGW64__
+#if defined(__MINGW64__) && !defined(__aarch64__)
 typedef intptr_t sigjmp_buf[5];
 #define sigsetjmp(x,y) __builtin_setjmp(x)
 #define siglongjmp __builtin_longjmp
-#else							/* !__MINGW64__ */
+#else							/* !__MINGW64__ || __aarch64__ */
 #define sigjmp_buf jmp_buf
 #define sigsetjmp(x,y) setjmp(x)
 #define siglongjmp longjmp
-#endif							/* __MINGW64__ */
+#endif							/* __MINGW64__ && !__aarch64__ */
 #endif							/* WIN32 */
 
 /* /port compatibility functions */
-- 
2.51.2

