cmd/gc: don't hash nor compare struct padding or blank fields.

Fixes #4585.

R=rsc, golang-dev
CC=golang-dev
https://golang.org/cl/7142052
diff --git a/test/fixedbugs/issue4585.go b/test/fixedbugs/issue4585.go
new file mode 100644
index 0000000..558bd1e
--- /dev/null
+++ b/test/fixedbugs/issue4585.go
@@ -0,0 +1,91 @@
+// 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
+}
+
+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 main() {
+	test1()
+	test2()
+	test3()
+}