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:
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user