Skip to content

Commit

Permalink
go/types, types2: don't crash in selectors referring to the type bein…
Browse files Browse the repository at this point in the history
…g 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>
  • Loading branch information
griesemer committed Mar 7, 2022
1 parent 7dc6c5e commit 114d5de
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 6 deletions.
8 changes: 7 additions & 1 deletion src/cmd/compile/internal/types2/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/types2/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/types2/typexpr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 7 additions & 1 deletion src/go/types/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/go/types/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions src/go/types/testdata/fixedbugs/issue51509.go
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion src/go/types/typexpr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 114d5de

Please sign in to comment.