--- /dev/null
+// 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) {}
// 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 {
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)
}
}
}