From 3c53667db8d44777c2fbceaf3c6d3a22a6c9caad Mon Sep 17 00:00:00 2001 From: riverbl <94326797+riverbl@users.noreply.github.com> Date: Mon, 27 Dec 2021 22:52:56 +0000 Subject: [PATCH] stage2: fix bug where performing wrapping or saturating arithmetic or saturating left shift on type comptime_int executed unreachable code --- src/Sema.zig | 36 +++++++++++++++++++++++------------- src/value.zig | 12 ++++++++++++ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index ac67b3f07f..8cb38cc9f5 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -7474,7 +7474,10 @@ fn zirShl( } const val = switch (air_tag) { .shl_exact => return sema.fail(block, lhs_src, "TODO implement Sema for comptime shl_exact", .{}), - .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod.getTarget()), + .shl_sat => if (lhs_ty.zigTypeTag() == .ComptimeInt) + try lhs_val.shl(rhs_val, sema.arena) + else + try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod.getTarget()), .shl => try lhs_val.shl(rhs_val, sema.arena), else => unreachable, }; @@ -8189,10 +8192,12 @@ fn analyzeArithmetic( return casted_lhs; } if (maybe_lhs_val) |lhs_val| { - return sema.addConstant( - scalar_type, - try lhs_val.intAddSat(rhs_val, scalar_type, sema.arena, target), - ); + const val = if (scalar_tag == .ComptimeInt) + try lhs_val.intAdd(rhs_val, sema.arena) + else + try lhs_val.intAddSat(rhs_val, scalar_type, sema.arena, target); + + return sema.addConstant(scalar_type, val); } else break :rs .{ .src = lhs_src, .air_tag = .add_sat }; } else break :rs .{ .src = rhs_src, .air_tag = .add_sat }; }, @@ -8280,10 +8285,12 @@ fn analyzeArithmetic( return sema.addConstUndef(scalar_type); } if (maybe_rhs_val) |rhs_val| { - return sema.addConstant( - scalar_type, - try lhs_val.intSubSat(rhs_val, scalar_type, sema.arena, target), - ); + const val = if (scalar_tag == .ComptimeInt) + try lhs_val.intSub(rhs_val, sema.arena) + else + try lhs_val.intSubSat(rhs_val, scalar_type, sema.arena, target); + + return sema.addConstant(scalar_type, val); } else break :rs .{ .src = rhs_src, .air_tag = .sub_sat }; } else break :rs .{ .src = lhs_src, .air_tag = .sub_sat }; }, @@ -8663,10 +8670,13 @@ fn analyzeArithmetic( if (lhs_val.isUndef()) { return sema.addConstUndef(scalar_type); } - return sema.addConstant( - scalar_type, - try lhs_val.intMulSat(rhs_val, scalar_type, sema.arena, target), - ); + + const val = if (scalar_tag == .ComptimeInt) + try lhs_val.intMul(rhs_val, sema.arena) + else + try lhs_val.intMulSat(rhs_val, scalar_type, sema.arena, target); + + return sema.addConstant(scalar_type, val); } else break :rs .{ .src = lhs_src, .air_tag = .mul_sat }; } else break :rs .{ .src = rhs_src, .air_tag = .mul_sat }; }, diff --git a/src/value.zig b/src/value.zig index faf4f38e80..df1531533b 100644 --- a/src/value.zig +++ b/src/value.zig @@ -2275,6 +2275,10 @@ pub const Value = extern union { ) !Value { if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef); + if (ty.zigTypeTag() == .ComptimeInt) { + return intAdd(lhs, rhs, arena); + } + if (ty.isAnyFloat()) { return floatAdd(lhs, rhs, ty, arena); } @@ -2361,6 +2365,10 @@ pub const Value = extern union { ) !Value { if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef); + if (ty.zigTypeTag() == .ComptimeInt) { + return intSub(lhs, rhs, arena); + } + if (ty.isAnyFloat()) { return floatSub(lhs, rhs, ty, arena); } @@ -2440,6 +2448,10 @@ pub const Value = extern union { ) !Value { if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef); + if (ty.zigTypeTag() == .ComptimeInt) { + return intMul(lhs, rhs, arena); + } + if (ty.isAnyFloat()) { return floatMul(lhs, rhs, ty, arena); }