aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/llvm.cff10
-rw-r--r--src/parse.cff10
-rw-r--r--test/2.cff2
3 files changed, 14 insertions, 8 deletions
diff --git a/src/llvm.cff b/src/llvm.cff
index e8c7dad..0ce97c8 100644
--- a/src/llvm.cff
+++ b/src/llvm.cff
@@ -555,7 +555,7 @@ fn genexpr(f *Fn, ex *Expr) Value {
let lhs0 = genload(f, ref);
let tmp = gentmp(ex.ty, "%s %t %v, %v", inst, ex.ty, lhs0, rhs);
genstore(f, ref, tmp);
- tmp;
+ genload(f, ref); // load again because value could have overflowed when storing it
)
]
switch b.op {
@@ -588,7 +588,7 @@ fn genexpr(f *Fn, ex *Expr) Value {
let ref = genref(f, b.lhs);
let rhs = convert(f, b.lhs.ty, b.rhs);
genstore(f, ref, rhs);
- return rhs;
+ return genload(f, ref); // load again because value could have overflowed when storing it
case '+=';
let ref = genref(f, b.lhs);
@@ -596,7 +596,7 @@ fn genexpr(f *Fn, ex *Expr) Value {
let lhs0 = genload(f, ref);
let tmp = genadd(ex.ty, lhs0, rhs);
genstore(f, ref, tmp);
- return tmp;
+ return genload(f, ref); // load again because value could have overflowed when storing it
case '-=';
let ref = genref(f, b.lhs);
@@ -604,7 +604,7 @@ fn genexpr(f *Fn, ex *Expr) Value {
let lhs0 = genload(f, ref);
let tmp = gensub(ex.ty, lhs0, rhs);
genstore(f, ref, tmp);
- return tmp;
+ return genload(f, ref); // load again because value could have overflowed when storing it
case '*=';
return genassignop(ex.ty->is(:Flo) ? "fdiv" : "mul", ex.ty, b.lhs, b.rhs);
@@ -715,7 +715,7 @@ fn genexpr(f *Fn, ex *Expr) Value {
gen("\t%v = add %t %v, %v\n", val, ex.ty, var, one);
}
genstore(f, ref, val);
- return val;
+ return genload(f, ref); // load again because value could have overflowed when storing it
case :postinc, :postdec;
let one = Value{ex.ty, :IImm(un.op == :postinc ? 1 : -1)};
diff --git a/src/parse.cff b/src/parse.cff
index b978f4b..ea965d6 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -2134,8 +2134,14 @@ fn pexassign(P *Parser) Expr {
case (typeof2(ex.ty, rhs.ty) == #null)
and !((ex.ty->is(:Ptr) and rhs.ty->is(:Int)
and (tok.t == '+=' or tok.t == '-=')));
- err(P, ex.loc,
- "operands %t and %t to assignment operator %qT have incompatible types",
+ err(P, tok.loc, "invalid operands %t and %t for assignment operator %qT",
+ ex.ty, rhs.ty, tok);
+ case okind == :IntFlo and (!isnumtype(ex.ty) or !isnumtype(rhs.ty));
+ err(P, tok.loc, "invalid operands %t and %t for assignment operator %qT",
+ ex.ty, rhs.ty, tok);
+
+ case okind == :Int and (!ex.ty->is(:Int) or !rhs.ty->is(:Int));
+ err(P, tok.loc, "invalid operands %t and %t for assignment operator %qT",
ex.ty, rhs.ty, tok);
case ex.ty.konst;
err(P, ex.loc, "left operand to assignment is const");
diff --git a/test/2.cff b/test/2.cff
index a677d16..04560ca 100644
--- a/test/2.cff
+++ b/test/2.cff
@@ -15,5 +15,5 @@ extern fn main() int {
foo.flag = #t;
foo.num = -2;
foo.num *= 10;
- printf("0x%X: %d, %d, %d\n", foo.#raw, foo.tag, foo.flag, foo.num);
+ printf("0x%X: %d, %d, %d\n", foo.#raw, foo.tag, foo.flag, foo.num += 532);
}