Commit f1c56f7f22

isaachier <isaachier@gmail.com>
2018-06-29 20:52:25
Clarify reason implicit cast does not work for large RHS (#1168)
* Clarify reason implicit cast does not work for large RHS
1 parent 0874a5b
Changed files (2)
src/ir.cpp
@@ -11432,6 +11432,26 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
     } else {
         TypeTableEntry *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen,
                 op1->value.type->data.integral.bit_count - 1);
+        if (bin_op_instruction->op_id == IrBinOpBitShiftLeftLossy &&
+            op2->value.type->id == TypeTableEntryIdComptimeInt) {
+            if (!bigint_fits_in_bits(&op2->value.data.x_bigint,
+                                     shift_amt_type->data.integral.bit_count,
+                                     op2->value.data.x_bigint.is_negative)) {
+                Buf *val_buf = buf_alloc();
+                bigint_append_buf(val_buf, &op2->value.data.x_bigint, 10);
+                ErrorMsg* msg = ir_add_error(ira,
+                    &bin_op_instruction->base,
+                    buf_sprintf("RHS of shift is too large for LHS type"));
+                add_error_note(
+                    ira->codegen,
+                    msg,
+                    op2->source_node,
+                    buf_sprintf("value %s cannot fit into type %s",
+                        buf_ptr(val_buf),
+                        buf_ptr(&shift_amt_type->name)));
+                return ira->codegen->builtin_types.entry_invalid;
+            }
+        }
 
         casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type);
         if (casted_op2 == ira->codegen->invalid_instruction)
test/compile_errors.zig
@@ -1677,6 +1677,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'",
     );
 
+    cases.add(
+        "invalid shift amount error",
+        \\const x : u8 = 2;
+        \\fn f() u16 {
+        \\    return x << 8;
+        \\}
+        \\export fn entry() u16 { return f(); }
+    ,
+        ".tmp_source.zig:3:14: error: RHS of shift is too large for LHS type",
+        ".tmp_source.zig:3:17: note: value 8 cannot fit into type u3",
+    );
+
     cases.add(
         "incompatible number literals",
         \\const x = 2 == 2.0;