]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: use same Go type for typedef to anonymous struct
authorIan Lance Taylor <iant@golang.org>
Mon, 2 Jun 2014 19:55:43 +0000 (12:55 -0700)
committerIan Lance Taylor <iant@golang.org>
Mon, 2 Jun 2014 19:55:43 +0000 (12:55 -0700)
If we see a typedef to an anonymous struct more than once,
presumably in two different Go files that import "C", use the
same Go type name.

Fixes #8133.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/102080043

misc/cgo/test/issue8331.h [new file with mode: 0644]
misc/cgo/test/issue8331a.go [new file with mode: 0644]
misc/cgo/test/issue8331b.go [new file with mode: 0644]
src/cmd/cgo/gcc.go

diff --git a/misc/cgo/test/issue8331.h b/misc/cgo/test/issue8331.h
new file mode 100644 (file)
index 0000000..936ae9d
--- /dev/null
@@ -0,0 +1,7 @@
+// Copyright 2014 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.
+
+typedef struct {
+       int i;
+} issue8331;
diff --git a/misc/cgo/test/issue8331a.go b/misc/cgo/test/issue8331a.go
new file mode 100644 (file)
index 0000000..7fa55be
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 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.
+
+// Issue 8331.  A typedef of an unnamed struct is the same struct when
+// #include'd twice.  No runtime test; just make sure it compiles.
+
+package cgotest
+
+// #include "issue8331.h"
+import "C"
+
+func issue8331a() C.issue8331 {
+       return issue8331Var
+}
diff --git a/misc/cgo/test/issue8331b.go b/misc/cgo/test/issue8331b.go
new file mode 100644 (file)
index 0000000..d52aed6
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2014 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.
+
+// Issue 8331.  A typedef of an unnamed struct is the same struct when
+// #include'd twice.  No runtime test; just make sure it compiles.
+
+package cgotest
+
+// #include "issue8331.h"
+import "C"
+
+var issue8331Var C.issue8331
index e403f6f5109f14f885ddaf784d242ae7c290d171..0160b4b9005e0a553fa50f768aa61394c938c996 100644 (file)
@@ -1269,7 +1269,8 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
                sub := c.Type(dt.Type, pos)
                t.Size = sub.Size
                t.Align = sub.Align
-               if _, ok := typedef[name.Name]; !ok {
+               oldType := typedef[name.Name]
+               if oldType == nil {
                        tt := *t
                        tt.Go = sub.Go
                        typedef[name.Name] = &tt
@@ -1281,6 +1282,15 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
                // In -godefs and -cdefs mode, do this for all typedefs.
                if isStructUnionClass(sub.Go) || *godefs || *cdefs {
                        t.Go = sub.Go
+
+                       // If we've seen this typedef before, and it
+                       // was an anonymous struct/union/class before
+                       // too, use the old definition.
+                       // TODO: it would be safer to only do this if
+                       // we verify that the types are the same.
+                       if oldType != nil && isStructUnionClass(oldType.Go) {
+                               t.Go = oldType.Go
+                       }
                }
 
        case *dwarf.UcharType: