checker: make negative literal index a checker error (#8242)

pull/8245/head
zakuro 2021-01-21 20:27:16 +09:00 committed by GitHub
parent f413c92f2f
commit 29b3077ea1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 35 deletions

View File

@ -4804,7 +4804,7 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) table.Type {
return right_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) index_type_sym := c.table.get_type_symbol(index_type)
// println('index expr left=$typ_sym.name $node.pos.line_nr') // 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) && // 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) 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) { if index_type.has_flag(.optional) {
type_str := if typ_sym.kind in [.string, .ustring] { type_str := if typ_sym.kind in [.string, .ustring] {
'(type `$typ_sym.name`)' '(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 mut node.index is ast.RangeExpr { // [1..2]
if node.index.has_low { if node.index.has_low {
index_type := c.expr(node.index.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 { if node.index.has_high {
index_type := c.expr(node.index.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 // array[1..2] => array
// fixed_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) c.error('invalid key: $err', node.pos)
} }
} else { } 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) value_type := c.table.value_type(typ)
if value_type != table.void_type { if value_type != table.void_type {

View File

@ -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() { 1 | fn test_invalid_index() {
2 | v := 4 2 | v := 4
3 | _ = v[0] 3 | _ = v[0]
| ~~~ | ~~~
4 | 4 |
5 | a := [2] 5 | a := [2]
vlib/v/checker/tests/index_expr.vv:6:7: error: non-integer index `[]int` (array type `[]int`) vlib/v/checker/tests/index_expr.vv:6:7: error: non-integer index `[]int` (array type `[]int`)
4 | 4 |
5 | a := [2] 5 | a := [2]
6 | _ = a[a] 6 | _ = a[a]
| ~~~ | ~~~
7 | } 7 | _ = a[-1]
8 | 8 | }
vlib/v/checker/tests/index_expr.vv:11:7: error: type `int` does not support indexing vlib/v/checker/tests/index_expr.vv:7:8: error: invalid index `-1` (index must be non-negative)
9 | fn test_invalid_slice() { 5 | a := [2]
10 | v := 4 6 | _ = a[a]
11 | _ = v[1..] 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 | _ = v[..1]
13 | 14 |
vlib/v/checker/tests/index_expr.vv:12:7: error: type `int` does not support indexing vlib/v/checker/tests/index_expr.vv:13:7: error: type `int` does not support indexing
10 | v := 4 11 | v := 4
11 | _ = v[1..] 12 | _ = v[1..]
12 | _ = v[..1] 13 | _ = v[..1]
| ~~~~~ | ~~~~~
13 | 14 |
14 | a := [2] 15 | a := [2]
vlib/v/checker/tests/index_expr.vv:15:7: error: non-integer index `[]int` (array type `[]int`) vlib/v/checker/tests/index_expr.vv:16:7: error: non-integer index `[]int` (array type `[]int`)
13 | 14 |
14 | a := [2] 15 | a := [2]
15 | _ = a[a..] 16 | _ = a[a..]
| ~~~~~ | ~~~~~
16 | _ = a[..a] 17 | _ = a[..a]
17 | } 18 | _ = a[-1..]
vlib/v/checker/tests/index_expr.vv:16:7: error: non-integer index `[]int` (array type `[]int`) vlib/v/checker/tests/index_expr.vv:17:7: error: non-integer index `[]int` (array type `[]int`)
14 | a := [2] 15 | a := [2]
15 | _ = a[a..] 16 | _ = a[a..]
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 | }

View File

@ -1,17 +1,21 @@
fn test_invalid_index() { fn test_invalid_index() {
v := 4 v := 4
_ = v[0] _ = v[0]
a := [2] a := [2]
_ = a[a] _ = a[a]
_ = a[-1]
} }
fn test_invalid_slice() { fn test_invalid_slice() {
v := 4 v := 4
_ = v[1..] _ = v[1..]
_ = v[..1] _ = v[..1]
a := [2] a := [2]
_ = a[a..] _ = a[a..]
_ = a[..a] _ = a[..a]
_ = a[-1..]
_ = a[..-1]
_ = a[-1..-2]
} }