1// run
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
7// Test equality and inequality operations.
8
9package main
10
11import "unsafe"
12
13var global bool
14func use(b bool) { global = b }
15
16func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) }
17
18func isfalse(b bool) {
19	if b {
20		// stack will explain where
21		panic("wanted false, got true")
22	}
23}
24
25func istrue(b bool) {
26	if !b {
27		// stack will explain where
28		panic("wanted true, got false")
29	}
30}
31
32type T *int
33
34func main() {
35	var a []int
36	var b map[string]int
37
38	var c string = "hello"
39	var d string = "hel" // try to get different pointer
40	d = d + "lo"
41	if stringptr(c) == stringptr(d) {
42		panic("compiler too smart -- got same string")
43	}
44
45	var e = make(chan int)
46
47	var ia interface{} = a
48	var ib interface{} = b
49	var ic interface{} = c
50	var id interface{} = d
51	var ie interface{} = e
52
53	// these comparisons are okay because
54	// string compare is okay and the others
55	// are comparisons where the types differ.
56	isfalse(ia == ib)
57	isfalse(ia == ic)
58	isfalse(ia == id)
59	isfalse(ib == ic)
60	isfalse(ib == id)
61	istrue(ic == id)
62	istrue(ie == ie)
63
64	istrue(ia != ib)
65	istrue(ia != ic)
66	istrue(ia != id)
67	istrue(ib != ic)
68	istrue(ib != id)
69	isfalse(ic != id)
70	isfalse(ie != ie)
71
72	// these are not okay, because there is no comparison on slices or maps.
73	//isfalse(a == ib)
74	//isfalse(a == ic)
75	//isfalse(a == id)
76	//isfalse(b == ic)
77	//isfalse(b == id)
78
79	istrue(c == id)
80	istrue(e == ie)
81
82	//isfalse(ia == b)
83	isfalse(ia == c)
84	isfalse(ia == d)
85	isfalse(ib == c)
86	isfalse(ib == d)
87	istrue(ic == d)
88	istrue(ie == e)
89
90	//istrue(a != ib)
91	//istrue(a != ic)
92	//istrue(a != id)
93	//istrue(b != ic)
94	//istrue(b != id)
95	isfalse(c != id)
96	isfalse(e != ie)
97
98	//istrue(ia != b)
99	istrue(ia != c)
100	istrue(ia != d)
101	istrue(ib != c)
102	istrue(ib != d)
103	isfalse(ic != d)
104	isfalse(ie != e)
105
106	// 6g used to let this go through as true.
107	var g uint64 = 123
108	var h int64 = 123
109	var ig interface{} = g
110	var ih interface{} = h
111	isfalse(ig == ih)
112	istrue(ig != ih)
113
114	// map of interface should use == on interface values,
115	// not memory.
116	var m = make(map[interface{}]int)
117	m[ic] = 1
118	m[id] = 2
119	if m[c] != 2 {
120		println("m[c] = ", m[c])
121		panic("bad m[c]")
122	}
123
124	// non-interface comparisons
125	{
126		c := make(chan int)
127		c1 := (<-chan int)(c)
128		c2 := (chan<- int)(c)
129		istrue(c == c1)
130		istrue(c == c2)
131		istrue(c1 == c)
132		istrue(c2 == c)
133
134		isfalse(c != c1)
135		isfalse(c != c2)
136		isfalse(c1 != c)
137		isfalse(c2 != c)
138
139		d := make(chan int)
140		isfalse(c == d)
141		isfalse(d == c)
142		isfalse(d == c1)
143		isfalse(d == c2)
144		isfalse(c1 == d)
145		isfalse(c2 == d)
146
147		istrue(c != d)
148		istrue(d != c)
149		istrue(d != c1)
150		istrue(d != c2)
151		istrue(c1 != d)
152		istrue(c2 != d)
153	}
154
155	// named types vs not
156	{
157		var x = new(int)
158		var y T
159		var z T = x
160
161		isfalse(x == y)
162		istrue(x == z)
163		isfalse(y == z)
164
165		isfalse(y == x)
166		istrue(z == x)
167		isfalse(z == y)
168
169		istrue(x != y)
170		isfalse(x != z)
171		istrue(y != z)
172
173		istrue(y != x)
174		isfalse(z != x)
175		istrue(z != y)
176	}
177
178	// structs
179	{
180		var x = struct {
181			x int
182			y string
183		}{1, "hi"}
184		var y = struct {
185			x int
186			y string
187		}{2, "bye"}
188		var z = struct {
189			x int
190			y string
191		}{1, "hi"}
192
193		isfalse(x == y)
194		isfalse(y == x)
195		isfalse(y == z)
196		isfalse(z == y)
197		istrue(x == z)
198		istrue(z == x)
199
200		istrue(x != y)
201		istrue(y != x)
202		istrue(y != z)
203		istrue(z != y)
204		isfalse(x != z)
205		isfalse(z != x)
206
207		var m = make(map[struct {
208			x int
209			y string
210		}]int)
211		m[x] = 10
212		m[y] = 20
213		m[z] = 30
214		istrue(m[x] == 30)
215		istrue(m[y] == 20)
216		istrue(m[z] == 30)
217		istrue(m[x] != 10)
218		isfalse(m[x] != 30)
219		isfalse(m[y] != 20)
220		isfalse(m[z] != 30)
221		isfalse(m[x] == 10)
222
223		var m1 = make(map[struct {
224			x int
225			y string
226		}]struct {
227			x int
228			y string
229		})
230		m1[x] = x
231		m1[y] = y
232		m1[z] = z
233		istrue(m1[x] == z)
234		istrue(m1[y] == y)
235		istrue(m1[z] == z)
236		istrue(m1[x] == x)
237		isfalse(m1[x] != z)
238		isfalse(m1[y] != y)
239		isfalse(m1[z] != z)
240		isfalse(m1[x] != x)
241
242		var ix, iy, iz interface{} = x, y, z
243
244		isfalse(ix == iy)
245		isfalse(iy == ix)
246		isfalse(iy == iz)
247		isfalse(iz == iy)
248		istrue(ix == iz)
249		istrue(iz == ix)
250
251		isfalse(x == iy)
252		isfalse(y == ix)
253		isfalse(y == iz)
254		isfalse(z == iy)
255		istrue(x == iz)
256		istrue(z == ix)
257
258		isfalse(ix == y)
259		isfalse(iy == x)
260		isfalse(iy == z)
261		isfalse(iz == y)
262		istrue(ix == z)
263		istrue(iz == x)
264
265		istrue(ix != iy)
266		istrue(iy != ix)
267		istrue(iy != iz)
268		istrue(iz != iy)
269		isfalse(ix != iz)
270		isfalse(iz != ix)
271
272		istrue(x != iy)
273		istrue(y != ix)
274		istrue(y != iz)
275		istrue(z != iy)
276		isfalse(x != iz)
277		isfalse(z != ix)
278
279		istrue(ix != y)
280		istrue(iy != x)
281		istrue(iy != z)
282		istrue(iz != y)
283		isfalse(ix != z)
284		isfalse(iz != x)
285	}
286
287	// structs with _ fields
288	{
289		var x = struct {
290			x int
291			_ []int
292			y float64
293			_ float64
294			z int
295		}{
296			x: 1, y: 2, z: 3,
297		}
298		var ix interface{} = x
299
300		istrue(x == x)
301		istrue(x == ix)
302		istrue(ix == x)
303		istrue(ix == ix)
304	}
305
306	// arrays
307	{
308		var x = [2]string{"1", "hi"}
309		var y = [2]string{"2", "bye"}
310		var z = [2]string{"1", "hi"}
311
312		isfalse(x == y)
313		isfalse(y == x)
314		isfalse(y == z)
315		isfalse(z == y)
316		istrue(x == z)
317		istrue(z == x)
318
319		istrue(x != y)
320		istrue(y != x)
321		istrue(y != z)
322		istrue(z != y)
323		isfalse(x != z)
324		isfalse(z != x)
325
326		var m = make(map[[2]string]int)
327		m[x] = 10
328		m[y] = 20
329		m[z] = 30
330		istrue(m[x] == 30)
331		istrue(m[y] == 20)
332		istrue(m[z] == 30)
333		isfalse(m[x] != 30)
334		isfalse(m[y] != 20)
335		isfalse(m[z] != 30)
336
337		var ix, iy, iz interface{} = x, y, z
338
339		isfalse(ix == iy)
340		isfalse(iy == ix)
341		isfalse(iy == iz)
342		isfalse(iz == iy)
343		istrue(ix == iz)
344		istrue(iz == ix)
345
346		isfalse(x == iy)
347		isfalse(y == ix)
348		isfalse(y == iz)
349		isfalse(z == iy)
350		istrue(x == iz)
351		istrue(z == ix)
352
353		isfalse(ix == y)
354		isfalse(iy == x)
355		isfalse(iy == z)
356		isfalse(iz == y)
357		istrue(ix == z)
358		istrue(iz == x)
359
360		istrue(ix != iy)
361		istrue(iy != ix)
362		istrue(iy != iz)
363		istrue(iz != iy)
364		isfalse(ix != iz)
365		isfalse(iz != ix)
366
367		istrue(x != iy)
368		istrue(y != ix)
369		istrue(y != iz)
370		istrue(z != iy)
371		isfalse(x != iz)
372		isfalse(z != ix)
373
374		istrue(ix != y)
375		istrue(iy != x)
376		istrue(iy != z)
377		istrue(iz != y)
378		isfalse(ix != z)
379		isfalse(iz != x)
380	}
381
382	shouldPanic(p1)
383	shouldPanic(p2)
384	shouldPanic(p3)
385	shouldPanic(p4)
386}
387
388func p1() {
389	var a []int
390	var ia interface{} = a
391	use(ia == ia)
392}
393
394func p2() {
395	var b []int
396	var ib interface{} = b
397	use(ib == ib)
398}
399
400func p3() {
401	var a []int
402	var ia interface{} = a
403	var m = make(map[interface{}]int)
404	m[ia] = 1
405}
406
407func p4() {
408	var b []int
409	var ib interface{} = b
410	var m = make(map[interface{}]int)
411	m[ib] = 1
412}
413
414func shouldPanic(f func()) {
415	defer func() {
416		if recover() == nil {
417			panic("function should panic")
418		}
419	}()
420	f()
421}
422