diff --git a/Makefile b/Makefile index 2e672ba5..f4b3f4ba 100644 --- a/Makefile +++ b/Makefile @@ -577,7 +577,7 @@ test-lang-byteid: $(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww # .s and their both-stage reject parity is owned by the fixture corpus. DATABYTEID_DIR = $(OUT)/databyteid DATABYTEID_FILES = $(wildcard test/wcc/data/*/case.ww) -DATABYTEID_EXPECTED_MIN = 911 +DATABYTEID_EXPECTED_MIN = 915 # Known cs!=ww divergences (loud over blind, the 989_lib_byteid DIVERGE # discipline): each entry must still build on both stages AND still differ. # When a compiler fix lands the entry fails demanding graduation out of diff --git a/docs/test-system-v2.md b/docs/test-system-v2.md index ee880221..d5efd18b 100644 --- a/docs/test-system-v2.md +++ b/docs/test-system-v2.md @@ -32,9 +32,9 @@ categories out of the ordinary developer target. | Fixed point and self-host | `test-bootstrap` | | Host linker/platform behavior | `test-platform` | -The live declarative compiler corpus has 1,225 fixtures and 2,450 C/WW cells: +The live declarative compiler corpus has 1,229 fixtures and 2,458 C/WW cells: 314 expected rejections (290 shared and 24 stage-specific), 12 compile-only -successes, 136 exit-zero programs, and 763 explicit-exit programs. +successes, 137 exit-zero programs, and 766 explicit-exit programs. 174 native C carriers remain. They are partitioned exactly once as five in-process units, 27 byte/artifact gates, six bootstrap gates, one platform @@ -196,7 +196,7 @@ parity is owned by the fixture corpus itself. Known cs/ww divergences are pinned in `DATABYTEID_DIVERGED` with the `989_lib_byteid` discipline: a pinned fixture must still build on both stages and still differ, so a compiler fix fails the gate demanding graduation rather than silently -widening coverage. The full sweep compares 911 fixtures in about a minute +widening coverage. The full sweep compares 915 fixtures in about a minute and is scratch-rooted under `out/`, not `/tmp`. Byte identity is an explicit proof gate. It is not a prerequisite of `test` or diff --git a/internal/wwfixture/types.ww b/internal/wwfixture/types.ww index 6ef3fbdd..1b2b39b7 100644 --- a/internal/wwfixture/types.ww +++ b/internal/wwfixture/types.ww @@ -1,13 +1,13 @@ package wwfixture; def protocolversion: i32 = 1; -def corpuscount: i32 = 1225; +def corpuscount: i32 = 1229; def errorcount: i32 = 314; def compilecount: i32 = 12; -def runcount: i32 = 136; -def runexitcount: i32 = 763; -def nativecount: i32 = 2450; -def corpushash: str = "a2e47b2967d51a517d39598caf69c2d23618ba488594a0b7e33fded27cc62f93"; +def runcount: i32 = 137; +def runexitcount: i32 = 766; +def nativecount: i32 = 2458; +def corpushash: str = "9d1db4b4bdde1b7e2b1f2e2ae5ca6c6b91b0162df585fd877021d27ec6863d89"; type directive = enum i32 { ERROR = 0, diff --git a/test/wcc/data/r660_i16_deref_store_adjacent/case.ww b/test/wcc/data/r660_i16_deref_store_adjacent/case.ww new file mode 100644 index 00000000..17eef4d7 --- /dev/null +++ b/test/wcc/data/r660_i16_deref_store_adjacent/case.ww @@ -0,0 +1,9 @@ +//ww:run-exit 42 +package main; +fn setneg(p: *i16) void = { *p = -16i64: i16; }; +fn main() i32 = { + let a: [4]i16 = [7i16, 7i16, 7i16, 7i16]; + setneg(&a[0]); + if (a[0]: i64 == -16i64 && a[1] == 7i16 && a[2] == 7i16 && a[3] == 7i16) { return 42; }; + return 1; +}; diff --git a/test/wcc/data/r71_tagged_widen_natural_size/case.ww b/test/wcc/data/r71_tagged_widen_natural_size/case.ww new file mode 100644 index 00000000..a7324a1c --- /dev/null +++ b/test/wcc/data/r71_tagged_widen_natural_size/case.ww @@ -0,0 +1,27 @@ +//ww:run-exit 100 +package main; +type small = struct { v: i32 }; +fn consume(r: (void | small)) i32 = { + match (r) { + case void => return 1; + case let v: small => { + let p: *i64 = (&v): *i64; + let w: i64 = *p; + if (w == 7i64) { return 100; }; + return 50; + }; + }; + return 0; +}; +fn dirty() void = { + let x: i64 = -1i64; +}; +fn probe() i32 = { + let s: small; + s.v = 7; + return consume(s); +}; +fn main() i32 = { + dirty(); + return probe(); +}; diff --git a/test/wcc/data/r76_typeeq_fn_second_variant/case.ww b/test/wcc/data/r76_typeeq_fn_second_variant/case.ww new file mode 100644 index 00000000..2ab6572c --- /dev/null +++ b/test/wcc/data/r76_typeeq_fn_second_variant/case.ww @@ -0,0 +1,13 @@ +//ww:run-exit 7 +package main; +fn a(x: i32) void = { }; +fn b(x: i32, y: i64) void = { }; +type t = (*fn(x: i32) void | *fn(x: i32, y: i64) void); +export fn main() i32 = { + let v: t = &b; + match (v) { + case *fn(x: i32) void => return 3; + case *fn(x: i32, y: i64) void => return 7; + }; + return -1; +}; diff --git a/test/wcc/data/r989_libclear_dotfield_borrow/case.ww b/test/wcc/data/r989_libclear_dotfield_borrow/case.ww new file mode 100644 index 00000000..76161dbc --- /dev/null +++ b/test/wcc/data/r989_libclear_dotfield_borrow/case.ww @@ -0,0 +1,36 @@ +//ww:run +// probe: after io.close flushes the encoder, encode_closer calls +// clear(e) = bytes.zero(e.ibuf); bytes.zero(e.obuf). Under a correct +// build, ibuf/obuf are all zero afterwards. Under the wwstage +// miscompile the zeroing slice has len 0 -> stale bytes survive. +package main; +import encoding.base64; +import io; +import memio; +export fn main() int = { + let out: memio.stream = memio.dynamic(); + let e: base64.encoder = base64.newencoder(&base64.std_encoding, &out.vt); + let raw: [5]u8 = ['f', 'o', 'o', 'b', 'a']; + match (io.write(&e.vt, raw)) { + case let n: size => void; + case let er: io.error => return 2; + }; + match (io.close(&e.vt)) { + case void => void; + case let er: io.error => return 3; + }; + // 5 = 3+2: the trailing 2-byte group went through the closer's + // pad path, so both ibuf and obuf held nonzero bytes before + // clear(). All must now read zero. + let i: i32 = 0; + for (i < 3) { + if (e.ibuf[i] != 0u8) { return (10 + i): int; }; + i += 1; + }; + i = 0; + for (i < 4) { + if (e.obuf[i] != 0u8) { return (20 + i): int; }; + i += 1; + }; + return 0; +};