check: gate C-style ... to bodiless decls, both stages (#11)
A bodied fn with a bare C-style `...` was silently accepted by cstage and SEGFAULTED wwstage (resolvefnbody walked a typeless `...` param). Gate it: bare C-`...` is allowed only on bodiless decls (extern / @symbol prototypes), the real FFI path; Hare-style `T...` is unaffected. ww restricts C-`...` to bodiless decls pending vastart/vaarg/vaend builtins (#16); harec permits bodied C-variadic fns (check.c:3656) -- a documented divergence, reopened when #16 lands. Test 852 runs both stages; its reject rows require the gate's diagnostic (not merely a nonzero exit), so a crash can't pass them vacuously.
This commit is contained in:
@@ -6306,6 +6306,20 @@ fn checktryprop(c: *checker, n: *syntax.node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// hascvariadic — true iff the param list ends in a bare C-style `...`
|
||||
// (the param whose str=="...", set by the parser; Hare-style `T...`
|
||||
// carries a name + op==TK_ELLIPSIS instead). Mirrors cstage
|
||||
// build_fn_type's `p->str && strcmp(p->str,"...")==0` test
|
||||
// (check.c:2646).
|
||||
fn hascvariadic(params: *syntax.node) bool = {
|
||||
let p: *syntax.node = params;
|
||||
for (p != nil) {
|
||||
if (syntax.streq(p.str, "...")) { return true; };
|
||||
p = p.next;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
// install_param — when entering a fn body, define its params in a
|
||||
// fresh local scope.
|
||||
//
|
||||
@@ -6781,6 +6795,17 @@ export fn checkfile(c: *checker, file: *syntax.node) void = {
|
||||
let k: syntax.nkind = d.kind;
|
||||
switch (k) {
|
||||
case syntax.nkind.N_FNDECL:
|
||||
// ww restricts C-style ... to bodiless decls pending
|
||||
// vastart/vaarg/vaend builtins (#16); harec permits bodied
|
||||
// C-variadic fns (check.c:3656). The bare C-style param is
|
||||
// the one with str=="..." (Hare-style `T...` carries a name
|
||||
// + op==TK_ELLIPSIS instead), mirroring cstage build_fn_type
|
||||
// check.c:2646.
|
||||
if (d.body != nil && hascvariadic(d.list)) {
|
||||
cerr(d.file);
|
||||
cerr(": error: C-style variadic '...' requires a bodiless declaration\n");
|
||||
c.errs += 1;
|
||||
};
|
||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type
|
||||
resolvefnbody(c, d);
|
||||
case syntax.nkind.N_DEF:
|
||||
|
||||
Reference in New Issue
Block a user