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