w6c+wcc/check: infer [_]T array length from initializer element count (fix #7)
`[_]T = [...]` (canonical Hare array-length inference) silently miscompiled to a zero-length array: the parser already left the array type's length child nil as the infer sentinel — distinct from an explicit [N] — but neither checker stamped the real count, so `len(x)` returned 0 with no diagnostic (rule-7 silent miscompile). Module-level was worse on wwstage, where `x.len` on ANY global array (even an explicit [N]) fell to the SB fallback and mis-emitted `MOVQ len(SB), AX` (linker: undefined reference to len). The length lives in the stamped TYPE and cgen already keys stride / length / data-emission off it, so stamping the inferred count at the one checker inference point closes it permanently (rob's #7 ruling): - check.c clet + module-level N_LET pass-2: count the initializer's elements and patch the array type's length (the Sym too, so a later x.len reads the inferred alen). No-init / non-array init can't infer -> loud error, never a silent zero-length array. - check.ww inferarraylen: the wwstage twin — stamp a synthesized N_INTLIT length child before resolvewalk caches the array tinfo; same loud-error rule. Idempotent for the module-level double-call. - cgenexpr.ww cgdot: the missing wwstage arm for a top-level [N]T global's .len / .ptr (cstage cgen.c:8011 already had it). - cgenutil.ww letslotsize: drop the now-redundant [_] slot-size intercept — a workaround for this very bug; the stamped length flows through the general slotsize path (rule 7). Both stages converge byte-identical; new table-driven test 684 covers [_]int/[_]str/[_]u8 local + module-level, len + element read-back, dual-stage runtime + asm byte-id, plus three negative no-infer rows.
This commit is contained in:
7
Makefile
7
Makefile
@@ -241,6 +241,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_arr_elem_field_write \
|
||||
$(BIN)/test_arr_enum_elem \
|
||||
$(BIN)/test_arr_strslice_elem \
|
||||
$(BIN)/test_arr_infer_len \
|
||||
$(BIN)/test_dot_str_chained_arg \
|
||||
$(BIN)/test_dot_slice_arg \
|
||||
$(BIN)/test_dot_tagged_source \
|
||||
@@ -561,6 +562,12 @@ $(BIN)/test_arr_strslice_elem: test/wcc/683_arr_strslice_elem.c $(BIN)/ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_arr_infer_len: test/wcc/684_arr_infer_len.c $(BIN)/ww \
|
||||
$(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_dot_str_chained_arg: test/wcc/692_dot_str_chained_arg.c $(BIN)/ww \
|
||||
$(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
|
||||
Reference in New Issue
Block a user