From fe5cb89b6f3b50fc4661b31865b707b779a23065 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 11:27:10 +0000 Subject: [PATCH] php: fix upstream's typo in the no-atomics arm, which nobody compiles zend_atomic.c:44 answered `argument prototype mismatch "IND STRUCT zend_atomic_bool_s" for "IND STRUCT zend_atomic_int_s"'. zend_atomic.h:323 declares zend_atomic_bool_compare_exchange_ex(zend_atomic_int *obj, ...) while the other four arms -- C11, GNUC, SYNC and WIN32 at :106, :161, :207 and :263 -- all say zend_atomic_bool *, as does every sibling _bool_ function in that same arm, and zend_atomic.c passes a zend_atomic_bool *. One word, fixed in the vendored source with the reasoning beside it. It survives because nobody compiles that arm: it is reached only by a platform with no C11 atomics, no GCC atomics, no __sync builtins and not Windows, which until kencc was no platform at all. And gcc only warns where kencc errors, so even someone who did compile it might not have noticed. Worth reporting upstream. The arm has exactly one bug, and that is measured rather than hoped. Compiling it in isolation found nothing, because the mismatch is between a caller and a callee and the arm is self-consistent within itself; forcing HAVE_NO_ATOMICS in a copy of the header and compiling the real zend_atomic.c against it reproduces the kencc diagnostic exactly, reports nothing else, and after the fix reports nothing at all. Forcing it took two attempts, which is the part worth keeping. The first -I did nothing, because zend_atomic.c includes "zend_atomic.h" quoted and that resolves next to the source file before any -I; the compile silently took the GNUC arm and reported a clean result. A forced configuration that was not actually forced reads exactly like a passing one, and the tell was the absent #warning. Also drops a `linux/*' from a comment in php_config.h, which put a `"/*" within comment' warning into all 513 compiles. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs --- docs/notes/php.md | 35 +++++++++++++++++++++++ sys/src/ape/cmd/php/cfg/main/php_config.h | 2 +- sys/src/external/php/Zend/zend_atomic.h | 16 ++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/docs/notes/php.md b/docs/notes/php.md index 85b81335a..4baf80749 100644 --- a/docs/notes/php.md +++ b/docs/notes/php.md @@ -284,6 +284,41 @@ confidently and wrongly*, which is the clearest single argument in this port for hand-answering rather than deriving: the mechanical method is right 90 times and this is one of the others. +### And the no-atomics arm had never been compiled by anyone + +`zend_atomic.c:44` answered +`argument prototype mismatch "IND STRUCT zend_atomic_bool_s" for +"IND STRUCT zend_atomic_int_s"`. It is **upstream's typo**, not +ours: `zend_atomic.h:323` declares +`zend_atomic_bool_compare_exchange_ex(zend_atomic_int *obj, ...)`, +while the other four arms -- C11, GNUC, SYNC and WIN32, at `:106`, +`:161`, `:207`, `:263` -- all say `zend_atomic_bool *`, as does every +sibling `_bool_` function in that same arm. + +***IT SURVIVES BECAUSE NOBODY COMPILES THAT ARM.*** It is reached +only by a platform with no C11 atomics, no GCC atomics, no `__sync` +builtins and not Windows -- which until kencc was no platform at all. +And **gcc only warns** (`-Wincompatible-pointer-types`) where kencc +errors, so even someone who did compile it might not have noticed. +Fixed in the vendored source, one word, with the reasoning beside it. +Worth reporting upstream. + +**The arm has exactly one bug, which is measured rather than hoped.** +Compiling it in isolation found nothing, because the mismatch is +between a caller and a callee and the arm is self-consistent within +itself. Forcing `HAVE_NO_ATOMICS` in a copy of the header and +compiling the real `zend_atomic.c` against it reproduces the kencc +diagnostic exactly and reports **nothing else** -- and after the fix, +nothing at all. + +*Forcing it took two attempts.* The first `-I` did nothing, because +`zend_atomic.c` includes `"zend_atomic.h"` **quoted**, which resolves +next to the source file before any `-I`; the compile silently took +the GNUC arm and reported a clean result. **A forced configuration +that was not actually forced reads exactly like a passing one** -- +the tell was that the `#warning` was absent, and checking for it is +what turned a false clean into a real one. + ### The atomics: not worth implementing for this build, and here is why `#warning No atomics support detected` appears on every file and is diff --git a/sys/src/ape/cmd/php/cfg/main/php_config.h b/sys/src/ape/cmd/php/cfg/main/php_config.h index 1dc42e87e..fab34768f 100644 --- a/sys/src/ape/cmd/php/cfg/main/php_config.h +++ b/sys/src/ape/cmd/php/cfg/main/php_config.h @@ -183,7 +183,7 @@ /* #undef HAVE_DLFCN_H */ /* #undef HAVE_LIBDL */ -/* absent: ODBC (14 names), tidy, linux/*, the SSE intrinsic headers, +/* absent: ODBC (14 names), tidy, the linux/ family, the SSE headers, * Windows, crypt.h, sys/ipc.h, sys/mount.h, sys/statfs.h, sys/vfs.h, * pty.h, ieeefp.h, cpuid.h, io.h, dns.h, libproc.h, valgrind. */ /* #undef HAVE_CRYPT_H */ diff --git a/sys/src/external/php/Zend/zend_atomic.h b/sys/src/external/php/Zend/zend_atomic.h index 5eeb212ec..eecf329b6 100644 --- a/sys/src/external/php/Zend/zend_atomic.h +++ b/sys/src/external/php/Zend/zend_atomic.h @@ -320,7 +320,21 @@ static zend_always_inline void zend_atomic_int_store_ex(zend_atomic_int *obj, in obj->value = desired; } -static zend_always_inline bool zend_atomic_bool_compare_exchange_ex(zend_atomic_int *obj, bool *expected, bool desired) { +/* + * APExp: `zend_atomic_int *' here was UPSTREAM'S TYPO and this is the + * one-word fix. The other four arms of this file -- C11, GNUC, SYNC + * and WIN32, at :106, :161, :207 and :263 -- all declare + * `zend_atomic_bool *', as does every sibling `_bool_' function in + * this same arm, and `zend_atomic.c:44' passes a `zend_atomic_bool *'. + * + * ***IT SURVIVES BECAUSE NOBODY COMPILES THIS ARM.*** It is reached + * only when a platform has no C11 atomics, no GCC atomics, no + * `__sync' builtins and is not Windows, which until kencc was no + * platform at all. gcc only WARNS here (`-Wincompatible-pointer- + * types'); kencc makes it an error, which is why APExp is the first + * to see it. Worth reporting upstream. + */ +static zend_always_inline bool zend_atomic_bool_compare_exchange_ex(zend_atomic_bool *obj, bool *expected, bool desired) { bool prev = obj->value; if (prev == *expected) { obj->value = desired;