diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-05-16 17:04:35 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-05-16 17:04:35 -0400 |
| commit | 9851a943ed0360433c9612449ed065a6800adc51 (patch) | |
| tree | dcf15bcb1dd31da8ba975dd2594d7a89f5ca46ae /src/ir.cpp | |
| parent | f37506391795353bbb87f49b73cf0f82ad9e2c17 (diff) | |
| download | zig-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.cpp | 20 |
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); |
