| // run | |
| // Copyright 2013 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // Issue 4585: comparisons and hashes process blank | |
| // fields and padding in structs. | |
| package main | |
| import "unsafe" | |
| // T is a structure with padding. | |
| type T struct { | |
| A int16 | |
| B int64 | |
| C int16 | |
| D int64 | |
| Dummy [64]byte | |
| } | |
| // U is a structure with a blank field | |
| type U struct { | |
| A, _, B int | |
| Dummy [64]byte | |
| } | |
| // USmall is like U but the frontend will inline comparison | |
| // instead of calling the generated eq function. | |
| type USmall struct { | |
| A, _, B int32 | |
| } | |
| // V has padding but not on the first field. | |
| type V struct { | |
| A1, A2, A3 int32 | |
| B int16 | |
| C int32 | |
| } | |
| // W has padding at the end. | |
| type W struct { | |
| A1, A2, A3 int32 | |
| B int32 | |
| C int8 | |
| } | |
| func test1() { | |
| var a, b U | |
| m := make(map[U]int) | |
| copy((*[16]byte)(unsafe.Pointer(&a))[:], "hello world!") | |
| a.A, a.B = 1, 2 | |
| b.A, b.B = 1, 2 | |
| if a != b { | |
| panic("broken equality: a != b") | |
| } | |
| m[a] = 1 | |
| m[b] = 2 | |
| if len(m) == 2 { | |
| panic("broken hash: len(m) == 2") | |
| } | |
| if m[a] != 2 { | |
| panic("m[a] != 2") | |
| } | |
| } | |
| func test2() { | |
| var a, b T | |
| m := make(map[T]int) | |
| copy((*[16]byte)(unsafe.Pointer(&a))[:], "hello world!") | |
| a.A, a.B, a.C, a.D = 1, 2, 3, 4 | |
| b.A, b.B, b.C, b.D = 1, 2, 3, 4 | |
| if a != b { | |
| panic("broken equality: a != b") | |
| } | |
| m[a] = 1 | |
| m[b] = 2 | |
| if len(m) == 2 { | |
| panic("broken hash: len(m) == 2") | |
| } | |
| if m[a] != 2 { | |
| panic("m[a] != 2") | |
| } | |
| } | |
| func test3() { | |
| var a, b USmall | |
| copy((*[12]byte)(unsafe.Pointer(&a))[:], "hello world!") | |
| a.A, a.B = 1, 2 | |
| b.A, b.B = 1, 2 | |
| if a != b { | |
| panic("broken equality: a != b") | |
| } | |
| } | |
| func test4() { | |
| var a, b V | |
| m := make(map[V]int) | |
| copy((*[20]byte)(unsafe.Pointer(&a))[:], "Hello World, Gopher!") | |
| a.A1, a.A2, a.A3, a.B, a.C = 1, 2, 3, 4, 5 | |
| b.A1, b.A2, b.A3, b.B, b.C = 1, 2, 3, 4, 5 | |
| if a != b { | |
| panic("broken equality: a != b") | |
| } | |
| m[a] = 1 | |
| m[b] = 2 | |
| if len(m) == 2 { | |
| panic("broken hash: len(m) == 2") | |
| } | |
| if m[a] != 2 { | |
| panic("m[a] != 2") | |
| } | |
| } | |
| func test5() { | |
| var a, b W | |
| m := make(map[W]int) | |
| copy((*[20]byte)(unsafe.Pointer(&a))[:], "Hello World, Gopher!") | |
| a.A1, a.A2, a.A3, a.B, a.C = 1, 2, 3, 4, 5 | |
| b.A1, b.A2, b.A3, b.B, b.C = 1, 2, 3, 4, 5 | |
| if a != b { | |
| panic("broken equality: a != b") | |
| } | |
| m[a] = 1 | |
| m[b] = 2 | |
| if len(m) == 2 { | |
| panic("broken hash: len(m) == 2") | |
| } | |
| if m[a] != 2 { | |
| panic("m[a] != 2") | |
| } | |
| } | |
| func main() { | |
| test1() | |
| test2() | |
| test3() | |
| test4() | |
| test5() | |
| } |