]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: use a plausible position for typedef error messages
authorIan Lance Taylor <iant@golang.org>
Mon, 3 Dec 2018 18:53:10 +0000 (10:53 -0800)
committerIan Lance Taylor <iant@golang.org>
Mon, 3 Dec 2018 20:26:04 +0000 (20:26 +0000)
Fixes #28069

Change-Id: I7e0f96b8b6d123de283325fcb78ec76455050f6d
Reviewed-on: https://go-review.googlesource.com/c/152158
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
misc/cgo/errors/errors_test.go
misc/cgo/errors/src/issue28069.go [new file with mode: 0644]
src/cmd/cgo/gcc.go
src/cmd/cgo/main.go

index 118187f23b8e7a8bf95b958f40828cbd998706d9..0d7ca4cf9d89c5fedef1e1e1497c1afc4587e93d 100644 (file)
@@ -126,7 +126,12 @@ func TestReportsTypeErrors(t *testing.T) {
        }
 
        if sizeofLongDouble(t) > 8 {
-               check(t, "err4.go")
+               for _, file := range []string{
+                       "err4.go",
+                       "issue28069.go",
+               } {
+                       check(t, file)
+               }
        }
 }
 
diff --git a/misc/cgo/errors/src/issue28069.go b/misc/cgo/errors/src/issue28069.go
new file mode 100644 (file)
index 0000000..e19a3b4
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+
+// Test that the error message for an unrepresentable typedef in a
+// union appears on the right line. This test is only run if the size
+// of long double is larger than 64.
+
+package main
+
+/*
+typedef long double             Float128;
+
+typedef struct SV {
+    union {
+        Float128         float128;
+    } value;
+} SV;
+*/
+import "C"
+
+type ts struct {
+       tv *C.SV // ERROR HERE
+}
+
+func main() {}
index 3c96af2be61bd25c0c6dcb0bc08b64158bfea672..4464b840dd69c0a7aad50300d232af6f97416a17 100644 (file)
@@ -171,11 +171,13 @@ func (p *Package) Translate(f *File) {
        for len(p.typedefs) > numTypedefs {
                numTypedefs = len(p.typedefs)
                // Also ask about any typedefs we've seen so far.
-               for _, a := range p.typedefList {
-                       f.Name[a] = &Name{
-                               Go: a,
-                               C:  a,
+               for _, info := range p.typedefList {
+                       n := &Name{
+                               Go: info.typedef,
+                               C:  info.typedef,
                        }
+                       f.Name[info.typedef] = n
+                       f.NamePos[n] = info.pos
                }
                needType := p.guessKinds(f)
                if len(needType) > 0 {
@@ -573,7 +575,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
                                fatalf("malformed __cgo__ name: %s", name)
                        }
                        types[i] = t.Type
-                       p.recordTypedefs(t.Type)
+                       p.recordTypedefs(t.Type, f.NamePos[names[i]])
                }
                if e.Tag != dwarf.TagCompileUnit {
                        r.SkipChildren()
@@ -641,10 +643,11 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
 }
 
 // recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
-func (p *Package) recordTypedefs(dtype dwarf.Type) {
-       p.recordTypedefs1(dtype, map[dwarf.Type]bool{})
+func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
+       p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
 }
-func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool) {
+
+func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
        if dtype == nil {
                return
        }
@@ -660,23 +663,23 @@ func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool)
                }
                if !p.typedefs[dt.Name] {
                        p.typedefs[dt.Name] = true
-                       p.typedefList = append(p.typedefList, dt.Name)
-                       p.recordTypedefs1(dt.Type, visited)
+                       p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
+                       p.recordTypedefs1(dt.Type, pos, visited)
                }
        case *dwarf.PtrType:
-               p.recordTypedefs1(dt.Type, visited)
+               p.recordTypedefs1(dt.Type, pos, visited)
        case *dwarf.ArrayType:
-               p.recordTypedefs1(dt.Type, visited)
+               p.recordTypedefs1(dt.Type, pos, visited)
        case *dwarf.QualType:
-               p.recordTypedefs1(dt.Type, visited)
+               p.recordTypedefs1(dt.Type, pos, visited)
        case *dwarf.FuncType:
-               p.recordTypedefs1(dt.ReturnType, visited)
+               p.recordTypedefs1(dt.ReturnType, pos, visited)
                for _, a := range dt.ParamType {
-                       p.recordTypedefs1(a, visited)
+                       p.recordTypedefs1(a, pos, visited)
                }
        case *dwarf.StructType:
                for _, f := range dt.Field {
-                       p.recordTypedefs1(f.Type, visited)
+                       p.recordTypedefs1(f.Type, pos, visited)
                }
        }
 }
index e28a57b1481d05115989c64fc95c11dc2fc7d1d4..7a845b17a4e7741eacaf142c797044490bcf64bc 100644 (file)
@@ -47,7 +47,14 @@ type Package struct {
        GccFiles    []string        // list of gcc output files
        Preamble    string          // collected preamble for _cgo_export.h
        typedefs    map[string]bool // type names that appear in the types of the objects we're interested in
-       typedefList []string
+       typedefList []typedefInfo
+}
+
+// A typedefInfo is an element on Package.typedefList: a typedef name
+// and the position where it was required.
+type typedefInfo struct {
+       typedef string
+       pos     token.Pos
 }
 
 // A File collects information about a single Go input file.