go: cmd/compile: internal compiler error: Type.Elem UNSAFEPTR
What version of Go are you using (go version
)?
$ go version go version devel +4091cf972a Sun Mar 31 23:35:35 2019 +0000 linux/amd64
Does this issue reproduce with the latest release?
reproducible only on tip
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GOARCH="amd64" GOBIN="" GOCACHE="/home/travis/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/travis/gopath" GOPROXY="" GORACE="" GOROOT="/home/travis/.gimme/versions/go" GOTMPDIR="" GOTOOLDIR="/home/travis/.gimme/versions/go/pkg/tool/linux_amd64" GCCGO="gccgo" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build848806544=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I have a pretty old package with some hacks for optimization.
I use some of its features in my web framework.
In travis, I check if the framework pass the tests on tip.
One of the steps in travis script is the go get -v
.
When go get tries to precompile that old package, it crashes.
So, one of the files looks like this:
package runtimer
import (
"unsafe" // #nosec
)
func PtrToString(ptr unsafe.Pointer) string {
return *(*string)(ptr)
}
func PtrToStringPtr(ptr unsafe.Pointer) *string {
return (*string)(ptr)
}
func PtrPtrToStringPtr(ptr *unsafe.Pointer) *string {
return (*string)(*ptr) // <- compiler complains about this line
}
Then I’ve commented out the last func.
Then the file looks like this:
package runtimer
import (
"unsafe" // #nosec
)
func PtrToString(ptr unsafe.Pointer) string {
return *(*string)(ptr)
}
func PtrToStringPtr(ptr unsafe.Pointer) *string {
return (*string)(ptr) // <- and then it complains about this line
}
/*
func PtrPtrToStringPtr(ptr *unsafe.Pointer) *string {
return (*string)(*ptr)
}
*/
What did you expect to see?
unsafe.Pointer
works as it work two years ago
What did you see instead?
# github.com/gramework/runtimer
../runtimer/utils.go:16:2: internal compiler error: Type.Elem UNSAFEPTR
goroutine 34 [running]:
runtime/debug.Stack(0x1039ae0, 0xc00000e018, 0x0)
/home/travis/.gimme/versions/go/src/runtime/debug/stack.go:24 +0x9d
cmd/compile/internal/gc.Fatalf(0xe8ef7d, 0xc, 0xc0007c7550, 0x1, 0x1)
/home/travis/.gimme/versions/go/src/cmd/compile/internal/gc/subr.go:190 +0x292
cmd/compile/internal/types.(*Type).Elem(0xc000061e60, 0xc000538460)
/home/travis/.gimme/versions/go/src/cmd/compile/internal/types/type.go:801 +0xff
cmd/compile/internal/ssa.(*Func).computeZeroMap(0xc000804000, 0xe12f01)
/home/travis/.gimme/versions/go/src/cmd/compile/internal/ssa/writebarrier.go:391 +0x101
cmd/compile/internal/ssa.writebarrier(0xc000804000)
/home/travis/.gimme/versions/go/src/cmd/compile/internal/ssa/writebarrier.go:80 +0x6b
cmd/compile/internal/ssa.Compile(0xc000804000)
/home/travis/.gimme/versions/go/src/cmd/compile/internal/ssa/compile.go:90 +0x476
cmd/compile/internal/gc.buildssa(0xc0003c9b80, 0x0, 0x0)
/home/travis/.gimme/versions/go/src/cmd/compile/internal/gc/ssa.go:288 +0xbf3
cmd/compile/internal/gc.compileSSA(0xc0003c9b80, 0x0)
/home/travis/.gimme/versions/go/src/cmd/compile/internal/gc/pgen.go:297 +0x4d
cmd/compile/internal/gc.compileFunctions.func2(0xc000404de0, 0xc000407200, 0x0)
/home/travis/.gimme/versions/go/src/cmd/compile/internal/gc/pgen.go:362 +0x49
created by cmd/compile/internal/gc.compileFunctions
/home/travis/.gimme/versions/go/src/cmd/compile/internal/gc/pgen.go:360 +0x128
About this issue
- Original URL
- State: open
- Created 5 years ago
- Comments: 22 (18 by maintainers)
Right. We’d have to plumb the line number to the error reporter some other way, so that it uses the function-currently-being-compiled line number instead of the global one.
We’re on a slow burn to remove all the global variables in the compiler anyway. This would be one step in that direction as well.
We do this all the time for unexported API. The fact that the function named
runtime.newobject
even exists from one release to the next is surprising. For example, all of these functions disappeared from packageruntime
from 1.11 to 1.12:linkname
is not even anunsafe
feature. It’s not documented in theunsafe
package or theunsafe
section of the spec. It’s doubly unsafe. We never intended it to be used outside the stdlib (which needs it to, e.g., allowreflect
to accessruntime
services).If you’re using
linkname
, the onus is on you to adapt to changes in the compiler and runtime.#31121 is about exported API, and that’s a totally different ballgame. For that we have the Go 1 compatibility guarantee. I think the relevant clause is
But I agree that it’s a grey area, and whether #31121 fits in that category isn’t as clear cut as this issue is.
That’s because the compiler has control over all calls to
runtime.newobject
(except forlinkname
shenanigans, of course), and ensures that the type of the result of that call is always correct - a pointer to a base type.