Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: internal compiler error: constant type mismatch when comparing two unsafe.Pointer rvalues #21221

Closed
vibhavp opened this issue Jul 30, 2017 · 10 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Milestone

Comments

@vibhavp
Copy link

vibhavp commented Jul 30, 2017

What version of Go are you using (go version)?

go version go1.8.3 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"

What did you do?

https://play.golang.org/p/MTZIms61wt

package main

import "unsafe"

func main() {
	println(unsafe.Pointer(uintptr(0)) == unsafe.Pointer(nil))
}

What did you expect to see?

go build should compile correctly and produce a binary that outputs true

What did you see instead?

The compiler errors out with the following message:

# command-line-arguments
./size.go:6: internal compiler error: constant type mismatch unsafe.Pointer(1) unsafe.Pointer(7)

goroutine 1 [running]:
runtime/debug.Stack(0x0, 0x0, 0x0)
	/usr/lib/go/src/runtime/debug/stack.go:24 +0x79
cmd/compile/internal/gc.Fatalf(0xacc786, 0x24, 0xc42036af68, 0x4, 0x4)
	/usr/lib/go/src/cmd/compile/internal/gc/subr.go:167 +0x226
cmd/compile/internal/gc.evconst(0xc4203570e0)
	/usr/lib/go/src/cmd/compile/internal/gc/const.go:871 +0x35bb
cmd/compile/internal/gc.typecheck1(0xc4203570e0, 0x2, 0x0)
	/usr/lib/go/src/cmd/compile/internal/gc/typecheck.go:706 +0x219c
cmd/compile/internal/gc.typecheck(0xc4203570e0, 0x2, 0x0)
	/usr/lib/go/src/cmd/compile/internal/gc/typecheck.go:188 +0x608
cmd/compile/internal/gc.typecheckslice(0xc420078538, 0x1, 0x1, 0x2)
	/usr/lib/go/src/cmd/compile/internal/gc/typecheck.go:49 +0x4e
cmd/compile/internal/gc.typecheck1(0xc420356cf0, 0x1, 0xc4200f4f30)
	/usr/lib/go/src/cmd/compile/internal/gc/typecheck.go:1862 +0x58fa
cmd/compile/internal/gc.typecheck1(0xc420356cf0, 0x1, 0x4)
	/usr/lib/go/src/cmd/compile/internal/gc/typecheck.go:1203 +0x45c7
cmd/compile/internal/gc.typecheck(0xc420356cf0, 0x1, 0x3)
	/usr/lib/go/src/cmd/compile/internal/gc/typecheck.go:188 +0x608
cmd/compile/internal/gc.typecheckslice(0xc420078540, 0x1, 0x1, 0x1)
	/usr/lib/go/src/cmd/compile/internal/gc/typecheck.go:49 +0x4e
cmd/compile/internal/gc.Main()
	/usr/lib/go/src/cmd/compile/internal/gc/main.go:374 +0x1938
main.main()
	/usr/lib/go/src/cmd/compile/main.go:50 +0xfe
@odeke-em
Copy link
Member

I can still reproduce this on tip/Go1.9 ac29f30

$ go run main.go 
# command-line-arguments
./main.go:6:37: internal compiler error: constant type mismatch unsafe.Pointer(1) unsafe.Pointer(7)

goroutine 1 [running]:
runtime/debug.Stack(0x0, 0x0, 0x0)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/runtime/debug/stack.go:24 +0xa7
cmd/compile/internal/gc.Fatalf(0x1767673, 0x24, 0xc4203309f0, 0x4, 0x4)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/subr.go:181 +0x230
cmd/compile/internal/gc.evconst(0xc4202f8d00)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/const.go:941 +0x2a83
cmd/compile/internal/gc.typecheck1(0xc4202f8d00, 0x2, 0x0)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/typecheck.go:727 +0x201d
cmd/compile/internal/gc.typecheck(0xc4202f8d00, 0x2, 0x0)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/typecheck.go:201 +0x782
cmd/compile/internal/gc.typecheckslice(0xc42000c520, 0x1, 0x1, 0x2)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/typecheck.go:55 +0x54
cmd/compile/internal/gc.typecheck1(0xc4202f8980, 0x1, 0xc4202d8b40)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/typecheck.go:1944 +0x99b1
cmd/compile/internal/gc.typecheck1(0xc4202f8980, 0x1, 0x10b2f91)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/typecheck.go:1229 +0x4163
cmd/compile/internal/gc.typecheck(0xc4202f8980, 0x1, 0x3)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/typecheck.go:201 +0x782
cmd/compile/internal/gc.typecheckslice(0xc42000c528, 0x1, 0x1, 0x1)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/typecheck.go:55 +0x54
cmd/compile/internal/gc.Main(0x17715d0)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/internal/gc/main.go:480 +0x1fd0
main.main()
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/cmd/compile/main.go:49 +0x95

Paging a few folks from the compiler squad @josharian @mdempsky @griesemer

@odeke-em odeke-em added this to the Go1.10 milestone Jul 30, 2017
@odeke-em
Copy link
Member

To help give a better picture of the root cause of the issue being when directly comparing unnamed constants and rvalues, the code below successfully compiles if it uses a permutation of lvalues https://play.golang.org/p/hti5OO9PcF or inlined below

package main

import (
	"unsafe"
)

func main() {
	a1 := unsafe.Pointer(uintptr(0))
	a2 := unsafe.Pointer(nil)
	println(a1 == unsafe.Pointer(nil))
	println(a2 == unsafe.Pointer(uintpr(0)))
        println(a1 == a2)
}

Successfully compiles and runs giving

true
true
true

@odeke-em odeke-em changed the title cmd/compile: internal compiler error: constant type mismatch cmd/compile: internal compiler error: constant type mismatch when comparing two unsafe.Pointer rvalues Jul 30, 2017
@ALTree ALTree added release-blocker NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jul 30, 2017
@ALTree
Copy link
Member

ALTree commented Jul 30, 2017

Can reproduce this in go1.1.1 so not exactly a recent regression

$ go version
go version go1.1.1 linux/amd64
$ go build crash.go 
# command-line-arguments
./crash.go:6: internal compiler error: constant type mismatch unsafe.Pointer(1) unsafe.Pointer(7)

I couldn't check go1.0 because the gcc version on my system refuses to build it.

@mdempsky
Copy link
Member

It looks like the problem is unsafe.Pointer(uintptr(0)) creates an OLITERAL with an Mpint Val, but unsafe.Pointer(nil) creates one with a NilVal instead. Comparing these then causes the evconst panic, because we don't expect to ever compare constants with identical Go types but different Val types.

@choleraehyq
Copy link
Contributor

Should we simply add an exceptional case in evconst to solve this? Seems no other types can have the same problem.

@gopherbot
Copy link

Change https://golang.org/cl/53644 mentions this issue: cmd/compile: fix const type check panic when comparing two unsafe.Pointer

@mdempsky mdempsky modified the milestones: Go1.10, Go1.11 Nov 29, 2017
@mdempsky
Copy link
Member

I'm leaning towards thinking we should just replace NilVal with Mpint(0), but that'll be a bit more involved solution.

@gopherbot
Copy link

Change https://golang.org/cl/85795 mentions this issue: cmd/compile: fix constant pointer comparison panic

@choleraehyq
Copy link
Contributor

Sorry for my delay, I'm a little bit busy these months.

Replacing NilVal with Mpint(0) in all places seems difficult, and rewriting NilVal to Mpint(0) in convlit1 also cause some side effects, so I've updated my CL back to the initial way, rewrite NilVal in evconst. It's not so elegant but work.

@gopherbot
Copy link

Change https://golang.org/cl/105315 mentions this issue: cmd/compile: fix constant pointer comparison failure

@golang golang locked and limited conversation to collaborators Apr 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Projects
None yet
Development

No branches or pull requests

6 participants