Skip to content

Commit 7c02beb

Browse files
committed
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 <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent b88efc7 commit 7c02beb

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

src/go/types/expr.go

+22
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,16 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
11251125
}
11261126

11271127
case *Array:
1128+
// Prevent crash if the array referred to is not yet set up.
1129+
// This is a stop-gap solution; a better approach would use the mechanism of
1130+
// Checker.ident (typexpr.go) using a path of types. But that would require
1131+
// passing the path everywhere (all expression-checking methods, not just
1132+
// type expression checking), and we're not set up for that (quite possibly
1133+
// an indication that cycle detection needs to be rethought). Was issue #18643.
1134+
if utyp.elem == nil {
1135+
check.error(e.Pos(), "illegal cycle in type declaration")
1136+
goto Error
1137+
}
11281138
n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
11291139
// If we have an "open" [...]T array, set the length now that we know it
11301140
// 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 {
11351145
}
11361146

11371147
case *Slice:
1148+
// Prevent crash if the slice referred to is not yet set up.
1149+
// See analogous comment for *Array.
1150+
if utyp.elem == nil {
1151+
check.error(e.Pos(), "illegal cycle in type declaration")
1152+
goto Error
1153+
}
11381154
check.indexedElts(e.Elts, utyp.elem, -1)
11391155

11401156
case *Map:
1157+
// Prevent crash if the map referred to is not yet set up.
1158+
// See analogous comment for *Array.
1159+
if utyp.key == nil || utyp.elem == nil {
1160+
check.error(e.Pos(), "illegal cycle in type declaration")
1161+
goto Error
1162+
}
11411163
visited := make(map[interface{}][]Type, len(e.Elts))
11421164
for _, e := range e.Elts {
11431165
kv, _ := e.(*ast.KeyValueExpr)

src/go/types/testdata/cycles.src

+10-1
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,13 @@ func (*T12) m() {}
140140
type (
141141
P3 *T13
142142
T13 /* ERROR cycle */ T13
143-
)
143+
)
144+
145+
// test cases for issue 18643
146+
// (type cycle detection when non-type expressions are involved)
147+
type (
148+
T14 [len(T14 /* ERROR cycle */ {})]int
149+
T15 [][len(T15 /* ERROR cycle */ {})]int
150+
T16 map[[len(T16 /* ERROR cycle */ {1:2})]int]int
151+
T17 map[int][len(T17 /* ERROR cycle */ {1:2})]int
152+
)

0 commit comments

Comments
 (0)