github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/test/fixedbugs/issue4585.go (about) 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 10 package main 11 12 import "unsafe" 13 14 // T is a structure with padding. 15 type 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 24 type 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. 31 type USmall struct { 32 A, _, B int32 33 } 34 35 // V has padding but not on the first field. 36 type V struct { 37 A1, A2, A3 int32 38 B int16 39 C int32 40 } 41 42 // W has padding at the end. 43 type W struct { 44 A1, A2, A3 int32 45 B int32 46 C int8 47 } 48 49 func 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 69 func 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 91 func 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 101 func 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 123 func 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 145 func main() { 146 test1() 147 test2() 148 test3() 149 test4() 150 test5() 151 }