From 803178353976fe4ef343aef25dfa6d8e418ef88f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 8 Dec 2021 19:09:37 -0700 Subject: [PATCH] stage1: fix regression of shift by negative value error The previous commit (38b2d6209239f0dad7cb38e656d9d38506f126ca) regressed the compile error test case for when doing saturating shift left of a comptime-known negative RHS. This commit additionally fixes the error for regular shifts in addition to saturating shifts. --- src/stage1/ir.cpp | 32 ++++++++++++++++++++++++-------- test/compile_errors.zig | 6 +++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 5cec62bc80..34ff4a4f04 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -10121,6 +10121,30 @@ static Stage1AirInst *ir_analyze_bit_shift(IrAnalyze *ira, Stage1ZirInstBinOp *b if (op2_val == nullptr) return ira->codegen->invalid_inst_gen; + if (op2_val->type->id == ZigTypeIdVector) { + expand_undef_array(ira->codegen, op2_val); + size_t len = op2_val->type->data.vector.len; + for (size_t i = 0; i < len; i += 1) { + ZigValue *scalar_val = &op2_val->data.x_array.data.s_none.elements[i]; + if (scalar_val->data.x_bigint.is_negative) { + Buf *val_buf = buf_alloc(); + bigint_append_buf(val_buf, &scalar_val->data.x_bigint, 10); + ir_add_error(ira, casted_op2, + buf_sprintf("shift by negative value %s at vector index %zu", + buf_ptr(val_buf), i)); + return ira->codegen->invalid_inst_gen; + } + } + } else { + if (op2_val->data.x_bigint.is_negative) { + Buf *val_buf = buf_alloc(); + bigint_append_buf(val_buf, &op2_val->data.x_bigint, 10); + ir_add_error(ira, casted_op2, + buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); + return ira->codegen->invalid_inst_gen; + } + } + if (value_cmp_numeric_val_all(op2_val, CmpEQ, nullptr)) return ir_analyze_cast(ira, bin_op_instruction->base.scope, bin_op_instruction->base.source_node, op1->value->type, op1); } @@ -10515,14 +10539,6 @@ static Stage1AirInst *ir_analyze_bin_op_math(IrAnalyze *ira, Stage1ZirInstBinOp return ira->codegen->invalid_inst_gen; } } - } else if (op_id == IrBinOpShlSat) { - if (op2_val->data.x_bigint.is_negative) { - Buf *val_buf = buf_alloc(); - bigint_append_buf(val_buf, &op2_val->data.x_bigint, 10); - ir_add_error(ira, casted_op2, - buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); - return ira->codegen->invalid_inst_gen; - } } return ir_analyze_math_op(ira, instruction->base.scope, instruction->base.source_node, resolved_type, op1_val, op_id, op2_val); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 7df818a708..c3de643e12 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -8913,7 +8913,7 @@ pub fn addCases(ctx: *TestContext) !void { }); ctx.objErrStage1("saturating arithmetic does not allow floats", - \\pub fn main() !void { + \\export fn a() void { \\ _ = @as(f32, 1.0) +| @as(f32, 1.0); \\} , &[_][]const u8{ @@ -8921,7 +8921,7 @@ pub fn addCases(ctx: *TestContext) !void { }); ctx.objErrStage1("saturating shl does not allow negative rhs at comptime", - \\pub fn main() !void { + \\export fn a() void { \\ _ = @as(i32, 1) <<| @as(i32, -2); \\} , &[_][]const u8{ @@ -8929,7 +8929,7 @@ pub fn addCases(ctx: *TestContext) !void { }); ctx.objErrStage1("saturating shl assign does not allow negative rhs at comptime", - \\pub fn main() !void { + \\export fn a() void { \\ comptime { \\ var x = @as(i32, 1); \\ x <<|= @as(i32, -2);