]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: use first error position instead of last one
authorHiroshi Ioka <hirochachacha@gmail.com>
Mon, 5 Jun 2017 00:06:30 +0000 (09:06 +0900)
committerIan Lance Taylor <iant@golang.org>
Mon, 14 Aug 2017 05:29:11 +0000 (05:29 +0000)
Just like https://golang.org/cl/34783

Given cgo.go:
     1 package main
     2
     3 /*
     4 long double x = 0;
     5 */
     6 import "C"
     7
     8 func main() {
     9 _ = C.x
    10 _ = C.x
    11 }

Before:
    ./cgo.go:10:6: unexpected: 16-byte float type - long double

After:
    ./cgo.go:9:6: unexpected: 16-byte float type - long double

The above test case is not portable. So it is tested on only amd64.

Change-Id: If0b84cf73d381a22e2ada71c8e9a6e6ec77ffd2e
Reviewed-on: https://go-review.googlesource.com/54950
Reviewed-by: Ian Lance Taylor <iant@golang.org>
misc/cgo/errors/err4.go [new file with mode: 0644]
misc/cgo/errors/test.bash
src/cmd/cgo/ast.go
src/cmd/cgo/gcc.go
src/cmd/cgo/main.go

diff --git a/misc/cgo/errors/err4.go b/misc/cgo/errors/err4.go
new file mode 100644 (file)
index 0000000..8e5f78e
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+package main
+
+/*
+long double x = 0;
+*/
+import "C"
+
+func main() {
+       _ = C.x // ERROR HERE
+       _ = C.x
+}
index ed0b0946925b4b7dfedc9752879776a443ab7125..04747a6913b257af4d4345abd68550ab58427611 100755 (executable)
@@ -37,6 +37,9 @@ expect() {
 check err1.go
 check err2.go
 check err3.go
+if [ $(go env GOARCH) == "amd64" ]; then # If we find a portable test case, we can remove this.
+       check err4.go
+fi
 check issue7757.go
 check issue8442.go
 check issue11097a.go
index 7122a9dbbebae6f841b84248b9dc30cba8cfb00a..8ce778cd5ff0df19902e94cade656ec1eddbb030 100644 (file)
@@ -63,6 +63,7 @@ func (f *File) ParseGo(name string, src []byte) {
 
        f.Package = ast1.Name.Name
        f.Name = make(map[string]*Name)
+       f.NamePos = make(map[*Name]token.Pos)
 
        // In ast1, find the import "C" line and get any extra C preamble.
        sawC := false
@@ -212,6 +213,7 @@ func (f *File) saveRef(n *ast.Expr, context string) {
                        Go: goname,
                }
                f.Name[goname] = name
+               f.NamePos[name] = sel.Pos()
        }
        f.Ref = append(f.Ref, &Ref{
                Name:    name,
index c0368f9bcbbc27b59131a4f1a3c54b39da1263f9..2990dc00faa67f91a39b78e919815b729020f4e6 100644 (file)
@@ -438,14 +438,7 @@ func (p *Package) guessKinds(f *File) []*Name {
        for i, n := range names {
                switch sniff[i] &^ notSignedIntConst {
                default:
-                       var tpos token.Pos
-                       for _, ref := range f.Ref {
-                               if ref.Name == n {
-                                       tpos = ref.Pos()
-                                       break
-                               }
-                       }
-                       error_(tpos, "could not determine kind of name for C.%s", fixGo(n.Go))
+                       error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go))
                case notStrLiteral | notType:
                        if sniff[i]&notSignedIntConst != 0 {
                                n.Kind = "uconst"
@@ -543,10 +536,6 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
 
        // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
        types := make([]dwarf.Type, len(names))
-       nameToRef := make(map[*Name]*Ref)
-       for _, ref := range f.Ref {
-               nameToRef[ref.Name] = ref
-       }
        r := d.Reader()
        for {
                e, err := r.Next()
@@ -597,10 +586,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
                if types[i] == nil {
                        continue
                }
-               pos := token.NoPos
-               if ref, ok := nameToRef[n]; ok {
-                       pos = ref.Pos()
-               }
+               pos := f.NamePos[n]
                f, fok := types[i].(*dwarf.FuncType)
                if n.Kind != "type" && fok {
                        n.Kind = "func"
index 3dc3d141b74d1c7a71732b841dc98e30cafc0b50..2964790efd54fa9eb3cd3a16d4c42f1d99340a96 100644 (file)
@@ -54,6 +54,7 @@ type File struct {
        Calls    []*Call             // all calls to C.xxx in AST
        ExpFunc  []*ExpFunc          // exported functions for this file
        Name     map[string]*Name    // map from Go name to Name
+       NamePos  map[*Name]token.Pos // map from Name to position of the first reference
 }
 
 func nameKeys(m map[string]*Name) []string {