]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: fix compiler bug for constant equality comparison
authorTrey Lawrence <lawrence.trey@gmail.com>
Tue, 23 Aug 2016 20:43:43 +0000 (16:43 -0400)
committerMatthew Dempsky <mdempsky@google.com>
Sat, 17 Sep 2016 01:12:24 +0000 (01:12 +0000)
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 <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/const.go
test/const.go

index 4e2468917c26eb330cac07ad3dbdedf1212502fe..1d6bb15272c9a86ac74cd8a64fdb76bdaae8da4e 100644 (file)
@@ -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
        }
 
index 6c29336396797280eb700d55429430fe81658e42..f8e0a753cbcb4db7d0e9626cab2fc80f4a5b8875 100644 (file)
@@ -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")