From fc5df089da6c02397897f11a875a593353dc0590 Mon Sep 17 00:00:00 2001 From: Trey Lawrence Date: Tue, 23 Aug 2016 16:43:43 -0400 Subject: [PATCH] cmd/compile: fix compiler bug for constant equality comparison The compiler incorrectly will error when comparing a nil pointer interface to a nil pointer of any other type. Example: (*int)(nil) == interface{}(nil) Will error with "gc: illegal constant expression: *int == interface {}" Fixes #16702 Change-Id: I1a15d651df2cfca6762b1783a28b377b2e6ff8c6 Reviewed-on: https://go-review.googlesource.com/27591 Run-TryBot: Matthew Dempsky TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/const.go | 3 +++ test/const.go | 35 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index 4e2468917c2..1d6bb15272c 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -827,6 +827,9 @@ func evconst(n *Node) { // check for compatible general types (numeric, string, etc) if wl != wr { + if wl == TINTER || wr == TINTER { + goto setfalse + } goto illegal } diff --git a/test/const.go b/test/const.go index 6c293363967..f8e0a753cbc 100644 --- a/test/const.go +++ b/test/const.go @@ -123,9 +123,44 @@ func floats() { assert(f == f1e3, "f == f1e3") } +func interfaces() { + var ( + nilN interface{} + nilI *int + five = 5 + + _ = nil == interface{}(nil) + _ = interface{}(nil) == nil + ) + ii := func(i1 interface{}, i2 interface{}) bool { return i1 == i2 } + ni := func(n interface{}, i int) bool { return n == i } + in := func(i int, n interface{}) bool { return i == n } + pi := func(p *int, i interface{}) bool { return p == i } + ip := func(i interface{}, p *int) bool { return i == p } + + assert((interface{}(nil) == interface{}(nil)) == ii(nilN, nilN), + "for interface{}==interface{} compiler == runtime") + + assert(((*int)(nil) == interface{}(nil)) == pi(nilI, nilN), + "for *int==interface{} compiler == runtime") + assert((interface{}(nil) == (*int)(nil)) == ip(nilN, nilI), + "for interface{}==*int compiler == runtime") + + assert((&five == interface{}(nil)) == pi(&five, nilN), + "for interface{}==*int compiler == runtime") + assert((interface{}(nil) == &five) == ip(nilN, &five), + "for interface{}==*int compiler == runtime") + + assert((5 == interface{}(5)) == ni(five, five), + "for int==interface{} compiler == runtime") + assert((interface{}(5) == 5) == in(five, five), + "for interface{}==int comipiler == runtime") +} + func main() { ints() floats() + interfaces() assert(ctrue == true, "ctrue == true") assert(cfalse == false, "cfalse == false")