]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: don't crash in selectors referring to the type being declared
authorRobert Griesemer <gri@golang.org>
Sun, 6 Mar 2022 23:44:42 +0000 (15:44 -0800)
committerRobert Griesemer <gri@golang.org>
Mon, 7 Mar 2022 20:00:56 +0000 (20:00 +0000)
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>
src/cmd/compile/internal/types2/call.go
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/testdata/fixedbugs/issue51509.go [new file with mode: 0644]
src/cmd/compile/internal/types2/typexpr.go
src/go/types/call.go
src/go/types/expr.go
src/go/types/testdata/fixedbugs/issue51509.go [new file with mode: 0644]
src/go/types/typexpr.go

index d12ee49adbc64904d9b7894c2861d349968d2ddc..6cc30a7015c287281963c5fd0e2c3fd9f5d8820b 100644 (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
index c587c40f80f8c5abf21be6ea8335c394d8d7dc77..861a83472daeb87213cf76d23d2f62096f2b2131 100644 (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) {
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 (file)
index 0000000..5ae4717
--- /dev/null
@@ -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
index 2847aa76c0939fcb9619d00ca2e001c73808803c..b9bc992a82f4634824b86cad7a495ccc5d2e6bcb 100644 (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:
index 854528ddfa76b1478d5277fa8531840a668c5fef..5d1f60d43263b0a1440dd64147ff68e2e7875265 100644 (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)
index 9241c243f212ef219c516b4f40ce1197859dd42c..68b0789d6504cfc0a0368a75a952e30762461c46 100644 (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)
diff --git a/src/go/types/testdata/fixedbugs/issue51509.go b/src/go/types/testdata/fixedbugs/issue51509.go
new file mode 100644 (file)
index 0000000..5ae4717
--- /dev/null
@@ -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
index 724c40963fd20b4251c65d8f165678d7f4429c24..838febc087b94ee1c68537960bd2fbc5fa7ab2e4 100644 (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: