--- /dev/null
+// Copyright 2018 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.
+
+// Failed to resolve typedefs consistently.
+// No runtime test; just make sure it compiles.
+// In separate directory to isolate #pragma GCC diagnostic.
+
+package issue27340
+
+// We use the #pragma to avoid a compiler warning about incompatible
+// pointer types, because we generate code passing a struct ptr rather
+// than using the typedef. This warning is expected and does not break
+// a normal build.
+// We can only disable -Wincompatible-pointer-types starting with GCC 5.
+
+// #if __GNU_MAJOR__ >= 5
+//
+// #pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
+//
+// typedef struct {
+// int a;
+// } issue27340Struct, *issue27340Ptr;
+//
+// static void issue27340CFunc(issue27340Ptr p) {}
+//
+// #else /* _GNU_MAJOR_ < 5 */
+//
+// typedef struct {
+// int a;
+// } issue27340Struct;
+//
+// static issue27340Struct* issue27340Ptr(issue27340Struct* p) { return p; }
+//
+// static void issue27340CFunc(issue27340Struct *p) {}
+// #endif /* _GNU_MAJOR_ < 5 */
+import "C"
+
+func Issue27340GoFunc() {
+ var s C.issue27340Struct
+ C.issue27340CFunc(C.issue27340Ptr(&s))
+}
// Convert C.ulong to C.unsigned long, etc.
cref.Name.C = cname(cref.Name.Go)
}
+
+ var conv typeConv
+ conv.Init(p.PtrSize, p.IntSize)
+
p.loadDefines(f)
p.typedefs = map[string]bool{}
p.typedefList = nil
}
needType := p.guessKinds(f)
if len(needType) > 0 {
- p.loadDWARF(f, needType)
+ p.loadDWARF(f, &conv, needType)
}
// In godefs mode we're OK with the typedefs, which
// loadDWARF parses the DWARF debug information generated
// by gcc to learn the details of the constants, variables, and types
// being referred to as C.xxx.
-func (p *Package) loadDWARF(f *File, names []*Name) {
+func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) {
// Extract the types from the DWARF section of an object
// from a well-formed C program. Gcc only generates DWARF info
// for symbols in the object file, so it is not enough to print the
}
// Record types and typedef information.
- var conv typeConv
- conv.Init(p.PtrSize, p.IntSize)
for i, n := range names {
if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true
// with equivalent memory layout.
type typeConv struct {
// Cache of already-translated or in-progress types.
- m map[dwarf.Type]*Type
+ m map[string]*Type
// Map from types to incomplete pointers to those types.
- ptrs map[dwarf.Type][]*Type
+ ptrs map[string][]*Type
// Keys of ptrs in insertion order (deterministic worklist)
// ptrKeys contains exactly the keys in ptrs.
ptrKeys []dwarf.Type
func (c *typeConv) Init(ptrSize, intSize int64) {
c.ptrSize = ptrSize
c.intSize = intSize
- c.m = make(map[dwarf.Type]*Type)
- c.ptrs = make(map[dwarf.Type][]*Type)
+ c.m = make(map[string]*Type)
+ c.ptrs = make(map[string][]*Type)
c.getTypeIDs = make(map[string]bool)
c.bool = c.Ident("bool")
c.byte = c.Ident("byte")
// Keep looping until they're all done.
for len(c.ptrKeys) > 0 {
dtype := c.ptrKeys[0]
+ dtypeKey := dtype.String()
c.ptrKeys = c.ptrKeys[1:]
- ptrs := c.ptrs[dtype]
- delete(c.ptrs, dtype)
+ ptrs := c.ptrs[dtypeKey]
+ delete(c.ptrs, dtypeKey)
- // Note Type might invalidate c.ptrs[dtype].
+ // Note Type might invalidate c.ptrs[dtypeKey].
t := c.Type(dtype, pos)
for _, ptr := range ptrs {
ptr.Go.(*ast.StarExpr).X = t.Go
// Type returns a *Type with the same memory layout as
// dtype when used as the type of a variable or a struct field.
func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
- if t, ok := c.m[dtype]; ok {
+ key := dtype.String()
+ if t, ok := c.m[key]; ok {
if t.Go == nil {
fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
}
t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
t.Align = -1
t.C = &TypeRepr{Repr: dtype.Common().Name}
- c.m[dtype] = t
+ c.m[key] = t
switch dt := dtype.(type) {
default:
// Placeholder initialization; completed in FinishType.
t.Go = &ast.StarExpr{}
t.C.Set("<incomplete>*")
- if _, ok := c.ptrs[dt.Type]; !ok {
+ key := dt.Type.String()
+ if _, ok := c.ptrs[key]; !ok {
c.ptrKeys = append(c.ptrKeys, dt.Type)
}
- c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
+ c.ptrs[key] = append(c.ptrs[key], t)
case *dwarf.QualType:
t1 := c.Type(dt.Type, pos)