]> Cypherpunks repositories - gostls13.git/commitdiff
go/types,types2: disallow illegal cycles through Unions
authorRobert Findley <rfindley@google.com>
Thu, 23 Sep 2021 16:19:05 +0000 (12:19 -0400)
committerRobert Findley <rfindley@google.com>
Thu, 23 Sep 2021 17:04:30 +0000 (17:04 +0000)
Checker.validType was not considering Unions when looking for illegal
cycles.

Fixes #48582

Change-Id: I11ad0279eeaaa56bb6d5731b0572c1c3a0c459eb
Reviewed-on: https://go-review.googlesource.com/c/go/+/351829
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue48582.go2 [new file with mode: 0644]
src/go/types/decl.go
src/go/types/testdata/fixedbugs/issue41124.go2
src/go/types/testdata/fixedbugs/issue48582.go2 [new file with mode: 0644]

index 994c19ea30aa959887294af3bb5f0567c9e88841..ab2e3b875f0a9fe3f0d4d188a855c7f39249dcd1 100644 (file)
@@ -315,6 +315,13 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
                        }
                }
 
+       case *Union:
+               for _, t := range t.terms {
+                       if check.validType(t.typ, path) == invalid {
+                               return invalid
+                       }
+               }
+
        case *Interface:
                for _, etyp := range t.embeddeds {
                        if check.validType(etyp, path) == invalid {
index 4642ab60fc8edaf7f78c709459f29b549258e33f..cef24bd237959f3befde6c55e5f01145c2e03cc6 100644 (file)
@@ -6,7 +6,7 @@ package p
 
 // Test case from issue.
 
-type Nat interface {
+type Nat /* ERROR cycle */ interface {
        Zero|Succ
 }
 
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48582.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48582.go2
new file mode 100644 (file)
index 0000000..c12091b
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2021 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 N /* ERROR cycle */ interface {
+       int | N
+}
+
+type A /* ERROR cycle */ interface {
+       int | B
+}
+
+type B interface {
+       int | A
+}
+
+type S /* ERROR cycle */ struct {
+       I // ERROR interface contains type constraints
+}
+
+type I interface {
+       int | S
+}
+
+type P interface {
+       *P // ERROR interface contains type constraints
+}
index 061fc018296cd23c6ea995600aa3dbf9d02edb3e..77914dd1af97d5b11dd40b9763d0a91661fa3df2 100644 (file)
@@ -314,6 +314,13 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
                        }
                }
 
+       case *Union:
+               for _, t := range t.terms {
+                       if check.validType(t.typ, path) == invalid {
+                               return invalid
+                       }
+               }
+
        case *Interface:
                for _, etyp := range t.embeddeds {
                        if check.validType(etyp, path) == invalid {
index 4642ab60fc8edaf7f78c709459f29b549258e33f..ac336a2eceb09b7f522ae34285f3c8404ab7d36e 100644 (file)
@@ -6,13 +6,13 @@ package p
 
 // Test case from issue.
 
-type Nat interface {
+type Nat /* ERROR cycle */ interface {
        Zero|Succ
 }
 
 type Zero struct{}
 type Succ struct{
-       Nat // ERROR interface contains type constraints
+       Nat /* ERROR interface contains type constraints */
 }
 
 // Struct tests.
diff --git a/src/go/types/testdata/fixedbugs/issue48582.go2 b/src/go/types/testdata/fixedbugs/issue48582.go2
new file mode 100644 (file)
index 0000000..c12091b
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2021 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 N /* ERROR cycle */ interface {
+       int | N
+}
+
+type A /* ERROR cycle */ interface {
+       int | B
+}
+
+type B interface {
+       int | A
+}
+
+type S /* ERROR cycle */ struct {
+       I // ERROR interface contains type constraints
+}
+
+type I interface {
+       int | S
+}
+
+type P interface {
+       *P // ERROR interface contains type constraints
+}