wcc: reject exported/bodyless/duplicate @test shapes

Both frontends, byte-stable fragments; -T-mode checks, so the rows
live in test/package (the fixture compile cell cannot reach -T).
This commit is contained in:
2026-08-08 14:19:50 +09:00
parent ff7bf08d81
commit 5ba410ff60
3 changed files with 95 additions and 10 deletions

View File

@@ -3230,14 +3230,31 @@ check_file(Checker *c, Node *file)
for (Node *d = file->list; d; d = d->next) {
if (d->kind != N_FNDECL)
continue;
int istest = 0;
int ntestattr = 0;
for (Node *at = d->attr; at; at = at->next)
if (at->str && strcmp(at->str, "test") == 0) {
istest = 1;
break;
}
if (!istest)
if (at->str && strcmp(at->str, "test") == 0)
ntestattr++;
if (ntestattr == 0)
continue;
/* Attribute-shape rejects, fixed order, first failure
* wins per fn; wording is byte-stable with the wwstage
* twin (check.ww). A silently-dropped shape here ships
* a test that never runs. */
if (ntestattr > 1) {
err(c, d->pos, "duplicate @test on fn '%s'",
d->str);
continue;
}
if (d->export) {
err(c, d->pos, "@test fn '%s' cannot be exported",
d->str);
continue;
}
if (d->body == NULL) {
err(c, d->pos, "@test fn '%s' needs a body",
d->str);
continue;
}
/* `fn f() void` parses the explicit `void` into d->lhs
* (parse.c:1329), so void-returning is lhs==NULL OR an
* N_TNAME "void" — not lhs==NULL alone. */