Home | History | Annotate | Download | only in fixedbugs
      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 }
    152