checker: fix unknown fixed array size for const n = int(sizeof(u64)); _ = [n]int{} (fix #21544) (#21548)

This commit is contained in:
Swastik Baranwal 2024-05-23 22:21:46 +05:30 committed by GitHub
parent 0fe2d6052d
commit ef758a76dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 37 additions and 6 deletions

View file

@ -212,9 +212,9 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
if left_type == ast.int_type { if left_type == ast.int_type {
if mut right is ast.IntegerLiteral { if mut right is ast.IntegerLiteral {
mut is_large := right.val.len > 13 mut is_large := right.val.len > 13
if !is_large && right.val.len > 8 { if !is_large && right.val.len > 9 {
val := right.val.i64() val := right.val.i64()
is_large = val > int_max || val < int_min is_large = overflows_i32(val)
} }
if is_large { if is_large {
c.error('overflow in implicit type `int`, use explicit type casting instead', c.error('overflow in implicit type `int`, use explicit type casting instead',

View file

@ -15,8 +15,6 @@ import v.pkgconfig
import v.transformer import v.transformer
import v.comptime import v.comptime
const int_min = int(0x80000000)
const int_max = int(0x7FFFFFFF)
// prevent stack overflows by restricting too deep recursion: // prevent stack overflows by restricting too deep recursion:
const expr_level_cutoff_limit = 40 const expr_level_cutoff_limit = 40
const stmt_level_cutoff_limit = 40 const stmt_level_cutoff_limit = 40
@ -1792,9 +1790,9 @@ fn (mut c Checker) const_decl(mut node ast.ConstDecl) {
if field.typ == ast.int_type { if field.typ == ast.int_type {
if mut field.expr is ast.IntegerLiteral { if mut field.expr is ast.IntegerLiteral {
mut is_large := field.expr.val.len > 13 mut is_large := field.expr.val.len > 13
if !is_large && field.expr.val.len > 8 { if !is_large && field.expr.val.len > 9 {
val := field.expr.val.i64() val := field.expr.val.i64()
is_large = val > checker.int_max || val < checker.int_min is_large = overflows_i32(val)
} }
if is_large { if is_large {
c.error('overflow in implicit type `int`, use explicit type casting instead', c.error('overflow in implicit type `int`, use explicit type casting instead',

View file

@ -402,6 +402,9 @@ fn (mut c Checker) eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.Comp
if expr.typ == ast.i64_type { if expr.typ == ast.i64_type {
return cast_expr_value.i64() or { return none } return cast_expr_value.i64() or { return none }
} }
if expr.typ == ast.int_type {
return cast_expr_value.i64() or { return none }
}
// //
if expr.typ == ast.u8_type { if expr.typ == ast.u8_type {
return cast_expr_value.u8() or { return none } return cast_expr_value.u8() or { return none }
@ -1021,3 +1024,27 @@ fn (mut c Checker) pop_comptime_info() {
c.comptime.comptime_for_method = old.comptime_for_method c.comptime.comptime_for_method = old.comptime_for_method
c.comptime.comptime_for_method_ret_type = old.comptime_for_method_ret_type c.comptime.comptime_for_method_ret_type = old.comptime_for_method_ret_type
} }
fn overflows_i8(val i64) bool {
return val > max_i8 || val < min_i8
}
fn overflows_i16(val i64) bool {
return val > max_i16 || val < min_i16
}
fn overflows_i32(val i64) bool {
return val > max_i32 || val < min_i32
}
fn overflows_u8(val i64) bool {
return val > max_u8 || val < min_u8
}
fn overflows_u16(val i64) bool {
return val > max_u16 || val < min_u16
}
fn overflows_u32(val i64) bool {
return val > max_u32 || val < min_u32
}

View file

@ -2,6 +2,7 @@ const size = 5
const u64_size = u64(5) const u64_size = u64(5)
const int_size = int(1) const int_size = int(1)
const infix_cast_size = int(100 / 50) const infix_cast_size = int(100 / 50)
const int_sizeof_cast_size = ((1600 / 8) / int(sizeof(u64)))
struct Foo { struct Foo {
bar [size]u8 bar [size]u8
@ -105,3 +106,8 @@ fn test_infix_const_expr_used_as_fixed_array_size() {
println(mat6) println(mat6)
assert mat6.data.len == 6 assert mat6.data.len == 6
} }
fn test_int_sizeof_size() {
arr_fixed := [int_sizeof_cast_size]int{}
assert arr_fixed.len == 25
}