blob: 80d1bf699fd9805cd0fb7f52a562e88f5efdc5cc [file] [log] [blame]
Russ Cox0b477ef2012-02-16 23:48:57 -05001// run
Russ Coxa7f6d402009-01-26 09:56:42 -08002
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 Pikefc0dc042012-02-19 13:19:43 +11007// Test equality and inequality operations.
8
Russ Coxa7f6d402009-01-26 09:56:42 -08009package main
10
Alan Donovanaa5aaab2013-02-21 12:48:38 -050011import (
12 "os"
13 "unsafe"
14)
Russ Coxa7f6d402009-01-26 09:56:42 -080015
Luuk van Dijk7e6890a2011-12-15 17:50:59 +010016var global bool
Alan Donovanaa5aaab2013-02-21 12:48:38 -050017
Luuk van Dijk7e6890a2011-12-15 17:50:59 +010018func use(b bool) { global = b }
Russ Coxa7f6d402009-01-26 09:56:42 -080019
Rob Pike325cf8e2010-03-24 16:46:53 -070020func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) }
Russ Coxa7f6d402009-01-26 09:56:42 -080021
22func isfalse(b bool) {
Rob Pike325cf8e2010-03-24 16:46:53 -070023 if b {
24 // stack will explain where
25 panic("wanted false, got true")
26 }
Russ Coxa7f6d402009-01-26 09:56:42 -080027}
28
29func istrue(b bool) {
Rob Pike325cf8e2010-03-24 16:46:53 -070030 if !b {
31 // stack will explain where
32 panic("wanted true, got false")
33 }
Russ Coxa7f6d402009-01-26 09:56:42 -080034}
35
Russ Cox23bd2142010-09-13 15:42:47 -040036type T *int
37
Rémy Oudomphenge5f01ae2014-02-27 08:07:50 +010038type X int
39
40func (X) x() {}
41
Robert Griesemer542099d2009-12-09 19:27:08 -080042func main() {
Rob Pike325cf8e2010-03-24 16:46:53 -070043 var a []int
44 var b map[string]int
Russ Coxa7f6d402009-01-26 09:56:42 -080045
Rob Pike325cf8e2010-03-24 16:46:53 -070046 var c string = "hello"
47 var d string = "hel" // try to get different pointer
48 d = d + "lo"
Alan Donovanaa5aaab2013-02-21 12:48:38 -050049
Alan Donovan8fb6c3a2013-07-16 12:18:00 -040050 // go.tools/ssa/interp can't handle unsafe.Pointer.
51 if os.Getenv("GOSSAINTERP") == "" {
Alan Donovanaa5aaab2013-02-21 12:48:38 -050052 if stringptr(c) == stringptr(d) {
53 panic("compiler too smart -- got same string")
54 }
Russ Coxa7f6d402009-01-26 09:56:42 -080055 }
56
Rob Pike325cf8e2010-03-24 16:46:53 -070057 var e = make(chan int)
Russ Coxa7f6d402009-01-26 09:56:42 -080058
Rob Pike325cf8e2010-03-24 16:46:53 -070059 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 Coxa7f6d402009-01-26 09:56:42 -080065 // these comparisons are okay because
66 // string compare is okay and the others
67 // are comparisons where the types differ.
Rob Pike325cf8e2010-03-24 16:46:53 -070068 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 Cox196b6632011-12-12 22:22:09 -050075
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 Cox23bd2142010-09-13 15:42:47 -040091 istrue(c == id)
92 istrue(e == ie)
93
Russ Cox196b6632011-12-12 22:22:09 -050094 //isfalse(ia == b)
Russ Cox23bd2142010-09-13 15:42:47 -040095 isfalse(ia == c)
96 isfalse(ia == d)
97 isfalse(ib == c)
98 isfalse(ib == d)
99 istrue(ic == d)
100 istrue(ie == e)
Russ Coxa7f6d402009-01-26 09:56:42 -0800101
Russ Cox196b6632011-12-12 22:22:09 -0500102 //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 Cox9b6d3852009-01-26 12:36:21 -0800118 // 6g used to let this go through as true.
Rob Pike325cf8e2010-03-24 16:46:53 -0700119 var g uint64 = 123
120 var h int64 = 123
121 var ig interface{} = g
122 var ih interface{} = h
123 isfalse(ig == ih)
Russ Cox196b6632011-12-12 22:22:09 -0500124 istrue(ig != ih)
Russ Cox9b6d3852009-01-26 12:36:21 -0800125
Russ Coxa7f6d402009-01-26 09:56:42 -0800126 // map of interface should use == on interface values,
127 // not memory.
Rob Pike325cf8e2010-03-24 16:46:53 -0700128 var m = make(map[interface{}]int)
129 m[ic] = 1
130 m[id] = 2
Russ Cox196b6632011-12-12 22:22:09 -0500131 if m[c] != 2 {
132 println("m[c] = ", m[c])
133 panic("bad m[c]")
Russ Coxa7f6d402009-01-26 09:56:42 -0800134 }
Russ Cox196b6632011-12-12 22:22:09 -0500135
Rémy Oudomphenge5f01ae2014-02-27 08:07:50 +0100136 // 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 Cox23bd2142010-09-13 15:42:47 -0400174 // 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 Cox196b6632011-12-12 22:22:09 -0500183
184 isfalse(c != c1)
185 isfalse(c != c2)
186 isfalse(c1 != c)
187 isfalse(c2 != c)
188
Russ Cox23bd2142010-09-13 15:42:47 -0400189 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 Cox196b6632011-12-12 22:22:09 -0500196
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 Cox23bd2142010-09-13 15:42:47 -0400203 }
204
205 // named types vs not
206 {
207 var x = new(int)
208 var y T
209 var z T = x
Russ Cox196b6632011-12-12 22:22:09 -0500210
Russ Cox23bd2142010-09-13 15:42:47 -0400211 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 Cox196b6632011-12-12 22:22:09 -0500218
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 Cox23bd2142010-09-13 15:42:47 -0400226 }
Russ Cox196b6632011-12-12 22:22:09 -0500227
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 Donovanaa5aaab2013-02-21 12:48:38 -0500336
Russ Coxc4c92eb2012-02-17 14:45:29 -0500337 // structs with _ fields
338 {
339 var x = struct {
340 x int
Rémy Oudompheng428ea682013-07-02 09:08:43 +0200341 _ string
Russ Coxc4c92eb2012-02-17 14:45:29 -0500342 y float64
343 _ float64
344 z int
345 }{
346 x: 1, y: 2, z: 3,
347 }
348 var ix interface{} = x
Alan Donovanaa5aaab2013-02-21 12:48:38 -0500349
Russ Coxc4c92eb2012-02-17 14:45:29 -0500350 istrue(x == x)
351 istrue(x == ix)
352 istrue(ix == x)
353 istrue(ix == ix)
354 }
Russ Cox196b6632011-12-12 22:22:09 -0500355
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 Oudompheng14b0af42014-02-24 19:51:59 +0100432 // 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 Cox4bdf1fc2011-09-26 19:35:21 -0400449 shouldPanic(p1)
450 shouldPanic(p2)
451 shouldPanic(p3)
452 shouldPanic(p4)
453}
454
455func p1() {
456 var a []int
457 var ia interface{} = a
458 use(ia == ia)
459}
460
461func p2() {
462 var b []int
463 var ib interface{} = b
464 use(ib == ib)
465}
466
467func p3() {
468 var a []int
469 var ia interface{} = a
Russ Cox196b6632011-12-12 22:22:09 -0500470 var m = make(map[interface{}]int)
Russ Cox4bdf1fc2011-09-26 19:35:21 -0400471 m[ia] = 1
472}
473
474func p4() {
475 var b []int
476 var ib interface{} = b
Russ Cox196b6632011-12-12 22:22:09 -0500477 var m = make(map[interface{}]int)
Russ Cox4bdf1fc2011-09-26 19:35:21 -0400478 m[ib] = 1
479}
480
481func shouldPanic(f func()) {
482 defer func() {
483 if recover() == nil {
484 panic("function should panic")
485 }
486 }()
487 f()
Russ Coxa7f6d402009-01-26 09:56:42 -0800488}