commit 409eaad8e100c7a8bb5ef0adf6f5ca51ca4570f5
parent ab7c2d2e1f5b5ffe84981551f86d3d71e1fe336b
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 30 Apr 2026 08:31:10 -0700
docs: TCC-TODO update — gcc-flat 130/22, gcc-libc-flat 152/0, cc.scm-tcc 13/139
Diffstat:
| M | docs/TCC-TODO.md | | | 83 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
1 file changed, 61 insertions(+), 22 deletions(-)
diff --git a/docs/TCC-TODO.md b/docs/TCC-TODO.md
@@ -74,9 +74,12 @@ make test SUITE=tcc-cc
Result:
```text
-13 passed, 140 failed
+13 passed, 139 failed
```
+(152 fixtures total; the count dropped by 1 since `068-main-noret`
+was retired as part of the host-baseline cleanup.)
+
Raw run log:
```text
@@ -130,17 +133,25 @@ Alpine gcc and use that gcc-built tcc to run the same `tests/cc`
fixtures. That control is not perfectly green, but it is far healthier:
```text
-gcc-built ARM64 tcc.flat.c: 126 passed, 27 failed
-cc.scm-built ARM64 tcc-boot2: 13 passed, 140 failed
+gcc-built ARM64 tcc.flat.c (no libc): 130 passed, 22 failed
+gcc-built ARM64 tcc.flat.c (libc + tcc hdrs): 152 passed, 0 failed
+cc.scm-built ARM64 tcc-boot2: 13 passed, 139 failed
```
-So there are two layers of signal:
-
-- 27 failures reproduce even when tcc is built by gcc from the
- flattened ARM64 source. Treat these as tcc/ARM64/flattened-source
- baseline failures until proven otherwise.
-- 114 additional fixtures fail only with the `cc.scm`-built tcc. That
- is the main evidence that our compiler is miscompiling tcc.
+So there are three layers of signal:
+
+- The **libc + tcc-headers** control is fully green. It links the
+ flattened tcc against `libc.flat.c` + libtcc1 + a tiny mes-libc
+ string runtime, and passes `-I tcc/include` so the bundled
+ `<stdarg.h>` resolves under `-nostdlib`. Run with
+ `scripts/run-gcc-libc-flat-tcc.sh`. This proves the fixtures and
+ the flattened tcc source are coherent end-to-end.
+- The **no-libc** control still has 22 failures. Most are stdarg.h
+ not on the include path (the script doesn't pass `-I tcc/include`)
+ and a handful are upstream tcc/AArch64 codegen bugs unrelated to
+ varargs (struct-ret, compound-literal, typedef-fnptr, etc.).
+- The remaining ~117 failures fire only with the `cc.scm`-built tcc.
+ That is the main evidence that our compiler is miscompiling tcc.
## Host Baseline
@@ -172,22 +183,50 @@ Current result:
```text
tcc version 0.9.26 (AArch64 Linux)
-126 passed, 27 failed
+130 passed, 22 failed
+```
+
+The libc-flat variant adds `-I tcc/include` and a real libc backing,
+and is fully green:
+
+```sh
+make tcc-gcc TCC_TARGET=ARM64
+podman run --rm --pull=never --platform linux/arm64 \
+ -v "$PWD":/work -w /work boot2-alpine-gcc:aarch64 \
+ sh scripts/run-gcc-libc-flat-tcc.sh
+# 152 passed, 0 failed
```
-Those 27 failures break down as:
+The 22 no-libc failures break down as:
-- Compile/link segfaults: `001-kitchen-sink`, `015-variadic`,
- `032-local-struct-desig`, `067-vararg-call`, `076-vararg-recv`,
- `079-vararg-deep`, `084-struct-assign`, `096-fwd-struct`,
- `097-vararg-many-named`, `099-init-zero-tail`,
- `108-typedef-fnptr`, `109-typedef-anon`, `111-struct-ret-1word`,
- `112-struct-ret-2word`, `113-struct-ret-3word`,
+- Compile/link failures from missing `<stdarg.h>` (the script doesn't
+ pass `-I tcc/include`): `001-kitchen-sink`, `015-variadic`,
+ `067-vararg-call`, `076-vararg-recv`, `079-vararg-deep`,
+ `097-vararg-many-named`, `116-struct-ret-vararg`, `131-vararg-mixed`.
+- Compile/link segfaults from upstream tcc/AArch64 codegen gaps:
+ `032-local-struct-desig`, `084-struct-assign`, `096-fwd-struct`,
+ `099-init-zero-tail`, `108-typedef-fnptr`, `109-typedef-anon`,
+ `111-struct-ret-1word`, `112-struct-ret-2word`, `113-struct-ret-3word`,
`114-struct-ret-many-args`, `115-struct-ret-3word-many-args`,
- `116-struct-ret-vararg`, `117-compound-literal`,
- `125-anon-union`, `129-extern-libp1pp`, `131-vararg-mixed`.
-- Runtime exit mismatches: `018-sext-narrow`, `068-main-noret`,
- `102-cmpd-narrow`, `119-float-parse`, `128-cast-signedness`.
+ `117-compound-literal`, `125-anon-union`, `129-extern-libp1pp`.
+
+The 5 prior runtime-exit mismatches (`018-sext-narrow`, `068-main-noret`,
+`102-cmpd-narrow`, `119-float-parse`, `128-cast-signedness`) are gone:
+the fixtures were cleaned up so they assume neither implicit
+`signed char` nor a specific `long double` size. `068-main-noret` was
+retired entirely because relying on the implicit return value of
+`main` is undefined.
+
+`scripts/simple-patches/tcc-0.9.26/` carries two AArch64 vararg fixes
+applied during stage1-flatten so any tcc rebuilt from this tree picks
+them up: `aarch64-stdarg-array.{before,after}` swaps the bundled
+`va_list` for `__va_list_struct[1]` (matches glibc/musl/x86_64 ABI),
+and the `arm64-va-{pointer-operand,arg-pointer}.{before,after}` pair
+teach `gen_va_start`/`gen_va_arg` to skip `gaddrof()` when the
+operand is already a pointer (the array-decayed/pointer-parameter
+case). Without this, `va_list` forwarding into a non-variadic helper
+(the `vfprintf` shape, e.g. `131-vararg-mixed`) hit `assert fail: 0`
+in `arm64-gen.c`.
Two fixture cleanups are part of that baseline: