]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/syntax: add PosBase.Trimmed
authorMatthew Dempsky <mdempsky@google.com>
Thu, 19 Aug 2021 22:52:53 +0000 (15:52 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 20 Aug 2021 19:44:02 +0000 (19:44 +0000)
With types2, some syntax.PosBases need to be constructed from export
data, which must only contain "trimmed" filenames (i.e., that they've
already been made absolute and undergone -trimpath processing).
However, it's not safe to apply trimming to a filename multiple times,
and in general we can't distinguish trimmed from untrimmed filenames.

This CL resolves this by adding a PosBase.Trimmed boolean so we can
distinguish whether the associated filename has been trimmed yet. This
is a bit hacky, but is the least bad solution I've come up with so
far.

This unblocks enabling -G=3 by default.

Change-Id: I7383becfb704680a36f7603e3246af38b21f100b
Reviewed-on: https://go-review.googlesource.com/c/go/+/343731
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/importer/iimport.go
src/cmd/compile/internal/noder/noder.go
src/cmd/compile/internal/noder/posmap.go
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/reader2.go
src/cmd/compile/internal/noder/writer.go
src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/syntax/pos.go

index ac5ec7c8f2928f7a39801189e939e63ed3db558c..4384e59c30a931769983a663562babf7041a3b6d 100644 (file)
@@ -257,7 +257,7 @@ func (p *iimporter) posBaseAt(off uint64) *syntax.PosBase {
                return posBase
        }
        filename := p.stringAt(off)
-       posBase := syntax.NewFileBase(filename)
+       posBase := syntax.NewTrimmedFileBase(filename, true)
        p.posBaseCache[off] = posBase
        return posBase
 }
index 6a2aacd3fea71fa5d46d361834cefc60993829f7..2b67a91b3f799bddc1f69927e2bd39cc669e4056 100644 (file)
@@ -191,13 +191,23 @@ func (p *noder) errorAt(pos syntax.Pos, format string, args ...interface{}) {
        base.ErrorfAt(p.makeXPos(pos), format, args...)
 }
 
-// TODO(gri) Can we eliminate fileh in favor of absFilename?
-func fileh(name string) string {
-       return objabi.AbsFile("", name, base.Flag.TrimPath)
-}
-
-func absFilename(name string) string {
-       return objabi.AbsFile(base.Ctxt.Pathname, name, base.Flag.TrimPath)
+// trimFilename returns the "trimmed" filename of b, which is the
+// absolute filename after applying -trimpath processing. This
+// filename form is suitable for use in object files and export data.
+//
+// If b's filename has already been trimmed (i.e., because it was read
+// in from an imported package's export data), then the filename is
+// returned unchanged.
+func trimFilename(b *syntax.PosBase) string {
+       filename := b.Filename()
+       if !b.Trimmed() {
+               dir := ""
+               if b.IsFileBase() {
+                       dir = base.Ctxt.Pathname
+               }
+               filename = objabi.AbsFile(dir, filename, base.Flag.TrimPath)
+       }
+       return filename
 }
 
 // noder transforms package syntax's AST into a Node tree.
@@ -1723,7 +1733,7 @@ func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.P
 // (primarily misuse of linker flags), other files are not.
 // See golang.org/issue/23672.
 func isCgoGeneratedFile(pos syntax.Pos) bool {
-       return strings.HasPrefix(filepath.Base(filepath.Clean(fileh(pos.Base().Filename()))), "_cgo_")
+       return strings.HasPrefix(filepath.Base(trimFilename(pos.Base())), "_cgo_")
 }
 
 // safeArg reports whether arg is a "safe" command-line argument,
index a6d3e2d7ef4d9ac0aa241eede47c23b2c6595e85..f22628f845f7225c3862d00ada9066eaf7c0054e 100644 (file)
@@ -45,8 +45,10 @@ func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
        b1, ok := m.bases[b0]
        if !ok {
                fn := b0.Filename()
+               absfn := trimFilename(b0)
+
                if b0.IsFileBase() {
-                       b1 = src.NewFileBase(fn, absFilename(fn))
+                       b1 = src.NewFileBase(fn, absfn)
                } else {
                        // line directive base
                        p0 := b0.Pos()
@@ -55,7 +57,7 @@ func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
                                panic("infinite recursion in makeSrcPosBase")
                        }
                        p1 := src.MakePos(m.makeSrcPosBase(p0b), p0.Line(), p0.Col())
-                       b1 = src.NewLinePragmaBase(p1, fn, fileh(fn), b0.Line(), b0.Col())
+                       b1 = src.NewLinePragmaBase(p1, fn, absfn, b0.Line(), b0.Col())
                }
                if m.bases == nil {
                        m.bases = make(map[*syntax.PosBase]*src.PosBase)
index 5481812b18d05c2f096797de8c91ad5499c876c9..985453a1bb3886912710f2e8ee32df378619e6f4 100644 (file)
@@ -194,16 +194,15 @@ func (pr *pkgReader) posBaseIdx(idx int) *src.PosBase {
        r := pr.newReader(relocPosBase, idx, syncPosBase)
        var b *src.PosBase
 
-       fn := r.string()
-       absfn := r.string()
+       filename := r.string()
 
        if r.bool() {
-               b = src.NewFileBase(fn, absfn)
+               b = src.NewFileBase(filename, filename)
        } else {
                pos := r.pos0()
                line := r.uint()
                col := r.uint()
-               b = src.NewLinePragmaBase(pos, fn, absfn, line, col)
+               b = src.NewLinePragmaBase(pos, filename, filename, line, col)
        }
 
        pr.posBases[idx] = b
index 22c742ab25176b6f4a25552a016a9ff8a73663cd..64c1612f70622962d855a717ab5832cca604f6fc 100644 (file)
@@ -109,15 +109,14 @@ func (pr *pkgReader2) posBaseIdx(idx int) *syntax.PosBase {
        var b *syntax.PosBase
 
        filename := r.string()
-       _ = r.string() // absolute file name
 
        if r.bool() {
-               b = syntax.NewFileBase(filename)
+               b = syntax.NewTrimmedFileBase(filename, true)
        } else {
                pos := r.pos()
                line := r.uint()
                col := r.uint()
-               b = syntax.NewLineBase(pos, filename, line, col)
+               b = syntax.NewLineBase(pos, filename, true, line, col)
        }
 
        pr.posBases[idx] = b
index d971bd0d164c7f7ec96f255cb3a6480248032ba4..a33b24e50cb9ad0a687330cfa33eabba01eec6ec 100644 (file)
@@ -189,11 +189,7 @@ func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) int {
        w := pw.newWriter(relocPosBase, syncPosBase)
        w.p.posBasesIdx[b] = w.idx
 
-       // TODO(mdempsky): What exactly does "fileh" do anyway? Is writing
-       // out both of these strings really the right thing to do here?
-       fn := b.Filename()
-       w.string(fn)
-       w.string(fileh(fn))
+       w.string(trimFilename(b))
 
        if !w.bool(b.IsFileBase()) {
                w.pos(b)
index 4fb6de10a820a527125a1e4bcd62e519e0dce7ef..c477ddd45d52adc83629294db9126a1cff5e9833 100644 (file)
@@ -146,11 +146,13 @@ func (p *parser) updateBase(pos Pos, tline, tcol uint, text string) {
        // If we have a column (//line filename:line:col form),
        // an empty filename means to use the previous filename.
        filename := text[:i-1] // lop off ":line"
+       trimmed := false
        if filename == "" && ok2 {
                filename = p.base.Filename()
+               trimmed = p.base.Trimmed()
        }
 
-       p.base = NewLineBase(pos, filename, line, col)
+       p.base = NewLineBase(pos, filename, trimmed, line, col)
 }
 
 func commentText(s string) string {
index baebcc995c759bbcb4719600e658b0a4920f881a..1494c0989fb11a1258649f6f0e45c39f7e147747 100644 (file)
@@ -133,13 +133,19 @@ type PosBase struct {
        pos       Pos
        filename  string
        line, col uint32
+       trimmed   bool // whether -trimpath has been applied
 }
 
 // NewFileBase returns a new PosBase for the given filename.
 // A file PosBase's position is relative to itself, with the
 // position being filename:1:1.
 func NewFileBase(filename string) *PosBase {
-       base := &PosBase{MakePos(nil, linebase, colbase), filename, linebase, colbase}
+       return NewTrimmedFileBase(filename, false)
+}
+
+// NewTrimmedFileBase is like NewFileBase, but allows specifying Trimmed.
+func NewTrimmedFileBase(filename string, trimmed bool) *PosBase {
+       base := &PosBase{MakePos(nil, linebase, colbase), filename, linebase, colbase, trimmed}
        base.pos.base = base
        return base
 }
@@ -149,8 +155,8 @@ func NewFileBase(filename string) *PosBase {
 // the comment containing the line directive. For a directive in a line comment,
 // that position is the beginning of the next line (i.e., the newline character
 // belongs to the line comment).
-func NewLineBase(pos Pos, filename string, line, col uint) *PosBase {
-       return &PosBase{pos, filename, sat32(line), sat32(col)}
+func NewLineBase(pos Pos, filename string, trimmed bool, line, col uint) *PosBase {
+       return &PosBase{pos, filename, sat32(line), sat32(col), trimmed}
 }
 
 func (base *PosBase) IsFileBase() bool {
@@ -188,6 +194,13 @@ func (base *PosBase) Col() uint {
        return uint(base.col)
 }
 
+func (base *PosBase) Trimmed() bool {
+       if base == nil {
+               return false
+       }
+       return base.trimmed
+}
+
 func sat32(x uint) uint32 {
        if x > PosMax {
                return PosMax