check integer const overflow at compilation

pull/1082/head
Alexander Medvednikov 2019-07-10 16:05:39 +02:00
parent 69d2db0f1e
commit 3d4cd0bbc0
4 changed files with 45 additions and 2 deletions

View File

@ -1994,6 +1994,9 @@ fn (p mut Parser) factor() string {
typ = 'f32'
// typ = 'f64' // TODO
}
if p.expected_type != '' && !is_valid_int_const(p.lit, p.expected_type) {
p.error('constant `$p.lit` overflows `$p.expected_type`')
}
p.gen(p.lit)
p.fgen(p.lit)
case Token.minus:
@ -2252,7 +2255,7 @@ fn (p mut Parser) string_expr() {
// '$age'! means the user wants this to be a tmp string (uses global buffer, no allocation,
// won't be used again)
if p.tok == .not {
p.next()
p.check(.not)
p.gen('_STR_TMP($format$args)')
}
else {
@ -2550,7 +2553,9 @@ fn (p mut Parser) cast(typ string) string {
p.next()
}
p.check(.lpar)
p.expected_type = typ
expr_typ := p.bool_expression()
p.expected_type = ''
p.check(.rpar)
// `string(buffer)` => `tos2(buffer)`
if typ == 'string' && (expr_typ == 'byte*' || expr_typ == 'byteptr') {
@ -2562,7 +2567,6 @@ fn (p mut Parser) cast(typ string) string {
}
else {
p.cgen.set_placeholder(pos, '($typ)(')
// p.fgen(typ)
}
p.gen(')')
return typ

View File

@ -4,6 +4,8 @@
module main
import math
struct Table {
mut:
types []Type
@ -637,3 +639,21 @@ fn (table &Table) cgen_name_type_pair(name, typ string) string {
return '$typ $name'
}
fn is_valid_int_const(val, typ string) bool {
x := val.int()
switch typ {
case 'byte', 'u8': return 0 <= x && x <= math.MaxU8
case 'u16': return 0 <= x && x <= math.MaxU16
case 'u32': return 0 <= x && x <= math.MaxU32
//case 'u64': return 0 <= x && x <= math.MaxU64
//////////////
case 'i8': return math.MinI8 <= x && x <= math.MaxI8
case 'i16': return math.MinI16 <= x && x <= math.MaxI16
case 'int', 'i32': return math.MinI32 <= x && x <= math.MaxI32
//case 'i64':
//x64 := val.i64()
//return i64(-(1<<63)) <= x64 && x64 <= i64((1<<63)-1)
}
return true
}

View File

@ -133,6 +133,10 @@ pub fn (s string) int() int {
return C.atoi(s.str)
}
pub fn (s string) i64() i64 {
return C.atoll(s.str)
}
pub fn (s string) f32() f32 {
return C.atof(s.str)
}

View File

@ -22,6 +22,21 @@ const (
Log10E = 1.0 / Ln10
)
const (
MaxI8 = (1<<7) - 1
MinI8 = -1 << 7
MaxI16 = (1<<15) - 1
MinI16 = -1 << 15
MaxI32 = (1<<31) - 1
MinI32 = -1 << 31
// MaxI64 = ((1<<63) - 1)
// MinI64 = (-(1 << 63) )
MaxU8 = (1<<8) - 1
MaxU16 = (1<<16) - 1
MaxU32 = (1<<32) - 1
MaxU64 = (1<<64) - 1
)
// Returns the absolute value.
pub fn abs(a f64) f64 {
if a < 0 {