]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: avoid endless recursion on recursive type
authorIan Lance Taylor <iant@golang.org>
Fri, 30 Aug 2024 22:44:02 +0000 (15:44 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 4 Oct 2024 18:07:31 +0000 (18:07 +0000)
Fixes #69176

Change-Id: I2e3b2a7cf7699697b957fc69ecf5200ebb137bc3
Reviewed-on: https://go-review.googlesource.com/c/go/+/609975
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Commit-Queue: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/cgo/internal/testerrors/errors_test.go
src/cmd/cgo/internal/testerrors/testdata/issue69176.go [new file with mode: 0644]
src/cmd/cgo/out.go

index 0780870fe0e69aaa4fdcdcee120b694fe66b71ad..941c7eff201245b1bbdadb13db95b141c45ff8ad 100644 (file)
@@ -132,6 +132,7 @@ func TestReportsTypeErrors(t *testing.T) {
                "issue50710.go",
                "issue67517.go",
                "issue67707.go",
+               "issue69176.go",
        } {
                check(t, file)
        }
diff --git a/src/cmd/cgo/internal/testerrors/testdata/issue69176.go b/src/cmd/cgo/internal/testerrors/testdata/issue69176.go
new file mode 100644 (file)
index 0000000..e52b1f8
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2024 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
+
+import "C"
+
+type T = T // ERROR HERE
+
+//export F
+func F(p *T) {}
index 0f58528c593392a293c27742ffe31b1a676de25f..954c4b70c954ebbf884b66443d828686df24c92a 100644 (file)
@@ -1418,9 +1418,18 @@ var goTypes = map[string]*Type{
 
 // Map an ast type to a Type.
 func (p *Package) cgoType(e ast.Expr) *Type {
+       return p.doCgoType(e, make(map[ast.Expr]bool))
+}
+
+// Map an ast type to a Type, avoiding cycles.
+func (p *Package) doCgoType(e ast.Expr, m map[ast.Expr]bool) *Type {
+       if m[e] {
+               fatalf("%s: invalid recursive type", fset.Position(e.Pos()))
+       }
+       m[e] = true
        switch t := e.(type) {
        case *ast.StarExpr:
-               x := p.cgoType(t.X)
+               x := p.doCgoType(t.X, m)
                return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("%s*", x.C)}
        case *ast.ArrayType:
                if t.Len == nil {
@@ -1465,7 +1474,12 @@ func (p *Package) cgoType(e ast.Expr) *Type {
                                        continue
                                }
                                if ts.Name.Name == t.Name {
-                                       return p.cgoType(ts.Type)
+                                       // Give a better error than the one
+                                       // above if we detect a recursive type.
+                                       if m[ts.Type] {
+                                               fatalf("%s: invalid recursive type: %s refers to itself", fset.Position(e.Pos()), t.Name)
+                                       }
+                                       return p.doCgoType(ts.Type, m)
                                }
                        }
                }