diff options
author | Robert Griesemer <gri@golang.org> | 2021-04-27 12:12:01 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-04-28 18:50:41 +0000 |
commit | ea65a12f895ce67ee6fd843b9cee97d42f6ad0b4 (patch) | |
tree | 5b59beb78316074ae398a42b830fe492cec12c04 /src/cmd/compile/internal/types2/index.go | |
parent | 90614ff46236e970acbcb3645edd03186718667a (diff) | |
download | go-ea65a12f895ce67ee6fd843b9cee97d42f6ad0b4.tar.gz go-ea65a12f895ce67ee6fd843b9cee97d42f6ad0b4.zip |
cmd/compile/internal/types2: catch unexpected expression lists
This is a modified port of the https://golang.org/cl/313909
change for go/types.
- add catch-all cases for unexpected expression lists
- add Checker.singleIndex function to check single indices
- better syntax error handling in parser for invalid type
instantiations that are missing a type argument
Change-Id: I6f0f396d637ad66b79f803d886fdc20ee55a98b3
Reviewed-on: https://go-review.googlesource.com/c/go/+/314409
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/index.go')
-rw-r--r-- | src/cmd/compile/internal/types2/index.go | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/types2/index.go b/src/cmd/compile/internal/types2/index.go index d9a402f212..c94017a8fb 100644 --- a/src/cmd/compile/internal/types2/index.go +++ b/src/cmd/compile/internal/types2/index.go @@ -77,8 +77,13 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo x.typ = typ.elem case *Map: + index := check.singleIndex(e) + if index == nil { + x.mode = invalid + return + } var key operand - check.expr(&key, e.Index) + check.expr(&key, index) check.assignment(&key, typ.key, "map index") // ok to continue even if indexing failed - map element type is known x.mode = mapindex @@ -132,8 +137,13 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo // If there are maps, the index expression must be assignable // to the map key type (as for simple map index expressions). if nmaps > 0 { + index := check.singleIndex(e) + if index == nil { + x.mode = invalid + return + } var key operand - check.expr(&key, e.Index) + check.expr(&key, index) check.assignment(&key, tkey, "map index") // ok to continue even if indexing failed - map element type is known @@ -170,24 +180,12 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo return } - if e.Index == nil { - check.errorf(e, invalidAST+"missing index for %s", x) + index := check.singleIndex(e) + if index == nil { x.mode = invalid return } - index := e.Index - if l, _ := index.(*syntax.ListExpr); l != nil { - if n := len(l.ElemList); n <= 1 { - check.errorf(e, invalidAST+"invalid use of ListExpr for index expression %v with %d indices", e, n) - x.mode = invalid - return - } - // len(l.ElemList) > 1 - check.error(l.ElemList[1], invalidOp+"more than one index") - index = l.ElemList[0] // continue with first index - } - // In pathological (invalid) cases (e.g.: type T1 [][[]T1{}[0][0]]T0) // the element type may be accessed before it's set. Make sure we have // a valid type. @@ -310,6 +308,27 @@ L: } } +// singleIndex returns the (single) index from the index expression e. +// If the index is missing, or if there are multiple indices, an error +// is reported and the result is nil. +func (check *Checker) singleIndex(e *syntax.IndexExpr) syntax.Expr { + index := e.Index + if index == nil { + check.errorf(e, invalidAST+"missing index for %s", e.X) + return nil + } + if l, _ := index.(*syntax.ListExpr); l != nil { + if n := len(l.ElemList); n <= 1 { + check.errorf(e, invalidAST+"invalid use of ListExpr for index expression %v with %d indices", e, n) + return nil + } + // len(l.ElemList) > 1 + check.error(l.ElemList[1], invalidOp+"more than one index") + index = l.ElemList[0] // continue with first index + } + return index +} + // index checks an index expression for validity. // If max >= 0, it is the upper bound for index. // If the result typ is != Typ[Invalid], index is valid and typ is its (possibly named) integer type. @@ -347,6 +366,10 @@ func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64) return x.typ, v } +// isValidIndex checks whether operand x satisfies the criteria for integer +// index values. If allowNegative is set, a constant operand may be negative. +// If the operand is not valid, an error is reported (using what as context) +// and the result is false. func (check *Checker) isValidIndex(x *operand, what string, allowNegative bool) bool { if x.mode == invalid { return false |