Skip to content

Commit

Permalink
[release-branch.go1.18] go/types, types2: don't crash in selectors re…
Browse files Browse the repository at this point in the history
…ferring 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>
(cherry picked from commit 114d5de)
Reviewed-on: https://go-review.googlesource.com/c/go/+/390423
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
griesemer authored and dmitshur committed Mar 8, 2022
1 parent f913f9d commit aeced24
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 aeced24

Please sign in to comment.