]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.14] cmd/cgo, misc/cgo: only cache anonymous struct typedefs with...
authorTobias Klauser <tklauser@distanz.ch>
Sun, 29 Mar 2020 22:38:09 +0000 (00:38 +0200)
committerIan Lance Taylor <iant@golang.org>
Mon, 30 Mar 2020 21:07:05 +0000 (21:07 +0000)
CL 181857 broke the translation of certain C types using cmd/cgo -godefs
because it stores each typedef, array and qualified type with their
parent type name in the translation cache.

Fix this by only considering the parent type for typedefs of anonymous
structs which is the only case where types might become ambiguous.

Fixes #37622

Change-Id: I301a749ec89585789cb0d213593bb8b7341beb88
Reviewed-on: https://go-review.googlesource.com/c/go/+/226341
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit a265c2c448497fcee1633d2e2b912da52ea22d3c)
Reviewed-on: https://go-review.googlesource.com/c/go/+/226497

misc/cgo/testgodefs/testdata/issue37479.go [new file with mode: 0644]
misc/cgo/testgodefs/testdata/issue37621.go [new file with mode: 0644]
misc/cgo/testgodefs/testdata/main.go
misc/cgo/testgodefs/testgodefs_test.go
src/cmd/cgo/gcc.go

diff --git a/misc/cgo/testgodefs/testdata/issue37479.go b/misc/cgo/testgodefs/testdata/issue37479.go
new file mode 100644 (file)
index 0000000..a210eb5
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2020 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.
+//
+// +build ignore
+
+package main
+
+/*
+typedef struct A A;
+
+typedef struct {
+       struct A *next;
+       struct A **prev;
+} N;
+
+struct A
+{
+       N n;
+};
+
+typedef struct B
+{
+       A* a;
+} B;
+*/
+import "C"
+
+type N C.N
+
+type A C.A
+
+type B C.B
diff --git a/misc/cgo/testgodefs/testdata/issue37621.go b/misc/cgo/testgodefs/testdata/issue37621.go
new file mode 100644 (file)
index 0000000..d5ace3f
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2020 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.
+//
+// +build ignore
+
+package main
+
+/*
+struct tt {
+       long long a;
+       long long b;
+};
+
+struct s {
+       struct tt ts[3];
+};
+*/
+import "C"
+
+type TT C.struct_tt
+
+type S C.struct_s
index 1ce0fd0d1e196472ca4c32ada4810e5283de2968..ef45b95e6553e34bc51385fb68c5574993885a10 100644 (file)
@@ -11,5 +11,13 @@ var v2 = v1.L
 // Test that P, Q, and R all point to byte.
 var v3 = Issue8478{P: (*byte)(nil), Q: (**byte)(nil), R: (***byte)(nil)}
 
+// Test that N, A and B are fully defined
+var v4 = N{}
+var v5 = A{}
+var v6 = B{}
+
+// Test that S is fully defined
+var v7 = S{}
+
 func main() {
 }
index c02c3ff0acd95ce5d7ddb74c2ce9fa4c1b647248..438d23d65c068f0d44d5af88495cc380483f8b8e 100644 (file)
@@ -21,6 +21,8 @@ var filePrefixes = []string{
        "anonunion",
        "issue8478",
        "fieldtypedef",
+       "issue37479",
+       "issue37621",
 }
 
 func TestGoDefs(t *testing.T) {
index fcab494ea0da0ad3c3403011b81dc95829eb99f2..c4128e9502e4667f0f6a71ee6dc3b9034ffb4257 100644 (file)
@@ -2243,7 +2243,7 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
                        // Translate to zero-length array instead.
                        count = 0
                }
-               sub := c.loadType(dt.Type, pos, key)
+               sub := c.Type(dt.Type, pos)
                t.Align = sub.Align
                t.Go = &ast.ArrayType{
                        Len: c.intExpr(count),
@@ -2388,7 +2388,7 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
                c.ptrs[key] = append(c.ptrs[key], t)
 
        case *dwarf.QualType:
-               t1 := c.loadType(dt.Type, pos, key)
+               t1 := c.Type(dt.Type, pos)
                t.Size = t1.Size
                t.Align = t1.Align
                t.Go = t1.Go
@@ -2472,7 +2472,13 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
                }
                name := c.Ident("_Ctype_" + dt.Name)
                goIdent[name.Name] = name
-               sub := c.loadType(dt.Type, pos, key)
+               akey := ""
+               if c.anonymousStructTypedef(dt) {
+                       // only load type recursively for typedefs of anonymous
+                       // structs, see issues 37479 and 37621.
+                       akey = key
+               }
+               sub := c.loadType(dt.Type, pos, akey)
                if c.badPointerTypedef(dt) {
                        // Treat this typedef as a uintptr.
                        s := *sub
@@ -2993,6 +2999,13 @@ func fieldPrefix(fld []*ast.Field) string {
        return prefix
 }
 
+// anonymousStructTypedef reports whether dt is a C typedef for an anonymous
+// struct.
+func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
+       st, ok := dt.Type.(*dwarf.StructType)
+       return ok && st.StructName == ""
+}
+
 // badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go.
 // A typedef is bad if C code sometimes stores non-pointers in this type.
 // TODO: Currently our best solution is to find these manually and list them as