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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ All notable changes to EigenScript are documented here.

### Fixed

- **The freestanding profile now enforces switch exhaustiveness
(#835).** `tools/freestanding_check.sh` was a third compile mechanism
alongside the Makefile and `build.sh`, and neither of its hand-written
`gcc` invocations carried `-Werror=switch` — so an unhandled
`ASTType`/opcode case that is a hard error on every other build path
only warned there. Both invocations are armed (verified with a planted
enum case: `make freestanding-check` now fails on it), and the [99i]
werror-switch gate learned to audit compile-bearing shell scripts —
comment-stripped, through the same classifier as the Makefile dry
runs, with the same zero-line hard failure and new selftest shapes —
so this can't regress silently. `build.sh` stays outside the gate,
stated honestly in the gate header: its compile lines name sources via
`$SOURCES` variables the recognizer cannot tell from a link line.

- **Widget drawing is contained (#823).** `render` now wraps every
widget's draw in a clip of its own rect intersected with its
ancestors' — `canvas` `on_paint` included, so a paint callback can no
Expand Down
14 changes: 8 additions & 6 deletions tests/run_all_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4261,15 +4261,17 @@ fi
rm -rf "$CONT_DIR"
echo ""

# [99i] Uniform -Werror=switch gate (#817 follow-up). Dry-runs every
# compiling Makefile target and asserts every emitted compile line carries
# the flag; --selftest proves the checker catches each planted fault shape
# (and that a zero-line audit is a hard failure, not a silent pass).
echo "[99i] werror-switch compile-line gate (#817)"
# [99i] Uniform -Werror=switch gate (#817 follow-up; #835 extended it to
# compile-bearing shell scripts). Dry-runs every compiling Makefile target
# plus the audited scripts (tools/freestanding_check.sh) and asserts every
# emitted compile line carries the flag; --selftest proves the checker
# catches each planted fault shape (and that a zero-line audit is a hard
# failure, not a silent pass).
echo "[99i] werror-switch compile-line gate (#817/#835)"
TOTAL=$((TOTAL + 1))
if bash "$TESTS_DIR/../tools/werror_switch_check.sh" && bash "$TESTS_DIR/../tools/werror_switch_check.sh" --selftest >/dev/null; then
PASS=$((PASS + 1))
echo " PASS: every dry-run compile line carries -Werror=switch (gate self-test green)"
echo " PASS: every dry-run + audited-script compile line carries -Werror=switch (gate self-test green)"
else
FAIL=$((FAIL + 1))
echo " FAIL: a compile line lacks -Werror=switch, or the gate self-test broke (see lines above)"
Expand Down
4 changes: 2 additions & 2 deletions tools/freestanding_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ trap 'rm -rf "$BUILD"' EXIT
SRC="eigenscript lexer parser builtins builtins_host builtins_tensor hash arena state strbuf ext_store fmt lint chunk compiler vm jit trace eigs_embed"
for f in $SRC; do
gcc -O2 -ffreestanding -fno-stack-protector -U_FORTIFY_SOURCE \
-Werror=implicit-function-declaration \
-Werror=implicit-function-declaration -Werror=switch \
-DEIGENSCRIPT_FREESTANDING=1 \
-DEIGENSCRIPT_EXT_HTTP=0 -DEIGENSCRIPT_EXT_MODEL=0 -DEIGENSCRIPT_EXT_DB=0 \
-c "src/$f.c" -o "$BUILD/$f.o"
Expand Down Expand Up @@ -53,7 +53,7 @@ echo "OK stage 1: freestanding import surface is within the ledger allowlist"
for f in mini_libc mini_libm mini_fmt mini_strtod; do
gcc -O2 -ffreestanding -fno-builtin -ffp-contract=off -fno-math-errno \
-fno-stack-protector -U_FORTIFY_SOURCE \
-Werror=implicit-function-declaration \
-Werror=implicit-function-declaration -Werror=switch \
-DEIGS_MINI_STANDARD_NAMES=1 \
-c "src/freestanding/$f.c" -o "$BUILD/$f.o"
done
Expand Down
62 changes: 54 additions & 8 deletions tools/werror_switch_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@
# `-Werror=switch-enum` is a different warning and must NOT satisfy
# this gate.
#
# Blind spots, stated honestly: compiles hidden INSIDE shell scripts are
# invisible to `make -n` and out of scope here — and the exclusion is not
# hypothetical: tools/freestanding_check.sh compiles its runtime set
# WITHOUT the flag (a known gap, tracked separately, deliberately not
# absorbed into this gate's scope); build.sh's three compile lines are
# armed (#786). This gate asserts the invariant over what `make` emits —
# no more, no less.
# Compiles hidden INSIDE shell scripts are invisible to `make -n`, so the
# scripts whose compile lines the classifier can recognize are audited
# DIRECTLY (#835): comment lines stripped, then the script text goes
# through the same join/split/classify pipeline as a dry-run stream, with
# the same per-script zero-line hard failure. Today that list is
# tools/freestanding_check.sh — its gcc lines name "src/$f.c" literally.
# Blind spot, stated honestly: build.sh stays out of scope — its three
# compile lines are armed (#786) but name their sources via
# $SOURCES/$LSP_SOURCES variables, which the recognizer cannot tell from
# a pure link line, so auditing it would assert nothing (and the lsp/
# minimal lines would trip the zero-line assertion spuriously).
#
# A gate that silently matches nothing is worse than no gate — it passes
# forever. Two assertions prevent that. PER TARGET: a dry run yielding
Expand Down Expand Up @@ -74,6 +78,15 @@ TARGETS="build full http zlib net gfx asan asan-http tsan valgrind poison \
lsp dap jit-smoke lib embed-smoke embed-smoke-gfx pgo coverage \
fuzz fuzz-libfuzzer freestanding-libc-diff"

# Compile-bearing shell scripts audited directly (#835) — see header.
SCRIPT_AUDITS="tools/freestanding_check.sh"

Comment on lines +81 to +83
# Comment lines must not be examined: a script comment QUOTING a bare
# compile line is not a compile.
strip_comments() {
grep -vE '^[[:space:]]*#'
}

EXAMINED=0 # compile invocations examined, all targets
VIOLATIONS=0 # examined invocations missing the flag
TARGET_EXAMINED=0 # examined within the current target (reset per target)
Expand Down Expand Up @@ -266,6 +279,28 @@ EOF
st_fail=1
fi

# Script-audit shapes (#835): a compile line inside a shell script is
# classified exactly like a dry-run line once comments are stripped.
expect_caught "script compile line, flag dropped" 'src/$f.c' <<'EOF'
gcc -O2 -ffreestanding -fno-stack-protector -U_FORTIFY_SOURCE -Werror=implicit-function-declaration -c "src/$f.c" -o "$BUILD/$f.o"
EOF
expect_clean "script compile line, flag present" <<'EOF'
gcc -O2 -ffreestanding -Werror=implicit-function-declaration -Werror=switch -c "src/$f.c" -o "$BUILD/$f.o"
EOF

# A comment quoting a bare compile must not be examined at all.
EXAMINED=0; VIOLATIONS=0; TARGET_EXAMINED=0
strip_comments <<'EOF' | join_continuations > "$st_joined"
# gcc -O2 -c src/vm.c -o vm.o (quoted in a comment; not a compile)
# indented comment: gcc -c src/jit.c
echo hello
EOF
audit_stream "selftest:script-comment" < "$st_joined"
if [ "$EXAMINED" -ne 0 ] || [ "$VIOLATIONS" -ne 0 ]; then
echo "SELFTEST FAILED: commented compile lines were examined ($EXAMINED/$VIOLATIONS)"
st_fail=1
fi

# `-Werror=switch-enum` is a DIFFERENT warning: it must not satisfy the
# check, and the real flag alongside it must.
expect_caught "switch-enum is not switch" "src/vm.c" <<'EOF'
Expand Down Expand Up @@ -338,6 +373,17 @@ for t in $TARGETS; do
audit_target "$t" <<< "$(printf '%s\n' "$dry" | join_continuations)" || empty_failed=1
done

# Compile-bearing scripts (#835): same classifier, same zero-line
# assertion, comment lines stripped first.
for s in $SCRIPT_AUDITS; do
if [ ! -f "$s" ]; then
echo "GATE ERROR: script '$s' not found — cannot audit it"
make_failed=1
continue
fi
audit_target "script:$s" <<< "$(strip_comments < "$s" | join_continuations)" || empty_failed=1
done

if [ "$make_failed" -ne 0 ] || [ "$empty_failed" -ne 0 ]; then
exit 1
fi
Expand All @@ -346,5 +392,5 @@ if [ "$VIOLATIONS" -gt 0 ]; then
echo "werror-switch gate FAILED: $VIOLATIONS of $EXAMINED compile invocations lack $FLAG"
exit 1
fi
echo "werror-switch gate OK: all $EXAMINED compile invocations across $(echo $TARGETS | wc -w | tr -d ' ') dry-run targets carry $FLAG"
echo "werror-switch gate OK: all $EXAMINED compile invocations across $(echo $TARGETS | wc -w | tr -d ' ') dry-run targets + $(echo $SCRIPT_AUDITS | wc -w | tr -d ' ') script(s) carry $FLAG"
exit 0
Loading