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: go1.8rc1 failure when comparing interface with struct #18661

Closed
danw opened this issue Jan 15, 2017 · 10 comments
Closed

cmd/compile: go1.8rc1 failure when comparing interface with struct #18661

danw opened this issue Jan 15, 2017 · 10 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@danw
Copy link

danw commented Jan 15, 2017

What did you do?

package main

func test(obj interface{}) {
        if obj != struct{a *string}{} {
        }
}

func main() {}

What did you expect to see?

Successful compile:

$ go build test.go
$

What did you see instead?

$ go build test.go
# test
./test.go:4: internal compiler error: arguments of comparison must be lvalues - <node IDATA> statictmp_0

goroutine 1 [running]:
runtime/debug.Stack(0x0, 0x0, 0x0)
	/usr/local/go/src/runtime/debug/stack.go:24 +0x79
cmd/compile/internal/gc.Fatalf(0x16c0b76, 0x2f, 0xc42034fd90, 0x2, 0x2)
	/usr/local/go/src/cmd/compile/internal/gc/subr.go:167 +0x226
cmd/compile/internal/gc.walkcompare(0xc420352090, 0xc420350860, 0xc42033fc20)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:3121 +0x1b7
cmd/compile/internal/gc.walkexpr(0xc420352090, 0xc420350860, 0xc42033fef0)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:580 +0x7d91
cmd/compile/internal/gc.walkexpr(0xc420352120, 0xc42033f330, 0xc420352120)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:591 +0x2038
cmd/compile/internal/gc.finishcompare(0xc42033f3b0, 0xc420352120, 0xc42033f330, 0xc420352120)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:3202 +0x50
cmd/compile/internal/gc.walkcompare(0xc42033f3b0, 0xc42033f330, 0xc42033fc20)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:3092 +0xbe9
cmd/compile/internal/gc.walkexpr(0xc42033f3b0, 0xc42033f330, 0x0)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:580 +0x7d91
cmd/compile/internal/gc.walkstmt(0xc42033f320, 0xc42032c7a0)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:280 +0x1326
cmd/compile/internal/gc.walkstmtlist(0xc42000c5e8, 0x1, 0x1)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:80 +0x44
cmd/compile/internal/gc.walk(0xc42033ec60)
	/usr/local/go/src/cmd/compile/internal/gc/walk.go:65 +0x1c0
cmd/compile/internal/gc.compile(0xc42033ec60)
	/usr/local/go/src/cmd/compile/internal/gc/pgen.go:350 +0x1c5
cmd/compile/internal/gc.funccompile(0xc42033ec60)
	/usr/local/go/src/cmd/compile/internal/gc/dcl.go:1292 +0xdc
cmd/compile/internal/gc.Main()
	/usr/local/go/src/cmd/compile/internal/gc/main.go:463 +0x1f0d
main.main()
	/usr/local/go/src/cmd/compile/main.go:50 +0xfe

$

Does this issue reproduce with the latest release (go1.7.4)?

This happens on go1.8rc1, but not go1.7.4.

The above test case was simplified from code on android.googlesource.com which broke when we upgraded to go1.8rc1.

System details

go version go1.8rc1 darwin/amd64
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/dwillemsen/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/1z/kwdn8sm90vq5k6dn_lw_hxl4003qx4/T/go-build876510221=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
GOROOT/bin/go version: go version go1.8rc1 darwin/amd64
GOROOT/bin/go tool compile -V: compile version go1.8rc1 X:framepointer
uname -v: Darwin Kernel Version 16.3.0: Thu Nov 17 20:23:58 PST 2016; root:xnu-3789.31.2~1/RELEASE_X86_64
ProductName:	Mac OS X
ProductVersion:	10.12.2
BuildVersion:	16C67
lldb --version: lldb-360.1.70
@davecheney
Copy link
Contributor

davecheney commented Jan 15, 2017 via email

@bradfitz bradfitz added this to the Go1.8 milestone Jan 15, 2017
@bradfitz
Copy link
Contributor

Thanks for the report and reduction.

@bradfitz bradfitz added the NeedsFix The path to resolution is known, but the work has not been done. label Jan 15, 2017
@JayNakrani
Copy link
Contributor

JayNakrani commented Jan 15, 2017

Below is Dump() of cmpl and cmpr at walk.go#L3120. Difference is that, we now generate OIDATA node for cmpl.

At tip:

cmpl [0xc42036a000]
.   IDATA u(2) l(4) tc(1) STRUCT-struct { a *string }
.   .   NAME-p.obj u(1) a(true) g(1) l(3) x(0) class(PPARAM) f(1) esc(no) tc(1) used(true) INTER-interface {}
cmpr [0xc420351c20]
.   NAME-p.statictmp_0 u(1) a(true) l(4) x(0) class(PEXTERN) f(1) tc(1) used(true) STRUCT-struct { a *string }
issue18661.go:4: internal compiler error: arguments of comparison must be lvalues - <node IDATA> statictmp_0

In branch release-branch.go1.7:

cmpl [0xc420429200]
.   NAME-p.autotmp_1 u(1) a(true) l(4) x(0+0) class(PAUTO) esc(N) tc(1) addrtaken assigned used(true) STRUCT-struct { a *string }
cmpr [0xc420429170]
.   NAME-p.statictmp_0 u(1) a(true) l(4) x(0+0) class(PEXTERN) f(1) tc(1) used(true) STRUCT-struct { a *string }

OIDATA was added in golang.org/cl/26659. Perhaps, islvalue() just needs to handle that case, now that compiler generates it. @josharian to confirm.

@davecheney
Copy link
Contributor

davecheney commented Jan 15, 2017 via email

@dsnet
Copy link
Member

dsnet commented Jan 15, 2017

Git bisect reports 1a7fc7b as the issue.

\cc @josharian @randall77

@josharian
Copy link
Contributor

Thanks for the report and concise reproducer, @danw. CL to come shortly.

@JayNakrani
Copy link
Contributor

@davecheney

the code sample provided by the OP was a syntax error, it should have been spotted earlier before it got to this part of the code gen

Perhaps, I'm missing something. What's the syntax error here? The spec says,

"A value x of non-interface type X and a value t of interface type T are comparable when values of type X are comparable and X implements T. They are equal if t's dynamic type is identical to X and t's dynamic value is equal to x"

I think obj != struct{...}{} satisfies that.

@gopherbot
Copy link

CL https://golang.org/cl/35236 mentions this issue.

@davecheney
Copy link
Contributor

davecheney commented Jan 15, 2017 via email

@gopherbot
Copy link

CL https://golang.org/cl/36126 mentions this issue.

gopherbot pushed a commit that referenced this issue Feb 2, 2017
Make sure that the lack of an lvalue doesn't
cause extra side-effects.

Updates #18661
Updates #18739

Change-Id: I52eb4b4a5c6f8ff5cddd2115455f853c18112c19
Reviewed-on: https://go-review.googlesource.com/36126
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
@golang golang locked and limited conversation to collaborators Feb 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

9 participants