Russ Cox | 0b477ef | 2012-02-16 23:48:57 -0500 | [diff] [blame] | 1 | // run |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 2 | |
| 3 | // Copyright 2009 The Go Authors. All rights reserved. |
| 4 | // Use of this source code is governed by a BSD-style |
| 5 | // license that can be found in the LICENSE file. |
| 6 | |
Rob Pike | fc0dc04 | 2012-02-19 13:19:43 +1100 | [diff] [blame] | 7 | // Test equality and inequality operations. |
| 8 | |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 9 | package main |
| 10 | |
Alan Donovan | aa5aaab | 2013-02-21 12:48:38 -0500 | [diff] [blame] | 11 | import ( |
| 12 | "os" |
| 13 | "unsafe" |
| 14 | ) |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 15 | |
Luuk van Dijk | 7e6890a | 2011-12-15 17:50:59 +0100 | [diff] [blame] | 16 | var global bool |
Alan Donovan | aa5aaab | 2013-02-21 12:48:38 -0500 | [diff] [blame] | 17 | |
Luuk van Dijk | 7e6890a | 2011-12-15 17:50:59 +0100 | [diff] [blame] | 18 | func use(b bool) { global = b } |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 19 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 20 | func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) } |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 21 | |
| 22 | func isfalse(b bool) { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 23 | if b { |
| 24 | // stack will explain where |
| 25 | panic("wanted false, got true") |
| 26 | } |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 27 | } |
| 28 | |
| 29 | func istrue(b bool) { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 30 | if !b { |
| 31 | // stack will explain where |
| 32 | panic("wanted true, got false") |
| 33 | } |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 34 | } |
| 35 | |
Russ Cox | 23bd214 | 2010-09-13 15:42:47 -0400 | [diff] [blame] | 36 | type T *int |
| 37 | |
Rémy Oudompheng | e5f01ae | 2014-02-27 08:07:50 +0100 | [diff] [blame] | 38 | type X int |
| 39 | |
| 40 | func (X) x() {} |
| 41 | |
Robert Griesemer | 542099d | 2009-12-09 19:27:08 -0800 | [diff] [blame] | 42 | func main() { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 43 | var a []int |
| 44 | var b map[string]int |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 45 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 46 | var c string = "hello" |
| 47 | var d string = "hel" // try to get different pointer |
| 48 | d = d + "lo" |
Alan Donovan | aa5aaab | 2013-02-21 12:48:38 -0500 | [diff] [blame] | 49 | |
Alan Donovan | 8fb6c3a | 2013-07-16 12:18:00 -0400 | [diff] [blame] | 50 | // go.tools/ssa/interp can't handle unsafe.Pointer. |
| 51 | if os.Getenv("GOSSAINTERP") == "" { |
Alan Donovan | aa5aaab | 2013-02-21 12:48:38 -0500 | [diff] [blame] | 52 | if stringptr(c) == stringptr(d) { |
| 53 | panic("compiler too smart -- got same string") |
| 54 | } |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 55 | } |
| 56 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 57 | var e = make(chan int) |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 58 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 59 | var ia interface{} = a |
| 60 | var ib interface{} = b |
| 61 | var ic interface{} = c |
| 62 | var id interface{} = d |
| 63 | var ie interface{} = e |
| 64 | |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 65 | // these comparisons are okay because |
| 66 | // string compare is okay and the others |
| 67 | // are comparisons where the types differ. |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 68 | isfalse(ia == ib) |
| 69 | isfalse(ia == ic) |
| 70 | isfalse(ia == id) |
| 71 | isfalse(ib == ic) |
| 72 | isfalse(ib == id) |
| 73 | istrue(ic == id) |
| 74 | istrue(ie == ie) |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 75 | |
| 76 | istrue(ia != ib) |
| 77 | istrue(ia != ic) |
| 78 | istrue(ia != id) |
| 79 | istrue(ib != ic) |
| 80 | istrue(ib != id) |
| 81 | isfalse(ic != id) |
| 82 | isfalse(ie != ie) |
| 83 | |
| 84 | // these are not okay, because there is no comparison on slices or maps. |
| 85 | //isfalse(a == ib) |
| 86 | //isfalse(a == ic) |
| 87 | //isfalse(a == id) |
| 88 | //isfalse(b == ic) |
| 89 | //isfalse(b == id) |
| 90 | |
Russ Cox | 23bd214 | 2010-09-13 15:42:47 -0400 | [diff] [blame] | 91 | istrue(c == id) |
| 92 | istrue(e == ie) |
| 93 | |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 94 | //isfalse(ia == b) |
Russ Cox | 23bd214 | 2010-09-13 15:42:47 -0400 | [diff] [blame] | 95 | isfalse(ia == c) |
| 96 | isfalse(ia == d) |
| 97 | isfalse(ib == c) |
| 98 | isfalse(ib == d) |
| 99 | istrue(ic == d) |
| 100 | istrue(ie == e) |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 101 | |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 102 | //istrue(a != ib) |
| 103 | //istrue(a != ic) |
| 104 | //istrue(a != id) |
| 105 | //istrue(b != ic) |
| 106 | //istrue(b != id) |
| 107 | isfalse(c != id) |
| 108 | isfalse(e != ie) |
| 109 | |
| 110 | //istrue(ia != b) |
| 111 | istrue(ia != c) |
| 112 | istrue(ia != d) |
| 113 | istrue(ib != c) |
| 114 | istrue(ib != d) |
| 115 | isfalse(ic != d) |
| 116 | isfalse(ie != e) |
| 117 | |
Russ Cox | 9b6d385 | 2009-01-26 12:36:21 -0800 | [diff] [blame] | 118 | // 6g used to let this go through as true. |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 119 | var g uint64 = 123 |
| 120 | var h int64 = 123 |
| 121 | var ig interface{} = g |
| 122 | var ih interface{} = h |
| 123 | isfalse(ig == ih) |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 124 | istrue(ig != ih) |
Russ Cox | 9b6d385 | 2009-01-26 12:36:21 -0800 | [diff] [blame] | 125 | |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 126 | // map of interface should use == on interface values, |
| 127 | // not memory. |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 128 | var m = make(map[interface{}]int) |
| 129 | m[ic] = 1 |
| 130 | m[id] = 2 |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 131 | if m[c] != 2 { |
| 132 | println("m[c] = ", m[c]) |
| 133 | panic("bad m[c]") |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 134 | } |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 135 | |
Rémy Oudompheng | e5f01ae | 2014-02-27 08:07:50 +0100 | [diff] [blame] | 136 | // interface comparisons (issue 7207) |
| 137 | { |
| 138 | type I1 interface { |
| 139 | x() |
| 140 | } |
| 141 | type I2 interface { |
| 142 | x() |
| 143 | } |
| 144 | a1 := I1(X(0)) |
| 145 | b1 := I1(X(1)) |
| 146 | a2 := I2(X(0)) |
| 147 | b2 := I2(X(1)) |
| 148 | a3 := I1(a2) |
| 149 | a4 := I2(a1) |
| 150 | var e interface{} = X(0) |
| 151 | a5 := e.(I1) |
| 152 | a6 := e.(I2) |
| 153 | isfalse(a1 == b1) |
| 154 | isfalse(a1 == b2) |
| 155 | isfalse(a2 == b1) |
| 156 | isfalse(a2 == b2) |
| 157 | istrue(a1 == a2) |
| 158 | istrue(a1 == a3) |
| 159 | istrue(a1 == a4) |
| 160 | istrue(a1 == a5) |
| 161 | istrue(a1 == a6) |
| 162 | istrue(a2 == a3) |
| 163 | istrue(a2 == a4) |
| 164 | istrue(a2 == a5) |
| 165 | istrue(a2 == a6) |
| 166 | istrue(a3 == a4) |
| 167 | istrue(a3 == a5) |
| 168 | istrue(a3 == a6) |
| 169 | istrue(a4 == a5) |
| 170 | istrue(a4 == a6) |
| 171 | istrue(a5 == a6) |
| 172 | } |
| 173 | |
Russ Cox | 23bd214 | 2010-09-13 15:42:47 -0400 | [diff] [blame] | 174 | // non-interface comparisons |
| 175 | { |
| 176 | c := make(chan int) |
| 177 | c1 := (<-chan int)(c) |
| 178 | c2 := (chan<- int)(c) |
| 179 | istrue(c == c1) |
| 180 | istrue(c == c2) |
| 181 | istrue(c1 == c) |
| 182 | istrue(c2 == c) |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 183 | |
| 184 | isfalse(c != c1) |
| 185 | isfalse(c != c2) |
| 186 | isfalse(c1 != c) |
| 187 | isfalse(c2 != c) |
| 188 | |
Russ Cox | 23bd214 | 2010-09-13 15:42:47 -0400 | [diff] [blame] | 189 | d := make(chan int) |
| 190 | isfalse(c == d) |
| 191 | isfalse(d == c) |
| 192 | isfalse(d == c1) |
| 193 | isfalse(d == c2) |
| 194 | isfalse(c1 == d) |
| 195 | isfalse(c2 == d) |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 196 | |
| 197 | istrue(c != d) |
| 198 | istrue(d != c) |
| 199 | istrue(d != c1) |
| 200 | istrue(d != c2) |
| 201 | istrue(c1 != d) |
| 202 | istrue(c2 != d) |
Russ Cox | 23bd214 | 2010-09-13 15:42:47 -0400 | [diff] [blame] | 203 | } |
| 204 | |
| 205 | // named types vs not |
| 206 | { |
| 207 | var x = new(int) |
| 208 | var y T |
| 209 | var z T = x |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 210 | |
Russ Cox | 23bd214 | 2010-09-13 15:42:47 -0400 | [diff] [blame] | 211 | isfalse(x == y) |
| 212 | istrue(x == z) |
| 213 | isfalse(y == z) |
| 214 | |
| 215 | isfalse(y == x) |
| 216 | istrue(z == x) |
| 217 | isfalse(z == y) |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 218 | |
| 219 | istrue(x != y) |
| 220 | isfalse(x != z) |
| 221 | istrue(y != z) |
| 222 | |
| 223 | istrue(y != x) |
| 224 | isfalse(z != x) |
| 225 | istrue(z != y) |
Russ Cox | 23bd214 | 2010-09-13 15:42:47 -0400 | [diff] [blame] | 226 | } |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 227 | |
| 228 | // structs |
| 229 | { |
| 230 | var x = struct { |
| 231 | x int |
| 232 | y string |
| 233 | }{1, "hi"} |
| 234 | var y = struct { |
| 235 | x int |
| 236 | y string |
| 237 | }{2, "bye"} |
| 238 | var z = struct { |
| 239 | x int |
| 240 | y string |
| 241 | }{1, "hi"} |
| 242 | |
| 243 | isfalse(x == y) |
| 244 | isfalse(y == x) |
| 245 | isfalse(y == z) |
| 246 | isfalse(z == y) |
| 247 | istrue(x == z) |
| 248 | istrue(z == x) |
| 249 | |
| 250 | istrue(x != y) |
| 251 | istrue(y != x) |
| 252 | istrue(y != z) |
| 253 | istrue(z != y) |
| 254 | isfalse(x != z) |
| 255 | isfalse(z != x) |
| 256 | |
| 257 | var m = make(map[struct { |
| 258 | x int |
| 259 | y string |
| 260 | }]int) |
| 261 | m[x] = 10 |
| 262 | m[y] = 20 |
| 263 | m[z] = 30 |
| 264 | istrue(m[x] == 30) |
| 265 | istrue(m[y] == 20) |
| 266 | istrue(m[z] == 30) |
| 267 | istrue(m[x] != 10) |
| 268 | isfalse(m[x] != 30) |
| 269 | isfalse(m[y] != 20) |
| 270 | isfalse(m[z] != 30) |
| 271 | isfalse(m[x] == 10) |
| 272 | |
| 273 | var m1 = make(map[struct { |
| 274 | x int |
| 275 | y string |
| 276 | }]struct { |
| 277 | x int |
| 278 | y string |
| 279 | }) |
| 280 | m1[x] = x |
| 281 | m1[y] = y |
| 282 | m1[z] = z |
| 283 | istrue(m1[x] == z) |
| 284 | istrue(m1[y] == y) |
| 285 | istrue(m1[z] == z) |
| 286 | istrue(m1[x] == x) |
| 287 | isfalse(m1[x] != z) |
| 288 | isfalse(m1[y] != y) |
| 289 | isfalse(m1[z] != z) |
| 290 | isfalse(m1[x] != x) |
| 291 | |
| 292 | var ix, iy, iz interface{} = x, y, z |
| 293 | |
| 294 | isfalse(ix == iy) |
| 295 | isfalse(iy == ix) |
| 296 | isfalse(iy == iz) |
| 297 | isfalse(iz == iy) |
| 298 | istrue(ix == iz) |
| 299 | istrue(iz == ix) |
| 300 | |
| 301 | isfalse(x == iy) |
| 302 | isfalse(y == ix) |
| 303 | isfalse(y == iz) |
| 304 | isfalse(z == iy) |
| 305 | istrue(x == iz) |
| 306 | istrue(z == ix) |
| 307 | |
| 308 | isfalse(ix == y) |
| 309 | isfalse(iy == x) |
| 310 | isfalse(iy == z) |
| 311 | isfalse(iz == y) |
| 312 | istrue(ix == z) |
| 313 | istrue(iz == x) |
| 314 | |
| 315 | istrue(ix != iy) |
| 316 | istrue(iy != ix) |
| 317 | istrue(iy != iz) |
| 318 | istrue(iz != iy) |
| 319 | isfalse(ix != iz) |
| 320 | isfalse(iz != ix) |
| 321 | |
| 322 | istrue(x != iy) |
| 323 | istrue(y != ix) |
| 324 | istrue(y != iz) |
| 325 | istrue(z != iy) |
| 326 | isfalse(x != iz) |
| 327 | isfalse(z != ix) |
| 328 | |
| 329 | istrue(ix != y) |
| 330 | istrue(iy != x) |
| 331 | istrue(iy != z) |
| 332 | istrue(iz != y) |
| 333 | isfalse(ix != z) |
| 334 | isfalse(iz != x) |
| 335 | } |
Alan Donovan | aa5aaab | 2013-02-21 12:48:38 -0500 | [diff] [blame] | 336 | |
Russ Cox | c4c92eb | 2012-02-17 14:45:29 -0500 | [diff] [blame] | 337 | // structs with _ fields |
| 338 | { |
| 339 | var x = struct { |
| 340 | x int |
Rémy Oudompheng | 428ea68 | 2013-07-02 09:08:43 +0200 | [diff] [blame] | 341 | _ string |
Russ Cox | c4c92eb | 2012-02-17 14:45:29 -0500 | [diff] [blame] | 342 | y float64 |
| 343 | _ float64 |
| 344 | z int |
| 345 | }{ |
| 346 | x: 1, y: 2, z: 3, |
| 347 | } |
| 348 | var ix interface{} = x |
Alan Donovan | aa5aaab | 2013-02-21 12:48:38 -0500 | [diff] [blame] | 349 | |
Russ Cox | c4c92eb | 2012-02-17 14:45:29 -0500 | [diff] [blame] | 350 | istrue(x == x) |
| 351 | istrue(x == ix) |
| 352 | istrue(ix == x) |
| 353 | istrue(ix == ix) |
| 354 | } |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 355 | |
| 356 | // arrays |
| 357 | { |
| 358 | var x = [2]string{"1", "hi"} |
| 359 | var y = [2]string{"2", "bye"} |
| 360 | var z = [2]string{"1", "hi"} |
| 361 | |
| 362 | isfalse(x == y) |
| 363 | isfalse(y == x) |
| 364 | isfalse(y == z) |
| 365 | isfalse(z == y) |
| 366 | istrue(x == z) |
| 367 | istrue(z == x) |
| 368 | |
| 369 | istrue(x != y) |
| 370 | istrue(y != x) |
| 371 | istrue(y != z) |
| 372 | istrue(z != y) |
| 373 | isfalse(x != z) |
| 374 | isfalse(z != x) |
| 375 | |
| 376 | var m = make(map[[2]string]int) |
| 377 | m[x] = 10 |
| 378 | m[y] = 20 |
| 379 | m[z] = 30 |
| 380 | istrue(m[x] == 30) |
| 381 | istrue(m[y] == 20) |
| 382 | istrue(m[z] == 30) |
| 383 | isfalse(m[x] != 30) |
| 384 | isfalse(m[y] != 20) |
| 385 | isfalse(m[z] != 30) |
| 386 | |
| 387 | var ix, iy, iz interface{} = x, y, z |
| 388 | |
| 389 | isfalse(ix == iy) |
| 390 | isfalse(iy == ix) |
| 391 | isfalse(iy == iz) |
| 392 | isfalse(iz == iy) |
| 393 | istrue(ix == iz) |
| 394 | istrue(iz == ix) |
| 395 | |
| 396 | isfalse(x == iy) |
| 397 | isfalse(y == ix) |
| 398 | isfalse(y == iz) |
| 399 | isfalse(z == iy) |
| 400 | istrue(x == iz) |
| 401 | istrue(z == ix) |
| 402 | |
| 403 | isfalse(ix == y) |
| 404 | isfalse(iy == x) |
| 405 | isfalse(iy == z) |
| 406 | isfalse(iz == y) |
| 407 | istrue(ix == z) |
| 408 | istrue(iz == x) |
| 409 | |
| 410 | istrue(ix != iy) |
| 411 | istrue(iy != ix) |
| 412 | istrue(iy != iz) |
| 413 | istrue(iz != iy) |
| 414 | isfalse(ix != iz) |
| 415 | isfalse(iz != ix) |
| 416 | |
| 417 | istrue(x != iy) |
| 418 | istrue(y != ix) |
| 419 | istrue(y != iz) |
| 420 | istrue(z != iy) |
| 421 | isfalse(x != iz) |
| 422 | isfalse(z != ix) |
| 423 | |
| 424 | istrue(ix != y) |
| 425 | istrue(iy != x) |
| 426 | istrue(iy != z) |
| 427 | istrue(iz != y) |
| 428 | isfalse(ix != z) |
| 429 | isfalse(iz != x) |
| 430 | } |
| 431 | |
Rémy Oudompheng | 14b0af4 | 2014-02-24 19:51:59 +0100 | [diff] [blame] | 432 | // named booleans |
| 433 | { |
| 434 | type mybool bool |
| 435 | var b mybool |
| 436 | |
| 437 | type T struct{ data [20]byte } |
| 438 | var x, y T |
| 439 | b = x == y |
| 440 | istrue(x == y) |
| 441 | istrue(bool(b)) |
| 442 | |
| 443 | m := make(map[string][10]interface{}) |
| 444 | b = m["x"] == m["y"] |
| 445 | istrue(m["x"] == m["y"]) |
| 446 | istrue(bool(b)) |
| 447 | } |
| 448 | |
Russ Cox | 4bdf1fc | 2011-09-26 19:35:21 -0400 | [diff] [blame] | 449 | shouldPanic(p1) |
| 450 | shouldPanic(p2) |
| 451 | shouldPanic(p3) |
| 452 | shouldPanic(p4) |
| 453 | } |
| 454 | |
| 455 | func p1() { |
| 456 | var a []int |
| 457 | var ia interface{} = a |
| 458 | use(ia == ia) |
| 459 | } |
| 460 | |
| 461 | func p2() { |
| 462 | var b []int |
| 463 | var ib interface{} = b |
| 464 | use(ib == ib) |
| 465 | } |
| 466 | |
| 467 | func p3() { |
| 468 | var a []int |
| 469 | var ia interface{} = a |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 470 | var m = make(map[interface{}]int) |
Russ Cox | 4bdf1fc | 2011-09-26 19:35:21 -0400 | [diff] [blame] | 471 | m[ia] = 1 |
| 472 | } |
| 473 | |
| 474 | func p4() { |
| 475 | var b []int |
| 476 | var ib interface{} = b |
Russ Cox | 196b663 | 2011-12-12 22:22:09 -0500 | [diff] [blame] | 477 | var m = make(map[interface{}]int) |
Russ Cox | 4bdf1fc | 2011-09-26 19:35:21 -0400 | [diff] [blame] | 478 | m[ib] = 1 |
| 479 | } |
| 480 | |
| 481 | func shouldPanic(f func()) { |
| 482 | defer func() { |
| 483 | if recover() == nil { |
| 484 | panic("function should panic") |
| 485 | } |
| 486 | }() |
| 487 | f() |
Russ Cox | a7f6d40 | 2009-01-26 09:56:42 -0800 | [diff] [blame] | 488 | } |