cmd/compile: report mismatched version set by //go:build

Fixes #63489

Change-Id: I5e02dc5165ada7f5c292d56203dc670e96eaf2c1
Reviewed-on: https://go-review.googlesource.com/c/go/+/534755
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Cuong Manh Le 2023-10-12 08:35:37 +07:00 committed by Gopher Robot
parent 40cdf69fc9
commit 1f25f96463
3 changed files with 54 additions and 11 deletions

View File

@ -29,8 +29,12 @@ func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info) {
// setup and syntax error reporting
files := make([]*syntax.File, len(noders))
// posBaseMap maps all file pos bases back to *syntax.File
// for checking Go version mismatched.
posBaseMap := make(map[*syntax.PosBase]*syntax.File)
for i, p := range noders {
files[i] = p.file
posBaseMap[p.file.Pos().Base()] = p.file
}
// typechecking
@ -43,17 +47,8 @@ func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info) {
Context: ctxt,
GoVersion: base.Flag.Lang,
IgnoreBranchErrors: true, // parser already checked via syntax.CheckBranches mode
Error: func(err error) {
terr := err.(types2.Error)
msg := terr.Msg
// if we have a version error, hint at the -lang setting
if versionErrorRx.MatchString(msg) {
msg = fmt.Sprintf("%s (-lang was set to %s; check go.mod)", msg, base.Flag.Lang)
}
base.ErrorfAt(m.makeXPos(terr.Pos), terr.Code, "%s", msg)
},
Importer: &importer,
Sizes: types2.SizesFor("gc", buildcfg.GOARCH),
Importer: &importer,
Sizes: types2.SizesFor("gc", buildcfg.GOARCH),
}
if base.Flag.ErrorURL {
conf.ErrorURL = " [go.dev/e/%s]"
@ -69,6 +64,27 @@ func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info) {
FileVersions: make(map[*syntax.PosBase]types2.Version),
// expand as needed
}
conf.Error = func(err error) {
terr := err.(types2.Error)
msg := terr.Msg
if versionErrorRx.MatchString(msg) {
posBase := terr.Pos.Base()
for !posBase.IsFileBase() { // line directive base
posBase = posBase.Pos().Base()
}
v := info.FileVersions[posBase]
fileVersion := fmt.Sprintf("go%d.%d", v.Major, v.Minor)
file := posBaseMap[posBase]
if file.GoVersion == fileVersion {
// If we have a version error caused by //go:build, report it.
msg = fmt.Sprintf("%s (file declares //go:build %s)", msg, fileVersion)
} else {
// Otherwise, hint at the -lang setting.
msg = fmt.Sprintf("%s (-lang was set to %s; check go.mod)", msg, base.Flag.Lang)
}
}
base.ErrorfAt(m.makeXPos(terr.Pos), terr.Code, "%s", msg)
}
pkg, err := conf.Check(base.Ctxt.Pkgpath, files, info)
base.ExitIfErrors()

View File

@ -0,0 +1,16 @@
// errorcheck -lang=go1.21
// 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.
//go:build go1.4
package p
const c = 0o123 // ERROR "file declares //go:build go1.4"
// ERROR "file declares //go:build go1.4"
//line issue63489a.go:13:1
const d = 0o124

View File

@ -0,0 +1,11 @@
// errorcheck -lang=go1.4
// 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.
//go:build go1.4
package p
const c = 0o123 // ERROR "file declares //go:build go1.4"