]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: record original and absolute file names for line directives
authorgriesemer <gri@golang.org>
Fri, 10 Nov 2017 19:38:51 +0000 (11:38 -0800)
committerRobert Griesemer <gri@golang.org>
Mon, 13 Nov 2017 16:47:41 +0000 (16:47 +0000)
Also, with this change, error locations don't print absolute positions
in [] brackets following positions relative to line directives. To get
the absolute positions as well, specify the -L flag.

Fixes #22660.

Change-Id: I9ecfa254f053defba9c802222874155fa12fee2c
Reviewed-on: https://go-review.googlesource.com/77090
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
12 files changed:
misc/cgo/errors/errors_test.go
src/cmd/asm/internal/lex/input.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/syntax/parser_test.go
src/cmd/internal/obj/line_test.go
src/cmd/internal/obj/util.go
src/cmd/internal/src/pos.go
src/cmd/internal/src/pos_test.go
src/cmd/internal/src/xpos_test.go
test/fixedbugs/issue22660.go [new file with mode: 0644]

index ebe28bae9048f89bcc494fb543096a42846fdadd..118187f23b8e7a8bf95b958f40828cbd998706d9 100644 (file)
@@ -63,7 +63,7 @@ func expect(t *testing.T, file string, errors []*regexp.Regexp) {
        defer os.RemoveAll(dir)
 
        dst := filepath.Join(dir, strings.TrimSuffix(file, ".go"))
-       cmd := exec.Command("go", "build", "-o="+dst, path(file))
+       cmd := exec.Command("go", "build", "-gcflags=-L", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted
        out, err := cmd.CombinedOutput()
        if err == nil {
                t.Errorf("expected cgo to fail but it succeeded")
index ddfcddf36d8bdd91a1c968a1697fa5ad3b9df8d3..666611e17996e176e0b59cb5d88b88fe0403a0c3 100644 (file)
@@ -13,6 +13,7 @@ import (
        "text/scanner"
 
        "cmd/asm/internal/flags"
+       "cmd/internal/objabi"
        "cmd/internal/src"
 )
 
@@ -454,7 +455,7 @@ func (in *Input) line() {
                in.Error("unexpected token at end of #line: ", tok)
        }
        pos := src.MakePos(in.Base(), uint(in.Line()), uint(in.Col()))
-       in.Stack.SetBase(src.NewLinePragmaBase(pos, file, uint(line)))
+       in.Stack.SetBase(src.NewLinePragmaBase(pos, file, objabi.AbsFile(objabi.WorkingDir(), file, *flags.TrimPath), uint(line)))
 }
 
 // #undef processing
index 6f633a494fbf69b2bee47e5a515d7bdf120a4095..be2fe552f6f8e7db6d646ccb5986b6e656d63d6a 100644 (file)
@@ -192,6 +192,7 @@ func Main(archInit func(*Arch)) {
        objabi.Flagcount("E", "debug symbol export", &Debug['E'])
        objabi.Flagfn1("I", "add `directory` to import search path", addidir)
        objabi.Flagcount("K", "debug missing line numbers", &Debug['K'])
+       objabi.Flagcount("L", "show full file names in error messages", &Debug['L'])
        objabi.Flagcount("N", "disable optimizations", &Debug['N'])
        flag.BoolVar(&Debug_asm, "S", false, "print assembly listing")
        objabi.AddVersionFlag() // -V
index b7d530c98c816aa07517b2b2d197f92a5a9c0ac4..81441ba7004e90cfd2a0aeb2bbaac77cfed088ef 100644 (file)
@@ -93,7 +93,7 @@ func hcrash() {
 }
 
 func linestr(pos src.XPos) string {
-       return Ctxt.OutermostPos(pos).Format(Debug['C'] == 0)
+       return Ctxt.OutermostPos(pos).Format(Debug['C'] == 0, Debug['L'] == 1)
 }
 
 // lasterror keeps track of the most recently issued error.
index 7047266a7049fd410c28dafd699f12d7206e5221..ff3e769864e8f3b74a19c4dbb5d40aed7cda4b9b 100644 (file)
@@ -80,11 +80,12 @@ func (p *parser) updateBase(line, col uint, text string) {
                p.error_at(p.pos_at(line, col+uint(i+1)), "invalid line number: "+nstr)
                return
        }
-       absFile := text[:i]
+       filename := text[:i]
+       absFilename := filename
        if p.fileh != nil {
-               absFile = p.fileh(absFile)
+               absFilename = p.fileh(filename)
        }
-       p.base = src.NewLinePragmaBase(src.MakePos(p.base.Pos().Base(), line, col), absFile, uint(n))
+       p.base = src.NewLinePragmaBase(src.MakePos(p.base.Pos().Base(), line, col), filename, absFilename, uint(n))
 }
 
 func (p *parser) got(tok token) bool {
index 0478088ec895d1d60e7e59918c61bcadac07ada5..309f1333f4e782765c0435d682caf74c0f808ec4 100644 (file)
@@ -221,7 +221,7 @@ func TestLineDirectives(t *testing.T) {
                if msg := perr.Msg; msg != test.msg {
                        t.Errorf("%s: got msg = %q; want %q", test.src, msg, test.msg)
                }
-               if filename := perr.Pos.RelFilename(); filename != test.filename {
+               if filename := perr.Pos.AbsFilename(); filename != test.filename {
                        t.Errorf("%s: got filename = %q; want %q", test.src, filename, test.filename)
                }
                if line := perr.Pos.RelLine(); line != test.line+linebase {
index 6b21abecd25c07d9ea58eb6be2ec9e27ac3ed1cf..f159a65e2b9e5fffe120bbf5f400092d2883d6d9 100644 (file)
@@ -17,7 +17,7 @@ func TestLinkgetlineFromPos(t *testing.T) {
 
        afile := src.NewFileBase("a.go", "a.go")
        bfile := src.NewFileBase("b.go", "/foo/bar/b.go")
-       lfile := src.NewLinePragmaBase(src.MakePos(afile, 7, 0), "linedir", 100)
+       lfile := src.NewLinePragmaBase(src.MakePos(afile, 7, 0), "linedir", "linedir", 100)
 
        var tests = []struct {
                pos  src.Pos
index f1ac1a88085f1385179265a0df3947c28ef737c5..867c69f3efb23659936a950a4c0651aa3f5eeeef 100644 (file)
@@ -15,7 +15,7 @@ const REG_NONE = 0
 
 // Line returns a string containing the filename and line number for p
 func (p *Prog) Line() string {
-       return p.Ctxt.OutermostPos(p.Pos).Format(false)
+       return p.Ctxt.OutermostPos(p.Pos).Format(false, true)
 }
 
 // LineNumber returns a string containing the line number for p's position
index a1ea3fcdac71acfe35b107872a709fda0b3cfd87..10fa924c0bef1bc7effea841387d885b74fcf81b 100644 (file)
@@ -79,15 +79,15 @@ func (p Pos) AbsFilename() string { return p.base.AbsFilename() }
 func (p Pos) SymFilename() string { return p.base.SymFilename() }
 
 func (p Pos) String() string {
-       return p.Format(true)
+       return p.Format(true, true)
 }
 
 // Format formats a position as "filename:line" or "filename:line:column",
-// controlled by the showCol flag.
-// If the position is relative to a line directive, the original position
-// is appended in square brackets without column (since the column doesn't
-// change).
-func (p Pos) Format(showCol bool) string {
+// controlled by the showCol flag. A position relative to a line directive
+// is always formatted without column information. In that case, if showOrig
+// is set, the original position (again controlled by showCol) is appended
+// in square brackets: "filename:line[origfile:origline:origcolumn]".
+func (p Pos) Format(showCol, showOrig bool) string {
        if !p.IsKnown() {
                return "<unknown line number>"
        }
@@ -105,8 +105,11 @@ func (p Pos) Format(showCol bool) string {
        // that's provided via a line directive).
        // TODO(gri) This may not be true if we have an inlining base.
        // We may want to differentiate at some point.
-       return format(p.RelFilename(), p.RelLine(), 0, false) +
-               "[" + format(p.Filename(), p.Line(), p.Col(), showCol) + "]"
+       s := format(p.RelFilename(), p.RelLine(), 0, false)
+       if showOrig {
+               s += "[" + format(p.Filename(), p.Line(), p.Col(), showCol) + "]"
+       }
+       return s
 }
 
 // format formats a (filename, line, col) tuple as "filename:line" (showCol
@@ -155,8 +158,8 @@ func NewFileBase(filename, absFilename string) *PosBase {
 // NewLinePragmaBase returns a new *PosBase for a line pragma of the form
 //      //line filename:line
 // at position pos.
-func NewLinePragmaBase(pos Pos, filename string, line uint) *PosBase {
-       return &PosBase{pos, filename, filename, FileSymPrefix + filename, line - 1, -1}
+func NewLinePragmaBase(pos Pos, filename, absFilename string, line uint) *PosBase {
+       return &PosBase{pos, filename, absFilename, FileSymPrefix + absFilename, line - 1, -1}
 }
 
 // NewInliningBase returns a copy of the old PosBase with the given inlining
index a101bc10b129e60c09f19d5d7e346e10eef0c7bb..b06d38253611879a583cd4877d598c53a89e355f 100644 (file)
@@ -12,16 +12,16 @@ import (
 func TestPos(t *testing.T) {
        f0 := NewFileBase("", "")
        f1 := NewFileBase("f1", "f1")
-       f2 := NewLinePragmaBase(Pos{}, "f2", 10)
-       f3 := NewLinePragmaBase(MakePos(f1, 10, 1), "f3", 100)
-       f4 := NewLinePragmaBase(MakePos(f3, 10, 1), "f4", 100)
+       f2 := NewLinePragmaBase(Pos{}, "f2", "f2", 10)
+       f3 := NewLinePragmaBase(MakePos(f1, 10, 1), "f3", "f3", 100)
+       f4 := NewLinePragmaBase(MakePos(f3, 10, 1), "f4", "f4", 100)
 
        // line directives from issue #19392
        fp := NewFileBase("p.go", "p.go")
-       fc := NewLinePragmaBase(MakePos(fp, 3, 0), "c.go", 10)
-       ft := NewLinePragmaBase(MakePos(fp, 6, 0), "t.go", 20)
-       fv := NewLinePragmaBase(MakePos(fp, 9, 0), "v.go", 30)
-       ff := NewLinePragmaBase(MakePos(fp, 12, 0), "f.go", 40)
+       fc := NewLinePragmaBase(MakePos(fp, 3, 0), "c.go", "c.go", 10)
+       ft := NewLinePragmaBase(MakePos(fp, 6, 0), "t.go", "t.go", 20)
+       fv := NewLinePragmaBase(MakePos(fp, 9, 0), "v.go", "v.go", 30)
+       ff := NewLinePragmaBase(MakePos(fp, 12, 0), "f.go", "f.go", 40)
 
        for _, test := range []struct {
                pos    Pos
index 4cfeedcd0567eb4261f124f135f8a1254153047e..8ac9c9dc4ec006e6d395f987bc6f1aec0f688c31 100644 (file)
@@ -19,7 +19,7 @@ func TestNoXPos(t *testing.T) {
 func TestConversion(t *testing.T) {
        b1 := NewFileBase("b1", "b1")
        b2 := NewFileBase("b2", "b2")
-       b3 := NewLinePragmaBase(MakePos(b1, 10, 0), "b3", 123)
+       b3 := NewLinePragmaBase(MakePos(b1, 10, 0), "b3", "b3", 123)
 
        var tab PosTable
        for _, want := range []Pos{
diff --git a/test/fixedbugs/issue22660.go b/test/fixedbugs/issue22660.go
new file mode 100644 (file)
index 0000000..48686fe
--- /dev/null
@@ -0,0 +1,50 @@
+// run
+
+// 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
+
+import (
+       "bytes"
+       "fmt"
+       "io/ioutil"
+       "log"
+       "os"
+       "os/exec"
+       "path/filepath"
+       "runtime"
+       "strings"
+)
+
+func main() {
+       if runtime.GOOS == "nacl" {
+               return // no file system available on builders
+       }
+
+       f, err := ioutil.TempFile("", "issue22660.go")
+       if err != nil {
+               log.Fatal(err)
+       }
+       f.Close()
+       defer os.Remove(f.Name())
+
+       // path must appear in error messages even if we strip them with -trimpath
+       path := filepath.Join("users", "xxx", "go")
+       var src bytes.Buffer
+       fmt.Fprintf(&src, "//line %s:1\n", filepath.Join(path, "foo.go"))
+
+       if err := ioutil.WriteFile(f.Name(), src.Bytes(), 0660); err != nil {
+               log.Fatal(err)
+       }
+
+       out, err := exec.Command("go", "tool", "compile", fmt.Sprintf("-trimpath=%s", path), f.Name()).CombinedOutput()
+       if err == nil {
+               log.Fatalf("expected compiling %s to fail", f.Name())
+       }
+
+       if !strings.HasPrefix(string(out), path) {
+               log.Fatalf("expected full path (%s) in error message, got:\n%s", path, out)
+       }
+}