wcc/ww: reject non-constant array dimension (tinfofornode N_TARRAY)
arrayelen silently folded a non-const dimension to 0 — the 0-sized slot aliased its neighbor (review item: cs loud / ww rc=0 clobber). Mirror cstage check.c:715. Test rows land with the wave's final commit.
This commit is contained in:
@@ -12434,7 +12434,32 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
// Reverts A.4's r.size override (which conflated stride with
|
||||
// natural size); the slot-padded stride now lives in slotsize
|
||||
// where cgenutil's fast-path reads it.
|
||||
let elen: u64 = arrayelen(c, n.rhs); // #141: fold def-dim
|
||||
// #38/F2 (review item 2): a non-const, non-`[_]T` dimension is
|
||||
// LOUD here, mirroring cstage resolve_type N_TARRAY
|
||||
// (cmd/wcc/check.c:715 "array length must be an integer literal").
|
||||
// arrayelen folds 0 for both the `[_]T` sentinel AND a runtime
|
||||
// dim, so the size-walker reader (astsize, via arrayelen) can't
|
||||
// tell them apart; resolve the type HERE — the one resolve seam
|
||||
// cstage gates at — so c.errs trips before any 0-sized slot ships.
|
||||
// The fold is inlined (not via arrayelen) to error exactly once:
|
||||
// evaldefconst itself reports div-by-zero / unsupported-op, so a
|
||||
// guard that re-folds would double-report. arrayelen stays the
|
||||
// fold SSoT for astsize's later size() read.
|
||||
let elen: u64 = 0u64; // #141: fold def-dim
|
||||
if (n.rhs != nil) {
|
||||
if (n.rhs.kind == nkind.N_INTLIT) {
|
||||
elen = n.rhs.uval;
|
||||
} else {
|
||||
let v: u64 = 0u64;
|
||||
if (evaldefconst(c, n.rhs, &v, 0)) {
|
||||
elen = v;
|
||||
} else {
|
||||
cerr(n.file); cerr(": ");
|
||||
cerr("error: array length must be an integer literal\n");
|
||||
c.errs += 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
||||
if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; };
|
||||
|
||||
@@ -2014,7 +2014,32 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
// Reverts A.4's r.size override (which conflated stride with
|
||||
// natural size); the slot-padded stride now lives in slotsize
|
||||
// where cgenutil's fast-path reads it.
|
||||
let elen: u64 = arrayelen(c, n.rhs); // #141: fold def-dim
|
||||
// #38/F2 (review item 2): a non-const, non-`[_]T` dimension is
|
||||
// LOUD here, mirroring cstage resolve_type N_TARRAY
|
||||
// (cmd/wcc/check.c:715 "array length must be an integer literal").
|
||||
// arrayelen folds 0 for both the `[_]T` sentinel AND a runtime
|
||||
// dim, so the size-walker reader (astsize, via arrayelen) can't
|
||||
// tell them apart; resolve the type HERE — the one resolve seam
|
||||
// cstage gates at — so c.errs trips before any 0-sized slot ships.
|
||||
// The fold is inlined (not via arrayelen) to error exactly once:
|
||||
// evaldefconst itself reports div-by-zero / unsupported-op, so a
|
||||
// guard that re-folds would double-report. arrayelen stays the
|
||||
// fold SSoT for astsize's later size() read.
|
||||
let elen: u64 = 0u64; // #141: fold def-dim
|
||||
if (n.rhs != nil) {
|
||||
if (n.rhs.kind == nkind.N_INTLIT) {
|
||||
elen = n.rhs.uval;
|
||||
} else {
|
||||
let v: u64 = 0u64;
|
||||
if (evaldefconst(c, n.rhs, &v, 0)) {
|
||||
elen = v;
|
||||
} else {
|
||||
cerr(n.file); cerr(": ");
|
||||
cerr("error: array length must be an integer literal\n");
|
||||
c.errs += 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
||||
if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; };
|
||||
|
||||
@@ -12434,7 +12434,32 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
||||
// Reverts A.4's r.size override (which conflated stride with
|
||||
// natural size); the slot-padded stride now lives in slotsize
|
||||
// where cgenutil's fast-path reads it.
|
||||
let elen: u64 = arrayelen(c, n.rhs); // #141: fold def-dim
|
||||
// #38/F2 (review item 2): a non-const, non-`[_]T` dimension is
|
||||
// LOUD here, mirroring cstage resolve_type N_TARRAY
|
||||
// (cmd/wcc/check.c:715 "array length must be an integer literal").
|
||||
// arrayelen folds 0 for both the `[_]T` sentinel AND a runtime
|
||||
// dim, so the size-walker reader (astsize, via arrayelen) can't
|
||||
// tell them apart; resolve the type HERE — the one resolve seam
|
||||
// cstage gates at — so c.errs trips before any 0-sized slot ships.
|
||||
// The fold is inlined (not via arrayelen) to error exactly once:
|
||||
// evaldefconst itself reports div-by-zero / unsupported-op, so a
|
||||
// guard that re-folds would double-report. arrayelen stays the
|
||||
// fold SSoT for astsize's later size() read.
|
||||
let elen: u64 = 0u64; // #141: fold def-dim
|
||||
if (n.rhs != nil) {
|
||||
if (n.rhs.kind == nkind.N_INTLIT) {
|
||||
elen = n.rhs.uval;
|
||||
} else {
|
||||
let v: u64 = 0u64;
|
||||
if (evaldefconst(c, n.rhs, &v, 0)) {
|
||||
elen = v;
|
||||
} else {
|
||||
cerr(n.file); cerr(": ");
|
||||
cerr("error: array length must be an integer literal\n");
|
||||
c.errs += 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
||||
if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; };
|
||||
|
||||
Reference in New Issue
Block a user