va_list is a struct, not an array of one
static int take(va_list ap) { return va_arg(ap, int); }
static int sz(va_list ap) { return (int)sizeof ap; }
/* f(0, 10, 20): take(ap) then va_arg(ap, int) */
/* gcc x86-64: take=10 next=20 param sizeof 8 */
/* pxx: take=10 next=10 param sizeof 24 */
Measured 2026-09-27 on v445 and after
bug-c-an-array-typedef-of-structs-is-not-modelled, which made array typedefs of
structs real and, to keep va_list exactly as it was, changed stdarg.h's
typedef struct __pxx_va_elem va_list[1]; (whose [1] pxx had always ignored)
to the plain struct its own comment describes.
Making it an array would change how every target passes one: abi.inc passes the 24-byte class by value in memory on SysV and indirectly on AAPCS64, and CVaListAddr, va_copy and the crtl v*printf family all assume a record. Do it only with every target's variadic tests (test-core's c_va_arg_every_target and the qemu jobs) and a caller-visible-consumption row per target, since the right answer differs by target (aarch64 gcc: a struct).