From cf82bd340705ac814bcadaf7a67b4f4bb960fe36 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 19 Jul 2021 17:44:03 +0800 Subject: [PATCH] checker: fix fixed array with const unint type size (fix #10826) (#10853) --- vlib/v/checker/checker.v | 3 +- vlib/v/checker/comptime_const_eval.v | 28 ++++++++++++++++ vlib/v/checker/tests/fixed_array_size_err.out | 6 ++-- vlib/v/tests/fixed_array_const_size_test.v | 33 ++++++++++++++++++- 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 2c0013447d..48a25c9165 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4379,7 +4379,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) ast.Type { } } if fixed_size <= 0 { - c.error('fixed size cannot be zero or negative', init_expr.position()) + c.error('fixed size cannot be zero or negative (fixed_size: $fixed_size)', + init_expr.position()) } idx := c.table.find_or_register_array_fixed(array_init.elem_type, int(fixed_size), init_expr) diff --git a/vlib/v/checker/comptime_const_eval.v b/vlib/v/checker/comptime_const_eval.v index b44ca9ebb0..0d20d89dbc 100644 --- a/vlib/v/checker/comptime_const_eval.v +++ b/vlib/v/checker/comptime_const_eval.v @@ -55,6 +55,34 @@ fn eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.ComptTimeConstValue return none } } + } else if left is u64 && right is i64 { + match expr.op { + .plus { return i64(left) + i64(right) } + .minus { return i64(left) - i64(right) } + .mul { return i64(left) * i64(right) } + .div { return i64(left) / i64(right) } + .mod { return i64(left) % i64(right) } + .xor { return i64(left) ^ i64(right) } + .pipe { return i64(left) | i64(right) } + .amp { return i64(left) & i64(right) } + .left_shift { return i64(left) << i64(right) } + .right_shift { return i64(left) >> i64(right) } + else { return none } + } + } else if left is i64 && right is u64 { + match expr.op { + .plus { return i64(left) + i64(right) } + .minus { return i64(left) - i64(right) } + .mul { return i64(left) * i64(right) } + .div { return i64(left) / i64(right) } + .mod { return i64(left) % i64(right) } + .xor { return i64(left) ^ i64(right) } + .pipe { return i64(left) | i64(right) } + .amp { return i64(left) & i64(right) } + .left_shift { return i64(left) << i64(right) } + .right_shift { return i64(left) >> i64(right) } + else { return none } + } } else if left is u64 && right is u64 { match expr.op { .plus { return left + right } diff --git a/vlib/v/checker/tests/fixed_array_size_err.out b/vlib/v/checker/tests/fixed_array_size_err.out index 9af6b6c10f..8e3c9eaa4b 100644 --- a/vlib/v/checker/tests/fixed_array_size_err.out +++ b/vlib/v/checker/tests/fixed_array_size_err.out @@ -1,11 +1,11 @@ -vlib/v/checker/tests/fixed_array_size_err.vv:4:8: error: fixed size cannot be zero or negative - 2 | +vlib/v/checker/tests/fixed_array_size_err.vv:4:8: error: fixed size cannot be zero or negative (fixed_size: -1) + 2 | 3 | fn main() { 4 | a := [size]int{} | ~~~~ 5 | b := [0]byte{} 6 | println(a) -vlib/v/checker/tests/fixed_array_size_err.vv:5:8: error: fixed size cannot be zero or negative +vlib/v/checker/tests/fixed_array_size_err.vv:5:8: error: fixed size cannot be zero or negative (fixed_size: 0) 3 | fn main() { 4 | a := [size]int{} 5 | b := [0]byte{} diff --git a/vlib/v/tests/fixed_array_const_size_test.v b/vlib/v/tests/fixed_array_const_size_test.v index d13171fa99..36e16a7095 100644 --- a/vlib/v/tests/fixed_array_const_size_test.v +++ b/vlib/v/tests/fixed_array_const_size_test.v @@ -1,5 +1,6 @@ const ( - size = 5 + size = 5 + u64_size = u64(5) ) struct Foo { @@ -13,3 +14,33 @@ fn test_fixed_array_const_size() { bar: [byte(0), 0, 0, 0, 0]! } } + +fn test_fixed_array_const_u64_size() { + a := [2 * u64_size]f64{} + println(a) + assert '$a' == '[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]' +} + +const n = u64(5_000) + +const nn = 5_000 + +fn test_u64_const_used_as_fixed_array_size() { + mut a := [2 * n]f64{} + dump(a.len) + assert a.len == 10000 + + mut b := [n * 2]f64{} + dump(b.len) + assert b.len == 10000 +} + +fn test_int_const_used_as_fixed_array_size() { + mut aa := [2 * nn]f64{} + dump(aa.len) + assert aa.len == 10_000 + + mut bb := [nn * 2]f64{} + dump(bb.len) + assert aa.len == 10_000 +}