Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions docs/notes/php.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion sys/src/ape/cmd/php/cfg/main/php_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
16 changes: 15 additions & 1 deletion sys/src/external/php/Zend/zend_atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading