mirror of
https://github.com/golang/go
synced 2024-11-23 15:50:07 -07:00
go/types: prevent crash in type cycles involving non-type expressions
Fixes #18643. Change-Id: I36dca943d552a178a71094ff883b0319fe03d130 Reviewed-on: https://go-review.googlesource.com/46467 Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
b88efc7e7a
commit
7c02beb96a
@ -1125,6 +1125,16 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
||||
}
|
||||
|
||||
case *Array:
|
||||
// Prevent crash if the array referred to is not yet set up.
|
||||
// This is a stop-gap solution; a better approach would use the mechanism of
|
||||
// Checker.ident (typexpr.go) using a path of types. But that would require
|
||||
// passing the path everywhere (all expression-checking methods, not just
|
||||
// type expression checking), and we're not set up for that (quite possibly
|
||||
// an indication that cycle detection needs to be rethought). Was issue #18643.
|
||||
if utyp.elem == nil {
|
||||
check.error(e.Pos(), "illegal cycle in type declaration")
|
||||
goto Error
|
||||
}
|
||||
n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
|
||||
// If we have an "open" [...]T array, set the length now that we know it
|
||||
// and record the type for [...] (usually done by check.typExpr which is
|
||||
@ -1135,9 +1145,21 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
||||
}
|
||||
|
||||
case *Slice:
|
||||
// Prevent crash if the slice referred to is not yet set up.
|
||||
// See analogous comment for *Array.
|
||||
if utyp.elem == nil {
|
||||
check.error(e.Pos(), "illegal cycle in type declaration")
|
||||
goto Error
|
||||
}
|
||||
check.indexedElts(e.Elts, utyp.elem, -1)
|
||||
|
||||
case *Map:
|
||||
// Prevent crash if the map referred to is not yet set up.
|
||||
// See analogous comment for *Array.
|
||||
if utyp.key == nil || utyp.elem == nil {
|
||||
check.error(e.Pos(), "illegal cycle in type declaration")
|
||||
goto Error
|
||||
}
|
||||
visited := make(map[interface{}][]Type, len(e.Elts))
|
||||
for _, e := range e.Elts {
|
||||
kv, _ := e.(*ast.KeyValueExpr)
|
||||
|
11
src/go/types/testdata/cycles.src
vendored
11
src/go/types/testdata/cycles.src
vendored
@ -140,4 +140,13 @@ func (*T12) m() {}
|
||||
type (
|
||||
P3 *T13
|
||||
T13 /* ERROR cycle */ T13
|
||||
)
|
||||
)
|
||||
|
||||
// test cases for issue 18643
|
||||
// (type cycle detection when non-type expressions are involved)
|
||||
type (
|
||||
T14 [len(T14 /* ERROR cycle */ {})]int
|
||||
T15 [][len(T15 /* ERROR cycle */ {})]int
|
||||
T16 map[[len(T16 /* ERROR cycle */ {1:2})]int]int
|
||||
T17 map[int][len(T17 /* ERROR cycle */ {1:2})]int
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user