mirror of
https://github.com/golang/go.git
synced 2026-01-29 07:02:05 +03:00
go/types, types2: add check for map value completeness in IndexExpr
An index expression can also go from map[K]V to V. Since V could be incomplete (due to some admittedly contrived syntax), we need a check. Change-Id: I03ffbfc0e5bcc9129591d60dfbaa5fafcf8fb183 Reviewed-on: https://go-review.googlesource.com/c/go/+/737620 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Mark Freeman <markfreeman@google.com>
This commit is contained in:
committed by
Gopher Robot
parent
8ca47fab42
commit
a977717393
@@ -52,11 +52,21 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
|
||||
x.mode = invalid
|
||||
return false
|
||||
}
|
||||
// Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
|
||||
// its base type must also be complete.
|
||||
if p, ok := x.typ.Underlying().(*Pointer); ok && !check.isComplete(p.base) {
|
||||
x.mode = invalid
|
||||
return false
|
||||
switch typ := x.typ.Underlying().(type) {
|
||||
case *Pointer:
|
||||
// Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
|
||||
// its base type must also be complete.
|
||||
if !check.isComplete(typ.base) {
|
||||
x.mode = invalid
|
||||
return false
|
||||
}
|
||||
case *Map:
|
||||
// Lastly, if x.typ is a map type, indexing must produce a value of a complete type, meaning
|
||||
// its element type must also be complete.
|
||||
if !check.isComplete(typ.elem) {
|
||||
x.mode = invalid
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ordinary index expression
|
||||
|
||||
@@ -53,11 +53,21 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
|
||||
x.mode = invalid
|
||||
return false
|
||||
}
|
||||
// Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
|
||||
// its base type must also be complete.
|
||||
if p, ok := x.typ.Underlying().(*Pointer); ok && !check.isComplete(p.base) {
|
||||
x.mode = invalid
|
||||
return false
|
||||
switch typ := x.typ.Underlying().(type) {
|
||||
case *Pointer:
|
||||
// Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
|
||||
// its base type must also be complete.
|
||||
if !check.isComplete(typ.base) {
|
||||
x.mode = invalid
|
||||
return false
|
||||
}
|
||||
case *Map:
|
||||
// Lastly, if x.typ is a map type, indexing must produce a value of a complete type, meaning
|
||||
// its element type must also be complete.
|
||||
if !check.isComplete(typ.elem) {
|
||||
x.mode = invalid
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ordinary index expression
|
||||
|
||||
2
src/internal/types/testdata/check/cycles6.go
vendored
2
src/internal/types/testdata/check/cycles6.go
vendored
@@ -69,3 +69,5 @@ type T11 /* ERROR "invalid recursive type" */ [unsafe.Sizeof(new(T11)[:])]int
|
||||
type T12 /* ERROR "invalid recursive type" */ [unsafe.Sizeof(T12{}[42])]int
|
||||
// index on pointer (case 3)
|
||||
type T13 /* ERROR "invalid recursive type" */ [unsafe.Sizeof(new(T13)[42])]int
|
||||
// index on map (case 1)
|
||||
type T14 /* ERROR "invalid recursive type" */ [unsafe.Sizeof((*new(map[int]T14))[42])]int
|
||||
|
||||
Reference in New Issue
Block a user