aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/index.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-04-27 12:12:01 -0700
committerRobert Griesemer <gri@golang.org>2021-04-28 18:50:41 +0000
commitea65a12f895ce67ee6fd843b9cee97d42f6ad0b4 (patch)
tree5b59beb78316074ae398a42b830fe492cec12c04 /src/cmd/compile/internal/types2/index.go
parent90614ff46236e970acbcb3645edd03186718667a (diff)
downloadgo-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.go55
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