check: reject duplicate struct field name in wwstage (catB-7/14)

The wwstage checker silently accepted a struct with repeated field names; cstage already rejects it (cmd/wcc/check.c:925-947). Add validatestructfields, dispatched once per struct decl from resolvewalk's eager type-decl arm (check.ww:792, sibling to the N_TENUM stampenumvals fire): a pure read-only O(n^2) named-field dup walk that emits "duplicate field 'X'" via cerr + c.errs, with no mutation -- valid-program codegen is unchanged so cstage==wwstage byte-id holds. Named fields only; ww has no struct embedding, so cstage's embed-collision arm is intentionally not ported (separate parser gap, catB-89).

Test: new table-driven both-stage reject test 849_dupfield_reject (adjacent / non-adjacent / different-type dup rows + a distinct-field control that builds and runs). Full make test: 451 green incl. 990-997 byte-id.
This commit is contained in:
2026-06-19 14:41:57 +09:00
parent e9f64a0727
commit c024c09bc6
3 changed files with 229 additions and 0 deletions

View File

@@ -247,6 +247,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_tuple_trailing_comma_reject \
$(BIN)/test_voidless_return_reject \
$(BIN)/test_const_reassign_reject \
$(BIN)/test_dupfield_reject \
$(BIN)/test_size_untyped_int \
$(BIN)/test_tagged_staticinit \
$(BIN)/test_arr_infer_len \
@@ -1542,6 +1543,12 @@ $(BIN)/test_const_reassign_reject: test/wcc/847_const_reassign_reject.c $(BIN)/w
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
$(BIN)/test_dupfield_reject: test/wcc/849_dupfield_reject.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_tagged_staticinit: test/wcc/843_tagged_staticinit.c $(BIN)/ww \
$(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \