From 29b3077ea138e5c9b1dd55099213a6b930b5b507 Mon Sep 17 00:00:00 2001 From: zakuro Date: Thu, 21 Jan 2021 20:27:16 +0900 Subject: [PATCH] checker: make negative literal index a checker error (#8242) --- vlib/v/checker/checker.v | 16 ++++-- vlib/v/checker/tests/index_expr.out | 86 +++++++++++++++++++---------- vlib/v/checker/tests/index_expr.vv | 8 ++- 3 files changed, 75 insertions(+), 35 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 51de44c72a..b27352aebf 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4804,7 +4804,7 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) table.Type { return right_type } -fn (mut c Checker) check_index_type(typ_sym &table.TypeSymbol, index_type table.Type, pos token.Position) { +fn (mut c Checker) check_index(typ_sym &table.TypeSymbol, index ast.Expr, index_type table.Type, pos token.Position) { index_type_sym := c.table.get_type_symbol(index_type) // println('index expr left=$typ_sym.name $node.pos.line_nr') // if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) && @@ -4818,6 +4818,14 @@ fn (mut c Checker) check_index_type(typ_sym &table.TypeSymbol, index_type table. } c.error('$type_str', pos) } + if index is ast.PrefixExpr { + if index.op == .minus && index.right is ast.IntegerLiteral { + val := (index.right as ast.IntegerLiteral).val + if val.int() > 0 { + c.error('invalid index `-$val` (index must be non-negative)', index.pos) + } + } + } if index_type.has_flag(.optional) { type_str := if typ_sym.kind in [.string, .ustring] { '(type `$typ_sym.name`)' @@ -4859,11 +4867,11 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { if mut node.index is ast.RangeExpr { // [1..2] if node.index.has_low { index_type := c.expr(node.index.low) - c.check_index_type(typ_sym, index_type, node.pos) + c.check_index(typ_sym, node.index.low, index_type, node.pos) } if node.index.has_high { index_type := c.expr(node.index.high) - c.check_index_type(typ_sym, index_type, node.pos) + c.check_index(typ_sym, node.index.high, index_type, node.pos) } // array[1..2] => array // fixed_array[1..2] => array @@ -4883,7 +4891,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { c.error('invalid key: $err', node.pos) } } else { - c.check_index_type(typ_sym, index_type, node.pos) + c.check_index(typ_sym, node.index, index_type, node.pos) } value_type := c.table.value_type(typ) if value_type != table.void_type { diff --git a/vlib/v/checker/tests/index_expr.out b/vlib/v/checker/tests/index_expr.out index e799440fbf..7a28dc8c00 100644 --- a/vlib/v/checker/tests/index_expr.out +++ b/vlib/v/checker/tests/index_expr.out @@ -1,41 +1,69 @@ -vlib/v/checker/tests/index_expr.vv:3:7: error: type `int` does not support indexing +vlib/v/checker/tests/index_expr.vv:3:7: error: type `int` does not support indexing 1 | fn test_invalid_index() { 2 | v := 4 3 | _ = v[0] | ~~~ - 4 | + 4 | 5 | a := [2] -vlib/v/checker/tests/index_expr.vv:6:7: error: non-integer index `[]int` (array type `[]int`) - 4 | +vlib/v/checker/tests/index_expr.vv:6:7: error: non-integer index `[]int` (array type `[]int`) + 4 | 5 | a := [2] 6 | _ = a[a] | ~~~ - 7 | } - 8 | -vlib/v/checker/tests/index_expr.vv:11:7: error: type `int` does not support indexing - 9 | fn test_invalid_slice() { - 10 | v := 4 - 11 | _ = v[1..] + 7 | _ = a[-1] + 8 | } +vlib/v/checker/tests/index_expr.vv:7:8: error: invalid index `-1` (index must be non-negative) + 5 | a := [2] + 6 | _ = a[a] + 7 | _ = a[-1] + | ^ + 8 | } + 9 | +vlib/v/checker/tests/index_expr.vv:12:7: error: type `int` does not support indexing + 10 | fn test_invalid_slice() { + 11 | v := 4 + 12 | _ = v[1..] | ~~~~~ - 12 | _ = v[..1] - 13 | -vlib/v/checker/tests/index_expr.vv:12:7: error: type `int` does not support indexing - 10 | v := 4 - 11 | _ = v[1..] - 12 | _ = v[..1] + 13 | _ = v[..1] + 14 | +vlib/v/checker/tests/index_expr.vv:13:7: error: type `int` does not support indexing + 11 | v := 4 + 12 | _ = v[1..] + 13 | _ = v[..1] | ~~~~~ - 13 | - 14 | a := [2] -vlib/v/checker/tests/index_expr.vv:15:7: error: non-integer index `[]int` (array type `[]int`) - 13 | - 14 | a := [2] - 15 | _ = a[a..] + 14 | + 15 | a := [2] +vlib/v/checker/tests/index_expr.vv:16:7: error: non-integer index `[]int` (array type `[]int`) + 14 | + 15 | a := [2] + 16 | _ = a[a..] | ~~~~~ - 16 | _ = a[..a] - 17 | } -vlib/v/checker/tests/index_expr.vv:16:7: error: non-integer index `[]int` (array type `[]int`) - 14 | a := [2] - 15 | _ = a[a..] - 16 | _ = a[..a] + 17 | _ = a[..a] + 18 | _ = a[-1..] +vlib/v/checker/tests/index_expr.vv:17:7: error: non-integer index `[]int` (array type `[]int`) + 15 | a := [2] + 16 | _ = a[a..] + 17 | _ = a[..a] | ~~~~~ - 17 | } + 18 | _ = a[-1..] + 19 | _ = a[..-1] +vlib/v/checker/tests/index_expr.vv:18:8: error: invalid index `-1` (index must be non-negative) + 16 | _ = a[a..] + 17 | _ = a[..a] + 18 | _ = a[-1..] + | ^ + 19 | _ = a[..-1] + 20 | _ = a[-1..-2] +vlib/v/checker/tests/index_expr.vv:19:10: error: invalid index `-1` (index must be non-negative) + 17 | _ = a[..a] + 18 | _ = a[-1..] + 19 | _ = a[..-1] + | ^ + 20 | _ = a[-1..-2] + 21 | } +vlib/v/checker/tests/index_expr.vv:20:8: error: invalid index `-1` (index must be non-negative) + 18 | _ = a[-1..] + 19 | _ = a[..-1] + 20 | _ = a[-1..-2] + | ^ + 21 | } diff --git a/vlib/v/checker/tests/index_expr.vv b/vlib/v/checker/tests/index_expr.vv index 7bce476514..072661d24b 100644 --- a/vlib/v/checker/tests/index_expr.vv +++ b/vlib/v/checker/tests/index_expr.vv @@ -1,17 +1,21 @@ fn test_invalid_index() { v := 4 _ = v[0] - + a := [2] _ = a[a] + _ = a[-1] } fn test_invalid_slice() { v := 4 _ = v[1..] _ = v[..1] - + a := [2] _ = a[a..] _ = a[..a] + _ = a[-1..] + _ = a[..-1] + _ = a[-1..-2] }