Summary
On the wasm32 musl port, size_t resolves to unsigned int, but clang for
wasm32 defines __SIZE_TYPE__ as unsigned long. Both are 32-bit on wasm32,
so the mismatch is binary-compatible and completely invisible to C code —
which is why it has gone unnoticed. It is fatal to C++: the language
requires operator new's first parameter to be exactly the implementation's
built-in size_t, so libc++abi (and any C++ translation unit that declares an
allocation function) fails to compile.
Root cause
arch/wasm32/bits/alltypes.h.in starts with:
#define _Addr int
musl derives size_t (and ptrdiff_t, intptr_t, …) from _Addr, so
_Addr int makes size_t = unsigned int. Every other arch in the tree whose
pointer-width type must match the compiler uses #define _Addr long
(x86_64, aarch64, riscv64); wasm32 is the odd one out. Clang's wasm32 target
uses unsigned long for __SIZE_TYPE__, so the header and the compiler
disagree.
Reproduction
Build any C++ that declares an allocation function (e.g. libc++abi) with the wasm32-hwjs toolchain:
clang: .../libcxxabi/src/stdlib_new_delete.cpp:73:20:
error: 'operator new' takes type size_t ('unsigned long') as 1st parameter
.../stdlib_new_delete.cpp:97:37:
error: 'operator new[]' takes type size_t ('unsigned long') as 1st parameter
.../cxa_vector.cpp:173:12:
error: no matching function for call to '__cxa_vec_new2'
Observed: size_t = unsigned int (from the header).
Expected: size_t = unsigned long (to match clang's __SIZE_TYPE__).
Proposed fix
Make wasm32 agree with the compiler, matching every other arch that pins
pointer-width types to long:
--- a/arch/wasm32/bits/alltypes.h.in
+++ b/arch/wasm32/bits/alltypes.h.in
@@ -1,1 +1,1 @@
-#define _Addr int
+#define _Addr long
On wasm32 long and int are both 32-bit, so this is ABI-neutral for existing
C objects; it only changes the spelling of size_t to the one clang expects,
which is what C++ requires. Verified: with this change libc++ + libc++abi
(static, no-exceptions, no-RTTI) compile and link cleanly, and an STL test
program (std::array / std::sort / std::string_view) builds and runs to a
correct result.
Proposed fix targets brintos/musl only — no distro submodule pins moved.
All distros share one lineage, so pin bumps are coordinated on merge, not
per-engineer.