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:
@@ -7134,16 +7134,38 @@ export fn checkfile(c: *checker, file: *syntax.node) void = {
|
||||
let t: *syntax.node = file.list;
|
||||
for (t != nil) {
|
||||
if (t.kind == syntax.nkind.N_FNDECL) {
|
||||
let istest: bool = false;
|
||||
let ntestattr: i32 = 0;
|
||||
let at: *syntax.node = t.attr;
|
||||
for (at != nil) {
|
||||
if (at.kind == syntax.nkind.N_ATTR
|
||||
&& syntax.streq(at.str, "test")) {
|
||||
istest = true;
|
||||
ntestattr += 1;
|
||||
};
|
||||
at = at.next;
|
||||
};
|
||||
if (istest) {
|
||||
// Attribute-shape rejects, fixed order, first
|
||||
// failure wins per fn; wording byte-stable with
|
||||
// the cstage twin (check.c). A silently-dropped
|
||||
// shape here ships a test that never runs.
|
||||
if (ntestattr > 1) {
|
||||
cerr(t.file);
|
||||
cerr(": error: duplicate @test on fn '");
|
||||
cerr(t.str);
|
||||
cerr("'\n");
|
||||
c.errs += 1;
|
||||
} else { if (ntestattr == 1 && t.exported != 0) {
|
||||
cerr(t.file);
|
||||
cerr(": error: @test fn '");
|
||||
cerr(t.str);
|
||||
cerr("' cannot be exported\n");
|
||||
c.errs += 1;
|
||||
} else { if (ntestattr == 1 && t.body == nil) {
|
||||
cerr(t.file);
|
||||
cerr(": error: @test fn '");
|
||||
cerr(t.str);
|
||||
cerr("' needs a body\n");
|
||||
c.errs += 1;
|
||||
} else { if (ntestattr == 1) {
|
||||
// `fn f() void` parses the explicit void
|
||||
// into t.lhs, so void-returning is lhs==nil
|
||||
// OR an N_TNAME "void".
|
||||
@@ -7172,7 +7194,7 @@ export fn checkfile(c: *checker, file: *syntax.node) void = {
|
||||
rtail = row;
|
||||
ntest += 1i32;
|
||||
};
|
||||
};
|
||||
}; }; }; };
|
||||
};
|
||||
t = t.next;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user