Don't use __builtin_setjmp on aarch64 MinGW/Windows

From: "Greg Burd" <greg(at)burd(dot)me>
To: "PostgreSQL Hackers" <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Cc: "Dave Cramer" <davecramer(at)gmail(dot)com>, "Alexander Lakhin" <exclusion(at)gmail(dot)com>, "Nathan Bossart" <nathandbossart(at)gmail(dot)com>, "John Naylor" <johncnaylorls(at)gmail(dot)com>
Subject: Don't use __builtin_setjmp on aarch64 MinGW/Windows
Date: 2026-07-28 13:10:54
Message-ID: c51b6de8-41fe-4751-b94c-605a19e00dc4@app.fastmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello fellow hackers!

My build farm animal "unicorn" has been sick for a while, apologies
for not jumping on that sooner, I'll get to that in another email.

This is a small issue that I found when trying to expand the testing
on my Windows/aarch64 host with two more animals, one for MSYS2 clang
and one with MinGW and gcc. This report/fix is fairly straight
forward in that it is a simple change in c.h for the MSYS2/clang on
aarch64 combo only.

I found that the build fails to compile as early as
src/common/pg_get_line.c, the first caller of sigsetjmp():

../pgsql/src/common/pg_get_line.c:129: error: incompatible pointer
types passing 'sigjmp_buf' (aka 'long long[5]') to parameter of
type 'void **' [-Wincompatible-pointer-types]

and, with a slightly different clang, the more fundamental:

error: __builtin_setjmp is not supported for the current target

Root cause
----------
c.h maps sigsetjmp()/siglongjmp() onto the gcc builtins for MinGW-64:

#ifdef WIN32
#ifdef __MINGW64__
typedef intptr_t sigjmp_buf[5];
#define sigsetjmp(x,y) __builtin_setjmp(x)
#define siglongjmp __builtin_longjmp
#else
...

This dates to commit 146cb3889c3 ("Work around issues in MinGW-64's
setjmp/longjmp support.", 2021), which was written for and tested on
x86_64 MinGW, where __builtin_setjmp works. On aarch64 MinGW
toolchains it does not:

* clang for aarch64-w64-windows-gnu does not implement
__builtin_setjmp at all; and

* where a builtin is accepted, its first parameter is a void **,
which is incompatible with the intptr_t sigjmp_buf[5] that the
same block declares.

So __MINGW64__ is too broad a condition: the builtin-setjmp workaround
is correct on x86_64 MinGW but wrong on aarch64 MinGW.

The underlying MinGW-64 setjmp bug that 146cb3889c3 works around is, as
far as I can tell, still unfixed: the attempt to narrow the workaround
to MSVCRT-only (c313fa4602d, "Use workaround of __builtin_setjmp only on
MINGW on MSVCRT") was reverted by 8f5e419484c because the problem "is
found to cause issues on x86_64 Windows even when using UCRT." So we
should keep the __builtin_setjmp path for x86_64 MinGW; this patch only
removes it where the builtin cannot be used at all.

Fix
---
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.

I tested this fix on my host with the proposed changes and can confirm
that it fixes the issue and that the 2021 defect was GCC-x86_64-MinGW
specific.

Testing
-------
Built and tested on real aarch64 Windows 11 hardware with the MSYS2
clangarm64 toolchain (clang 22.1.8, target aarch64-w64-windows-gnu):

* Without the patch the tree fails to compile at
src/common/pg_get_line.c (the first sigsetjmp() caller), as above.

* With the patch the full tree builds cleanly (ninja: 2103/2103
targets, postgres.exe produced) and, importantly, the resulting
server exercises the setjmp/longjmp path correctly at runtime:
initdb succeeds; 25 consecutive elog(ERROR) cycles (each a
siglongjmp back to the main loop) are caught and recovered; nested
PL/pgSQL exception blocks work; the server stays healthy with no
TRAP/PANIC/crash in the log across the run.

So on this toolchain the plain setjmp()/longjmp() fallback is not merely
a compile fix -- it is runtime-correct. The original MinGW-64
setjmp/longjmp defect that 146cb3889c3 works around appears to be
specific to the x86_64 GCC MinGW toolchain and not present in
clang-aarch64-mingw, which has its own setjmp lowering. I have not
tested a GCC-based aarch64 MinGW toolchain.

I have not exercised a full check-world on this platform yet (that is
gated on a separate atomics issue I am handling in a different thread);
this result is initdb + targeted error-path testing, not the full
regression suite.

The patch is attached (v1). It applies on master and is a one-line
condition change plus a comment update; it changes no behavior on any
currently-supported platform (only aarch64 MinGW, which does not build
today, takes the new path). As is becoming more and more common, yes
I did use AI/LLMs to help diagnose, propose a fix, exhaustively test,
and write this email. I have reviewed the results, the patch, the
tests, and the email content myself and feel that this is a small but
important change that allows for use of Postgres on Windows 11 built
using MSYS2/clang on aarch64 hosts.

best,

-greg

Attachment Content-Type Size
v1-0001-c-h-no-builtin-setjmp-on-aarch64-mingw.patch text/x-patch 2.8 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Daniel Gustafsson 2026-07-28 13:13:54 Re: datachecksums: handle invalid and dropped databases during enable
Previous Message Tender Wang 2026-07-28 13:03:51 Re: remove_useless_joins vs. bug #19560