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;