From: Robert Griesemer Date: Sun, 6 Mar 2022 23:44:42 +0000 (-0800) Subject: [release-branch.go1.18] go/types, types2: don't crash in selectors referring to the... X-Git-Tag: go1.18~18 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=aeced244987a870a8c52a5e340e43d301015ecdb;p=gostls13.git [release-branch.go1.18] 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 Reviewed-by: Robert Findley (cherry picked from commit 114d5deac2f513a7397ab4c2ee8d2d567a901266) Reviewed-on: https://go-review.googlesource.com/c/go/+/390423 Trust: Dmitri Shuralyov Run-TryBot: Dmitri Shuralyov TryBot-Result: Gopher Robot --- diff --git a/src/cmd/compile/internal/types2/call.go b/src/cmd/compile/internal/types2/call.go index d12ee49adb..6cc30a7015 100644 --- a/src/cmd/compile/internal/types2/call.go +++ b/src/cmd/compile/internal/types2/call.go @@ -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 diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go index c587c40f80..861a83472d 100644 --- a/src/cmd/compile/internal/types2/expr.go +++ b/src/cmd/compile/internal/types2/expr.go @@ -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) { diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51509.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51509.go new file mode 100644 index 0000000000..5ae47176d0 --- /dev/null +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51509.go @@ -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 diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go index 2847aa76c0..b9bc992a82 100644 --- a/src/cmd/compile/internal/types2/typexpr.go +++ b/src/cmd/compile/internal/types2/typexpr.go @@ -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: diff --git a/src/go/types/call.go b/src/go/types/call.go index 854528ddfa..5d1f60d432 100644 --- a/src/go/types/call.go +++ b/src/go/types/call.go @@ -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) diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 9241c243f2..68b0789d65 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -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) diff --git a/src/go/types/testdata/fixedbugs/issue51509.go b/src/go/types/testdata/fixedbugs/issue51509.go new file mode 100644 index 0000000000..5ae47176d0 --- /dev/null +++ b/src/go/types/testdata/fixedbugs/issue51509.go @@ -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 diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 724c40963f..838febc087 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -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: