diff --git a/src/aro/Parser.zig b/src/aro/Parser.zig index ebaa3182..50ee6dff 100644 --- a/src/aro/Parser.zig +++ b/src/aro/Parser.zig @@ -6445,9 +6445,11 @@ fn addExpr(p: *Parser) Error!Result { const lhs_ty = lhs.ty; if (try lhs.adjustTypes(minus.?, &rhs, p, if (plus != null) .add else .sub)) { if (plus != null) { - if (try lhs.val.add(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(plus.?, lhs); + if (try lhs.val.add(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(plus.?, lhs); } else { - if (try lhs.val.sub(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(minus.?, lhs); + if (try lhs.val.sub(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(minus.?, lhs); } } if (lhs.ty.specifier != .invalid and lhs_ty.isPtr() and !lhs_ty.isVoidStar() and lhs_ty.elemType().hasIncompleteSize()) { @@ -6484,9 +6486,11 @@ fn mulExpr(p: *Parser) Error!Result { if (try lhs.adjustTypes(percent.?, &rhs, p, if (tag == .mod_expr) .integer else .arithmetic)) { if (mul != null) { - if (try lhs.val.mul(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(mul.?, lhs); + if (try lhs.val.mul(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(mul.?, lhs); } else if (div != null) { - if (try lhs.val.div(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(mul.?, lhs); + if (try lhs.val.div(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(mul.?, lhs); } else { var res = try Value.rem(lhs.val, rhs.val, lhs.ty, p.comp); if (res.opt_ref == .none) { diff --git a/test/cases/arithmetic overflow.c b/test/cases/arithmetic overflow.c new file mode 100644 index 00000000..b763b18e --- /dev/null +++ b/test/cases/arithmetic overflow.c @@ -0,0 +1,6 @@ +_Static_assert(0xFFFFFFFF + 1 == 0, "'"); +_Static_assert(1 + 0xFFFFFFFF == 0, "'"); +_Static_assert(0 - 0x00000001 == 0xFFFFFFFF, "'"); +_Static_assert(0x00000000 - 0x00000001 == 0xFFFFFFFF, "'"); +_Static_assert(0x80000000 * 2 == 0, "'"); +_Static_assert(2 * 0x80000000 == 0, "'");