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,16 +8406,13 @@ 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));
|
||||
ins2(c, A_MOVQ, areg(D_BX),
|
||||
masym(c, n->lhs->str));
|
||||
break;
|
||||
}
|
||||
cgexpr(c, n->rhs, locals);
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user