From: Ian Lance Taylor Date: Fri, 30 Aug 2024 22:44:02 +0000 (-0700) Subject: cmd/cgo: avoid endless recursion on recursive type X-Git-Tag: go1.24rc1~750 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f22afc584455081d518bbb2bd86737eeaf76a276;p=gostls13.git cmd/cgo: avoid endless recursion on recursive type Fixes #69176 Change-Id: I2e3b2a7cf7699697b957fc69ecf5200ebb137bc3 Reviewed-on: https://go-review.googlesource.com/c/go/+/609975 LUCI-TryBot-Result: Go LUCI Reviewed-by: Ian Lance Taylor Commit-Queue: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Reviewed-by: Cherry Mui --- diff --git a/src/cmd/cgo/internal/testerrors/errors_test.go b/src/cmd/cgo/internal/testerrors/errors_test.go index 0780870fe0..941c7eff20 100644 --- a/src/cmd/cgo/internal/testerrors/errors_test.go +++ b/src/cmd/cgo/internal/testerrors/errors_test.go @@ -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 index 0000000000..e52b1f84c6 --- /dev/null +++ b/src/cmd/cgo/internal/testerrors/testdata/issue69176.go @@ -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) {} diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index 0f58528c59..954c4b70c9 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -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) } } }