wcc: modulo is integer-only; compound ops carry their operand class
Hare's rule (harec check.c binarithm): % and the bitwise/shift five are integer-only; + - * / need numeric operands. ww grouped % with the numeric ops, and compound assigns never op-checked at all, so `a % b` on floats compiled half-lowered (live cs!=ww divergence), `a %= 2.0` plain-stored the rhs (op silently dropped, both stages), and `s += "cd"` garbled str headers. Gate both at the checker, both stages; the cgen float-compound fallbacks and the three unknown- compound legacy defaults (deref/global/local) demote to rule-7 hard stops. 34 compound-on-tagged/str/slice fixtures re-pin from the old cgen "not wired" stops to the earlier checker diagnostics; 3 new reject fixtures pin the closed shapes.
This commit is contained in:
@@ -7041,25 +7041,20 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
case TK_SLASHEQ: fop = divop; break;
|
||||
default: break;
|
||||
}
|
||||
/* Non-SSE compound on a float lvalue is checker-
|
||||
* rejected (modulo/bitwise integer-only); a survivor
|
||||
* here means a checker gap — loud, never the old
|
||||
* plain-store of rhs that dropped the op. */
|
||||
if (fop < 0)
|
||||
fatal("float compound: op has no SSE "
|
||||
"lowering (rule 7)");
|
||||
if (off != 0) {
|
||||
if (fop < 0) {
|
||||
/* Unsupported compound (e.g., %= on float):
|
||||
* fall back to plain store of rhs. */
|
||||
ins2(c, mvop, areg(D_X0),
|
||||
amem(D_BP, off));
|
||||
break;
|
||||
}
|
||||
ins2(c, mvop, amem(D_BP, off), areg(D_X1));
|
||||
ins2(c, fop, areg(D_X0), areg(D_X1));
|
||||
ins2(c, mvop, areg(D_X1), amem(D_BP, off));
|
||||
} else {
|
||||
ins2(c, A_LEAQ, masym(c, n->lhs->str),
|
||||
areg(D_CX));
|
||||
if (fop < 0) {
|
||||
ins2(c, mvop, areg(D_X0),
|
||||
amem(D_CX, 0));
|
||||
break;
|
||||
}
|
||||
ins2(c, mvop, amem(D_CX, 0), areg(D_X1));
|
||||
ins2(c, fop, areg(D_X0), areg(D_X1));
|
||||
ins2(c, mvop, areg(D_X1), amem(D_CX, 0));
|
||||
@@ -7921,10 +7916,12 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* unknown compound: legacy fallback —
|
||||
* store rhs only. */
|
||||
ins2(c, A_MOVQ, areg(D_CX), areg(D_AX));
|
||||
break;
|
||||
/* all 10 compound tokens enumerated
|
||||
* above — an 11th means a parser/
|
||||
* checker gap, never a plain store
|
||||
* of rhs (rule 7). */
|
||||
fatal("deref compound: unknown "
|
||||
"compound op (rule 7)");
|
||||
}
|
||||
ins2(c, store_op, areg(D_AX), amem(D_BX, 0));
|
||||
break;
|
||||
@@ -8364,7 +8361,6 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
ins2(c, glop, amem(D_CX, 0),
|
||||
areg(D_BX));
|
||||
}
|
||||
int did_compound = 1;
|
||||
switch (n->op) {
|
||||
case TK_PLUSEQ: ins2(c, A_ADDQ, areg(D_AX), areg(D_BX)); break;
|
||||
case TK_MINUSEQ: ins2(c, A_SUBQ, areg(D_AX), areg(D_BX)); break;
|
||||
@@ -8410,14 +8406,11 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* unknown compound: legacy fallback —
|
||||
* store rhs only. */
|
||||
did_compound = 0;
|
||||
ins2(c, A_MOVQ, areg(D_AX),
|
||||
masym(c, n->lhs->str));
|
||||
break;
|
||||
/* all 10 compound tokens enumerated
|
||||
* above (rule 7). */
|
||||
fatal("global compound: unknown "
|
||||
"compound op (rule 7)");
|
||||
}
|
||||
if (did_compound)
|
||||
ins2(c, A_MOVQ, areg(D_BX),
|
||||
masym(c, n->lhs->str));
|
||||
break;
|
||||
@@ -8490,12 +8483,12 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* unknown: just store rhs (legacy fallback) */
|
||||
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, off));
|
||||
goto skip_assign_store;
|
||||
/* all 10 compound tokens enumerated above
|
||||
* (rule 7). */
|
||||
fatal("local compound: unknown compound op "
|
||||
"(rule 7)");
|
||||
}
|
||||
ins2(c, A_MOVQ, areg(D_BX), amem(D_BP, off));
|
||||
skip_assign_store: ;
|
||||
}
|
||||
/* C1 residual (task #22): a non-DOT lvalue no arm above
|
||||
* matched still falls out SILENT here — the known member is
|
||||
|
||||
@@ -1282,6 +1282,11 @@ cbinop(Checker *c, Node *n)
|
||||
return ty_i64;
|
||||
if (!type_isnum(l) || !type_isnum(r))
|
||||
return err(c, n->pos, "arithmetic on non-numeric type");
|
||||
/* % is integer-only (harec check.c binarithm BIN_MODULO):
|
||||
* floats have no SSE modulo lowering, so an admitted float %
|
||||
* fell through cgen half-lowered (cs!=ww divergence). */
|
||||
if (n->op == TK_PERCENT && (!type_isint(l) || !type_isint(r)))
|
||||
return err(c, n->pos, "modulo on non-integer type");
|
||||
return unify_arith(c, n->pos, l, r);
|
||||
case TK_AMP: case TK_PIPE: case TK_CARET: case TK_LSHIFT:
|
||||
case TK_RSHIFT:
|
||||
@@ -2016,6 +2021,32 @@ cexpr(Checker *c, Node *n)
|
||||
!assignable_addrfn(c, l, n->rhs))
|
||||
err(c, n->pos, "cannot assign %s to %s",
|
||||
type_name(c->a, r), type_name(c->a, l));
|
||||
/* Compound ops carry their binary op's operand class (harec
|
||||
* check.c binarithm): += -= *= /= need numeric operands,
|
||||
* %= modulo-integer, the bitwise/shift five integer. The
|
||||
* assignability check above cannot see the op, so `f %= x`
|
||||
* and `s += "x"` passed and cgen's fallback plain-stored the
|
||||
* rhs, silently dropping the operation. */
|
||||
if (n->op != TK_ASSIGN && l != ty_err && r != ty_err) {
|
||||
switch (n->op) {
|
||||
case TK_PLUSEQ: case TK_MINUSEQ: case TK_STAREQ:
|
||||
case TK_SLASHEQ:
|
||||
if (!type_isnum(l) || !type_isnum(r))
|
||||
err(c, n->pos, "arithmetic on "
|
||||
"non-numeric type");
|
||||
break;
|
||||
case TK_PERCENTEQ:
|
||||
if (!type_isint(l) || !type_isint(r))
|
||||
err(c, n->pos, "modulo on "
|
||||
"non-integer type");
|
||||
break;
|
||||
default:
|
||||
if (!type_isint(l) || !type_isint(r))
|
||||
err(c, n->pos, "bitwise on "
|
||||
"non-integer type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* #120: `w = 1.0` narrows the rhs literal to the lvalue's f32. */
|
||||
coerce_floatlit(n->rhs, l);
|
||||
/* #258: `s = arr` borrows the array as a full slice.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package wwfixture;
|
||||
|
||||
def protocolversion: i32 = 1;
|
||||
def corpuscount: i32 = 1746;
|
||||
def errorcount: i32 = 346;
|
||||
def corpuscount: i32 = 1749;
|
||||
def errorcount: i32 = 349;
|
||||
def compilecount: i32 = 21;
|
||||
def runcount: i32 = 209;
|
||||
def runexitcount: i32 = 1170;
|
||||
def nativecount: i32 = 3492;
|
||||
def corpushash: str = "6afbab274e0c6d1479a2f0cb6e575b14f5e4ffd25a9cb8a3701307db97d3c489";
|
||||
def nativecount: i32 = 3498;
|
||||
def corpushash: str = "616b3e7f4fca31cb99409c58a29ac73623c997967ddd57651a1370c2c2e2be6a";
|
||||
|
||||
type directive = enum i32 {
|
||||
ERROR = 0,
|
||||
|
||||
@@ -9322,6 +9322,15 @@ fn cgassign(c: *cgen, n: *syntax.node) void = {
|
||||
else { combineop = "SARQ"; };
|
||||
};
|
||||
}; }; }; }; }; }; };
|
||||
// all 10 compound tokens enumerated above
|
||||
// (/= %= returned earlier) — a MOVQ
|
||||
// combineop is the old rhs-plain-store
|
||||
// legacy fallback. Rule 7.
|
||||
if (syntax.streq(combineop, "MOVQ")) {
|
||||
let mdc: str = "deref compound: unknown compound op (rule 7)\n";
|
||||
os.write(2, mdc.ptr, mdc.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
emitline("\t");
|
||||
emitline(combineop);
|
||||
emitline("\tCX, AX\n");
|
||||
@@ -12555,12 +12564,14 @@ fn cgassign(c: *cgen, n: *syntax.node) void = {
|
||||
if (n.op == syntax.tkind.TK_STAREQ) { fop = mulf; };
|
||||
if (n.op == syntax.tkind.TK_SLASHEQ) { fop = divf; };
|
||||
if (fop.len == 0) {
|
||||
// Unsupported (e.g., %= on float):
|
||||
// fall back to plain store of rhs.
|
||||
emitline("\t");
|
||||
emitline(mov);
|
||||
emitline("\tX0, (CX)\n");
|
||||
return;
|
||||
// Non-SSE compound on a float lvalue is
|
||||
// checker-rejected (modulo/bitwise
|
||||
// integer-only); a survivor here means a
|
||||
// checker gap — loud, never the old
|
||||
// plain-store of rhs that dropped the op.
|
||||
let mfc: str = "float compound: op has no SSE lowering (rule 7)\n";
|
||||
os.write(2, mfc.ptr, mfc.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
emitline("\t");
|
||||
emitline(mov);
|
||||
@@ -12722,7 +12733,6 @@ fn cgassign(c: *cgen, n: *syntax.node) void = {
|
||||
emitline(glop);
|
||||
emitline("\t(CX), BX\n");
|
||||
};
|
||||
let didcompound: bool = true;
|
||||
if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); }
|
||||
else { if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); }
|
||||
else { if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); }
|
||||
@@ -12778,19 +12788,15 @@ fn cgassign(c: *cgen, n: *syntax.node) void = {
|
||||
};
|
||||
}
|
||||
else {
|
||||
// Unsupported compound: store rhs
|
||||
// directly. Mirrors the local path's
|
||||
// legacy fallback for unknown ops.
|
||||
didcompound = false;
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitsymname(c, nm);
|
||||
emitline("(SB)\n");
|
||||
// all 10 compound tokens enumerated
|
||||
// above (rule 7).
|
||||
let mgc: str = "global compound: unknown compound op (rule 7)\n";
|
||||
os.write(2, mgc.ptr, mgc.len: u64);
|
||||
os.exit(1);
|
||||
};};};};};};};};};
|
||||
if (didcompound) {
|
||||
emitline("\tMOVQ\tBX, ");
|
||||
emitsymname(c, nm);
|
||||
emitline("(SB)\n");
|
||||
};
|
||||
return;
|
||||
};
|
||||
// #10 Fold B: over-cap tuple reassign `t = f();`. t's
|
||||
@@ -12978,12 +12984,14 @@ fn cgassign(c: *cgen, n: *syntax.node) void = {
|
||||
if (n.op == syntax.tkind.TK_STAREQ) { fop = mulf; };
|
||||
if (n.op == syntax.tkind.TK_SLASHEQ) { fop = divf; };
|
||||
if (fop.len == 0) {
|
||||
emitline("\t");
|
||||
emitline(mov);
|
||||
emitline("\tX0, ");
|
||||
emitoff(off: i64);
|
||||
emitline("(BP)\n");
|
||||
return;
|
||||
// Non-SSE compound on a float lvalue is
|
||||
// checker-rejected (modulo/bitwise
|
||||
// integer-only); a survivor here means a
|
||||
// checker gap — loud, never the old
|
||||
// plain-store of rhs that dropped the op.
|
||||
let mfc: str = "float compound: op has no SSE lowering (rule 7)\n";
|
||||
os.write(2, mfc.ptr, mfc.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
emitline("\t");
|
||||
emitline(mov);
|
||||
@@ -13156,6 +13164,18 @@ fn cgassign(c: *cgen, n: *syntax.node) void = {
|
||||
emitline("\tMOVQ\tDX, BX\n");
|
||||
};
|
||||
};
|
||||
// all 10 compound tokens enumerated above — an 11th
|
||||
// stored the untouched loaded value back (silent
|
||||
// no-op). Rule 7.
|
||||
if (n.op != syntax.tkind.TK_PLUSEQ && n.op != syntax.tkind.TK_MINUSEQ
|
||||
&& n.op != syntax.tkind.TK_STAREQ && n.op != syntax.tkind.TK_AMPEQ
|
||||
&& n.op != syntax.tkind.TK_PIPEEQ && n.op != syntax.tkind.TK_CARETEQ
|
||||
&& n.op != syntax.tkind.TK_LSHIFTEQ && n.op != syntax.tkind.TK_RSHIFTEQ
|
||||
&& n.op != syntax.tkind.TK_SLASHEQ && n.op != syntax.tkind.TK_PERCENTEQ) {
|
||||
let mlc: str = "local compound: unknown compound op (rule 7)\n";
|
||||
os.write(2, mlc.ptr, mlc.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
emitline("\tMOVQ\tBX, ");
|
||||
emitoff(off: i64);
|
||||
emitline("(BP)\n");
|
||||
|
||||
@@ -3069,6 +3069,15 @@ fn binoptype(c: *checker, e: *syntax.node) *syntax.node = {
|
||||
(rtn != nil && !numkindast(c, rtn))) {
|
||||
deffolderr(c, e, "arithmetic on non-numeric type");
|
||||
};
|
||||
// % is integer-only (harec check.c binarithm BIN_MODULO):
|
||||
// floats have no SSE modulo lowering, so an admitted float %
|
||||
// fell through cgen half-lowered (cs!=ww divergence).
|
||||
if (op == syntax.tkind.TK_PERCENT) {
|
||||
if ((ltn != nil && !intkindast(c, ltn)) ||
|
||||
(rtn != nil && !intkindast(c, rtn))) {
|
||||
deffolderr(c, e, "modulo on non-integer type");
|
||||
};
|
||||
};
|
||||
return unifyarith(c, e, ltn, rtn);
|
||||
};
|
||||
if (op == syntax.tkind.TK_AMP || op == syntax.tkind.TK_PIPE ||
|
||||
@@ -6137,6 +6146,34 @@ fn checkassign(c: *checker, n: *syntax.node) void = {
|
||||
};
|
||||
let ltn: *syntax.node = exprtype(c, n.lhs, nil);
|
||||
let rtn: *syntax.node = exprtype(c, n.rhs, nil);
|
||||
// Compound ops carry their binary op's operand class (harec
|
||||
// check.c binarithm): += -= *= /= need numeric operands,
|
||||
// %= modulo-integer, the bitwise/shift five integer. Without
|
||||
// this `f %= x` and `s += "x"` passed and cgen's fallback
|
||||
// plain-stored the rhs, silently dropping the operation.
|
||||
// Mirror cstage cmd/wcc/check.c N_ASSIGN compound gate.
|
||||
if (n.op != syntax.tkind.TK_ASSIGN) {
|
||||
if (n.op == syntax.tkind.TK_PLUSEQ || n.op == syntax.tkind.TK_MINUSEQ ||
|
||||
n.op == syntax.tkind.TK_STAREQ || n.op == syntax.tkind.TK_SLASHEQ) {
|
||||
if ((ltn != nil && !numkindast(c, ltn)) ||
|
||||
(rtn != nil && !numkindast(c, rtn))) {
|
||||
cerr("error: arithmetic on non-numeric type\n");
|
||||
c.errs += 1;
|
||||
};
|
||||
} else { if (n.op == syntax.tkind.TK_PERCENTEQ) {
|
||||
if ((ltn != nil && !intkindast(c, ltn)) ||
|
||||
(rtn != nil && !intkindast(c, rtn))) {
|
||||
cerr("error: modulo on non-integer type\n");
|
||||
c.errs += 1;
|
||||
};
|
||||
} else {
|
||||
if ((ltn != nil && !intkindast(c, ltn)) ||
|
||||
(rtn != nil && !intkindast(c, rtn))) {
|
||||
cerr("error: bitwise on non-integer type\n");
|
||||
c.errs += 1;
|
||||
};
|
||||
}; };
|
||||
};
|
||||
// #120: `w = 1.0` narrows the rhs literal to the lvalue's f32. Mirror
|
||||
// cstage cmd/wcc/check.c N_ASSIGN coerce_floatlit.
|
||||
coercefloatlit(c, n.rhs, ltn);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "single-dot field compound on slice field"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
// Lifted from test/wcc/949_dotfield_compound_run.c reject row "dotfld_he_slice"
|
||||
// (#34/rule-7): a compound assign on a single-dot SLICE field is unwired in
|
||||
// both stages and MUST loud-fail. The substring is the shared diagnostic body
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "single-dot field compound on str field"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
// Lifted from test/wcc/949_dotfield_compound_run.c reject row "dotfld_he_str"
|
||||
// (#34/rule-7): a compound assign on a single-dot STR field is unwired in both
|
||||
// stages and MUST loud-fail. The substring is the shared diagnostic body —
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "single-dot field compound on tagged field"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
// Lifted from test/wcc/949_dotfield_compound_run.c reject row "dotfld_he_tagged"
|
||||
// (#34/rule-7): a compound assign on a single-dot TAGGED-union field is unwired
|
||||
// in both stages and MUST loud-fail. The substring is the shared diagnostic
|
||||
|
||||
11
test/wcc/data/float_mod_reject/case.ww
Normal file
11
test/wcc/data/float_mod_reject/case.ww
Normal file
@@ -0,0 +1,11 @@
|
||||
//ww:error "modulo on non-integer type"
|
||||
// % is integer-only (harec check.c binarithm BIN_MODULO). Pre-gate a
|
||||
// float % half-lowered through cgen as a live cs!=ww divergence.
|
||||
package main;
|
||||
export fn main() i32 = {
|
||||
let a: f64 = 7.0;
|
||||
let b: f64 = 2.0;
|
||||
let m: f64 = a % b;
|
||||
if (m == 1.0) { return 1; };
|
||||
return 0;
|
||||
};
|
||||
12
test/wcc/data/float_modeq_reject/case.ww
Normal file
12
test/wcc/data/float_modeq_reject/case.ww
Normal file
@@ -0,0 +1,12 @@
|
||||
//ww:error "modulo on non-integer type"
|
||||
// Compound ops carry their binary op's operand class: %= on a float
|
||||
// lvalue plain-stored the rhs pre-gate (`a %= 2.0` became `a = 2.0`,
|
||||
// silently, both stages).
|
||||
package main;
|
||||
let g: f64 = 9.0;
|
||||
export fn main() i32 = {
|
||||
let a: f64 = 7.0;
|
||||
a %= 2.0;
|
||||
g %= 2.0;
|
||||
return 0;
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "indexed-lvalue compound on str element not wired (#133/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
// Lifted from test/wcc/948_idx_compound_run.c reject row "he_str_indexed"
|
||||
// (#133-expanded rule-7): a compound assign on an indexed STR element is
|
||||
// unwired in both stages and MUST loud-fail. The substring is the FULL shared
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "arr[i].field compound on slice field"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
// Lifted from test/wcc/949_idxfield_compound_run.c reject row "fld_he_slice"
|
||||
// (#33/rule-7): a compound assign on an indexed-element SLICE field is unwired
|
||||
// in both stages and MUST loud-fail. The substring is the shared diagnostic
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "arr[i].field compound on str field"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
// Lifted from test/wcc/949_idxfield_compound_run.c reject row "fld_he_str"
|
||||
// (#33/rule-7): a compound assign on an indexed-element STR field is unwired in
|
||||
// both stages and MUST loud-fail. The substring is the shared diagnostic body
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "arr[i].field compound on tagged field"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
// Lifted from test/wcc/949_idxfield_compound_run.c reject row "fld_he_tagged"
|
||||
// (#33/rule-7): a compound assign on an indexed-element TAGGED-union field is
|
||||
// unwired in both stages and MUST loud-fail. The substring is the shared
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: compound on aggregate field not wired (rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
type capture = struct { content: str, start: size, end: size };
|
||||
type t = struct { pc: size, cap: capture };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: compound on str/slice field not wired (rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
type t = struct { pc: size, name: str };
|
||||
fn addname(ts: *[]t, i: size) void = { (*ts)[i].name += "x"; };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "modulo on non-integer type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "assign-resolver: tagged field not wired (rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let v: (int | bool) = 7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "ident compound on tagged not wired (#21/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
let g: (int | bool) = 7;
|
||||
export fn main() int = { g += 1; return 0; };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "indexed-lvalue compound on tagged element not wired (#133/rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
let gs: [3](int | bool) = [1, 2, 3];
|
||||
export fn main() int = { gs[0] ^= 1; return 0; };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "indexed-lvalue compound on tagged element not wired (#133/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
let gs: [3](int | bool) = [1, 2, 3];
|
||||
export fn main() int = { gs[0] += 1; return 0; };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "indexed-lvalue compound on tagged element not wired (#133/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
let gs: [3](int | bool) = [1, 2, 3];
|
||||
export fn main() int = { gs[0] *= 1; return 0; };
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//ww:error "ident compound on tagged not wired (#21/rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = { let g: (int | bool) = 7; g ^= 1; return 0; };
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//ww:error "ident compound on tagged not wired (#21/rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = { let g: (int | bool) = 7; g <<= 1; return 0; };
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//ww:error "ident compound on tagged not wired (#21/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = { let g: (int | bool) = 7; g -= 1; return 0; };
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//ww:error "ident compound on tagged not wired (#21/rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = { let g: (int | bool) = 7; g |= 1; return 0; };
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//ww:error "ident compound on tagged not wired (#21/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = { let g: (int | bool) = 7; g += 1; return 0; };
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//ww:error "ident compound on tagged not wired (#21/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = { let g: (int | bool) = 7; g /= 1; return 0; };
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//ww:error "ident compound on tagged not wired (#21/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = { let g: (int | bool) = 7; g *= 1; return 0; };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "indexed-lvalue compound on tagged element not wired (#133/rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let a: [3](int | bool) = [1, 2, 3];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "indexed-lvalue compound on tagged element not wired (#133/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let a: [3](int | bool) = [1, 2, 3];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "indexed-lvalue compound on tagged element not wired (#133/rule-7)"
|
||||
//ww:error "bitwise on non-integer type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let a: [3](int | bool) = [1, 2, 3];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//ww:error "indexed-lvalue compound on tagged element not wired (#133/rule-7)"
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
package main;
|
||||
export fn main() int = {
|
||||
let a: [3](int | bool) = [1, 2, 3];
|
||||
|
||||
9
test/wcc/data/str_pluseq_reject/case.ww
Normal file
9
test/wcc/data/str_pluseq_reject/case.ww
Normal file
@@ -0,0 +1,9 @@
|
||||
//ww:error "arithmetic on non-numeric type"
|
||||
// += needs numeric operands; `s += "cd"` passed the op-blind
|
||||
// assignability check and cgen garbled the header words silently.
|
||||
package main;
|
||||
export fn main() i32 = {
|
||||
let s: str = "ab";
|
||||
s += "cd";
|
||||
return 0;
|
||||
};
|
||||
Reference in New Issue
Block a user