add compile error for compile-time integer cast truncating bits
closes #371
This commit is contained in:
parent
f375063917
commit
9851a943ed
20
src/ir.cpp
20
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);
|
ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
|
||||||
if (!val)
|
if (!val)
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
if (val->data.x_bignum.is_negative && wanted_type->id == TypeTableEntryIdInt &&
|
if (wanted_type->id == TypeTableEntryIdInt) {
|
||||||
!wanted_type->data.integral.is_signed)
|
if (val->data.x_bignum.is_negative && !wanted_type->data.integral.is_signed) {
|
||||||
{
|
ir_add_error(ira, source_instr,
|
||||||
ir_add_error(ira, source_instr,
|
buf_sprintf("attempt to cast negative value to unsigned integer"));
|
||||||
buf_sprintf("attempt to cast negative value to unsigned integer"));
|
return ira->codegen->invalid_instruction;
|
||||||
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,
|
IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
|
||||||
source_instr->source_node, wanted_type);
|
source_instr->source_node, wanted_type);
|
||||||
|
@ -314,3 +314,11 @@ const global_array = {
|
|||||||
}
|
}
|
||||||
result
|
result
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test "compile-time downcast when the bits fit" {
|
||||||
|
comptime {
|
||||||
|
const spartan_count: u16 = 255;
|
||||||
|
const byte = u8(spartan_count);
|
||||||
|
assert(byte == 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1827,4 +1827,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
|
|||||||
\\}
|
\\}
|
||||||
,
|
,
|
||||||
".tmp_source.zig:4:17: error: division by zero is undefined");
|
".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");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user