-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
Go version
tip
Output of go env in your module/workspace:
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/iant/.cache/go-build'
GOENV='/home/iant/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/iant/gopath/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/iant/gopath'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org'
GOROOT='/home/iant/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/iant/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='devel go1.23-377646589d Fri May 24 22:23:55 2024 +0000'
GODEBUG=''
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/iant/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3319284758=/tmp/go-build -gno-record-gcc-switches'What did you do?
Build this package:
package p
import "C"
func F() *C.char {
s, err := C.CString("hi")
if err != nil {
println(err)
}
return s
}What did you see happen?
With no -gcflags option:
# command-line-arguments
$WORK/b001/_cgo_gotypes.go:75:6: _Cfunc_CString redeclared in this block
$WORK/b001/_cgo_gotypes.go:53:6: other declaration of _Cfunc_CString
foo.go:6:12: undefined: _C2func_CString
With -gcflags=-L:
# command-line-arguments
$WORK/b001/_cgo_gotypes.go:75:6: C.CString redeclared in this block
$WORK/b001/_cgo_gotypes.go:53:6: other declaration of C.CString
foo.go:6:12: undefined: C.CString
What did you expect to see?
I don't expect -gcflags=L to change the function name reported by the compiler. The -L option is documented as "Show complete file path in error messages." Why should that change the function name?
This turns out to happen because of some code in cmd/go/internal/work/shell.go. That code looks for lines that match the regexp \[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]. With -gcflags=-L, the compiler emits lines like
./foo.go:6:12[/tmp/go-build1291356211/b001/foo.cgo1.go:9:28]: undefined: _C2func_CString
That matches the regexp. In that case cmd/go strips the line in square brackets, and then translates _C2func_ to C.. That was introduced in https://go.dev/cl/7231075 for the Go 1.1 release. From looking at the source code, it does appear that at that time the compiler always printed the original file name in square brackets if a //line directive had been used. Today that only happens if the -L option has been used.