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
|
// Reverts A.4's r.size override (which conflated stride with
|
||||||
// natural size); the slot-padded stride now lives in slotsize
|
// natural size); the slot-padded stride now lives in slotsize
|
||||||
// where cgenutil's fast-path reads it.
|
// 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);
|
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||||
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
||||||
if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; };
|
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
|
// Reverts A.4's r.size override (which conflated stride with
|
||||||
// natural size); the slot-padded stride now lives in slotsize
|
// natural size); the slot-padded stride now lives in slotsize
|
||||||
// where cgenutil's fast-path reads it.
|
// 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);
|
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||||
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
||||||
if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; };
|
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
|
// Reverts A.4's r.size override (which conflated stride with
|
||||||
// natural size); the slot-padded stride now lives in slotsize
|
// natural size); the slot-padded stride now lives in slotsize
|
||||||
// where cgenutil's fast-path reads it.
|
// 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);
|
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||||
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
// #62/#69: `type a = [2]a` value cycle — loud, cstage twin.
|
||||||
if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; };
|
if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; };
|
||||||
|
|||||||
Reference in New Issue
Block a user