mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
check integer const overflow at compilation
This commit is contained in:
parent
69d2db0f1e
commit
3d4cd0bbc0
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user