diff --git a/misc/cgo/errors/errors_test.go b/misc/cgo/errors/errors_test.go index 1bdf843451d..07e6b570870 100644 --- a/misc/cgo/errors/errors_test.go +++ b/misc/cgo/errors/errors_test.go @@ -107,6 +107,7 @@ func TestReportsTypeErrors(t *testing.T) { for _, file := range []string{ "err1.go", "err2.go", + "err5.go", "issue11097a.go", "issue11097b.go", "issue18452.go", diff --git a/misc/cgo/errors/testdata/err5.go b/misc/cgo/errors/testdata/err5.go new file mode 100644 index 00000000000..573ebe34da7 --- /dev/null +++ b/misc/cgo/errors/testdata/err5.go @@ -0,0 +1,7 @@ +// Copyright 2023 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 +//line /tmp/_cgo_.go:1 +//go:cgo_dynamic_linker "/elf/interp" // ERROR HERE: only allowed in cgo-generated code +func main() {} diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index 802aab22684..b4d3024f987 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -1612,6 +1612,25 @@ func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.P return pragma } +// 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 = Ctxt.Pathname + } + filename = objabi.AbsFile(dir, filename, pathPrefix) + } + return filename +} + // isCgoGeneratedFile reports whether pos is in a file // generated by cgo, which is to say a file with name // beginning with "_cgo_". Such files are allowed to @@ -1619,7 +1638,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().Pos().Base())), "_cgo_") } // safeArg reports whether arg is a "safe" command-line argument, diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go index 9601fab9e0d..45ca4033a47 100644 --- a/src/cmd/compile/internal/syntax/parser.go +++ b/src/cmd/compile/internal/syntax/parser.go @@ -146,11 +146,14 @@ 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 { diff --git a/src/cmd/compile/internal/syntax/pos.go b/src/cmd/compile/internal/syntax/pos.go index c683c7fcfc1..64e70c70b85 100644 --- a/src/cmd/compile/internal/syntax/pos.go +++ b/src/cmd/compile/internal/syntax/pos.go @@ -93,15 +93,21 @@ 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} - base.pos.base = base - return base + 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 } // NewLineBase returns a new PosBase for a line directive "line filename:line:col" @@ -109,8 +115,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 { @@ -148,6 +154,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