diff options
Diffstat (limited to 'test/cmp.go')
-rw-r--r-- | test/cmp.go | 488 |
1 files changed, 488 insertions, 0 deletions
diff --git a/test/cmp.go b/test/cmp.go new file mode 100644 index 0000000..6db9ce5 --- /dev/null +++ b/test/cmp.go @@ -0,0 +1,488 @@ +// run + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test equality and inequality operations. + +package main + +import ( + "os" + "unsafe" +) + +var global bool + +func use(b bool) { global = b } + +func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) } + +func isfalse(b bool) { + if b { + // stack will explain where + panic("wanted false, got true") + } +} + +func istrue(b bool) { + if !b { + // stack will explain where + panic("wanted true, got false") + } +} + +type T *int + +type X int + +func (X) x() {} + +func main() { + var a []int + var b map[string]int + + var c string = "hello" + var d string = "hel" // try to get different pointer + d = d + "lo" + + // go.tools/ssa/interp can't handle unsafe.Pointer. + if os.Getenv("GOSSAINTERP") == "" { + if stringptr(c) == stringptr(d) { + panic("compiler too smart -- got same string") + } + } + + var e = make(chan int) + + var ia interface{} = a + var ib interface{} = b + var ic interface{} = c + var id interface{} = d + var ie interface{} = e + + // these comparisons are okay because + // string compare is okay and the others + // are comparisons where the types differ. + isfalse(ia == ib) + isfalse(ia == ic) + isfalse(ia == id) + isfalse(ib == ic) + isfalse(ib == id) + istrue(ic == id) + istrue(ie == ie) + + istrue(ia != ib) + istrue(ia != ic) + istrue(ia != id) + istrue(ib != ic) + istrue(ib != id) + isfalse(ic != id) + isfalse(ie != ie) + + // these are not okay, because there is no comparison on slices or maps. + //isfalse(a == ib) + //isfalse(a == ic) + //isfalse(a == id) + //isfalse(b == ic) + //isfalse(b == id) + + istrue(c == id) + istrue(e == ie) + + //isfalse(ia == b) + isfalse(ia == c) + isfalse(ia == d) + isfalse(ib == c) + isfalse(ib == d) + istrue(ic == d) + istrue(ie == e) + + //istrue(a != ib) + //istrue(a != ic) + //istrue(a != id) + //istrue(b != ic) + //istrue(b != id) + isfalse(c != id) + isfalse(e != ie) + + //istrue(ia != b) + istrue(ia != c) + istrue(ia != d) + istrue(ib != c) + istrue(ib != d) + isfalse(ic != d) + isfalse(ie != e) + + // gc used to let this go through as true. + var g uint64 = 123 + var h int64 = 123 + var ig interface{} = g + var ih interface{} = h + isfalse(ig == ih) + istrue(ig != ih) + + // map of interface should use == on interface values, + // not memory. + var m = make(map[interface{}]int) + m[ic] = 1 + m[id] = 2 + if m[c] != 2 { + println("m[c] = ", m[c]) + panic("bad m[c]") + } + + // interface comparisons (issue 7207) + { + type I1 interface { + x() + } + type I2 interface { + x() + } + a1 := I1(X(0)) + b1 := I1(X(1)) + a2 := I2(X(0)) + b2 := I2(X(1)) + a3 := I1(a2) + a4 := I2(a1) + var e interface{} = X(0) + a5 := e.(I1) + a6 := e.(I2) + isfalse(a1 == b1) + isfalse(a1 == b2) + isfalse(a2 == b1) + isfalse(a2 == b2) + istrue(a1 == a2) + istrue(a1 == a3) + istrue(a1 == a4) + istrue(a1 == a5) + istrue(a1 == a6) + istrue(a2 == a3) + istrue(a2 == a4) + istrue(a2 == a5) + istrue(a2 == a6) + istrue(a3 == a4) + istrue(a3 == a5) + istrue(a3 == a6) + istrue(a4 == a5) + istrue(a4 == a6) + istrue(a5 == a6) + } + + // non-interface comparisons + { + c := make(chan int) + c1 := (<-chan int)(c) + c2 := (chan<- int)(c) + istrue(c == c1) + istrue(c == c2) + istrue(c1 == c) + istrue(c2 == c) + + isfalse(c != c1) + isfalse(c != c2) + isfalse(c1 != c) + isfalse(c2 != c) + + d := make(chan int) + isfalse(c == d) + isfalse(d == c) + isfalse(d == c1) + isfalse(d == c2) + isfalse(c1 == d) + isfalse(c2 == d) + + istrue(c != d) + istrue(d != c) + istrue(d != c1) + istrue(d != c2) + istrue(c1 != d) + istrue(c2 != d) + } + + // named types vs not + { + var x = new(int) + var y T + var z T = x + + isfalse(x == y) + istrue(x == z) + isfalse(y == z) + + isfalse(y == x) + istrue(z == x) + isfalse(z == y) + + istrue(x != y) + isfalse(x != z) + istrue(y != z) + + istrue(y != x) + isfalse(z != x) + istrue(z != y) + } + + // structs + { + var x = struct { + x int + y string + }{1, "hi"} + var y = struct { + x int + y string + }{2, "bye"} + var z = struct { + x int + y string + }{1, "hi"} + + isfalse(x == y) + isfalse(y == x) + isfalse(y == z) + isfalse(z == y) + istrue(x == z) + istrue(z == x) + + istrue(x != y) + istrue(y != x) + istrue(y != z) + istrue(z != y) + isfalse(x != z) + isfalse(z != x) + + var m = make(map[struct { + x int + y string + }]int) + m[x] = 10 + m[y] = 20 + m[z] = 30 + istrue(m[x] == 30) + istrue(m[y] == 20) + istrue(m[z] == 30) + istrue(m[x] != 10) + isfalse(m[x] != 30) + isfalse(m[y] != 20) + isfalse(m[z] != 30) + isfalse(m[x] == 10) + + var m1 = make(map[struct { + x int + y string + }]struct { + x int + y string + }) + m1[x] = x + m1[y] = y + m1[z] = z + istrue(m1[x] == z) + istrue(m1[y] == y) + istrue(m1[z] == z) + istrue(m1[x] == x) + isfalse(m1[x] != z) + isfalse(m1[y] != y) + isfalse(m1[z] != z) + isfalse(m1[x] != x) + + var ix, iy, iz interface{} = x, y, z + + isfalse(ix == iy) + isfalse(iy == ix) + isfalse(iy == iz) + isfalse(iz == iy) + istrue(ix == iz) + istrue(iz == ix) + + isfalse(x == iy) + isfalse(y == ix) + isfalse(y == iz) + isfalse(z == iy) + istrue(x == iz) + istrue(z == ix) + + isfalse(ix == y) + isfalse(iy == x) + isfalse(iy == z) + isfalse(iz == y) + istrue(ix == z) + istrue(iz == x) + + istrue(ix != iy) + istrue(iy != ix) + istrue(iy != iz) + istrue(iz != iy) + isfalse(ix != iz) + isfalse(iz != ix) + + istrue(x != iy) + istrue(y != ix) + istrue(y != iz) + istrue(z != iy) + isfalse(x != iz) + isfalse(z != ix) + + istrue(ix != y) + istrue(iy != x) + istrue(iy != z) + istrue(iz != y) + isfalse(ix != z) + isfalse(iz != x) + } + + // structs with _ fields + { + var x = struct { + x int + _ string + y float64 + _ float64 + z int + }{ + x: 1, y: 2, z: 3, + } + var ix interface{} = x + + istrue(x == x) + istrue(x == ix) + istrue(ix == x) + istrue(ix == ix) + } + + // arrays + { + var x = [2]string{"1", "hi"} + var y = [2]string{"2", "bye"} + var z = [2]string{"1", "hi"} + + isfalse(x == y) + isfalse(y == x) + isfalse(y == z) + isfalse(z == y) + istrue(x == z) + istrue(z == x) + + istrue(x != y) + istrue(y != x) + istrue(y != z) + istrue(z != y) + isfalse(x != z) + isfalse(z != x) + + var m = make(map[[2]string]int) + m[x] = 10 + m[y] = 20 + m[z] = 30 + istrue(m[x] == 30) + istrue(m[y] == 20) + istrue(m[z] == 30) + isfalse(m[x] != 30) + isfalse(m[y] != 20) + isfalse(m[z] != 30) + + var ix, iy, iz interface{} = x, y, z + + isfalse(ix == iy) + isfalse(iy == ix) + isfalse(iy == iz) + isfalse(iz == iy) + istrue(ix == iz) + istrue(iz == ix) + + isfalse(x == iy) + isfalse(y == ix) + isfalse(y == iz) + isfalse(z == iy) + istrue(x == iz) + istrue(z == ix) + + isfalse(ix == y) + isfalse(iy == x) + isfalse(iy == z) + isfalse(iz == y) + istrue(ix == z) + istrue(iz == x) + + istrue(ix != iy) + istrue(iy != ix) + istrue(iy != iz) + istrue(iz != iy) + isfalse(ix != iz) + isfalse(iz != ix) + + istrue(x != iy) + istrue(y != ix) + istrue(y != iz) + istrue(z != iy) + isfalse(x != iz) + isfalse(z != ix) + + istrue(ix != y) + istrue(iy != x) + istrue(iy != z) + istrue(iz != y) + isfalse(ix != z) + isfalse(iz != x) + } + + // named booleans + { + type mybool bool + var b mybool + + type T struct{ data [20]byte } + var x, y T + b = x == y + istrue(x == y) + istrue(bool(b)) + + m := make(map[string][10]interface{}) + b = m["x"] == m["y"] + istrue(m["x"] == m["y"]) + istrue(bool(b)) + } + + shouldPanic(p1) + shouldPanic(p2) + shouldPanic(p3) + shouldPanic(p4) +} + +func p1() { + var a []int + var ia interface{} = a + use(ia == ia) +} + +func p2() { + var b []int + var ib interface{} = b + use(ib == ib) +} + +func p3() { + var a []int + var ia interface{} = a + var m = make(map[interface{}]int) + m[ia] = 1 +} + +func p4() { + var b []int + var ib interface{} = b + var m = make(map[interface{}]int) + m[ib] = 1 +} + +func shouldPanic(f func()) { + defer func() { + if recover() == nil { + panic("function should panic") + } + }() + f() +} |