1
0
mirror of https://github.com/golang/go synced 2024-09-29 15:34:30 -06:00

go/types, types2: don't crash in selectors referring to the type being declared

In Checker.typInternal, the SelectorExpr case was the only case that
didn't either set or pass along the incoming def *Named type.

Handle this by passing it along to Checker.selector and report a
cycle if one is detected.

Fixes #51509.

Change-Id: I6c2d46835f225aeb4cb25fe0ae55f6180cef038b
Reviewed-on: https://go-review.googlesource.com/c/go/+/390314
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2022-03-06 15:44:42 -08:00
parent 7dc6c5ec34
commit 114d5deac2
8 changed files with 32 additions and 6 deletions

View File

@ -423,7 +423,7 @@ var cgoPrefixes = [...]string{
"_Cmacro_", // function to evaluate the expanded expression
}
func (check *Checker) selector(x *operand, e *syntax.SelectorExpr) {
func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
// these must be declared before the "goto Error" statements
var (
obj Object
@ -526,6 +526,12 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr) {
check.exprOrType(x, e.X, false)
switch x.mode {
case typexpr:
// don't crash for "type T T.x" (was issue #51509)
if def != nil && x.typ == def {
check.cycleError([]Object{def.obj})
goto Error
}
case builtin:
check.errorf(e.Pos(), "cannot select on %s", x)
goto Error

View File

@ -1556,7 +1556,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
return kind
case *syntax.SelectorExpr:
check.selector(x, e)
check.selector(x, e, nil)
case *syntax.IndexExpr:
if check.indexExpr(x, e) {

View File

@ -0,0 +1,7 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
type T /* ERROR illegal cycle */ T.x

View File

@ -256,7 +256,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
case *syntax.SelectorExpr:
var x operand
check.selector(&x, e)
check.selector(&x, e, def)
switch x.mode {
case typexpr:

View File

@ -429,7 +429,7 @@ var cgoPrefixes = [...]string{
"_Cmacro_", // function to evaluate the expanded expression
}
func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named) {
// these must be declared before the "goto Error" statements
var (
obj Object
@ -528,6 +528,12 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
check.exprOrType(x, e.X, false)
switch x.mode {
case typexpr:
// don't crash for "type T T.x" (was issue #51509)
if def != nil && x.typ == def {
check.cycleError([]Object{def.obj})
goto Error
}
case builtin:
// types2 uses the position of '.' for the error
check.errorf(e.Sel, _UncalledBuiltin, "cannot select on %s", x)

View File

@ -1533,7 +1533,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
return kind
case *ast.SelectorExpr:
check.selector(x, e)
check.selector(x, e, nil)
case *ast.IndexExpr, *ast.IndexListExpr:
ix := typeparams.UnpackIndexExpr(e)

View File

@ -0,0 +1,7 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
type T /* ERROR illegal cycle */ T.x

View File

@ -254,7 +254,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
case *ast.SelectorExpr:
var x operand
check.selector(&x, e)
check.selector(&x, e, def)
switch x.mode {
case typexpr: