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
}
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 {

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() {
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 | }

View File

@ -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]
}