aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-05-16 17:04:35 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-05-16 17:04:35 -0400
commit9851a943ed0360433c9612449ed065a6800adc51 (patch)
treedcf15bcb1dd31da8ba975dd2594d7a89f5ca46ae /src/ir.cpp
parentf37506391795353bbb87f49b73cf0f82ad9e2c17 (diff)
downloadzig-9851a943ed0360433c9612449ed065a6800adc51.tar.gz
zig-9851a943ed0360433c9612449ed065a6800adc51.zip
add compile error for compile-time integer cast truncating bits
closes #371
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index f506fa093b..53c3d1e241 100644
--- a/src/ir.cpp
+++ b/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);