diff --git a/.github/workflows/allocfault.yml b/.github/workflows/allocfault.yml new file mode 100644 index 0000000..b3ea74d --- /dev/null +++ b/.github/workflows/allocfault.yml @@ -0,0 +1,33 @@ +name: allocfault + +on: + workflow_dispatch: + push: + paths: + - "tools/allocfault/**" + - "scripts/run-original-suite.sh" + - ".github/workflows/allocfault.yml" + +jobs: + smoke-interposer: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Zig 0.16.0 + run: | + curl -sL https://ziglang.org/download/0.16.0/zig-x86_64-linux-0.16.0.tar.xz | tar -xJ + echo "$(pwd)/zig-x86_64-linux-0.16.0" >> "$GITHUB_PATH" + - name: Build and probe interposer + run: | + export CACHE="$HOME/.cache/zig-tinyexpr" + # Short corpus via env override: run script but the script builds its own corpus. + # Probe only: compile interposer and assert counter advances on one expression. + WORK=.local/allocfault + mkdir -p "$WORK" + cc -shared -fPIC -O2 -ldl -pthread tools/allocfault/interposer.c -o "$WORK/liballocfault.so" + cc -O0 -g -I third_party/tinyexpr-c -c tools/allocfault/driver.c -o "$WORK/driver.o" + cc -O0 -g -I third_party/tinyexpr-c -c third_party/tinyexpr-c/tinyexpr.c -o "$WORK/te.o" + cc -O0 -g "$WORK/driver.o" "$WORK/te.o" -o "$WORK/driver-c" -ldl -lm + OUT="$(LD_PRELOAD=$WORK/liballocfault.so ALLOCFAULT_COUNT_ONLY=1 ALLOCFAULT_SILENT=1 $WORK/driver-c '1+2*3')" + echo "$OUT" + python3 -c 'import json,sys; j=json.loads(sys.argv[1]); assert j["allocs"]>0, j' "$OUT" diff --git a/.github/workflows/fuzz-smoke.yml b/.github/workflows/fuzz-smoke.yml new file mode 100644 index 0000000..b615210 --- /dev/null +++ b/.github/workflows/fuzz-smoke.yml @@ -0,0 +1,28 @@ +name: fuzz-smoke + +on: + workflow_dispatch: + push: + paths: + - "fuzz/**" + - "scripts/run-fuzz.sh" + - "scripts/run-metamorphic.sh" + - ".github/workflows/fuzz-smoke.yml" + +jobs: + certified-short: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Zig 0.16.0 + run: | + curl -sL https://ziglang.org/download/0.16.0/zig-x86_64-linux-0.16.0.tar.xz | tar -xJ + echo "$(pwd)/zig-x86_64-linux-0.16.0" >> "$GITHUB_PATH" + - name: 5s differential fuzz smoke + run: | + export CACHE="$HOME/.cache/zig-tinyexpr" + bash scripts/run-fuzz.sh 5 fuzz/logs/ci-smoke.txt ci-smoke + - name: Metamorphic smoke + run: | + export CACHE="$HOME/.cache/zig-tinyexpr" + bash scripts/run-metamorphic.sh diff --git a/.github/workflows/sanitizer-matrix.yml b/.github/workflows/sanitizer-matrix.yml new file mode 100644 index 0000000..e075c76 --- /dev/null +++ b/.github/workflows/sanitizer-matrix.yml @@ -0,0 +1,30 @@ +name: sanitizer-matrix + +on: + workflow_dispatch: + push: + paths: + - "scripts/run-sanitizer-matrix.sh" + - "scripts/run-original-suite.sh" + - "tools/zig_probe_stub.c" + - ".github/workflows/sanitizer-matrix.yml" + +jobs: + matrix: + runs-on: ubuntu-latest + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + - name: Install Zig 0.16.0 + run: | + curl -sL https://ziglang.org/download/0.16.0/zig-x86_64-linux-0.16.0.tar.xz | tar -xJ + echo "$(pwd)/zig-x86_64-linux-0.16.0" >> "$GITHUB_PATH" + - name: Run sanitizer matrix + run: | + export CACHE="$HOME/.cache/zig-tinyexpr" + bash scripts/run-sanitizer-matrix.sh + - name: Upload report + uses: actions/upload-artifact@v4 + with: + name: sanitizers-md + path: docs/evidence/sanitizers.md diff --git a/DECISIONS.md b/DECISIONS.md index 03d14d4..1a9342d 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -301,3 +301,76 @@ Entries that only restate a diff will be deleted. - Evidence: `scripts/run-enumerate.sh`, `docs/evidence/fragments/enumeration.json` (`total` 11505, `divergences` 0 at string length 3 / AST depth 1). + +## D021 — One malloc interposer for C and Zig ABI + +- Constraint: Track G asks for allocator-misuse evidence; both implementations + must be failed at every allocation ordinal on a shared corpus. +- Options: separate Zig GPA fault injection; `ld --wrap=malloc`; `LD_PRELOAD` + over libc `malloc`/`calloc`/`realloc`/`free`. +- Choice: `tools/allocfault` LD_PRELOAD interposer for the main campaign. The + Zig static library allocates through libc `malloc` at the ABI boundary just + as the C original does, so **one interposer drives both**. ASan builds use a + preprocessor shim TU (`tinyexpr_instrumented.c`) because ASan owns `malloc` + and GNU `--wrap` did not redirect libc `malloc` on this host. +- Consequence: ordinal campaigns are directly comparable; ledger diffs are + meaningful; ASan ordinal runs are C-shim-only with Zig still on LD_PRELOAD. +- Evidence: `tools/allocfault/run.sh`, + `docs/evidence/fragments/allocfault.json` (271 ordinals, 0 crashes, ledger + identical on `1+2*3` with 11 events). + +## D022 — Differential fuzz engines and ReleaseFast link + +- Constraint: bonus needs 60 continuous seconds with zero divergences; Debug + Zig fuzzing is known-crashy; linking ReleaseSafe `.a` into a gcc main fails + on `__zig_probe_stack`. +- Options: Zig `std.testing` fuzz only; libFuzzer only; dual harness. +- Choice: in-process C-renamed + Zig harness at `fuzz/harness.c` with + structured generation, plus `fuzz/harness.zig` Smith metamorphic tests. + Build the Zig archive as ReleaseFast for C-linked drivers; provide + `tools/zig_probe_stub.c` when Debug/ReleaseSafe archives must link into gcc. +- Consequence: certified run publishes executions, not only wall-clock; + metamorphic transforms are a separate campaign. +- Evidence: `fuzz/log.txt` (48512558 execs / 60s / 0 divergences), + `docs/evidence/fragments/metamorphic.json` (45 cases / 0 failures). + +## D023 — Sanitizer matrix and float flags + +- Constraint: judges need a glanceable matrix across C sanitizers, Zig opt + modes, and flag configs; float contraction would silently break bit-exact + equivalence. +- Options: cite prompt-1 measurements; re-measure at HEAD. +- Choice: re-measure via `scripts/run-sanitizer-matrix.sh` at the current + commit; record Valgrind as `tool_missing` when absent; empirically check + `cc -O2 -###` for fast-math flags. +- Consequence: sixteen Zig suite cells (4 modes x 4 configs) plus C + UBSan/ASan cells are first-class evidence; float claim is measured. +- Evidence: `docs/evidence/sanitizers.md`, + `docs/evidence/fragments/sanitizers.json`. + +## D024 — Signed-char ctype lead closed by trapping wrapper + +- Constraint: UBSan on glibc did not diagnose `isalpha` on high-bit bytes; + editing `third_party/` is forbidden. +- Options: declare unverifiable; rely on standard citations alone; inject a + trapping ctype via compiler `-include`. +- Choice: ship `scripts/run-buglead-ctype.sh` with a trap header that aborts + on negative ctype arguments; feed bytes `0x80..0xFF` through `te_interp`. +- Consequence: Lead B is a confirmed UB surface with a one-line stderr + reproducer (`ctype_trap: isalpha(-128)`), ready for upstream filing. +- Evidence: `docs/findings.md` Lead B, + `docs/evidence/fragments/buglead-ctype.json`. + +## D025 — Locale lead: correctness yes, hang no; Zig shares strtod + +- Constraint: Lead C claimed a possible non-advancing `s->next` DoS under + `de_DE.UTF-8`; the port was expected to be locale-independent. +- Options: change Zig to locale-independent parsing now; keep strtod parity. +- Choice: keep `libm.strtod` for bit-exact parity; measure both under + `setlocale(LC_ALL, "de_DE.UTF-8")`; hard-timeout the suspected hang inputs. +- Consequence: `1.5` fails on both sides after setlocale (correctness bug in + the original, shared by the port); `.5` does not hang within 3s; smoke under + env-only LC_ALL is not a trigger because smoke never calls setlocale. + Equivalence for decimal literals is scoped to the C locale. +- Evidence: `docs/findings.md` Lead C, + `docs/evidence/fragments/buglead-locale.json`. diff --git a/build.zig b/build.zig index 07870cc..da86d1e 100644 --- a/build.zig +++ b/build.zig @@ -129,7 +129,11 @@ pub fn build(b: *std.Build) void { const cross_step = b.step("cross", "Cross-compile matrix"); cross_step.dependOn(&cross_cmd.step); - _ = b.step("fuzz", "Prompt 4+: differential fuzz"); + const fuzz_cmd = b.addSystemCommand(&.{ "bash", "scripts/run-fuzz.sh", "5", "fuzz/logs/fuzz-verify.txt", "verify" }); + fuzz_cmd.setCwd(b.path(".")); + const fuzz_step = b.step("fuzz", "Short differential fuzz tier"); + fuzz_step.dependOn(&fuzz_cmd.step); + const cover_cmd = b.addSystemCommand(&.{ "bash", "scripts/run-coverage-c.sh" }); cover_cmd.setCwd(b.path(".")); const cover_step = b.step("cover", "lcov coverage of original C + evidence fragment"); @@ -146,6 +150,25 @@ pub fn build(b: *std.Build) void { const enumerate_quick_step = b.step("enumerate-quick", "Short differential-enumeration tier"); enumerate_quick_step.dependOn(&enumerate_quick_cmd.step); - _ = b.step("alloc-fault", "Prompt 4+: malloc failure injection"); + const alloc_cmd = b.addSystemCommand(&.{ "bash", "tools/allocfault/run.sh" }); + alloc_cmd.setCwd(b.path(".")); + const alloc_step = b.step("alloc-fault", "Malloc ordinal failure injection"); + alloc_step.dependOn(&alloc_cmd.step); + + // Wire anatomy fuzz/harness.zig as a ReleaseSafe test module. + const harness_mod = b.createModule(.{ + .root_source_file = b.path("fuzz/harness.zig"), + .target = target, + .optimize = .ReleaseSafe, + .link_libc = true, + }); + harness_mod.addImport("tinyexpr", root_mod); + const harness_tests = b.addTest(.{ + .name = "fuzz-harness", + .root_module = harness_mod, + }); + const run_harness_tests = b.addRunArtifact(harness_tests); + fuzz_step.dependOn(&run_harness_tests.step); + _ = b.step("demo", "Prompt 9: demo assets"); } diff --git a/docs/evidence/allocfault-asan.log b/docs/evidence/allocfault-asan.log new file mode 100644 index 0000000..977f418 --- /dev/null +++ b/docs/evidence/allocfault-asan.log @@ -0,0 +1,150 @@ +=== allocfault metadata === +started_at_utc=2026-08-02T05:31:27Z +git_sha=b5e302ed15281e3d96c0998e64e0b8aa20afeee0 +host=Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux +asan=1 +/mnt/d/hackathons/portmortem/tinyexpr.zig/tools/allocfault/interposer.c: In function ‘ledger_write’: +/mnt/d/hackathons/portmortem/tinyexpr.zig/tools/allocfault/interposer.c:38:11: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 38 | (void)write(ledger_fd, buf, n); + | ^~~~~~~~~~~~~~~~~~~~~~~~ +/mnt/d/hackathons/portmortem/tinyexpr.zig/tools/allocfault/interposer.c: In function ‘fail_alloc’: +/mnt/d/hackathons/portmortem/tinyexpr.zig/tools/allocfault/interposer.c:76:26: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 76 | if (m > 0) (void)write(STDERR_FILENO, msg, (size_t)m); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +interposer_probe={"ok":true,"error":0,"bits":"0x401c000000000000","allocs":5} +interposer_ok allocs= 5 +107 +expr='1' n_c=1 n_z=1 sampled_divergences_so_far=0 +expr='1+2' n_c=3 n_z=3 sampled_divergences_so_far=0 +expr='1+2*3' n_c=5 n_z=5 sampled_divergences_so_far=0 +expr='(1+2)*3' n_c=5 n_z=5 sampled_divergences_so_far=0 +expr='sin(0)' n_c=2 n_z=2 sampled_divergences_so_far=0 +expr='fac(5)' n_c=2 n_z=2 sampled_divergences_so_far=0 +expr='ncr(10,3)' n_c=3 n_z=3 sampled_divergences_so_far=0 +expr='atan2(1,1)' n_c=3 n_z=3 sampled_divergences_so_far=0 +expr='((((1))))' n_c=1 n_z=1 sampled_divergences_so_far=0 +expr='1+(2+(3+(4+5)))' n_c=9 n_z=9 sampled_divergences_so_far=0 +expr='pi*e' n_c=3 n_z=3 sampled_divergences_so_far=0 +expr='abs(-3)+floor(2.7)' n_c=6 n_z=6 sampled_divergences_so_far=0 +expr='(' n_c=1 n_z=0 sampled_divergences_so_far=1 +expr='1+' n_c=3 n_z=1 sampled_divergences_so_far=3 +expr='sin(' n_c=2 n_z=0 sampled_divergences_so_far=5 +expr='unknown(1)' n_c=1 n_z=0 sampled_divergences_so_far=6 +expr='1,,2' n_c=3 n_z=1 sampled_divergences_so_far=8 +expr='((((((1+2)*3)/4)^2)%3)' n_c=11 n_z=11 sampled_divergences_so_far=8 +expr='1)' n_c=1 n_z=1 sampled_divergences_so_far=8 +expr='(1' n_c=1 n_z=1 sampled_divergences_so_far=8 +expr='1**1' n_c=3 n_z=1 sampled_divergences_so_far=10 +expr='1*2(+4' n_c=3 n_z=3 sampled_divergences_so_far=10 +expr='1*2(1+4' n_c=3 n_z=3 sampled_divergences_so_far=10 +expr='a+5' n_c=1 n_z=0 sampled_divergences_so_far=11 +expr='!+5' n_c=1 n_z=0 sampled_divergences_so_far=12 +expr='_a+5' n_c=1 n_z=0 sampled_divergences_so_far=13 +expr='#a+5' n_c=1 n_z=0 sampled_divergences_so_far=14 +expr='1^^5' n_c=3 n_z=1 sampled_divergences_so_far=16 +expr='1**5' n_c=3 n_z=1 sampled_divergences_so_far=18 +expr='sin(cos5' n_c=2 n_z=0 sampled_divergences_so_far=20 +expr='((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((1)' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1)))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((1))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((1)))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1)))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((1))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((((1)))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1)))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((((1))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1))))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((((((1)))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1)))))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((((((1))))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='0' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='2' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='3' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='2+3' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='2*3+4' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='(1+2)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='1,2,3' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='2^3' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='-1' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='-2^2' n_c=4 n_z=4 sampled_divergences_so_far=20 +expr='pi' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='e' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='cos(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='tan(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='sqrt(4)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='abs(-5)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='npr(10,3)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='log(100)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='ln(e)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='exp(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='pow(2,3)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='1/0' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='0/0' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='-1/0' n_c=4 n_z=4 sampled_divergences_so_far=20 +expr='0/1' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='1.5+2.5' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='sin(pi)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='cos(pi)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='fac(4.8)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='ncr(16,7)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='npr(20,5)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='sin(cos(tan(0)))' n_c=4 n_z=4 sampled_divergences_so_far=20 +expr='sqrt(sin(0)^2+cos(0)^2)' n_c=10 n_z=10 sampled_divergences_so_far=20 +expr='2+3*4' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='1*(2+3)' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='((1+2))' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='(1,2,3)' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='2^3^2' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='-2' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='1-2-3' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='10/2/2' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='1%3' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='1+2+3+4+5' n_c=9 n_z=9 sampled_divergences_so_far=20 +expr='sin(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='cos(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='tan(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='asin(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='acos(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='atan(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='sinh(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='cosh(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='tanh(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='sqrt(2)' n_c=2 n_z=2 sampled_divergences_so_far=20 +{ + "schema_version": 1, + "subject": "allocfault", + "command_line": "bash tools/allocfault/run.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux", + "started_at_utc": "2026-08-02T05:31:27Z", + "completed_at_utc": "2026-08-02T05:31:37Z", + "asan": true, + "corpus_inputs": 107, + "ordinals_tested": 271, + "behaviour_divergences": 20, + "crashes_c": 0, + "crashes_zig": 0, + "leaks_detected": "see_asan_log", + "ledger_input": "1+2*3", + "ledger_identical": false, + "ledger_c_events": 0, + "ledger_zig_events": 11, + "ledger_claim": "ledgers differ; equivalence claim limited to return value / error / crash at each ordinal", + "track_g_allocator_misuse_criterion": "not_satisfied_negative_result", + "allocator_misuse_events": [], + "oom_error_position_divergences": 20, + "behaviour_divergence_note": "20/20 divergences are C error=-1 (te_compile NULL root / OOM) vs Zig positive error offset; not crashes or success/failure flips" +} +wrote /mnt/d/hackathons/portmortem/tinyexpr.zig/docs/evidence/fragments/allocfault-asan.json +completed_at_utc=2026-08-02T05:31:37Z diff --git a/docs/evidence/allocfault.log b/docs/evidence/allocfault.log new file mode 100644 index 0000000..dea3574 --- /dev/null +++ b/docs/evidence/allocfault.log @@ -0,0 +1,150 @@ +=== allocfault metadata === +started_at_utc=2026-08-02T05:27:21Z +git_sha=b5e302ed15281e3d96c0998e64e0b8aa20afeee0 +host=Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux +asan=0 +/mnt/d/hackathons/portmortem/tinyexpr.zig/tools/allocfault/interposer.c: In function ‘ledger_write’: +/mnt/d/hackathons/portmortem/tinyexpr.zig/tools/allocfault/interposer.c:38:11: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 38 | (void)write(ledger_fd, buf, n); + | ^~~~~~~~~~~~~~~~~~~~~~~~ +/mnt/d/hackathons/portmortem/tinyexpr.zig/tools/allocfault/interposer.c: In function ‘fail_alloc’: +/mnt/d/hackathons/portmortem/tinyexpr.zig/tools/allocfault/interposer.c:76:26: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 76 | if (m > 0) (void)write(STDERR_FILENO, msg, (size_t)m); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +interposer_probe={"ok":true,"error":0,"bits":"0x401c000000000000","allocs":5} +interposer_ok allocs= 5 +107 +expr='1' n_c=1 n_z=1 sampled_divergences_so_far=0 +expr='1+2' n_c=3 n_z=3 sampled_divergences_so_far=0 +expr='1+2*3' n_c=5 n_z=5 sampled_divergences_so_far=0 +expr='(1+2)*3' n_c=5 n_z=5 sampled_divergences_so_far=0 +expr='sin(0)' n_c=2 n_z=2 sampled_divergences_so_far=0 +expr='fac(5)' n_c=2 n_z=2 sampled_divergences_so_far=0 +expr='ncr(10,3)' n_c=3 n_z=3 sampled_divergences_so_far=0 +expr='atan2(1,1)' n_c=3 n_z=3 sampled_divergences_so_far=0 +expr='((((1))))' n_c=1 n_z=1 sampled_divergences_so_far=0 +expr='1+(2+(3+(4+5)))' n_c=9 n_z=9 sampled_divergences_so_far=0 +expr='pi*e' n_c=3 n_z=3 sampled_divergences_so_far=0 +expr='abs(-3)+floor(2.7)' n_c=6 n_z=6 sampled_divergences_so_far=0 +expr='(' n_c=1 n_z=0 sampled_divergences_so_far=1 +expr='1+' n_c=3 n_z=1 sampled_divergences_so_far=3 +expr='sin(' n_c=2 n_z=0 sampled_divergences_so_far=5 +expr='unknown(1)' n_c=1 n_z=0 sampled_divergences_so_far=6 +expr='1,,2' n_c=3 n_z=1 sampled_divergences_so_far=8 +expr='((((((1+2)*3)/4)^2)%3)' n_c=11 n_z=11 sampled_divergences_so_far=8 +expr='1)' n_c=1 n_z=1 sampled_divergences_so_far=8 +expr='(1' n_c=1 n_z=1 sampled_divergences_so_far=8 +expr='1**1' n_c=3 n_z=1 sampled_divergences_so_far=10 +expr='1*2(+4' n_c=3 n_z=3 sampled_divergences_so_far=10 +expr='1*2(1+4' n_c=3 n_z=3 sampled_divergences_so_far=10 +expr='a+5' n_c=1 n_z=0 sampled_divergences_so_far=11 +expr='!+5' n_c=1 n_z=0 sampled_divergences_so_far=12 +expr='_a+5' n_c=1 n_z=0 sampled_divergences_so_far=13 +expr='#a+5' n_c=1 n_z=0 sampled_divergences_so_far=14 +expr='1^^5' n_c=3 n_z=1 sampled_divergences_so_far=16 +expr='1**5' n_c=3 n_z=1 sampled_divergences_so_far=18 +expr='sin(cos5' n_c=2 n_z=0 sampled_divergences_so_far=20 +expr='((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((1)' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1)))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((1))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((1)))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1)))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((1))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((((1)))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1)))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((((1))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1))))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='((((((((1)))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((((((1' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='1)))))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='(((((((((1))))))))' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='0' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='2' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='3' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='2+3' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='2*3+4' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='(1+2)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='1,2,3' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='2^3' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='-1' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='-2^2' n_c=4 n_z=4 sampled_divergences_so_far=20 +expr='pi' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='e' n_c=1 n_z=1 sampled_divergences_so_far=20 +expr='cos(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='tan(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='sqrt(4)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='abs(-5)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='npr(10,3)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='log(100)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='ln(e)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='exp(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='pow(2,3)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='1/0' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='0/0' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='-1/0' n_c=4 n_z=4 sampled_divergences_so_far=20 +expr='0/1' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='1.5+2.5' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='sin(pi)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='cos(pi)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='fac(4.8)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='ncr(16,7)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='npr(20,5)' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='sin(cos(tan(0)))' n_c=4 n_z=4 sampled_divergences_so_far=20 +expr='sqrt(sin(0)^2+cos(0)^2)' n_c=10 n_z=10 sampled_divergences_so_far=20 +expr='2+3*4' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='1*(2+3)' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='((1+2))' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='(1,2,3)' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='2^3^2' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='-2' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='1-2-3' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='10/2/2' n_c=5 n_z=5 sampled_divergences_so_far=20 +expr='1%3' n_c=3 n_z=3 sampled_divergences_so_far=20 +expr='1+2+3+4+5' n_c=9 n_z=9 sampled_divergences_so_far=20 +expr='sin(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='cos(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='tan(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='asin(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='acos(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='atan(1)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='sinh(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='cosh(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='tanh(0)' n_c=2 n_z=2 sampled_divergences_so_far=20 +expr='sqrt(2)' n_c=2 n_z=2 sampled_divergences_so_far=20 +{ + "schema_version": 1, + "subject": "allocfault", + "command_line": "bash tools/allocfault/run.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux", + "started_at_utc": "2026-08-02T05:27:21Z", + "completed_at_utc": "2026-08-02T05:27:31Z", + "asan": false, + "corpus_inputs": 107, + "ordinals_tested": 271, + "behaviour_divergences": 20, + "crashes_c": 0, + "crashes_zig": 0, + "leaks_detected": "asan_required", + "ledger_input": "1+2*3", + "ledger_identical": true, + "ledger_c_events": 11, + "ledger_zig_events": 11, + "ledger_claim": "identical ordered malloc/free ledgers", + "track_g_allocator_misuse_criterion": "not_satisfied_negative_result", + "allocator_misuse_events": [], + "oom_error_position_divergences": 20, + "behaviour_divergence_note": "20/20 divergences are C error=-1 (te_compile NULL root / OOM) vs Zig positive error offset; not crashes or success/failure flips" +} +wrote /mnt/d/hackathons/portmortem/tinyexpr.zig/docs/evidence/fragments/allocfault.json +completed_at_utc=2026-08-02T05:27:31Z diff --git a/docs/evidence/buglead-ctype.log b/docs/evidence/buglead-ctype.log new file mode 100644 index 0000000..57e444c --- /dev/null +++ b/docs/evidence/buglead-ctype.log @@ -0,0 +1,9 @@ +plain={"bytes":128,"interp_ok":0,"interp_rejected":128,"direct_ctype_calls":256} +ubsan_exit=0 +trap_exit=134 +ubsan_err= + +trap_err= +ctype_trap: isalpha(-128) +timeout: the monitored command dumped core + diff --git a/docs/evidence/buglead-locale.log b/docs/evidence/buglead-locale.log new file mode 100644 index 0000000..9e868f6 --- /dev/null +++ b/docs/evidence/buglead-locale.log @@ -0,0 +1,19 @@ +{ + "schema_version": 1, + "lead": "C_strtod_LC_NUMERIC", + "command": "bash scripts/run-buglead-locale.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.39", + "utc_start": "2026-08-02T05:23:26Z", + "utc_end": "2026-08-02T05:24:18Z", + "locale": "de_DE.UTF-8", + "c_exit": 0, + "zig_exit": 0, + "smoke_exit": 0, + "c_stdout": "expr=1.5 err=1 value=nan\nexpr=1,5 err=0 value=1,5\nexpr=2.25+3.5 err=1 value=nan\nexpr=0.5 err=1 value=nan\nexpr=.5 err=1 value=nan\nexpr=1. err=1 value=nan\n", + "zig_stdout": "expr=1.5 err=1 value=nan\nexpr=1,5 err=0 value=1,5\nexpr=2.25+3.5 err=1 value=nan\nexpr=0.5 err=1 value=nan\nexpr=.5 err=1 value=nan\nexpr=1. err=1 value=nan\n", + "c_stderr": "", + "zig_stderr": "", + "smoke_stderr_tail": "", + "verdict": "C te_interp completed under locale; inspect value/err lines for decimal divergence; upstream smoke exit=0 under locale; Zig ABI te_interp completed under same locale (locale-independent lexer expected)" +} diff --git a/docs/evidence/divergences.md b/docs/evidence/divergences.md index 0c14333..e22a5ba 100644 --- a/docs/evidence/divergences.md +++ b/docs/evidence/divergences.md @@ -31,6 +31,13 @@ Control probes that **agree**: | `1%0` | both NaN | | `ncr(0,1)` | both NaN | +## Locale scope (Lead C) + +Under `setlocale(LC_ALL, "de_DE.UTF-8")`, both C and Zig (via `libm.strtod`) +reject `1.5` and accept `1,5`. This is shared behaviour, not a port bug. +Bit-exact equivalence for decimal literals is claimed for the C locale only. +See `docs/findings.md` Lead C. + ## Wasm See `docs/evidence/fragments/enumeration-wasm.json`. Sample only, not the diff --git a/docs/evidence/fragments/allocfault-asan.json b/docs/evidence/fragments/allocfault-asan.json new file mode 100644 index 0000000..c94a32e --- /dev/null +++ b/docs/evidence/fragments/allocfault-asan.json @@ -0,0 +1,5024 @@ +{ + "schema_version": 1, + "subject": "allocfault", + "command_line": "bash tools/allocfault/run.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux", + "started_at_utc": "2026-08-02T05:31:27Z", + "completed_at_utc": "2026-08-02T05:31:37Z", + "asan": true, + "corpus_inputs": 107, + "ordinals_tested": 271, + "behaviour_divergences": 20, + "crashes_c": 0, + "crashes_zig": 0, + "leaks_detected": "see_asan_log", + "ledger_input": "1+2*3", + "ledger_identical": false, + "ledger_c_events": 0, + "ledger_zig_events": 11, + "ledger_claim": "ledgers differ; equivalence claim limited to return value / error / crash at each ordinal", + "track_g_allocator_misuse_criterion": "not_satisfied_negative_result", + "results": [ + { + "expression": "1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1+2", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1+2*3", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(1+2)*3", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sin(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "fac(5)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "ncr(10,3)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "atan2(1,1)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((1))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1+(2+(3+(4+5)))", + "allocs_c": 9, + "allocs_zig": 9, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 9, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "pi*e", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "abs(-3)+floor(2.7)", + "allocs_c": 6, + "allocs_zig": 6, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 6, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1+", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 2, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 2, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "sin(", + "allocs_c": 2, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 4, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 4, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "unknown(1)", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 7, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1,,2", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "((((((1+2)*3)/4)^2)%3)", + "allocs_c": 11, + "allocs_zig": 11, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 11, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1**1", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1*2(+4", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1*2(1+4", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "a+5", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "!+5", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "_a+5", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "#a+5", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1^^5", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1**5", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "sin(cos5", + "allocs_c": 2, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 8, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 8, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((1)", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((1))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((1)))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((1))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((((1)))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((((1))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1))))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((((((1)))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)))))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((((((1))))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "0", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "3", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2+3", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2*3+4", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(1+2)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1,2,3", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2^3", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "-1", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "-2^2", + "allocs_c": 4, + "allocs_zig": 4, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 4, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "pi", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "e", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "cos(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "tan(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sqrt(4)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "abs(-5)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "npr(10,3)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "log(100)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "ln(e)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "exp(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "pow(2,3)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1/0", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "0/0", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "-1/0", + "allocs_c": 4, + "allocs_zig": 4, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 4, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "0/1", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1.5+2.5", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sin(pi)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "cos(pi)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "fac(4.8)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "ncr(16,7)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "npr(20,5)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sin(cos(tan(0)))", + "allocs_c": 4, + "allocs_zig": 4, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 4, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sqrt(sin(0)^2+cos(0)^2)", + "allocs_c": 10, + "allocs_zig": 10, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 10, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2+3*4", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1*(2+3)", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((1+2))", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(1,2,3)", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2^3^2", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "-2", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1-2-3", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "10/2/2", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1%3", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1+2+3+4+5", + "allocs_c": 9, + "allocs_zig": 9, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 9, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sin(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "cos(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "tan(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "asin(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "acos(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "atan(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sinh(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "cosh(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "tanh(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sqrt(2)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + } + ], + "allocator_misuse_events": [], + "oom_error_position_divergences": 20, + "behaviour_divergence_note": "20/20 divergences are C error=-1 (te_compile NULL root / OOM) vs Zig positive error offset; not crashes or success/failure flips" +} diff --git a/docs/evidence/fragments/allocfault.json b/docs/evidence/fragments/allocfault.json new file mode 100644 index 0000000..371007f --- /dev/null +++ b/docs/evidence/fragments/allocfault.json @@ -0,0 +1,5024 @@ +{ + "schema_version": 1, + "subject": "allocfault", + "command_line": "bash tools/allocfault/run.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux", + "started_at_utc": "2026-08-02T05:27:21Z", + "completed_at_utc": "2026-08-02T05:27:31Z", + "asan": false, + "corpus_inputs": 107, + "ordinals_tested": 271, + "behaviour_divergences": 20, + "crashes_c": 0, + "crashes_zig": 0, + "leaks_detected": "asan_required", + "ledger_input": "1+2*3", + "ledger_identical": true, + "ledger_c_events": 11, + "ledger_zig_events": 11, + "ledger_claim": "identical ordered malloc/free ledgers", + "track_g_allocator_misuse_criterion": "not_satisfied_negative_result", + "results": [ + { + "expression": "1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1+2", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1+2*3", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(1+2)*3", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sin(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "fac(5)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "ncr(10,3)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "atan2(1,1)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((1))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1+(2+(3+(4+5)))", + "allocs_c": 9, + "allocs_zig": 9, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 9, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "pi*e", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "abs(-3)+floor(2.7)", + "allocs_c": 6, + "allocs_zig": 6, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 6, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1+", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 2, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 2, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "sin(", + "allocs_c": 2, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 4, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 4, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "unknown(1)", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 7, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1,,2", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "((((((1+2)*3)/4)^2)%3)", + "allocs_c": 11, + "allocs_zig": 11, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 11, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1**1", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1*2(+4", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1*2(1+4", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "a+5", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "!+5", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "_a+5", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "#a+5", + "allocs_c": 1, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1^^5", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "1**5", + "allocs_c": 3, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 3, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "sin(cos5", + "allocs_c": 2, + "allocs_zig": 0, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 8, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": 8, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": true + } + ] + }, + { + "expression": "((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((1)", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((1))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((1)))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((1))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((((1)))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((((1))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1))))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((((((((1)))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((((((1", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1)))))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(((((((((1))))))))", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "0", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "3", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2+3", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2*3+4", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(1+2)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1,2,3", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2^3", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "-1", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "-2^2", + "allocs_c": 4, + "allocs_zig": 4, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 4, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "pi", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "e", + "allocs_c": 1, + "allocs_zig": 1, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "cos(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "tan(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sqrt(4)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "abs(-5)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "npr(10,3)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "log(100)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "ln(e)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "exp(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "pow(2,3)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1/0", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "0/0", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "-1/0", + "allocs_c": 4, + "allocs_zig": 4, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 4, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "0/1", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1.5+2.5", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sin(pi)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "cos(pi)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "fac(4.8)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "ncr(16,7)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "npr(20,5)", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sin(cos(tan(0)))", + "allocs_c": 4, + "allocs_zig": 4, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 4, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sqrt(sin(0)^2+cos(0)^2)", + "allocs_c": 10, + "allocs_zig": 10, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 10, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2+3*4", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1*(2+3)", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "((1+2))", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "(1,2,3)", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "2^3^2", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "-2", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1-2-3", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "10/2/2", + "allocs_c": 5, + "allocs_zig": 5, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 5, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1%3", + "allocs_c": 3, + "allocs_zig": 3, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "1+2+3+4+5", + "allocs_c": 9, + "allocs_zig": 9, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 3, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 9, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sin(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "cos(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "tan(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "asin(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "acos(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "atan(1)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sinh(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "cosh(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "tanh(0)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + }, + { + "expression": "sqrt(2)", + "allocs_c": 2, + "allocs_zig": 2, + "ordinals": [ + { + "n": 1, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + }, + { + "n": 2, + "c": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "zig": { + "ok": false, + "error": -1, + "bits": null, + "crashed": false, + "signal": null + }, + "diverge": false + } + ] + } + ], + "allocator_misuse_events": [], + "oom_error_position_divergences": 20, + "behaviour_divergence_note": "20/20 divergences are C error=-1 (te_compile NULL root / OOM) vs Zig positive error offset; not crashes or success/failure flips" +} diff --git a/docs/evidence/fragments/buglead-ctype.json b/docs/evidence/fragments/buglead-ctype.json new file mode 100644 index 0000000..aee35ca --- /dev/null +++ b/docs/evidence/fragments/buglead-ctype.json @@ -0,0 +1,17 @@ +{ + "schema_version": 1, + "lead": "B_signed_char_ctype", + "command": "bash scripts/run-buglead-ctype.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.39", + "utc_start": "2026-08-02T05:23:26Z", + "utc_end": "2026-08-02T05:23:37Z", + "ubsan_exit": 0, + "trap_ctype_exit": 134, + "ubsan_reported_runtime_error": false, + "trap_ctype_aborted": true, + "plain_stdout": "{\"bytes\":128,\"interp_ok\":0,\"interp_rejected\":128,\"direct_ctype_calls\":256}", + "ubsan_stderr_tail": "", + "trap_stderr_tail": "ctype_trap: isalpha(-128)\ntimeout: the monitored command dumped core\n", + "verdict": "trapping ctype wrapper aborted on high-bit signed char; C99 7.4p1 UB confirmed reachable" +} diff --git a/docs/evidence/fragments/buglead-locale.json b/docs/evidence/fragments/buglead-locale.json new file mode 100644 index 0000000..9e868f6 --- /dev/null +++ b/docs/evidence/fragments/buglead-locale.json @@ -0,0 +1,19 @@ +{ + "schema_version": 1, + "lead": "C_strtod_LC_NUMERIC", + "command": "bash scripts/run-buglead-locale.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.39", + "utc_start": "2026-08-02T05:23:26Z", + "utc_end": "2026-08-02T05:24:18Z", + "locale": "de_DE.UTF-8", + "c_exit": 0, + "zig_exit": 0, + "smoke_exit": 0, + "c_stdout": "expr=1.5 err=1 value=nan\nexpr=1,5 err=0 value=1,5\nexpr=2.25+3.5 err=1 value=nan\nexpr=0.5 err=1 value=nan\nexpr=.5 err=1 value=nan\nexpr=1. err=1 value=nan\n", + "zig_stdout": "expr=1.5 err=1 value=nan\nexpr=1,5 err=0 value=1,5\nexpr=2.25+3.5 err=1 value=nan\nexpr=0.5 err=1 value=nan\nexpr=.5 err=1 value=nan\nexpr=1. err=1 value=nan\n", + "c_stderr": "", + "zig_stderr": "", + "smoke_stderr_tail": "", + "verdict": "C te_interp completed under locale; inspect value/err lines for decimal divergence; upstream smoke exit=0 under locale; Zig ABI te_interp completed under same locale (locale-independent lexer expected)" +} diff --git a/docs/evidence/fragments/fuzz-certified.json b/docs/evidence/fragments/fuzz-certified.json new file mode 100644 index 0000000..69290a6 --- /dev/null +++ b/docs/evidence/fragments/fuzz-certified.json @@ -0,0 +1,18 @@ +{ + "executions": 48512558, + "divergences": 0, + "first_token_reject": 1844576, + "seconds": 60.0, + "exec_per_sec": 808542.63, + "seed": 1785633007, + "schema_version": 1, + "command": "bash scripts/run-fuzz.sh 60", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux", + "utc_start": "2026-08-02T05:17:52Z", + "utc_end": "2026-08-02T05:18:55Z", + "mode": "certified", + "requested_seconds": 60.0, + "harness_exit": 0, + "zig": "0.16.0" +} diff --git a/docs/evidence/fragments/metamorphic.json b/docs/evidence/fragments/metamorphic.json new file mode 100644 index 0000000..c459a91 --- /dev/null +++ b/docs/evidence/fragments/metamorphic.json @@ -0,0 +1,17 @@ +{ + "metamorphic_cases": 45, + "failures": 0, + "schema_version": 1, + "command": "bash scripts/run-metamorphic.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.39", + "utc_start": "2026-08-02T05:23:26Z", + "utc_end": "2026-08-02T05:23:38Z", + "transforms": [ + "redundant_parens", + "plus_zero", + "double_parens", + "zero_plus" + ], + "note": "float commute/reassociate omitted where IEEE non-associativity applies; 0+x checked separately from x+0" +} diff --git a/docs/evidence/fragments/sanitizers.json b/docs/evidence/fragments/sanitizers.json new file mode 100644 index 0000000..e8240cc --- /dev/null +++ b/docs/evidence/fragments/sanitizers.json @@ -0,0 +1,39 @@ +{ + "schema_version": 1, + "command": "bash scripts/run-sanitizer-matrix.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.39", + "started_at_utc": "2026-08-02T05:23:26Z", + "completed_at_utc": "2026-08-02T05:26:36Z", + "cells": 26, + "float_math": "no_fast_math_flags_in_-O2_invocation", + "report": "docs/evidence/sanitizers.md", + "summary": { + "c_ubsan_default": "pass_suite", + "c_ubsan_pow": "pass_suite", + "c_ubsan_natlog": "pass_suite", + "c_ubsan_pow_natlog": "pass_suite", + "c_asan_default": "pass_suite", + "c_asan_pow": "pass_suite", + "c_asan_natlog": "pass_suite", + "c_asan_pow_natlog": "pass_suite", + "c_valgrind_default": "tool_missing", + "zig_Debug_default": "pass_suite", + "zig_Debug_pow": "pass_suite", + "zig_Debug_natlog": "pass_suite", + "zig_Debug_pow_natlog": "pass_suite", + "zig_ReleaseSafe_default": "pass_suite", + "zig_ReleaseSafe_pow": "pass_suite", + "zig_ReleaseSafe_natlog": "pass_suite", + "zig_ReleaseSafe_pow_natlog": "pass_suite", + "zig_ReleaseFast_default": "pass_suite", + "zig_ReleaseFast_pow": "pass_suite", + "zig_ReleaseFast_natlog": "pass_suite", + "zig_ReleaseFast_pow_natlog": "pass_suite", + "zig_ReleaseSmall_default": "pass_suite", + "zig_ReleaseSmall_pow": "pass_suite", + "zig_ReleaseSmall_natlog": "pass_suite", + "zig_ReleaseSmall_pow_natlog": "pass_suite", + "float_contraction_check": "no_fast_math_flags_in_-O2_invocation" + } +} diff --git a/docs/evidence/metamorphic.log b/docs/evidence/metamorphic.log new file mode 100644 index 0000000..75f838f --- /dev/null +++ b/docs/evidence/metamorphic.log @@ -0,0 +1,19 @@ +{"metamorphic_cases":45,"failures":0} + +{ + "metamorphic_cases": 45, + "failures": 0, + "schema_version": 1, + "command": "bash scripts/run-metamorphic.sh", + "git_sha": "b5e302ed15281e3d96c0998e64e0b8aa20afeee0", + "host": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.39", + "utc_start": "2026-08-02T05:23:26Z", + "utc_end": "2026-08-02T05:23:38Z", + "transforms": [ + "redundant_parens", + "plus_zero", + "double_parens", + "zero_plus" + ], + "note": "float commute/reassociate omitted where IEEE non-associativity applies; 0+x checked separately from x+0" +} \ No newline at end of file diff --git a/docs/evidence/nm-smoke-default-zig-static.txt b/docs/evidence/nm-smoke-default-zig-static.txt index 0640c44..e1205cd 100644 --- a/docs/evidence/nm-smoke-default-zig-static.txt +++ b/docs/evidence/nm-smoke-default-zig-static.txt @@ -1,10 +1,10 @@ === nm defined (Zig .a excerpt) === 0000000000000000 T next_token -000000000019d800 T te_compile -00000000001a7e70 T te_eval -000000000019e1f0 T te_free -000000000019e5b0 T te_free_parameters -000000000019d730 T te_interp -000000000019cfc0 T te_print +000000000000062c T te_compile +0000000000001880 T te_eval +0000000000000975 T te_free +0000000000000a2f T te_free_parameters +00000000000005e7 T te_interp +00000000000004d6 T te_print === nm undefined te_* in smoke binary === - U dl_iterate_phdr@GLIBC_2.2.5 +(none matching) diff --git a/docs/evidence/nm-smoke-natlog-zig-static.txt b/docs/evidence/nm-smoke-natlog-zig-static.txt index 0640c44..e1205cd 100644 --- a/docs/evidence/nm-smoke-natlog-zig-static.txt +++ b/docs/evidence/nm-smoke-natlog-zig-static.txt @@ -1,10 +1,10 @@ === nm defined (Zig .a excerpt) === 0000000000000000 T next_token -000000000019d800 T te_compile -00000000001a7e70 T te_eval -000000000019e1f0 T te_free -000000000019e5b0 T te_free_parameters -000000000019d730 T te_interp -000000000019cfc0 T te_print +000000000000062c T te_compile +0000000000001880 T te_eval +0000000000000975 T te_free +0000000000000a2f T te_free_parameters +00000000000005e7 T te_interp +00000000000004d6 T te_print === nm undefined te_* in smoke binary === - U dl_iterate_phdr@GLIBC_2.2.5 +(none matching) diff --git a/docs/evidence/nm-smoke-pow-zig-static.txt b/docs/evidence/nm-smoke-pow-zig-static.txt index 814682f..3d8f7cd 100644 --- a/docs/evidence/nm-smoke-pow-zig-static.txt +++ b/docs/evidence/nm-smoke-pow-zig-static.txt @@ -1,10 +1,10 @@ === nm defined (Zig .a excerpt) === 0000000000000000 T next_token -000000000019d800 T te_compile -00000000001a8230 T te_eval -000000000019e1f0 T te_free -000000000019e5b0 T te_free_parameters -000000000019d730 T te_interp -000000000019cfc0 T te_print +000000000000062c T te_compile +00000000000018d7 T te_eval +0000000000000975 T te_free +0000000000000a2f T te_free_parameters +00000000000005e7 T te_interp +00000000000004d6 T te_print === nm undefined te_* in smoke binary === - U dl_iterate_phdr@GLIBC_2.2.5 +(none matching) diff --git a/docs/evidence/nm-smoke-pow_natlog-zig-static.txt b/docs/evidence/nm-smoke-pow_natlog-zig-static.txt index 814682f..3d8f7cd 100644 --- a/docs/evidence/nm-smoke-pow_natlog-zig-static.txt +++ b/docs/evidence/nm-smoke-pow_natlog-zig-static.txt @@ -1,10 +1,10 @@ === nm defined (Zig .a excerpt) === 0000000000000000 T next_token -000000000019d800 T te_compile -00000000001a8230 T te_eval -000000000019e1f0 T te_free -000000000019e5b0 T te_free_parameters -000000000019d730 T te_interp -000000000019cfc0 T te_print +000000000000062c T te_compile +00000000000018d7 T te_eval +0000000000000975 T te_free +0000000000000a2f T te_free_parameters +00000000000005e7 T te_interp +00000000000004d6 T te_print === nm undefined te_* in smoke binary === - U dl_iterate_phdr@GLIBC_2.2.5 +(none matching) diff --git a/docs/evidence/original-suite-default-c-original.txt b/docs/evidence/original-suite-default-c-original.txt index 03185f2..aa6da0a 100644 --- a/docs/evidence/original-suite-default-c-original.txt +++ b/docs/evidence/original-suite-default-c-original.txt @@ -1,6 +1,6 @@ === original suite transcript === config: default (c-original) -git: 6084132a5efb04a3436676333ef308a6fcb8ec4c +git: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 zig: 0.16.0 compiler: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux @@ -12,7 +12,7 @@ link: /mnt/d/hackathons/portmortem/tinyexpr.zig/third_party/tinyexpr-c/tinyexpr. NaNs pass:55 fail: 0 0ms INFs pass:50 fail: 0 0ms Variables pass:36 fail: 0 0ms - Functions pass:4406 fail: 0 2ms + Functions pass:4406 fail: 0 0ms Dynamic pass:44 fail: 0 0ms Closure pass:17 fail: 0 0ms Optimize pass:12 fail: 0 0ms diff --git a/docs/evidence/original-suite-default-zig-static.txt b/docs/evidence/original-suite-default-zig-static.txt index b591227..a0276f7 100644 --- a/docs/evidence/original-suite-default-zig-static.txt +++ b/docs/evidence/original-suite-default-zig-static.txt @@ -1,18 +1,18 @@ === original suite transcript === config: default (zig-static) -git: 6084132a5efb04a3436676333ef308a6fcb8ec4c +git: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 zig: 0.16.0 compiler: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux cflags: -Wall -Wshadow -O2 -I/mnt/d/hackathons/portmortem/tinyexpr.zig/third_party/tinyexpr-c -link: /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-out-default/lib/libtinyexpr.a -lm +link: /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-out-default/lib/libtinyexpr.a /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-probe-stub.o -lm === stdout === - Results pass:158 fail: 0 4ms + Results pass:158 fail: 0 0ms Syntax pass:70 fail: 0 0ms NaNs pass:55 fail: 0 0ms INFs pass:50 fail: 0 0ms - Variables pass:36 fail: 0 2ms - Functions pass:4406 fail: 0 15ms + Variables pass:36 fail: 0 0ms + Functions pass:4406 fail: 0 0ms Dynamic pass:44 fail: 0 0ms Closure pass:17 fail: 0 0ms Optimize pass:12 fail: 0 0ms diff --git a/docs/evidence/original-suite-natlog-c-original.txt b/docs/evidence/original-suite-natlog-c-original.txt index 7a1270b..8217d38 100644 --- a/docs/evidence/original-suite-natlog-c-original.txt +++ b/docs/evidence/original-suite-natlog-c-original.txt @@ -1,6 +1,6 @@ === original suite transcript === config: natlog (c-original) -git: 6084132a5efb04a3436676333ef308a6fcb8ec4c +git: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 zig: 0.16.0 compiler: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux @@ -12,7 +12,7 @@ link: /mnt/d/hackathons/portmortem/tinyexpr.zig/third_party/tinyexpr-c/tinyexpr. NaNs pass:55 fail: 0 0ms INFs pass:50 fail: 0 0ms Variables pass:36 fail: 0 0ms - Functions pass:4406 fail: 0 1ms + Functions pass:4406 fail: 0 0ms Dynamic pass:44 fail: 0 0ms Closure pass:17 fail: 0 0ms Optimize pass:12 fail: 0 0ms diff --git a/docs/evidence/original-suite-natlog-zig-static.txt b/docs/evidence/original-suite-natlog-zig-static.txt index 0ea90fb..781e6e7 100644 --- a/docs/evidence/original-suite-natlog-zig-static.txt +++ b/docs/evidence/original-suite-natlog-zig-static.txt @@ -1,18 +1,18 @@ === original suite transcript === config: natlog (zig-static) -git: 6084132a5efb04a3436676333ef308a6fcb8ec4c +git: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 zig: 0.16.0 compiler: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux cflags: -Wall -Wshadow -O2 -I/mnt/d/hackathons/portmortem/tinyexpr.zig/third_party/tinyexpr-c -DTE_NAT_LOG -link: /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-out-natlog/lib/libtinyexpr.a -lm +link: /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-out-natlog/lib/libtinyexpr.a /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-probe-stub.o -lm === stdout === Results pass:162 fail: 0 0ms Syntax pass:70 fail: 0 0ms NaNs pass:55 fail: 0 0ms INFs pass:50 fail: 0 0ms Variables pass:36 fail: 0 0ms - Functions pass:4406 fail: 0 3ms + Functions pass:4406 fail: 0 1ms Dynamic pass:44 fail: 0 0ms Closure pass:17 fail: 0 0ms Optimize pass:12 fail: 0 0ms diff --git a/docs/evidence/original-suite-pow-c-original.txt b/docs/evidence/original-suite-pow-c-original.txt index 8f4ff28..4ae78a9 100644 --- a/docs/evidence/original-suite-pow-c-original.txt +++ b/docs/evidence/original-suite-pow-c-original.txt @@ -1,6 +1,6 @@ === original suite transcript === config: pow (c-original) -git: 6084132a5efb04a3436676333ef308a6fcb8ec4c +git: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 zig: 0.16.0 compiler: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux @@ -12,7 +12,7 @@ link: /mnt/d/hackathons/portmortem/tinyexpr.zig/third_party/tinyexpr-c/tinyexpr. NaNs pass:55 fail: 0 0ms INFs pass:50 fail: 0 0ms Variables pass:36 fail: 0 0ms - Functions pass:4406 fail: 0 0ms + Functions pass:4406 fail: 0 1ms Dynamic pass:44 fail: 0 0ms Closure pass:17 fail: 0 0ms Optimize pass:12 fail: 0 0ms diff --git a/docs/evidence/original-suite-pow-zig-static.txt b/docs/evidence/original-suite-pow-zig-static.txt index 330f49d..f27f7c8 100644 --- a/docs/evidence/original-suite-pow-zig-static.txt +++ b/docs/evidence/original-suite-pow-zig-static.txt @@ -1,18 +1,18 @@ === original suite transcript === config: pow (zig-static) -git: 6084132a5efb04a3436676333ef308a6fcb8ec4c +git: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 zig: 0.16.0 compiler: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux cflags: -Wall -Wshadow -O2 -I/mnt/d/hackathons/portmortem/tinyexpr.zig/third_party/tinyexpr-c -DTE_POW_FROM_RIGHT -link: /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-out-pow/lib/libtinyexpr.a -lm +link: /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-out-pow/lib/libtinyexpr.a /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-probe-stub.o -lm === stdout === Results pass:158 fail: 0 0ms Syntax pass:70 fail: 0 0ms NaNs pass:55 fail: 0 0ms INFs pass:50 fail: 0 0ms Variables pass:36 fail: 0 0ms - Functions pass:4406 fail: 0 4ms + Functions pass:4406 fail: 0 0ms Dynamic pass:44 fail: 0 0ms Closure pass:17 fail: 0 0ms Optimize pass:12 fail: 0 0ms diff --git a/docs/evidence/original-suite-pow_natlog-c-original.txt b/docs/evidence/original-suite-pow_natlog-c-original.txt index b54dd30..b81e499 100644 --- a/docs/evidence/original-suite-pow_natlog-c-original.txt +++ b/docs/evidence/original-suite-pow_natlog-c-original.txt @@ -1,6 +1,6 @@ === original suite transcript === config: pow_natlog (c-original) -git: 6084132a5efb04a3436676333ef308a6fcb8ec4c +git: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 zig: 0.16.0 compiler: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux diff --git a/docs/evidence/original-suite-pow_natlog-zig-static.txt b/docs/evidence/original-suite-pow_natlog-zig-static.txt index 7319b8e..033ae3b 100644 --- a/docs/evidence/original-suite-pow_natlog-zig-static.txt +++ b/docs/evidence/original-suite-pow_natlog-zig-static.txt @@ -1,18 +1,18 @@ === original suite transcript === config: pow_natlog (zig-static) -git: 6084132a5efb04a3436676333ef308a6fcb8ec4c +git: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 zig: 0.16.0 compiler: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux cflags: -Wall -Wshadow -O2 -I/mnt/d/hackathons/portmortem/tinyexpr.zig/third_party/tinyexpr-c -DTE_POW_FROM_RIGHT -DTE_NAT_LOG -link: /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-out-pow_natlog/lib/libtinyexpr.a -lm +link: /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-out-pow_natlog/lib/libtinyexpr.a /mnt/d/hackathons/portmortem/tinyexpr.zig/zig-probe-stub.o -lm === stdout === Results pass:162 fail: 0 0ms Syntax pass:70 fail: 0 0ms NaNs pass:55 fail: 0 0ms INFs pass:50 fail: 0 0ms Variables pass:36 fail: 0 0ms - Functions pass:4406 fail: 0 4ms + Functions pass:4406 fail: 0 1ms Dynamic pass:44 fail: 0 0ms Closure pass:17 fail: 0 0ms Optimize pass:12 fail: 0 0ms diff --git a/docs/evidence/sanitizers.md b/docs/evidence/sanitizers.md new file mode 100644 index 0000000..f587293 --- /dev/null +++ b/docs/evidence/sanitizers.md @@ -0,0 +1,52 @@ +# Sanitizer and safety matrix +Measured at `b5e302ed1528` starting `2026-08-02T05:23:26Z` on `Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.39`. +| Cell | Verdict | Command | +| --- | --- | --- | +| `c_ubsan_default` | **pass_suite** | `/mnt/d/hackathons/portmortem/tinyexpr.zig/.local/sanitizers/smoke-ubsan-default` | +| `c_ubsan_pow` | **pass_suite** | `/mnt/d/hackathons/portmortem/tinyexpr.zig/.local/sanitizers/smoke-ubsan-pow` | +| `c_ubsan_natlog` | **pass_suite** | `/mnt/d/hackathons/portmortem/tinyexpr.zig/.local/sanitizers/smoke-ubsan-natlog` | +| `c_ubsan_pow_natlog` | **pass_suite** | `/mnt/d/hackathons/portmortem/tinyexpr.zig/.local/sanitizers/smoke-ubsan-pow-natlog` | +| `c_asan_default` | **pass_suite** | `env ASAN_OPTIONS=detect_leaks=1 /mnt/d/hackathons/portmortem/tinyexpr.zig/.local/sanitizers/smoke...` | +| `c_asan_pow` | **pass_suite** | `env ASAN_OPTIONS=detect_leaks=1 /mnt/d/hackathons/portmortem/tinyexpr.zig/.local/sanitizers/smoke...` | +| `c_asan_natlog` | **pass_suite** | `env ASAN_OPTIONS=detect_leaks=1 /mnt/d/hackathons/portmortem/tinyexpr.zig/.local/sanitizers/smoke...` | +| `c_asan_pow_natlog` | **pass_suite** | `env ASAN_OPTIONS=detect_leaks=1 /mnt/d/hackathons/portmortem/tinyexpr.zig/.local/sanitizers/smoke...` | +| `c_valgrind_default` | **tool_missing** | `valgrind` | +| `zig_Debug_default` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh default -Doptimize=D...` | +| `zig_Debug_pow` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh pow -Doptimize=Debug...` | +| `zig_Debug_natlog` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh natlog -Doptimize=De...` | +| `zig_Debug_pow_natlog` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh pow_natlog -Doptimiz...` | +| `zig_ReleaseSafe_default` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh default -Doptimize=R...` | +| `zig_ReleaseSafe_pow` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh pow -Doptimize=Relea...` | +| `zig_ReleaseSafe_natlog` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh natlog -Doptimize=Re...` | +| `zig_ReleaseSafe_pow_natlog` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh pow_natlog -Doptimiz...` | +| `zig_ReleaseFast_default` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh default -Doptimize=R...` | +| `zig_ReleaseFast_pow` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh pow -Doptimize=Relea...` | +| `zig_ReleaseFast_natlog` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh natlog -Doptimize=Re...` | +| `zig_ReleaseFast_pow_natlog` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh pow_natlog -Doptimiz...` | +| `zig_ReleaseSmall_default` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh default -Doptimize=R...` | +| `zig_ReleaseSmall_pow` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh pow -Doptimize=Relea...` | +| `zig_ReleaseSmall_natlog` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh natlog -Doptimize=Re...` | +| `zig_ReleaseSmall_pow_natlog` | **pass_suite** | `bash /mnt/d/hackathons/portmortem/tinyexpr.zig/scripts/run-original-suite.sh pow_natlog -Doptimiz...` | +| `float_contraction_check` | **no_fast_math_flags_in_-O2_invocation** | `cc -O2 -### tinyexpr.c` | + +## Float / fast-math + +Empirical `cc -O2 -###` on `tinyexpr.c`: **no_fast_math_flags_in_-O2_invocation**. +Zig builds do not pass `-ffast-math`. Equivalence claims assume C locale and no fast-math. + +## Zig-native safety tests + +Separate from gcc-linked smoke: + +| Cell | Verdict | Command | +| --- | --- | --- | +| `zig_build_test_Debug` | **pass** | `zig build test -Doptimize=Debug` (exit 0) | +| `zig_build_test_ReleaseSafe` | **pass** | `zig build test -Doptimize=ReleaseSafe` (exit 0) | + +Debug/ReleaseSafe static libraries need `tools/zig_probe_stub.c` when a gcc +driver links them (`__zig_probe_stack`). + +## Valgrind + +`valgrind` was **not installed** on the measurement host (`tool_missing`). +ASan+LSan cells above cover leak detection for the original suite. diff --git a/docs/findings.md b/docs/findings.md index 73382ac..d6d7730 100644 --- a/docs/findings.md +++ b/docs/findings.md @@ -1,7 +1,6 @@ # Findings -Unverified hypotheses only. Do not treat these as confirmed bugs until the -named experiment has been run and recorded. +Measured verdicts and reproducers. Unverified leads are marked as such. ## Independent reproduction: upstream issue #136 @@ -9,7 +8,7 @@ Stack overflow on deeply nested expressions via `te_interp` / `te_compile`. Filed upstream 2026-02-16 as issue #136 (CWE-674). Still open, unpatched at our pin. Not claimed as novel. Measured thresholds: see STATUS / journal. -## Lead A — non-static `next_token` (external linkage) +## Lead A: non-static `next_token` (external linkage) Hypothesis: `next_token` at `third_party/tinyexpr-c/tinyexpr.c:239` is declared `void next_token(state *s)` with no `static`, while every other @@ -23,22 +22,48 @@ translation unit that defines its own non-static `next_token`. Record what happens at static link and at dynamic link. Check whether this is already reported upstream before claiming novelty. -Status: unverified. +Status: unverified (owned by the second machine's upstream engagement). -## Lead B — `isalpha` / `isdigit` on signed `char` (C99 7.4p1) +## Lead B: `isalpha` / `isdigit` on signed `char` (C99 7.4p1) Hypothesis: lines 255 and 258 pass `s->next[0]` (type `char`) to `isalpha` and `isdigit`. Where `char` is signed, any byte at or above 0x80 becomes a negative `int`. Passing a negative value other than `EOF` to those functions is undefined behaviour under C99 7.4 paragraph 1. -Experiment: feed high-bit bytes through `te_interp`, run under UBSan and -also under a libc or build configuration that traps the call. Determine -whether glibc's table padding is the only reason it appears to work. +### Measured verdict (2026-08-02, elmengo / glibc 2.39) -Status: unverified. +Command: `bash scripts/run-buglead-ctype.sh` -## Lead C — `strtod` + `LC_NUMERIC` locale DoS +1. Plain `te_interp` on every single-byte string `0x80..0xFF`: all 128 + rejected (`interp_ok=0`, `interp_rejected=128`). No crash. +2. Same under UBSan (`-fsanitize=undefined -fno-sanitize-recover=undefined`): + exit 0, **no** UBSan diagnostic. glibc's ctype table padding masks the + C99 violation on this host. +3. Same with a trapping ctype wrapper via `-include` that `abort`s on + `c < 0 || c > 255` (cannot edit `third_party/`): **aborts on first byte + `0x80`** with stderr `ctype_trap: isalpha(-128)`. The call is reached from + `next_token` before the probe's own direct ctype calls return, so the + original's `isalpha(s->next[0])` path is confirmed. + +Raw fragment: `docs/evidence/fragments/buglead-ctype.json`. +Log: `docs/evidence/buglead-ctype.log`. + +Minimal reproducer for upstream: + +```bash +# Build tinyexpr with a trapping isalpha (illustrates the UB surface): +# any byte >= 0x80 as the first character of the expression reaches +# isalpha with a negative argument on signed-char platforms. +printf '\x80' | xxd # input is a single high-bit byte +# te_interp("", &err) -> isalpha(-128) under signed char +``` + +Status: **confirmed UB surface**. Not a visible crash on stock glibc; a +conforming ctype implementation may trap. Suitable for an upstream issue +citing C99 7.4p1 and recommending `(unsigned char)s->next[0]`. + +## Lead C: `strtod` + `LC_NUMERIC` locale DoS Hypothesis: line 251 calls `strtod`, which respects `LC_NUMERIC`, but the number branch is entered whenever the next character is a digit or `.`, @@ -47,16 +72,68 @@ should return 1.0 and stop at the `.`; on the next call `strtod(".5")` should fail and leave `endptr` equal to the input, yet the code still sets `TOK_NUMBER`, which means `s->next` may not advance. -Experiment: generate `de_DE.UTF-8`, then under a hard timeout evaluate -`te_interp("1.5")` and a set of decimal expressions. Separately run the -unmodified upstream `smoke` binary under that locale and record whether -it fails or hangs. If this reproduces as a hang it is a denial of service -reachable by an environment variable on input that is valid in the C -locale. +### Measured verdict (2026-08-02, elmengo) + +Command: `bash scripts/run-buglead-locale.sh` plus hang probes under +`de_DE.UTF-8` (generated via `localedef` into `.local/bugleads`, +`LOCPATH` set; `setlocale(LC_ALL, "de_DE.UTF-8")` succeeds). + +`strtod` under `de_DE.UTF-8` (direct probe): + +| Input | value | bytes advanced | +| --- | --- | --- | +| `1.5` | 1 | 1 (stops at `.`) | +| `1,5` | 1.5 | 3 | +| `.5` | 0 | **0** (endptr == start) | +| `1.` | 1 | 1 | + +`te_interp` after `setlocale(LC_ALL, "de_DE.UTF-8")` (timeout 3s each): + +| Expression | err | notes | +| --- | --- | --- | +| `1.5` | 1 | completes; value nan; **no hang** | +| `.5` | 1 | completes; **no hang** despite `strtod` advancing 0 | +| `1,5` | 0 | value 1.5 (printf shows `1,5` under the locale) | +| `2.25+3.5` | 1 | completes | + +Hang hypothesis for `te_interp`: **not reproduced**. When `strtod` fails to +advance on `.5`, the parser still returns a compile error (`err=1`) instead +of looping forever. The non-advancing token does not become a DoS on this +glibc under a 3s hard timeout. + +Correctness bug under non-C `LC_NUMERIC`: **confirmed**. Expressions that +are valid in the C locale (`1.5`, `2.25+3.5`) fail to parse after +`setlocale` to `de_DE.UTF-8`. `1,5` succeeds. + +Upstream `smoke` under `LC_ALL=de_DE.UTF-8` alone: exit 0. Smoke never +calls `setlocale`, so it stays in the C locale despite the environment +variable. Env-only is not a valid trigger; the program must call +`setlocale(LC_ALL, "")` or an explicit locale name. + +### Zig port under the same locale + +The port's lexer calls `libm.strtod` (`src/lexer.zig`) for bit-exact +parity with the C original. Under the same `setlocale` + `de_DE.UTF-8` +probe, Zig ABI `te_interp` output matched C byte-for-byte on the tested +expressions. This is **not** a favourable divergence: both sides inherit +`strtod`'s locale behaviour. Equivalence claims that mention decimal +literals should be scoped to the C locale (or to `setlocale` never having +selected a comma-decimal `LC_NUMERIC`). + +Raw fragment: `docs/evidence/fragments/buglead-locale.json`. +Log: `docs/evidence/buglead-locale.log`. + +Status: **locale-dependent parse failure confirmed; DoS hang not +reproduced**. Upstream-ready with the `strtod` table and `setlocale` +requirement above. + +## Allocator-misuse (Track G exit criterion) -Also determine what the Zig port does under the same locale (Zig float -parsing is locale-independent). If the port is unaffected, that is a -favourable divergence and needs an entry in the divergence table with the -equivalence claim scoped to the C locale. +See `docs/evidence/fragments/allocfault.json` and `allocfault-asan.json`. -Status: unverified. +Plain LD_PRELOAD campaign: 107 inputs, 271 ordinals, 0 crashes either side, +20 OOM error-position divergences (C `-1` vs Zig offset), identical ledger on +`1+2*3` (11 events). ASan+shim campaign on C: same 271 ordinals, 0 crashes, +no LeakSanitizer findings in the run log; Zig compared via LD_PRELOAD (cannot +shim the Zig `.a`). Track G allocator-misuse criterion: +`not_satisfied_negative_result`. diff --git a/docs/journal.md b/docs/journal.md index 1aca72d..aa12f1f 100644 --- a/docs/journal.md +++ b/docs/journal.md @@ -179,3 +179,33 @@ NaN to `unsigned` in `fac`. Recorded as a real divergence with Zig the more defensive side. Deep nesting remains an intentional C-UB / port-error split and is not run against C in-process. +## 2026-08-02 elmengo allocfault-fuzz-sanitizers + +Code freeze is 2026-08-03 18:00 UTC. Long differential fuzz started first +(`bash scripts/run-fuzz.sh 14400 fuzz/log-long.txt long`) and continues in +the background while the other campaigns run. + +Pillar 4 allocfault (`tools/allocfault`): one LD_PRELOAD interposer for C and +Zig ABI. Corpus 107 inputs, **271** allocation ordinals tested, **0** crashes +on either side, **20** behaviour divergences, all of them C `error=-1` (NULL +root / OOM path in `te_compile`) versus Zig positive error offsets. Ordered +malloc/free ledger on `1+2*3` is **identical** (11 events). Track G +allocator-misuse criterion: **not satisfied** (honest negative: no C crash or +leak on this campaign). ASan ordinal re-run uses a preprocessor shim TU +because ASan owns malloc; Valgrind is not installed on the measurement host. + +Certified differential fuzz (60s): **48,512,558** executions, **0** +divergences, 808,542.63 exec/s, first-token reject 1,844,576 (~3.8% of +inputs). Metamorphic campaign: 45 cases, 0 failures (parens, `+0`, `0+`). + +Sanitizer matrix: C UBSan/ASan all four flag configs pass the original suite; +all sixteen Zig opt-mode x flag-config suite cells pass (Debug/ReleaseSafe +need `tools/zig_probe_stub.c` when gcc links the `.a`). `cc -O2 -###` shows +no fast-math flags. `zig build test` Debug and ReleaseSafe both exit 0. + +Lead B (signed-char ctype): trapping wrapper aborts on `isalpha(-128)` for +input byte `0x80`; UBSan silent on glibc. Lead C (locale): under +`de_DE.UTF-8` after `setlocale`, `1.5` fails on C and Zig (shared `strtod`); +hang on `.5` not reproduced within 3s; smoke under env-only LC_ALL stays C +locale. + diff --git a/fuzz/harness.c b/fuzz/harness.c new file mode 100644 index 0000000..94fc4fc --- /dev/null +++ b/fuzz/harness.c @@ -0,0 +1,191 @@ +/* Differential fuzz harness: C (c_te_*) vs Zig (te_*) in one process. + * Filename required by Port Mortem anatomy: fuzz/harness.* (C companion to harness.zig). + */ +#define _POSIX_C_SOURCE 200809L + +#include "../third_party/tinyexpr-c/tinyexpr.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +extern te_expr *c_te_compile(const char *expression, const te_variable *variables, + int var_count, int *error); +extern double c_te_eval(const te_expr *n); +extern void c_te_print(const te_expr *n); +extern void c_te_free(te_expr *n); + +struct stats { + uint64_t executions; + uint64_t divergences; + uint64_t parse_errors; + uint64_t first_token_reject; +}; + +static uint64_t f64_bits(double value) { + uint64_t bits; + memcpy(&bits, &value, sizeof(bits)); + return bits; +} + +static unsigned compare_one(const char *expression) { + te_expr *c_expr; + te_expr *z_expr; + int c_error = INT_MIN; + int z_error = INT_MIN; + unsigned mismatch = 0; + + c_expr = c_te_compile(expression, NULL, 0, &c_error); + z_expr = te_compile(expression, NULL, 0, &z_error); + if ((c_expr == NULL) != (z_expr == NULL)) mismatch |= 1; + if (c_error != z_error) mismatch |= 2; + if (c_expr != NULL && z_expr != NULL) { + if (f64_bits(c_te_eval(c_expr)) != f64_bits(te_eval(z_expr))) mismatch |= 4; + /* te_print for constants only; skip pointerful prints. */ + } + if (c_expr == NULL && z_expr == NULL && c_error == 1 && z_error == 1) { + /* likely first-token reject */ + } + c_te_free(c_expr); + te_free(z_expr); + return mismatch; +} + +static int is_first_token_reject(const char *expression) { + int error = 0; + te_expr *expr = te_compile(expression, NULL, 0, &error); + int reject = (expr == NULL && (error == 1 || (expression[0] != '\0' && error > 0 && error <= 2))); + te_free(expr); + return reject; +} + +/* Structured generator: mostly near-valid expressions. */ +static void generate(char *out, size_t cap, uint64_t seed) { + static const char *atoms[] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "pi", "e", "1.5", "0.0", "-1", "10", + }; + static const char *unops[] = { "", "-", "+" }; + static const char *binops[] = { "+", "-", "*", "/", "^", "%" }; + static const char *ufn[] = { "sin", "cos", "abs", "sqrt", "fac", "log", "floor", "ceil" }; + static const char *bfn[] = { "atan2", "pow", "ncr", "npr", "min", "max" }; + uint64_t x = seed * 0x9E3779B97F4A7C15ull + 1; + unsigned mode = (unsigned)(x % 100); + x >>= 7; + + if (mode < 8) { + /* raw-ish mutation: short random alphabet string */ + static const char alphabet[] = "0123456789.+-*/^%(), a"; + size_t length = 1 + (x % 12); + size_t i; + for (i = 0; i < length && i + 1 < cap; ++i) { + x = x * 0x9E3779B97F4A7C15ull + 1; + out[i] = alphabet[x % (sizeof(alphabet) - 1)]; + } + out[i] = '\0'; + return; + } + + const char *a = atoms[x % (sizeof(atoms) / sizeof(atoms[0]))]; + x >>= 4; + const char *b = atoms[x % (sizeof(atoms) / sizeof(atoms[0]))]; + x >>= 4; + const char *u = unops[x % (sizeof(unops) / sizeof(unops[0]))]; + x >>= 3; + const char *op = binops[x % (sizeof(binops) / sizeof(binops[0]))]; + x >>= 4; + + if (mode < 40) { + snprintf(out, cap, "%s%s%s%s", u, a, op, b); + } else if (mode < 55) { + snprintf(out, cap, "(%s%s%s%s)", u, a, op, b); + } else if (mode < 70) { + const char *f = ufn[x % (sizeof(ufn) / sizeof(ufn[0]))]; + snprintf(out, cap, "%s(%s%s)", f, u, a); + } else if (mode < 85) { + const char *f = bfn[x % (sizeof(bfn) / sizeof(bfn[0]))]; + snprintf(out, cap, "%s(%s,%s)", f, a, b); + } else if (mode < 92) { + snprintf(out, cap, "%s+0", a); + } else { + snprintf(out, cap, "((%s))", a); + } +} + +static double now_secs(void) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (double)ts.tv_sec + (double)ts.tv_nsec / 1e9; +} + +int main(int argc, char **argv) { + double duration = 60.0; + const char *seed_path = NULL; + uint64_t seed = (uint64_t)time(NULL) ^ (uint64_t)getpid(); + struct stats stats = { 0 }; + char buffer[256]; + double start; + double end; + int index; + + for (index = 1; index < argc; ++index) { + if (strcmp(argv[index], "--seconds") == 0 && index + 1 < argc) { + duration = strtod(argv[++index], NULL); + } else if (strcmp(argv[index], "--seed") == 0 && index + 1 < argc) { + seed = strtoull(argv[++index], NULL, 10); + } else if (strcmp(argv[index], "--seed-corpus") == 0 && index + 1 < argc) { + seed_path = argv[++index]; + } else { + fprintf(stderr, "usage: %s [--seconds N] [--seed N] [--seed-corpus PATH]\n", argv[0]); + return 2; + } + } + + start = now_secs(); + end = start + duration; + + /* Seed corpus first (once each). */ + if (seed_path) { + FILE *fp = fopen(seed_path, "r"); + if (fp) { + while (fgets(buffer, sizeof(buffer), fp)) { + size_t n = strlen(buffer); + while (n && (buffer[n - 1] == '\n' || buffer[n - 1] == '\r')) buffer[--n] = 0; + if (!n) continue; + ++stats.executions; + if (is_first_token_reject(buffer)) ++stats.first_token_reject; + if (compare_one(buffer) != 0) { + ++stats.divergences; + fprintf(stderr, "DIVERGENCE seed: %s\n", buffer); + } + } + fclose(fp); + } + } + + while (now_secs() < end) { + generate(buffer, sizeof(buffer), seed + stats.executions); + ++stats.executions; + if (is_first_token_reject(buffer)) ++stats.first_token_reject; + if (compare_one(buffer) != 0) { + ++stats.divergences; + fprintf(stderr, "DIVERGENCE: %s\n", buffer); + /* keep going; count all */ + } + } + + { + double elapsed = now_secs() - start; + printf("{\"executions\":%" PRIu64 ",\"divergences\":%" PRIu64 + ",\"first_token_reject\":%" PRIu64 + ",\"seconds\":%.6f,\"exec_per_sec\":%.2f,\"seed\":%" PRIu64 "}\n", + stats.executions, stats.divergences, stats.first_token_reject, + elapsed, stats.executions / (elapsed > 0 ? elapsed : 1.0), seed); + return stats.divergences == 0 ? 0 : 1; + } +} diff --git a/fuzz/harness.zig b/fuzz/harness.zig new file mode 100644 index 0000000..5ed6f7e --- /dev/null +++ b/fuzz/harness.zig @@ -0,0 +1,68 @@ +//! Differential / metamorphic fuzz harness. Anatomy name: fuzz/harness.zig +//! Built as a Zig test module (ReleaseSafe). The certified C-vs-Zig sixty-second +//! campaign is scripts/run-fuzz.sh + fuzz/harness.c. + +const std = @import("std"); +const tinyexpr = @import("tinyexpr"); + +fn evalBits(allocator: std.mem.Allocator, expression: [:0]const u8) struct { ok: bool, bits: u64 } { + var error_pos: c_int = 0; + const value = tinyexpr.interp(allocator, expression.ptr, &error_pos); + if (error_pos != 0) return .{ .ok = false, .bits = 0 }; + const bits: u64 = @bitCast(value); + return .{ .ok = true, .bits = bits }; +} + +test "metamorphic plus-zero and parens on seeds" { + const a = std.testing.allocator; + const seeds = [_][:0]const u8{ "1", "1+2", "sin(0)", "fac(5)", "(1+2)*3" }; + for (seeds) |seed| { + const base = evalBits(a, seed); + if (!base.ok) continue; + var paren_buf: [128]u8 = undefined; + const paren = try std.fmt.bufPrintZ(&paren_buf, "({s})", .{seed}); + const p = evalBits(a, paren); + try std.testing.expect(p.ok); + try std.testing.expectEqual(base.bits, p.bits); + + var plus_buf: [128]u8 = undefined; + const plus = try std.fmt.bufPrintZ(&plus_buf, "({s})+0", .{seed}); + const z = evalBits(a, plus); + try std.testing.expect(z.ok); + const bv: f64 = @bitCast(base.bits); + if (!std.math.isNan(bv)) { + try std.testing.expectEqual(base.bits, z.bits); + } + } +} + +test "structured Smith fuzz metamorphic" { + const Context = struct { + fn testOne(_: void, smith: *std.testing.Smith) !void { + var raw: [48]u8 = undefined; + const n = smith.slice(&raw); + if (n == 0) return; + // Keep near the printable expression alphabet. + var i: usize = 0; + while (i < n) : (i += 1) { + const c = raw[i]; + if (c < 0x20 or c > 0x7e) raw[i] = '1'; + } + var zbuf: [64]u8 = undefined; + const expr = try std.fmt.bufPrintZ(&zbuf, "{s}", .{raw[0..n]}); + const a = std.testing.allocator; + const base = evalBits(a, expr); + if (!base.ok) return; + var paren_buf: [80]u8 = undefined; + const paren = try std.fmt.bufPrintZ(&paren_buf, "({s})", .{expr}); + const other = evalBits(a, paren); + if (other.ok) { + const bv: f64 = @bitCast(base.bits); + if (!std.math.isNan(bv)) try std.testing.expectEqual(base.bits, other.bits); + } + } + }; + try std.testing.fuzz({}, Context.testOne, .{ + .corpus = &.{ "1+2", "sin(0)", "(1)", "1+0", "fac(3)" }, + }); +} diff --git a/fuzz/log.txt b/fuzz/log.txt new file mode 100644 index 0000000..3ad1bb3 --- /dev/null +++ b/fuzz/log.txt @@ -0,0 +1,12 @@ +# Differential fuzz log (certified) +command: bash scripts/run-fuzz.sh 60 fuzz/log.txt certified +git_sha: b5e302ed15281e3d96c0998e64e0b8aa20afeee0 +host: Linux elmengo 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux +zig: 0.16.0 +cc: cc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 +started_at_utc: 2026-08-02T05:17:52Z +completed_at_utc: 2026-08-02T05:18:55Z +harness_exit: 0 +result_json: +{"executions":48512558,"divergences":0,"first_token_reject":1844576,"seconds":60.000000,"exec_per_sec":808542.63,"seed":1785633007} + diff --git a/scripts/run-buglead-ctype.sh b/scripts/run-buglead-ctype.sh new file mode 100644 index 0000000..747246c --- /dev/null +++ b/scripts/run-buglead-ctype.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +# Lead B: signed-char isalpha/isdigit UB probe (bytes 0x80-0xFF through te_interp). +set -euo pipefail +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +WORK="$ROOT/.local/bugleads" +EV="$ROOT/docs/evidence" +mkdir -p "$WORK" "$EV" +START="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +SHA="$(git -C "$ROOT" rev-parse HEAD)" + +cat >"$WORK/ctype_probe.c" <<'C' +#include "tinyexpr.h" +#include +#include +#include +int main(void) { + unsigned traps = 0, ok_count = 0, reject_count = 0; + for (int b = 0x80; b <= 0xFF; ++b) { + char buf[4] = { (char)b, 0, 0, 0 }; + /* Also try as leading byte of an "identifier-like" token. */ + int err = 0; + double v = te_interp(buf, &err); + (void)v; + if (err == 0) ++ok_count; else ++reject_count; + /* Direct ctype on the same byte as tinyexpr does. */ + int c = (int)(char)b; /* signedness-dependent */ + volatile int alpha = isalpha(c); + volatile int digit = isdigit(c); + (void)alpha; (void)digit; + (void)traps; + } + printf("{\"bytes\":128,\"interp_ok\":%u,\"interp_rejected\":%u,\"direct_ctype_calls\":256}\n", + ok_count, reject_count); + return 0; +} +C + +cc -O0 -g -fsanitize=undefined -fno-sanitize-recover=undefined \ + -I"$ROOT/third_party/tinyexpr-c" \ + "$WORK/ctype_probe.c" "$ROOT/third_party/tinyexpr-c/tinyexpr.c" -lm \ + -o "$WORK/ctype_probe_ubsan" 2>"$WORK/ctype_compile.txt" || true + +set +e +timeout 30 "$WORK/ctype_probe_ubsan" >"$WORK/ctype_ubsan_out.txt" 2>"$WORK/ctype_ubsan_err.txt" +UBSAN_STATUS=$? +set -e + +# Also without UBSan for baseline behaviour +cc -O0 -g -I"$ROOT/third_party/tinyexpr-c" \ + "$WORK/ctype_probe.c" "$ROOT/third_party/tinyexpr-c/tinyexpr.c" -lm \ + -o "$WORK/ctype_probe_plain" +"$WORK/ctype_probe_plain" >"$WORK/ctype_plain_out.txt" 2>"$WORK/ctype_plain_err.txt" + +# Also compile with a trapping ctype wrapper via -include (cannot edit third_party). +cat >"$WORK/trap_ctype.h" <<'H' +#include +#include +#include +static inline int te_trap_isalpha(int c) { + if (c != EOF && (c < 0 || c > 255)) { + fprintf(stderr, "ctype_trap: isalpha(%d)\n", c); + abort(); + } + return isalpha(c); +} +static inline int te_trap_isdigit(int c) { + if (c != EOF && (c < 0 || c > 255)) { + fprintf(stderr, "ctype_trap: isdigit(%d)\n", c); + abort(); + } + return isdigit(c); +} +#undef isalpha +#undef isdigit +#define isalpha(c) te_trap_isalpha(c) +#define isdigit(c) te_trap_isdigit(c) +H + +cc -O0 -g -include "$WORK/trap_ctype.h" -I"$ROOT/third_party/tinyexpr-c" \ + "$WORK/ctype_probe.c" "$ROOT/third_party/tinyexpr-c/tinyexpr.c" -lm \ + -o "$WORK/ctype_probe_trap" +set +e +timeout 30 "$WORK/ctype_probe_trap" >"$WORK/ctype_trap_out.txt" 2>"$WORK/ctype_trap_err.txt" +TRAP_STATUS=$? +set -e + +python3 - "$ROOT" "$WORK" "$START" "$SHA" "$UBSAN_STATUS" "$TRAP_STATUS" <<'PY' +import json, platform, time +from pathlib import Path +root, work, started, sha, status, trap_status = __import__('sys').argv[1:] +root = Path(root) +work = Path(work) +plain = (work/'ctype_plain_out.txt').read_text(errors='replace').strip() +ubsan_out = (work/'ctype_ubsan_out.txt').read_text(errors='replace') +ubsan_err = (work/'ctype_ubsan_err.txt').read_text(errors='replace') +trap_err = (work/'ctype_trap_err.txt').read_text(errors='replace') +ubsan_hit = 'runtime error' in ubsan_err.lower() or 'undefined' in ubsan_err.lower() +trap_hit = 'ctype_trap' in trap_err or int(trap_status) in (134, 6) # abort +fragment = { + "schema_version": 1, + "lead": "B_signed_char_ctype", + "command": "bash scripts/run-buglead-ctype.sh", + "git_sha": sha, + "host": platform.platform(), + "utc_start": started, + "utc_end": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "ubsan_exit": int(status), + "trap_ctype_exit": int(trap_status), + "ubsan_reported_runtime_error": ubsan_hit, + "trap_ctype_aborted": trap_hit, + "plain_stdout": plain, + "ubsan_stderr_tail": ubsan_err[-1500:], + "trap_stderr_tail": trap_err[-1500:], + "verdict": ( + "trapping ctype wrapper aborted on high-bit signed char; C99 7.4p1 UB confirmed reachable" + if trap_hit else + "UBSan diagnosed ctype UB on high-bit bytes" + if ubsan_hit else + "no UBSan diagnostic on this glibc/UBSan; trapping wrapper also did not abort; high-bit bytes rejected by te_interp before ctype or glibc padding masks it" + ), +} +(root/'docs/evidence/fragments/buglead-ctype.json').write_text(json.dumps(fragment, indent=2)+'\n') +(root/'docs/evidence/buglead-ctype.log').write_text( + f"plain={plain}\nubsan_exit={status}\ntrap_exit={trap_status}\nubsan_err=\n{ubsan_err}\ntrap_err=\n{trap_err}\n" +) +print(json.dumps(fragment, indent=2)) +PY diff --git a/scripts/run-buglead-locale.sh b/scripts/run-buglead-locale.sh new file mode 100644 index 0000000..4713845 --- /dev/null +++ b/scripts/run-buglead-locale.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +# Lead C: LC_NUMERIC / strtod locale DoS probe. +set -euo pipefail +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +WORK="$ROOT/.local/bugleads" +EV="$ROOT/docs/evidence" +mkdir -p "$WORK" "$EV" +START="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +SHA="$(git -C "$ROOT" rev-parse HEAD)" +CACHE="${CACHE:-$HOME/.cache/zig-tinyexpr}" +export PATH="$HOME/.local/zig:/opt/zig:$PATH" + +# Ensure locale exists (best effort without root) +locale -a | grep -i 'de_DE.utf8\|de_DE.UTF-8' || { + echo "generating de_DE.UTF-8 via localedef (may fail without privileges)" + localedef -f UTF-8 -i de_DE "$WORK/de_DE.UTF-8" 2>"$WORK/localedef.err" || true +} +export LOCPATH="${LOCPATH:-$WORK}" +LOCALE_NAME="$(locale -a | grep -i 'de_DE.utf8\|de_DE.UTF-8' | head -1 || true)" +if [[ -z "$LOCALE_NAME" && -d "$WORK/de_DE.UTF-8" ]]; then + LOCALE_NAME="de_DE.UTF-8" +fi +echo "locale_name=${LOCALE_NAME:-MISSING}" + +cat >"$WORK/locale_probe.c" <<'C' +#include "tinyexpr.h" +#include +#include +#include +#include +int main(int argc, char **argv) { + const char *loc = argc > 1 ? argv[1] : "C"; + if (!setlocale(LC_ALL, loc)) { + fprintf(stderr, "setlocale failed for %s\n", loc); + return 2; + } + const char *exprs[] = {"1.5", "1,5", "2.25+3.5", "0.5", ".5", "1.", NULL}; + for (int i = 0; exprs[i]; ++i) { + int err = 0; + double v = te_interp(exprs[i], &err); + printf("expr=%s err=%d value=%g\n", exprs[i], err, v); + fflush(stdout); + } + return 0; +} +C + +cc -O0 -g -I"$ROOT/third_party/tinyexpr-c" \ + "$WORK/locale_probe.c" "$ROOT/third_party/tinyexpr-c/tinyexpr.c" -lm \ + -o "$WORK/locale_probe_c" + +# Zig ABI driver (locale should not affect Zig parsing of the expression string +# when going through the port's own lexer; still call te_interp from Zig lib). +cc -O0 -g -I"$ROOT/third_party/tinyexpr-c" \ + "$WORK/locale_probe.c" -c -o "$WORK/locale_probe.o" +(cd "$ROOT" && zig build -Doptimize=Debug -p "$WORK/zig-out" --cache-dir "$CACHE") +cc -O0 -g "$WORK/locale_probe.o" "$WORK/zig-out/lib/libtinyexpr.a" -lm \ + -o "$WORK/locale_probe_zig" + +run_with_timeout() { + local bin="$1" out="$2" err="$3" + set +e + if [[ -n "$LOCALE_NAME" ]]; then + timeout 5 env LC_ALL="$LOCALE_NAME" LC_NUMERIC="$LOCALE_NAME" "$bin" "$LOCALE_NAME" >"$out" 2>"$err" + else + timeout 5 env LC_ALL=C "$bin" C >"$out" 2>"$err" + fi + echo $? >"${out}.status" + set -e +} + +run_with_timeout "$WORK/locale_probe_c" "$WORK/locale_c_out.txt" "$WORK/locale_c_err.txt" +run_with_timeout "$WORK/locale_probe_zig" "$WORK/locale_zig_out.txt" "$WORK/locale_zig_err.txt" + +# Upstream smoke under locale (short timeout) +cc -O0 -I"$ROOT/third_party/tinyexpr-c" \ + "$ROOT/tests/original/smoke.c" "$ROOT/third_party/tinyexpr-c/tinyexpr.c" -lm \ + -o "$WORK/smoke_c" 2>/dev/null || true +set +e +if [[ -n "$LOCALE_NAME" && -x "$WORK/smoke_c" ]]; then + timeout 20 env LC_ALL="$LOCALE_NAME" LC_NUMERIC="$LOCALE_NAME" "$WORK/smoke_c" \ + >"$WORK/smoke_locale_out.txt" 2>"$WORK/smoke_locale_err.txt" + echo $? >"$WORK/smoke_locale.status" +fi +set -e + +python3 - "$ROOT" "$WORK" "$START" "$SHA" "${LOCALE_NAME:-}" <<'PY' +import json, platform, time +from pathlib import Path +root, work, started, sha, locale = __import__('sys').argv[1:] +root = Path(root) +work = Path(work) + +def read(p): + path = work/p + return path.read_text(errors='replace') if path.exists() else '' + +def status(p): + path = work/p + return int(path.read_text().strip()) if path.exists() else None + +c_out = read('locale_c_out.txt') +z_out = read('locale_zig_out.txt') +c_status = status('locale_c_out.txt.status') +z_status = status('locale_zig_out.txt.status') +smoke_status = status('smoke_locale.status') + +hung_c = c_status == 124 +hung_smoke = smoke_status == 124 +verdict = [] +if not locale: + verdict.append("de_DE.UTF-8 locale unavailable on host; ran C locale only") +if hung_c: + verdict.append("C te_interp hung under locale (timeout 5s) — DoS hypothesis supported") +elif c_status == 0: + verdict.append("C te_interp completed under locale; inspect value/err lines for decimal divergence") +if hung_smoke: + verdict.append("upstream smoke hung under locale (timeout 20s)") +elif smoke_status is not None: + verdict.append(f"upstream smoke exit={smoke_status} under locale") +if z_status == 0: + verdict.append("Zig ABI te_interp completed under same locale (locale-independent lexer expected)") +elif z_status == 124: + verdict.append("Zig ABI also timed out under locale") + +fragment = { + "schema_version": 1, + "lead": "C_strtod_LC_NUMERIC", + "command": "bash scripts/run-buglead-locale.sh", + "git_sha": sha, + "host": platform.platform(), + "utc_start": started, + "utc_end": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "locale": locale or None, + "c_exit": c_status, + "zig_exit": z_status, + "smoke_exit": smoke_status, + "c_stdout": c_out, + "zig_stdout": z_out, + "c_stderr": read('locale_c_err.txt')[-1000:], + "zig_stderr": read('locale_zig_err.txt')[-1000:], + "smoke_stderr_tail": read('smoke_locale_err.txt')[-1000:], + "verdict": "; ".join(verdict) if verdict else "inconclusive", +} +(root/'docs/evidence/fragments/buglead-locale.json').write_text(json.dumps(fragment, indent=2)+'\n') +(root/'docs/evidence/buglead-locale.log').write_text(json.dumps(fragment, indent=2)+'\n') +print(json.dumps(fragment, indent=2)[:3000]) +PY diff --git a/scripts/run-fuzz.sh b/scripts/run-fuzz.sh new file mode 100644 index 0000000..ba66e41 --- /dev/null +++ b/scripts/run-fuzz.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# Build and run the differential fuzz harness (C driver + renamed C oracle + Zig). +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +WORK="$ROOT/.local/fuzz" +CACHE="${CACHE:-$HOME/.cache/zig-tinyexpr}" +export PATH="$HOME/.local/zig:/opt/zig:$PATH" +SECONDS_ARG="${1:-60}" +OUT_LOG="${2:-$ROOT/fuzz/log.txt}" +MODE="${3:-certified}" + +mkdir -p "$WORK" "$ROOT/fuzz/logs" "$(dirname "$OUT_LOG")" +START_UTC="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +SHA="$(git -C "$ROOT" rev-parse HEAD)" +HOST="$(uname -a)" + +cc -std=c11 -O3 -Wall -Wextra -Wno-array-bounds \ + -c "$ROOT/third_party/tinyexpr-c/tinyexpr.c" -o "$WORK/tinyexpr-c.o" +mapfile -t EXPORTED < <( + nm -g --defined-only "$WORK/tinyexpr-c.o" | awk '{print $3}' | awk '/^te_|^next_token$/' +) +RENAME_ARGS=() +for symbol in "${EXPORTED[@]}"; do + RENAME_ARGS+=(--redefine-sym "$symbol=c_$symbol") +done +objcopy "${RENAME_ARGS[@]}" "$WORK/tinyexpr-c.o" "$WORK/tinyexpr-c-renamed.o" + +(cd "$ROOT" && zig build -Doptimize=ReleaseFast -p "$WORK/zig-out" --cache-dir "$CACHE") +cc -std=c11 -O3 -Wall -Wextra -Werror \ + "$ROOT/fuzz/harness.c" "$WORK/tinyexpr-c-renamed.o" "$WORK/zig-out/lib/libtinyexpr.a" \ + -lm -o "$WORK/harness" + +# Flatten seed corpus +SEED="$WORK/seed.txt" +: >"$SEED" +cat "$ROOT/fuzz/corpus-seed/"* >>"$SEED" 2>/dev/null || true +python3 - "$ROOT" "$SEED" <<'PY' +from pathlib import Path +import json, sys +root = Path(sys.argv[1]) +seed = Path(sys.argv[2]) +lines = seed.read_text(encoding='utf-8').splitlines() if seed.exists() else [] +for fixture in sorted((root/'tests/port/fixtures').glob('*.jsonl')): + for raw in fixture.read_text(encoding='utf-8').splitlines()[:80]: + if not raw: continue + expr = json.loads(raw).get('expression') + if expr: lines.append(expr.replace('\n',' ')) +seed.write_text('\n'.join(lines)+'\n', encoding='utf-8') +print(len(lines)) +PY + +RESULT="$WORK/result-$MODE.json" +set +e +"$WORK/harness" --seconds "$SECONDS_ARG" --seed-corpus "$SEED" >"$RESULT" +STATUS=$? +set -e +END_UTC="$(date -u +%Y-%m-%dT%H:%M:%SZ)" + +{ + echo "# Differential fuzz log ($MODE)" + echo "command: bash scripts/run-fuzz.sh $SECONDS_ARG $OUT_LOG $MODE" + echo "git_sha: $SHA" + echo "host: $HOST" + echo "zig: $(zig version)" + echo "cc: $(cc --version | head -1)" + echo "started_at_utc: $START_UTC" + echo "completed_at_utc: $END_UTC" + echo "harness_exit: $STATUS" + echo "result_json:" + cat "$RESULT" + echo +} | tee "$OUT_LOG" + +python3 - "$RESULT" "$ROOT/docs/evidence/fragments/fuzz-$MODE.json" \ + "$START_UTC" "$END_UTC" "$SHA" "$HOST" "$SECONDS_ARG" "$MODE" "$STATUS" <<'PY' +import json, platform, subprocess, sys +from pathlib import Path +raw, out, started, ended, sha, host, seconds, mode, status = sys.argv[1:] +result = json.loads(Path(raw).read_text()) +result.update({ + "schema_version": 1, + "command": f"bash scripts/run-fuzz.sh {seconds}", + "git_sha": sha, + "host": host, + "utc_start": started, + "utc_end": ended, + "mode": mode, + "requested_seconds": float(seconds), + "harness_exit": int(status), + "zig": subprocess.check_output(["zig","version"], text=True).strip(), +}) +Path(out).write_text(json.dumps(result, indent=2)+"\n") +print(json.dumps(result, indent=2)) +PY +exit "$STATUS" diff --git a/scripts/run-metamorphic.sh b/scripts/run-metamorphic.sh new file mode 100644 index 0000000..2ae47ef --- /dev/null +++ b/scripts/run-metamorphic.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# Metamorphic differential campaign: transforms that must preserve semantics. +set -euo pipefail +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +WORK="$ROOT/.local/fuzz" +CACHE="${CACHE:-$HOME/.cache/zig-tinyexpr}" +export PATH="$HOME/.local/zig:/opt/zig:$PATH" +FRAGMENT="$ROOT/docs/evidence/fragments/metamorphic.json" +LOG="$ROOT/docs/evidence/metamorphic.log" +mkdir -p "$WORK" "$ROOT/docs/evidence/fragments" +START="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +SHA="$(git -C "$ROOT" rev-parse HEAD)" + +# Reuse renamed dual harness object build from run-fuzz if present, else build. +bash "$ROOT/scripts/run-fuzz.sh" 1 "$WORK/warmup-log.txt" warmup >/dev/null || true + +python3 - "$ROOT" "$WORK" "$FRAGMENT" "$START" "$SHA" <<'PY' +import json, os, subprocess, platform, time +from pathlib import Path + +root, work, fragment, started, sha = __import__('sys').argv[1:] +root = Path(root) +work = Path(work) +fragment = Path(fragment) +harness = work/'harness' +# Build a tiny metamorphic runner in Python calling the in-process probe via +# compiling a one-shot C file is heavy; instead shell the dual harness compare +# through a dedicated binary we compile here. + +src = work/'meta.c' +inc = root/'third_party'/'tinyexpr-c'/'tinyexpr.h' +src.write_text(f''' +#define _POSIX_C_SOURCE 200809L +#include "{inc.as_posix()}" +#include +#include +#include +#include +extern te_expr *c_te_compile(const char*, const te_variable*, int, int*); +extern double c_te_eval(const te_expr*); +extern void c_te_free(te_expr*); +static uint64_t bits(double v){{uint64_t b;memcpy(&b,&v,8);return b;}} +static int eval_both(const char *e, uint64_t *cb, uint64_t *zb, int *ce, int *ze, int *cok, int *zok){{ + te_expr *c=c_te_compile(e,0,0,ce); te_expr *z=te_compile(e,0,0,ze); + *cok=c!=NULL; *zok=z!=NULL; + if(c){{*cb=bits(c_te_eval(c)); c_te_free(c);}} else *cb=0; + if(z){{*zb=bits(te_eval(z)); te_free(z);}} else *zb=0; + return (*cok!=*zok)||(*ce!=*ze)||(*cok && *cb!=*zb); +}} +int main(void){{ + const char *base[]={{"1","1+2","sin(0)","(1+2)*3","fac(5)","abs(-2)","2^3","pi","1.5+2.5",NULL}}; + unsigned tested=0, fails=0; + for(int i=0;base[i];++i){{ + char t1[128], t2[128], t3[128], t4[128]; + snprintf(t1,sizeof t1,"(%s)", base[i]); + snprintf(t2,sizeof t2,"%s+0", base[i]); + snprintf(t3,sizeof t3,"((%s))", base[i]); + /* x -> (x) already covered; commute only for + of two literals where order is fixed in base */ + snprintf(t4,sizeof t4,"0+%s", base[i]); + const char *vars[]={{base[i], t1, t2, t3, t4}}; + uint64_t ref_c=0, ref_z=0; int ce=0,ze=0,cok=0,zok=0; + eval_both(base[i], &ref_c,&ref_z,&ce,&ze,&cok,&zok); + for(int j=0;j<5;++j){{ + uint64_t cb,zb; int e1,e2,o1,o2; + int bad=eval_both(vars[j], &cb,&zb,&e1,&e2,&o1,&o2); + ++tested; + if(cok && o1 && o2 && (cb!=ref_c || zb!=ref_z || cb!=zb)) {{ ++fails; printf("FAIL %s vs %s\\n", base[i], vars[j]); }} + if(bad) {{ ++fails; printf("DIVERGE %s\\n", vars[j]); }} + }} + }} + printf("{{\\"metamorphic_cases\\":%u,\\"failures\\":%u}}\\n", tested, fails); + return fails?1:0; +}} +''') + +subprocess.check_call([ + 'cc','-O2',str(src), str(work/'tinyexpr-c-renamed.o'), + str(work/'zig-out/lib/libtinyexpr.a'), '-lm', '-o', str(work/'meta') +], cwd=str(root)) +out = subprocess.check_output([str(work/'meta')], text=True) +line=[l for l in out.splitlines() if l.startswith('{')][-1] +result=json.loads(line) +result.update({ + 'schema_version':1, + 'command':'bash scripts/run-metamorphic.sh', + 'git_sha':sha, + 'host':platform.platform(), + 'utc_start':started, + 'utc_end':time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), + 'transforms':['redundant_parens','plus_zero','double_parens','zero_plus'], + 'note':'float commute/reassociate omitted where IEEE non-associativity applies; 0+x checked separately from x+0', +}) +fragment.write_text(json.dumps(result, indent=2)+'\n') +print(json.dumps(result, indent=2)) +(root/'docs/evidence/metamorphic.log').write_text(out + '\n' + json.dumps(result, indent=2)) +PY diff --git a/scripts/run-original-suite.sh b/scripts/run-original-suite.sh index 4e8a30a..4159d5e 100644 --- a/scripts/run-original-suite.sh +++ b/scripts/run-original-suite.sh @@ -51,7 +51,13 @@ run_one() { local label="$1" shift local bin="$ROOT/smoke-$NAME-$label" - gcc "${CFLAGS[@]}" -o "$bin" "$SMOKE" "$@" -lm + local objs=("$@") + # Zig Debug/ReleaseSafe objects may reference __zig_probe_stack. + if [[ "$label" == zig-static ]]; then + gcc -c -O2 "$ROOT/tools/zig_probe_stub.c" -o "$ROOT/zig-probe-stub.o" + objs+=("$ROOT/zig-probe-stub.o") + fi + gcc "${CFLAGS[@]}" -o "$bin" "$SMOKE" "${objs[@]}" -lm { echo "=== original suite transcript ===" echo "config: $NAME ($label)" @@ -60,7 +66,7 @@ run_one() { echo "compiler: $GCC_VER" echo "host: $HOST" echo "cflags: ${CFLAGS[*]}" - echo "link: $* -lm" + echo "link: ${objs[*]} -lm" echo "=== stdout ===" "$bin" } | tee "$OUT/original-suite-${NAME}-${label}.txt" diff --git a/scripts/run-sanitizer-matrix.sh b/scripts/run-sanitizer-matrix.sh new file mode 100644 index 0000000..d63bb83 --- /dev/null +++ b/scripts/run-sanitizer-matrix.sh @@ -0,0 +1,146 @@ +#!/usr/bin/env bash +# Sanitizer / safety matrix (Prompt 5 Task 3). Writes docs/evidence/sanitizers.md +set -euo pipefail +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +WORK="$ROOT/.local/sanitizers" +CACHE="${CACHE:-$HOME/.cache/zig-tinyexpr}" +export PATH="$HOME/.local/zig:/opt/zig:$PATH" +EV="$ROOT/docs/evidence" +mkdir -p "$WORK" "$EV/fragments" +START="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +SHA="$(git -C "$ROOT" rev-parse HEAD)" +REPORT="$EV/sanitizers.md" +: >"$WORK/matrix.tsv" + +run_cell() { + local cell="$1"; shift + set +e + local out="$WORK/${cell}.out" + local err="$WORK/${cell}.err" + timeout 180 "$@" >"$out" 2>"$err" + local st=$? + set -e + local verdict="pass" + if [[ $st -eq 124 ]]; then verdict="timeout" + elif [[ $st -ne 0 ]]; then verdict="fail_exit_$st" + fi + if grep -qiE 'runtime error|ERROR: AddressSanitizer|Invalid read|LeakSanitizer|definitely lost' "$err" "$out" 2>/dev/null; then + verdict="sanitizer_finding" + fi + # Suite success marker + if grep -q 'ALL TESTS PASSED' "$out" 2>/dev/null; then + if [[ "$verdict" == "pass" ]]; then verdict="pass_suite"; fi + fi + printf '%s\t%s\t%s\n' "$cell" "$verdict" "$*" >>"$WORK/matrix.tsv" + echo "cell=$cell verdict=$verdict" +} + +# --- C original under sanitizers (four flag configs) --- +build_c_smoke() { + local name="$1"; shift + cc -O1 -g "$@" -I"$ROOT/third_party/tinyexpr-c" \ + "$ROOT/tests/original/smoke.c" "$ROOT/third_party/tinyexpr-c/tinyexpr.c" -lm \ + -o "$WORK/smoke-$name" +} + +# UBSan +build_c_smoke ubsan-default -fsanitize=undefined -fno-sanitize-recover=undefined +run_cell c_ubsan_default "$WORK/smoke-ubsan-default" + +build_c_smoke ubsan-pow -fsanitize=undefined -fno-sanitize-recover=undefined -DTE_POW_FROM_RIGHT +run_cell c_ubsan_pow "$WORK/smoke-ubsan-pow" + +build_c_smoke ubsan-natlog -fsanitize=undefined -fno-sanitize-recover=undefined -DTE_NAT_LOG +run_cell c_ubsan_natlog "$WORK/smoke-ubsan-natlog" + +build_c_smoke ubsan-pow-natlog -fsanitize=undefined -fno-sanitize-recover=undefined -DTE_POW_FROM_RIGHT -DTE_NAT_LOG +run_cell c_ubsan_pow_natlog "$WORK/smoke-ubsan-pow-natlog" + +# ASan+LSan +build_c_smoke asan-default -fsanitize=address,leak -fno-omit-frame-pointer +run_cell c_asan_default env ASAN_OPTIONS=detect_leaks=1 "$WORK/smoke-asan-default" + +build_c_smoke asan-pow -fsanitize=address,leak -fno-omit-frame-pointer -DTE_POW_FROM_RIGHT +run_cell c_asan_pow env ASAN_OPTIONS=detect_leaks=1 "$WORK/smoke-asan-pow" + +build_c_smoke asan-natlog -fsanitize=address,leak -fno-omit-frame-pointer -DTE_NAT_LOG +run_cell c_asan_natlog env ASAN_OPTIONS=detect_leaks=1 "$WORK/smoke-asan-natlog" + +build_c_smoke asan-pow-natlog -fsanitize=address,leak -fno-omit-frame-pointer -DTE_POW_FROM_RIGHT -DTE_NAT_LOG +run_cell c_asan_pow_natlog env ASAN_OPTIONS=detect_leaks=1 "$WORK/smoke-asan-pow-natlog" + +# Valgrind sample (default only — slow) +if command -v valgrind >/dev/null 2>&1; then + build_c_smoke valgrind-default + run_cell c_valgrind_default valgrind --quiet --error-exitcode=99 --leak-check=full "$WORK/smoke-valgrind-default" +else + printf '%s\t%s\t%s\n' "c_valgrind_default" "tool_missing" "valgrind" >>"$WORK/matrix.tsv" +fi + +# --- Zig library + original suite under four opt modes --- +for mode in Debug ReleaseSafe ReleaseFast ReleaseSmall; do + for cfg in default pow natlog pow_natlog; do + extra=() + case "$cfg" in + pow) extra+=(-Dpow-from-right=true) ;; + natlog) extra+=(-Dnat-log=true) ;; + pow_natlog) extra+=(-Dpow-from-right=true -Dnat-log=true) ;; + esac + run_cell "zig_${mode}_${cfg}" \ + bash "$ROOT/scripts/run-original-suite.sh" "$cfg" -Doptimize="$mode" "${extra[@]}" + done +done + +# Float contraction / fast-math empirical check +echo 'int main(){return 0;}' | cc -O2 -fno-fast-math -fno-associative-math -x c - -c -o "$WORK/fm.o" -### 2>"$WORK/cc_O2.txt" || true +cc -O2 -c "$ROOT/third_party/tinyexpr-c/tinyexpr.c" -I"$ROOT/third_party/tinyexpr-c" -o "$WORK/te_O2.o" -### 2>"$WORK/te_O2_cmd.txt" || true +if grep -E 'ffast-math|funsafe-math|associative-math' "$WORK/te_O2_cmd.txt" >/dev/null; then + FM_VERDICT="fast_math_flags_present" +else + FM_VERDICT="no_fast_math_flags_in_-O2_invocation" +fi +printf '%s\t%s\t%s\n' "float_contraction_check" "$FM_VERDICT" "cc -O2 -### tinyexpr.c" >>"$WORK/matrix.tsv" + +python3 - "$ROOT" "$WORK" "$REPORT" "$START" "$SHA" "$FM_VERDICT" <<'PY' +import json, time, platform +from pathlib import Path +root, work, report, started, sha, fm = __import__('sys').argv[1:] +root = Path(root) +work = Path(work) +report = Path(report) +rows = [] +for line in (work/'matrix.tsv').read_text().splitlines(): + cell, verdict, cmd = line.split('\t', 2) + rows.append({"cell": cell, "verdict": verdict, "command": cmd}) + +md = [] +md.append("# Sanitizer and safety matrix\n") +md.append(f"Measured at `{sha[:12]}` starting `{started}` on `{platform.platform()}`.\n") +md.append("| Cell | Verdict | Command |\n| --- | --- | --- |\n") +for r in rows: + cmd = r["command"].replace("|", "\\|") + if len(cmd) > 100: cmd = cmd[:97] + "..." + md.append(f"| `{r['cell']}` | **{r['verdict']}** | `{cmd}` |\n") +md.append("\n## Float / fast-math\n\n") +md.append(f"Empirical `cc -O2 -###` on `tinyexpr.c`: **{fm}**.\n") +md.append("Zig builds do not pass `-ffast-math`. Equivalence claims assume C locale and no fast-math.\n") +report.write_text("".join(md)) + +fragment = { + "schema_version": 1, + "command": "bash scripts/run-sanitizer-matrix.sh", + "git_sha": sha, + "host": platform.platform(), + "started_at_utc": started, + "completed_at_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "cells": len(rows), + "float_math": fm, + "report": "docs/evidence/sanitizers.md", + "summary": {r["cell"]: r["verdict"] for r in rows}, +} +(root/"docs/evidence/fragments/sanitizers.json").write_text(json.dumps(fragment, indent=2)+"\n") +fails = [r for r in rows if not r["verdict"].startswith("pass") and r["verdict"] != "tool_missing"] +print(f"cells={len(rows)} nonpass={len(fails)}") +for r in fails[:20]: + print(r) +PY diff --git a/tools/allocfault/alloc_shim.c b/tools/allocfault/alloc_shim.c new file mode 100644 index 0000000..09037d0 --- /dev/null +++ b/tools/allocfault/alloc_shim.c @@ -0,0 +1,60 @@ +#define _GNU_SOURCE +/* Undefine shim macros before implementing the real wrappers. */ +#include +#include +#include + +static unsigned long long alloc_count = 0; +static unsigned long long fail_at = 0; +static int count_only = 0; +static int inited = 0; + +static void init(void) { + if (inited) return; + const char *fail = getenv("ALLOCFAULT_FAIL_AT"); + if (fail && fail[0]) fail_at = strtoull(fail, NULL, 10); + count_only = getenv("ALLOCFAULT_COUNT_ONLY") != NULL; + inited = 1; +} + +static int should_fail(void) { + init(); + if (count_only || fail_at == 0) return 0; + return alloc_count == fail_at; +} + +void *allocfault_shim_malloc(size_t size) { + init(); + ++alloc_count; + if (should_fail()) { errno = ENOMEM; return NULL; } + return malloc(size); +} + +void *allocfault_shim_calloc(size_t nmemb, size_t size) { + init(); + ++alloc_count; + if (should_fail()) { errno = ENOMEM; return NULL; } + return calloc(nmemb, size); +} + +void *allocfault_shim_realloc(void *ptr, size_t size) { + init(); + ++alloc_count; + if (should_fail()) { errno = ENOMEM; return NULL; } + return realloc(ptr, size); +} + +void allocfault_shim_free(void *ptr) { + init(); + free(ptr); +} + +unsigned long long allocfault_count(void) { + init(); + return alloc_count; +} + +void allocfault_reset(void) { + init(); + alloc_count = 0; +} diff --git a/tools/allocfault/alloc_shim.h b/tools/allocfault/alloc_shim.h new file mode 100644 index 0000000..276034e --- /dev/null +++ b/tools/allocfault/alloc_shim.h @@ -0,0 +1,20 @@ +/* Compile tinyexpr.c with: cc -include alloc_shim.h ... + * Rewrites malloc/calloc/realloc/free at the preprocessor level so ASan and + * ordinal injection coexist (unlike LD_PRELOAD+ASan or --wrap+libc). + */ +#ifndef ALLOCFAULT_SHIM_H +#define ALLOCFAULT_SHIM_H + +#include + +void *allocfault_shim_malloc(size_t size); +void *allocfault_shim_calloc(size_t nmemb, size_t size); +void *allocfault_shim_realloc(void *ptr, size_t size); +void allocfault_shim_free(void *ptr); + +#define malloc(size) allocfault_shim_malloc(size) +#define calloc(n, s) allocfault_shim_calloc((n), (s)) +#define realloc(p, s) allocfault_shim_realloc((p), (s)) +#define free(p) allocfault_shim_free(p) + +#endif diff --git a/tools/allocfault/driver.c b/tools/allocfault/driver.c new file mode 100644 index 0000000..5b5a3dc --- /dev/null +++ b/tools/allocfault/driver.c @@ -0,0 +1,60 @@ +/* Driver: evaluate one expression through te_* and print a JSON line. */ +#define _GNU_SOURCE +#include "tinyexpr.h" + +#include +#include +#include +#include +#include + +/* Prefer a direct link when alloc_shim.o / interposer exports these. */ +unsigned long long allocfault_count(void) __attribute__((weak)); +void allocfault_reset(void) __attribute__((weak)); + +static uint64_t bits(double value) { + uint64_t out; + memcpy(&out, &value, sizeof(out)); + return out; +} + +static unsigned long long read_alloc_count(void) { + if (allocfault_count) return allocfault_count(); + unsigned long long (*fn)(void) = dlsym(RTLD_DEFAULT, "allocfault_count"); + if (!fn) return 0; + return fn(); +} + +static void reset_alloc_count(void) { + if (allocfault_reset) { + allocfault_reset(); + return; + } + void (*reset)(void) = dlsym(RTLD_DEFAULT, "allocfault_reset"); + if (reset) reset(); +} + +int main(int argc, char **argv) { + if (argc < 2) { + fprintf(stderr, "usage: %s EXPR\n", argv[0]); + return 2; + } + const char *expression = argv[1]; + reset_alloc_count(); + + int error = 0; + te_expr *node = te_compile(expression, NULL, 0, &error); + unsigned long long count = read_alloc_count(); + if (node == NULL) { + printf("{\"ok\":false,\"error\":%d,\"bits\":null,\"allocs\":%llu}\n", error, + (unsigned long long)count); + return 0; + } + double value = te_eval(node); + uint64_t b = bits(value); + te_free(node); + count = read_alloc_count(); + printf("{\"ok\":true,\"error\":%d,\"bits\":\"0x%016llx\",\"allocs\":%llu}\n", error, + (unsigned long long)b, (unsigned long long)count); + return 0; +} diff --git a/tools/allocfault/interposer.c b/tools/allocfault/interposer.c new file mode 100644 index 0000000..d3367b1 --- /dev/null +++ b/tools/allocfault/interposer.c @@ -0,0 +1,155 @@ +/* LD_PRELOAD malloc/calloc/realloc/free interposer for ordinal failure injection. + * Env: + * ALLOCFAULT_FAIL_AT=N fail the Nth allocation (1-based); 0 = never fail + * ALLOCFAULT_COUNT_ONLY=1 never fail; only count + * ALLOCFAULT_LOG=path append ledger lines via write(2) (no fprintf→malloc) + * ALLOCFAULT_SILENT=1 suppress stderr counters + * + * One interposer works for both C original and Zig ABI because both allocate + * through libc malloc at the ABI boundary. + */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void *(*real_malloc)(size_t) = NULL; +static void *(*real_calloc)(size_t, size_t) = NULL; +static void *(*real_realloc)(void *, size_t) = NULL; +static void (*real_free)(void *) = NULL; + +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned long long alloc_count = 0; +static unsigned long long fail_at = 0; +static int count_only = 0; +static int silent = 0; +static int ledger_fd = -1; +static int initialized = 0; + +static void ledger_write(const char *buf, size_t n) { + if (ledger_fd < 0) return; + /* Best-effort; ignore short writes / EINTR to avoid recursion. */ + (void)write(ledger_fd, buf, n); +} + +static void init_once(void) { + if (initialized) return; + real_malloc = dlsym(RTLD_NEXT, "malloc"); + real_calloc = dlsym(RTLD_NEXT, "calloc"); + real_realloc = dlsym(RTLD_NEXT, "realloc"); + real_free = dlsym(RTLD_NEXT, "free"); + + const char *fail = getenv("ALLOCFAULT_FAIL_AT"); + if (fail && fail[0]) fail_at = strtoull(fail, NULL, 10); + count_only = getenv("ALLOCFAULT_COUNT_ONLY") != NULL; + silent = getenv("ALLOCFAULT_SILENT") != NULL; + const char *log_path = getenv("ALLOCFAULT_LOG"); + if (log_path && log_path[0]) { + ledger_fd = open(log_path, O_WRONLY | O_CREAT | O_APPEND, 0644); + } + initialized = 1; +} + +static int should_fail(void) { + if (count_only) return 0; + if (fail_at == 0) return 0; + return alloc_count == fail_at; +} + +static void *fail_alloc(void) { + errno = ENOMEM; + char buf[64]; + int n = snprintf(buf, sizeof(buf), "fail %llu\n", (unsigned long long)fail_at); + if (n > 0) ledger_write(buf, (size_t)n); + if (!silent) { + /* write(2) to stderr to avoid buffered IO malloc recursion */ + char msg[96]; + int m = snprintf(msg, sizeof(msg), + "allocfault: failing allocation ordinal %llu\n", + (unsigned long long)fail_at); + if (m > 0) (void)write(STDERR_FILENO, msg, (size_t)m); + } + return NULL; +} + +void *malloc(size_t size) { + init_once(); + pthread_mutex_lock(&lock); + ++alloc_count; + unsigned long long ordinal = alloc_count; + int fail = should_fail(); + if (ledger_fd >= 0) { + char buf[96]; + int n = snprintf(buf, sizeof(buf), "malloc %zu ordinal=%llu%s\n", size, ordinal, + fail ? " FAIL" : ""); + if (n > 0) ledger_write(buf, (size_t)n); + } + pthread_mutex_unlock(&lock); + if (fail) return fail_alloc(); + return real_malloc(size); +} + +void *calloc(size_t nmemb, size_t size) { + init_once(); + pthread_mutex_lock(&lock); + ++alloc_count; + unsigned long long ordinal = alloc_count; + int fail = should_fail(); + if (ledger_fd >= 0) { + char buf[112]; + int n = snprintf(buf, sizeof(buf), "calloc %zu*%zu ordinal=%llu%s\n", nmemb, size, + ordinal, fail ? " FAIL" : ""); + if (n > 0) ledger_write(buf, (size_t)n); + } + pthread_mutex_unlock(&lock); + if (fail) return fail_alloc(); + return real_calloc(nmemb, size); +} + +void *realloc(void *ptr, size_t size) { + init_once(); + pthread_mutex_lock(&lock); + ++alloc_count; + unsigned long long ordinal = alloc_count; + int fail = should_fail(); + if (ledger_fd >= 0) { + char buf[96]; + int n = snprintf(buf, sizeof(buf), "realloc %zu ordinal=%llu%s\n", size, ordinal, + fail ? " FAIL" : ""); + if (n > 0) ledger_write(buf, (size_t)n); + } + pthread_mutex_unlock(&lock); + if (fail) return fail_alloc(); + return real_realloc(ptr, size); +} + +void free(void *ptr) { + init_once(); + if (ledger_fd >= 0 && ptr != NULL) { + pthread_mutex_lock(&lock); + ledger_write("free\n", 5); + pthread_mutex_unlock(&lock); + } + real_free(ptr); +} + +unsigned long long allocfault_count(void) { + init_once(); + pthread_mutex_lock(&lock); + unsigned long long value = alloc_count; + pthread_mutex_unlock(&lock); + return value; +} + +void allocfault_reset(void) { + init_once(); + pthread_mutex_lock(&lock); + alloc_count = 0; + pthread_mutex_unlock(&lock); +} diff --git a/tools/allocfault/run.sh b/tools/allocfault/run.sh new file mode 100644 index 0000000..cf83c63 --- /dev/null +++ b/tools/allocfault/run.sh @@ -0,0 +1,307 @@ +#!/usr/bin/env bash +# Run allocation-failure injection across a corpus for C original and Zig ABI. +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +WORK="$ROOT/.local/allocfault" +CACHE="${CACHE:-$HOME/.cache/zig-tinyexpr}" +export PATH="$HOME/.local/zig:/opt/zig:$PATH" +EV="$ROOT/docs/evidence" +CORPUS="$WORK/corpus.txt" +ASAN="${ALLOCFAULT_ASAN:-0}" +FRAGMENT="$EV/fragments/allocfault.json" +LOG="$EV/allocfault.log" +if [[ "$ASAN" == "1" ]]; then + FRAGMENT="$EV/fragments/allocfault-asan.json" + LOG="$EV/allocfault-asan.log" +fi + +mkdir -p "$WORK" "$EV/fragments" "$ROOT/fuzz/logs" +exec > >(tee "$LOG") 2>&1 + +STARTED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +GIT_SHA="$(git -C "$ROOT" rev-parse HEAD)" +HOST="$(uname -a)" + +echo "=== allocfault metadata ===" +echo "started_at_utc=$STARTED_AT" +echo "git_sha=$GIT_SHA" +echo "host=$HOST" +echo "asan=$ASAN" + +# Build interposer (LD_PRELOAD for non-ASan) +cc -shared -fPIC -O2 -ldl -pthread \ + "$ROOT/tools/allocfault/interposer.c" -o "$WORK/liballocfault.so" +cc -O2 -c "$ROOT/tools/allocfault/alloc_shim.c" -o "$WORK/alloc_shim.o" +cc -O2 -c "$ROOT/tools/zig_probe_stub.c" -o "$WORK/zig_probe_stub.o" + +# Build C original driver +CFLAGS=(-O0 -g -I"$ROOT/third_party/tinyexpr-c") +SHIM_OBJS=() +TE_SRC="$ROOT/third_party/tinyexpr-c/tinyexpr.c" +if [[ "$ASAN" == "1" ]]; then + # Instrumented TU rewrites malloc at preprocessor level after system headers. + TE_SRC="$ROOT/tools/allocfault/tinyexpr_instrumented.c" + CFLAGS+=(-fsanitize=address,leak -fno-omit-frame-pointer) + LINKFLAGS=(-fsanitize=address,leak -ldl -pthread) + SHIM_OBJS=("$WORK/alloc_shim.o") + export ASAN_OPTIONS="${ASAN_OPTIONS:-detect_leaks=1:abort_on_error=0:halt_on_error=0:allocator_may_return_null=1}" + export LSAN_OPTIONS="${LSAN_OPTIONS:-allocator_may_return_null=1:exitcode=0}" +else + LINKFLAGS=(-ldl -pthread -lm) +fi +cc "${CFLAGS[@]}" -c "$TE_SRC" -o "$WORK/tinyexpr-c.o" +cc -O0 -g -I"$ROOT/third_party/tinyexpr-c" -c "$ROOT/tools/allocfault/driver.c" -o "$WORK/driver.o" +if [[ "$ASAN" == "1" ]]; then + cc -O0 -g -fsanitize=address,leak "$WORK/driver.o" "$WORK/tinyexpr-c.o" "${SHIM_OBJS[@]}" \ + -o "$WORK/driver-c" -fsanitize=address,leak -ldl -pthread -lm +else + cc -O0 -g "$WORK/driver.o" "$WORK/tinyexpr-c.o" -o "$WORK/driver-c" "${LINKFLAGS[@]}" -lm +fi + +# Build Zig library + driver. +(cd "$ROOT" && zig build -Doptimize=ReleaseFast -p "$WORK/zig-out" --cache-dir "$CACHE") +cc -O0 -g -I"$ROOT/third_party/tinyexpr-c" -c "$ROOT/tools/allocfault/driver.c" -o "$WORK/driver.o" +cc -O0 -g "$WORK/driver.o" "$WORK/zig-out/lib/libtinyexpr.a" "$WORK/zig_probe_stub.o" \ + -o "$WORK/driver-zig" -ldl -pthread -lm + +# Verify counter advances +if [[ "$ASAN" == "1" ]]; then + COUNT_JSON="$( + env -u LD_PRELOAD ALLOCFAULT_COUNT_ONLY=1 ALLOCFAULT_SILENT=1 \ + env -u ALLOCFAULT_FAIL_AT "$WORK/driver-c" "1+2*3" + )" +else + COUNT_JSON="$( + env LD_PRELOAD="$WORK/liballocfault.so" ALLOCFAULT_COUNT_ONLY=1 ALLOCFAULT_SILENT=1 \ + env -u ALLOCFAULT_FAIL_AT "$WORK/driver-c" "1+2*3" + )" +fi +echo "interposer_probe=$COUNT_JSON" +python3 -c 'import json,sys; j=json.loads(sys.argv[1].strip().splitlines()[-1]); assert j["allocs"]>0, j; print("interposer_ok allocs=", j["allocs"])' "$COUNT_JSON" + +# Corpus spanning shallow/deep, success/error, builtins +python3 - "$ROOT" "$CORPUS" <<'PY' +from pathlib import Path +import json, sys +root = Path(sys.argv[1]) +out = Path(sys.argv[2]) +exprs = [ + "1", + "1+2", + "1+2*3", + "(1+2)*3", + "sin(0)", + "fac(5)", + "ncr(10,3)", + "atan2(1,1)", + "((((1))))", + "1+(2+(3+(4+5)))", + "pi*e", + "abs(-3)+floor(2.7)", + "(", + "1+", + "sin(", + "unknown(1)", + "1,,2", + "((((((1+2)*3)/4)^2)%3)", +] +# Add fixture samples +for fixture in sorted((root / "tests/port/fixtures").glob("*.jsonl")): + for line in fixture.read_text(encoding="utf-8").splitlines()[:40]: + if not line: continue + expr = json.loads(line).get("expression") + if expr and len(expr) < 120: + exprs.append(expr) +# dedupe preserving order +seen=set(); uniq=[] +for e in exprs: + if e not in seen: + seen.add(e); uniq.append(e) +out.write_text("\n".join(uniq)+"\n", encoding="utf-8") +print(len(uniq)) +PY + +python3 - "$WORK" "$CORPUS" "$FRAGMENT" "$STARTED_AT" "$GIT_SHA" "$HOST" "$ASAN" <<'PY' +import json, os, subprocess, sys, time, signal +from pathlib import Path + +work, corpus, fragment, started, sha, host, asan = sys.argv[1:] +lib = str(Path(work) / "liballocfault.so") +drivers = { + "c": str(Path(work) / "driver-c"), + "zig": str(Path(work) / "driver-zig"), +} + +def run_one(driver, expr, fail_at=None, count_only=False, ledger=None): + env = os.environ.copy() + env.pop("LD_PRELOAD", None) + # C ASan build uses compile-time shim (no preload). Zig driver always needs preload. + use_preload = asan != "1" or Path(driver).name.endswith("zig") or "driver-zig" in driver + if asan == "1" and "driver-c" in driver: + use_preload = False + if use_preload: + env["LD_PRELOAD"] = lib + env["ALLOCFAULT_SILENT"] = "1" + env["ASAN_OPTIONS"] = "detect_leaks=1:abort_on_error=0:halt_on_error=0:allocator_may_return_null=1" + env["LSAN_OPTIONS"] = "allocator_may_return_null=1:exitcode=0" + if count_only: + env["ALLOCFAULT_COUNT_ONLY"] = "1" + env.pop("ALLOCFAULT_FAIL_AT", None) + else: + env.pop("ALLOCFAULT_COUNT_ONLY", None) + env["ALLOCFAULT_FAIL_AT"] = str(fail_at) + if ledger: + env["ALLOCFAULT_LOG"] = ledger + else: + env.pop("ALLOCFAULT_LOG", None) + try: + proc = subprocess.run( + [driver, expr], + env=env, + capture_output=True, + text=True, + timeout=5, + ) + signal_name = None + crashed = proc.returncode < 0 or proc.returncode >= 128 + if proc.returncode < 0: + signal_name = -proc.returncode + elif proc.returncode >= 128: + signal_name = proc.returncode - 128 + line = "" + for raw in reversed(proc.stdout.splitlines()): + raw = raw.strip() + if raw.startswith("{"): + line = raw + break + payload = json.loads(line) if line else {"ok": None, "parse_error": True} + payload["crashed"] = crashed + payload["signal"] = signal_name + payload["returncode"] = proc.returncode + payload["stderr_tail"] = proc.stderr[-200:] + return payload + except subprocess.TimeoutExpired: + return {"ok": None, "crashed": True, "signal": "timeout", "allocs": None} + +exprs = Path(corpus).read_text(encoding="utf-8").splitlines() +results = [] +total_ordinals = 0 +divergences = 0 +crashes_c = 0 +crashes_zig = 0 +# We cannot detect leaks without ASan; record asan mode. +for expr in exprs: + # Count allocations on C (reference N). Also measure Zig N. + c_count = run_one(drivers["c"], expr, count_only=True) + z_count = run_one(drivers["zig"], expr, count_only=True) + n_c = int(c_count.get("allocs") or 0) + n_z = int(z_count.get("allocs") or 0) + n = max(n_c, n_z) + if n == 0: + # Still exercise fail_at=1 to see behaviour with zero planned allocs. + n = 1 + entry = { + "expression": expr, + "allocs_c": n_c, + "allocs_zig": n_z, + "ordinals": [], + } + for ordinal in range(1, n + 1): + total_ordinals += 1 + c_res = run_one(drivers["c"], expr, fail_at=ordinal) + z_res = run_one(drivers["zig"], expr, fail_at=ordinal) + if c_res.get("crashed"): + crashes_c += 1 + if z_res.get("crashed"): + crashes_zig += 1 + diverge = ( + bool(c_res.get("ok")) != bool(z_res.get("ok")) + or c_res.get("error") != z_res.get("error") + or c_res.get("bits") != z_res.get("bits") + or bool(c_res.get("crashed")) != bool(z_res.get("crashed")) + ) + if diverge: + divergences += 1 + if diverge or c_res.get("crashed") or z_res.get("crashed") or ordinal <= 3 or ordinal == n: + entry["ordinals"].append({ + "n": ordinal, + "c": {k: c_res.get(k) for k in ("ok", "error", "bits", "crashed", "signal")}, + "zig": {k: z_res.get(k) for k in ("ok", "error", "bits", "crashed", "signal")}, + "diverge": diverge, + }) + results.append(entry) + print(f"expr={expr!r} n_c={n_c} n_z={n_z} sampled_divergences_so_far={divergences}") + +# Allocation ledger comparison on a fixed success input +ledger_c = str(Path(work) / "ledger-c.txt") +ledger_z = str(Path(work) / "ledger-zig.txt") +for path in (ledger_c, ledger_z): + Path(path).write_text("") +run_one(drivers["c"], "1+2*3", count_only=True, ledger=ledger_c) +run_one(drivers["zig"], "1+2*3", count_only=True, ledger=ledger_z) +ledger_c_lines = Path(ledger_c).read_text().splitlines() +ledger_z_lines = Path(ledger_z).read_text().splitlines() +ledger_identical = ledger_c_lines == ledger_z_lines + +completed = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) +out = { + "schema_version": 1, + "subject": "allocfault", + "command_line": "bash tools/allocfault/run.sh", + "git_sha": sha, + "host": host, + "started_at_utc": started, + "completed_at_utc": completed, + "asan": asan == "1", + "corpus_inputs": len(exprs), + "ordinals_tested": total_ordinals, + "behaviour_divergences": divergences, + "crashes_c": crashes_c, + "crashes_zig": crashes_zig, + "leaks_detected": "asan_required" if asan != "1" else "see_asan_log", + "ledger_input": "1+2*3", + "ledger_identical": ledger_identical, + "ledger_c_events": len(ledger_c_lines), + "ledger_zig_events": len(ledger_z_lines), + "ledger_claim": ( + "identical ordered malloc/free ledgers" + if ledger_identical + else "ledgers differ; equivalence claim limited to return value / error / crash at each ordinal" + ), + "track_g_allocator_misuse_criterion": "pending_summary", + "results": results, +} +# Fill criterion after scan +misuse = [] +for entry in results: + for ord_row in entry["ordinals"]: + if ord_row["c"].get("crashed"): + misuse.append({"side": "c", "expression": entry["expression"], "ordinal": ord_row["n"], "signal": ord_row["c"].get("signal")}) + if ord_row["zig"].get("crashed"): + misuse.append({"side": "zig", "expression": entry["expression"], "ordinal": ord_row["n"], "signal": ord_row["zig"].get("signal")}) +out["allocator_misuse_events"] = misuse +# Classify behaviour divergences (typically C error=-1 on OOM vs Zig offset) +oom_pos_div = 0 +for entry in results: + for ord_row in entry["ordinals"]: + if not ord_row.get("diverge"): + continue + c, z = ord_row["c"], ord_row["zig"] + if (not c.get("ok") and not z.get("ok") and c.get("error") == -1 and isinstance(z.get("error"), int) and z.get("error") > 0): + oom_pos_div += 1 +out["oom_error_position_divergences"] = oom_pos_div +out["behaviour_divergence_note"] = ( + f"{oom_pos_div}/{divergences} divergences are C error=-1 (te_compile NULL root / OOM) vs Zig positive error offset; " + "not crashes or success/failure flips" +) +out["track_g_allocator_misuse_criterion"] = ( + "satisfied" if any(m["side"] == "c" for m in misuse) else "not_satisfied_negative_result" +) +Path(fragment).write_text(json.dumps(out, indent=2) + "\n", encoding="utf-8") +print(json.dumps({k: out[k] for k in out if k != "results"}, indent=2)) +print(f"wrote {fragment}") +PY + +COMPLETED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +echo "completed_at_utc=$COMPLETED_AT" diff --git a/tools/allocfault/tinyexpr_instrumented.c b/tools/allocfault/tinyexpr_instrumented.c new file mode 100644 index 0000000..0b9484a --- /dev/null +++ b/tools/allocfault/tinyexpr_instrumented.c @@ -0,0 +1,19 @@ +/* Instrumented translation unit: system headers first, then malloc macros, then + * the pinned tinyexpr.c body (include guards skip duplicate headers). */ +#include +#include +#include +#include +#include + +void *allocfault_shim_malloc(size_t size); +void *allocfault_shim_calloc(size_t nmemb, size_t size); +void *allocfault_shim_realloc(void *ptr, size_t size); +void allocfault_shim_free(void *ptr); + +#define malloc(size) allocfault_shim_malloc(size) +#define calloc(n, s) allocfault_shim_calloc((n), (s)) +#define realloc(p, s) allocfault_shim_realloc((p), (s)) +#define free(p) allocfault_shim_free(p) + +#include "../../third_party/tinyexpr-c/tinyexpr.c" diff --git a/tools/allocfault/wrap.c b/tools/allocfault/wrap.c new file mode 100644 index 0000000..cd47d25 --- /dev/null +++ b/tools/allocfault/wrap.c @@ -0,0 +1,68 @@ +/* Link-time --wrap interposer for ASan builds (LD_PRELOAD fights ASan). + * Compile with: -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=realloc -Wl,--wrap=free + */ +#define _GNU_SOURCE +#include +#include +#include +#include + +extern void *__real_malloc(size_t); +extern void *__real_calloc(size_t, size_t); +extern void *__real_realloc(void *, size_t); +extern void __real_free(void *); + +static unsigned long long alloc_count = 0; +static unsigned long long fail_at = 0; +static int count_only = 0; +static int inited = 0; + +static void init(void) { + if (inited) return; + const char *fail = getenv("ALLOCFAULT_FAIL_AT"); + if (fail && fail[0]) fail_at = strtoull(fail, NULL, 10); + count_only = getenv("ALLOCFAULT_COUNT_ONLY") != NULL; + inited = 1; +} + +static int should_fail(void) { + init(); + if (count_only || fail_at == 0) return 0; + return alloc_count == fail_at; +} + +void *__wrap_malloc(size_t size) { + init(); + ++alloc_count; + if (should_fail()) { errno = ENOMEM; return NULL; } + return __real_malloc(size); +} + +void *__wrap_calloc(size_t nmemb, size_t size) { + init(); + ++alloc_count; + if (should_fail()) { errno = ENOMEM; return NULL; } + return __real_calloc(nmemb, size); +} + +void *__wrap_realloc(void *ptr, size_t size) { + init(); + ++alloc_count; + if (should_fail()) { errno = ENOMEM; return NULL; } + return __real_realloc(ptr, size); +} + +void __wrap_free(void *ptr) { + init(); + __real_free(ptr); +} + +unsigned long long allocfault_count(void) { + init(); + return alloc_count; +} + +void allocfault_reset(void) { + init(); + alloc_count = 0; +} diff --git a/tools/zig_probe_stub.c b/tools/zig_probe_stub.c new file mode 100644 index 0000000..385ba3a --- /dev/null +++ b/tools/zig_probe_stub.c @@ -0,0 +1,4 @@ +/* Provide when linking a Zig static library into a gcc-driven C main. + * Zig 0.16 emits calls to __zig_probe_stack under Debug/ReleaseSafe; gcc + * does not define it. Empty body is enough for smoke linking. */ +void __zig_probe_stack(void) {}