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  }