boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

cc-ext — c-testsuite coverage for cc.scm

External breadth-coverage for cc.scm, on top of the hand-written tests/cc/ and tests/cc-libc/ fixtures. Each fixture is a small, self-contained C program from c-testsuite (vendored under vendor/c-testsuite/single-exec/); per the suite's spec the program returns 0 on success and the .expected file pins stdout+stderr.

The point of having someone else's tests in the tree is that they exercise corners of C we would not naturally write tests for — they surface bugs we don't know to look for.

Running

make test SUITE=cc-ext                              # full suite, every arch
make test SUITE=cc-ext ARCH=aarch64                 # one arch
sh scripts/run-tests.sh --suite=cc-ext \
    --arch=aarch64 00050 00089                      # specific fixtures

make test SUITE=cc-ext is opt-in — it is not part of the default make test loop, since most fixtures still fail and we don't want that drowning out signal from the curated suites.

Each fixture's .tags file lists feature requirements (portable, c89, c99, c11, needs-libc, needs-cpp). The runner switches pipelines on the tags:

Compile, assemble, and runtime errors all count as FAIL. There are no auto-skips: the goal is an honest pass/fail count that drops as cc.scm grows.

Current status (aarch64, snapshot 2026-05-02)

Failure groups, largest first:

count error likely root cause
62 #include: file inclusion is handled upstream by pre-flatten preprocessor doesn't resolve system headers; needs-libc tests use #include <stdio.h>. The cc-libc suite sidesteps this with explicit extern int printf(...) declarations. Either (a) add an include search path + minimal stdio.h/stdlib.h/string.h shims that emit the same extern declarations, or (b) pre-flatten these fixtures before handing them to cc.scm.
5 const-expr: bad operand: lbrack designated array initializer [N] = .... Out of scope — cc.scm intentionally doesn't support designated array init.
4 P1pp assemble (hex2 link) failed — fixtures 00210/00211/00215/00217 undefined symbols against libc. 00211/00215/00217 are tagged needs-libc but call routines we haven't wired up; 00210 uses printf without the needs-libc tag, so the runner pipelines it bare.
2 unexp: lbrace — fixtures 00213, 00214 GCC statement expression ({ ... }). Substantial feature; not on the path for tcc.c bootstrap.
1 init: too many fields — fixture 00216 extensive use of designated/range/flex-array initializer features ([1 ... 5] = 9, etc.).
1 field — fixture 00218 bit-field declaration (enum tree_code code : 8). Bit-fields not implemented.
1 floating-point literal not supported — fixture 00123 no float support in cc.scm. Out of scope.
1 undecl: L — fixture 00098 wide-char literal L"..." / L'x'. Out of scope.

Recently fixed

The 2026-05-02 sweep flipped 5 singletons green via small targeted changes:

Plus three preparatory changes that don't flip a test on their own but unblock attribute-heavy code: parse-aggregate-spec and eat-cv-quals! eat __attribute__ between tag and {, between * and the next declarator piece; parse-decl-cont accepts a leading __attribute__; and parse-cast-or-unary recognises a leading attribute on the cast typename. __builtin_expect(x, y) is stubbed as (x).

Next steps for bug hunting

Designated array init ([N] = ...), wide literals, and floats are intentionally not supported. The remaining tractable bucket is small and feature-shaped — statement expressions (213/214), bit-fields (218), and the kitchen-sink initializer fixture (216) — each is a substantial standalone feature, so spend time on them only if the underlying capability is wanted for tcc.c.

The 60+ #include failures are gated on a single design call: either land a minimal header search path or accept that these fixtures stay as a TODO until we lift libc declarations into shipped headers.

Layout

vendor/c-testsuite/
    LICENSE                # MIT (runner / scaffolding)
    TESTS-LICENSE          # case-by-case (per-test attribution upstream)
    README.md              # snapshot tag + integration notes
    single-exec/
        NNNNN.c
        NNNNN.c.expected   # exact stdout+stderr (often empty)
        NNNNN.c.tags       # portable / c89 / c99 / needs-libc / ...

Build artifacts live under build/$ARCH/tests/cc-ext/$name, intermediates under build/$ARCH/.work/tests/cc-ext/$name/. Logs: cc.log (cc.scm output), p1pp.log (P1pp assemble + hex2 link).