1// run
2
3// Copyright 2013 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// Issue 4585: comparisons and hashes process blank
8// fields and padding in structs.
9
10package main
11
12import "unsafe"
13
14// T is a structure with padding.
15type T struct {
16	A     int16
17	B     int64
18	C     int16
19	D     int64
20	Dummy [64]byte
21}
22
23// U is a structure with a blank field
24type U struct {
25	A, _, B int
26	Dummy   [64]byte
27}
28
29// USmall is like U but the frontend will inline comparison
30// instead of calling the generated eq function.
31type USmall struct {
32	A, _, B int32
33}
34
35// V has padding but not on the first field.
36type V struct {
37	A1, A2, A3 int32
38	B          int16
39	C          int32
40}
41
42// W has padding at the end.
43type W struct {
44	A1, A2, A3 int32
45	B          int32
46	C          int8
47}
48
49func test1() {
50	var a, b U
51	m := make(map[U]int)
52	copy((*[16]byte)(unsafe.Pointer(&a))[:], "hello world!")
53	a.A, a.B = 1, 2
54	b.A, b.B = 1, 2
55	if a != b {
56		panic("broken equality: a != b")
57	}
58
59	m[a] = 1
60	m[b] = 2
61	if len(m) == 2 {
62		panic("broken hash: len(m) == 2")
63	}
64	if m[a] != 2 {
65		panic("m[a] != 2")
66	}
67}
68
69func test2() {
70	var a, b T
71	m := make(map[T]int)
72
73	copy((*[16]byte)(unsafe.Pointer(&a))[:], "hello world!")
74	a.A, a.B, a.C, a.D = 1, 2, 3, 4
75	b.A, b.B, b.C, b.D = 1, 2, 3, 4
76
77	if a != b {
78		panic("broken equality: a != b")
79	}
80
81	m[a] = 1
82	m[b] = 2
83	if len(m) == 2 {
84		panic("broken hash: len(m) == 2")
85	}
86	if m[a] != 2 {
87		panic("m[a] != 2")
88	}
89}
90
91func test3() {
92	var a, b USmall
93	copy((*[12]byte)(unsafe.Pointer(&a))[:], "hello world!")
94	a.A, a.B = 1, 2
95	b.A, b.B = 1, 2
96	if a != b {
97		panic("broken equality: a != b")
98	}
99}
100
101func test4() {
102	var a, b V
103	m := make(map[V]int)
104
105	copy((*[20]byte)(unsafe.Pointer(&a))[:], "Hello World, Gopher!")
106	a.A1, a.A2, a.A3, a.B, a.C = 1, 2, 3, 4, 5
107	b.A1, b.A2, b.A3, b.B, b.C = 1, 2, 3, 4, 5
108
109	if a != b {
110		panic("broken equality: a != b")
111	}
112
113	m[a] = 1
114	m[b] = 2
115	if len(m) == 2 {
116		panic("broken hash: len(m) == 2")
117	}
118	if m[a] != 2 {
119		panic("m[a] != 2")
120	}
121}
122
123func test5() {
124	var a, b W
125	m := make(map[W]int)
126
127	copy((*[20]byte)(unsafe.Pointer(&a))[:], "Hello World, Gopher!")
128	a.A1, a.A2, a.A3, a.B, a.C = 1, 2, 3, 4, 5
129	b.A1, b.A2, b.A3, b.B, b.C = 1, 2, 3, 4, 5
130
131	if a != b {
132		panic("broken equality: a != b")
133	}
134
135	m[a] = 1
136	m[b] = 2
137	if len(m) == 2 {
138		panic("broken hash: len(m) == 2")
139	}
140	if m[a] != 2 {
141		panic("m[a] != 2")
142	}
143}
144
145func main() {
146	test1()
147	test2()
148	test3()
149	test4()
150	test5()
151}
152