blob: ad1242d1e5f25627ecb779647e2fd973bce6f29a [file] [log] [blame]
Rémy Oudompheng2ad57b42013-01-18 18:26:43 +01001// 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
Rémy Oudompheng1d6eb2e2013-01-18 22:40:32 +010035// 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
Rémy Oudompheng2ad57b42013-01-18 18:26:43 +010049func 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
Rémy Oudompheng1d6eb2e2013-01-18 22:40:32 +0100101func 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
Rémy Oudompheng2ad57b42013-01-18 18:26:43 +0100145func main() {
146 test1()
147 test2()
148 test3()
Rémy Oudompheng1d6eb2e2013-01-18 22:40:32 +0100149 test4()
150 test5()
Rémy Oudompheng2ad57b42013-01-18 18:26:43 +0100151}