Commit 9851a943ed
Changed files (3)
src
test
src/ir.cpp
@@ -7053,12 +7053,20 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction
ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
if (!val)
return ira->codegen->invalid_instruction;
- if (val->data.x_bignum.is_negative && wanted_type->id == TypeTableEntryIdInt &&
- !wanted_type->data.integral.is_signed)
- {
- ir_add_error(ira, source_instr,
- buf_sprintf("attempt to cast negative value to unsigned integer"));
- return ira->codegen->invalid_instruction;
+ if (wanted_type->id == TypeTableEntryIdInt) {
+ if (val->data.x_bignum.is_negative && !wanted_type->data.integral.is_signed) {
+ ir_add_error(ira, source_instr,
+ buf_sprintf("attempt to cast negative value to unsigned integer"));
+ return ira->codegen->invalid_instruction;
+ }
+ if (!bignum_fits_in_bits(&val->data.x_bignum, wanted_type->data.integral.bit_count,
+ wanted_type->data.integral.is_signed))
+ {
+ ir_add_error(ira, source_instr,
+ buf_sprintf("cast from '%s' to '%s' truncates bits",
+ buf_ptr(&target->value.type->name), buf_ptr(&wanted_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
}
IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
source_instr->source_node, wanted_type);
test/cases/eval.zig
@@ -314,3 +314,11 @@ const global_array = {
}
result
};
+
+test "compile-time downcast when the bits fit" {
+ comptime {
+ const spartan_count: u16 = 255;
+ const byte = u8(spartan_count);
+ assert(byte == 255);
+ }
+}
test/compile_errors.zig
@@ -1827,4 +1827,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
\\}
,
".tmp_source.zig:4:17: error: division by zero is undefined");
+
+ cases.add("compile-time integer cast truncates bits",
+ \\comptime {
+ \\ const spartan_count: u16 = 300;
+ \\ const byte = u8(spartan_count);
+ \\}
+ ,
+ ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");
}