diff options
author | Tobias Klauser <tklauser@distanz.ch> | 2020-03-30 00:38:09 +0200 |
---|---|---|
committer | Tobias Klauser <tobias.klauser@gmail.com> | 2020-03-30 18:44:17 +0000 |
commit | a265c2c448497fcee1633d2e2b912da52ea22d3c (patch) | |
tree | 9be12ed6eeb6259f3856ac2b76530ef13b348a59 /src/cmd/cgo | |
parent | 3ee782b11da3fb0313603ad0e3be8ab6755802a9 (diff) | |
download | go-a265c2c448497fcee1633d2e2b912da52ea22d3c.tar.gz go-a265c2c448497fcee1633d2e2b912da52ea22d3c.zip |
cmd/cgo, misc/cgo: only cache anonymous struct typedefs with parent name
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.
Updates #31891
Fixes #37479
Fixes #37621
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>
Diffstat (limited to 'src/cmd/cgo')
-rw-r--r-- | src/cmd/cgo/gcc.go | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go index fcab494ea0..c4128e9502 100644 --- a/src/cmd/cgo/gcc.go +++ b/src/cmd/cgo/gcc.go @@ -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 |