summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/gc/subr.c18
-rw-r--r--test/blank.go11
-rw-r--r--test/blank1.go7
-rw-r--r--test/cmp.go2
-rw-r--r--test/cmp6.go2
-rw-r--r--test/fixedbugs/issue5698.go18
6 files changed, 47 insertions, 11 deletions
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index e49709dc6..dee5b0161 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -615,23 +615,23 @@ algtype1(Type *t, Type **bad)
return -1; // needs special compare
case TSTRUCT:
- if(t->type != T && t->type->down == T) {
+ if(t->type != T && t->type->down == T && !isblanksym(t->type->sym)) {
// One-field struct is same as that one field alone.
return algtype1(t->type->type, bad);
}
ret = AMEM;
for(t1=t->type; t1!=T; t1=t1->down) {
- // Blank fields and padding must be ignored,
- // so need special compare.
- if(isblanksym(t1->sym) || ispaddedfield(t1, t->width)) {
+ // All fields must be comparable.
+ a = algtype1(t1->type, bad);
+ if(a == ANOEQ)
+ return ANOEQ;
+
+ // Blank fields, padded fields, fields with non-memory
+ // equality need special compare.
+ if(a != AMEM || isblanksym(t1->sym) || ispaddedfield(t1, t->width)) {
ret = -1;
continue;
}
- a = algtype1(t1->type, bad);
- if(a == ANOEQ)
- return ANOEQ; // not comparable
- if(a != AMEM)
- ret = -1; // needs special compare
}
return ret;
}
diff --git a/test/blank.go b/test/blank.go
index 7f7d9f6f7..46b61559d 100644
--- a/test/blank.go
+++ b/test/blank.go
@@ -27,6 +27,10 @@ func (T) _() {
func (T) _() {
}
+type U struct {
+ _ struct{ a, b, c int }
+}
+
const (
c0 = iota
_
@@ -116,6 +120,13 @@ func main() {
if t1 != t2 {
panic("T{} != T{}")
}
+
+ var u1, u2 interface{}
+ u1 = *(*U)(unsafe.Pointer(&T1{1, 2, 3}))
+ u2 = *(*U)(unsafe.Pointer(&T1{4, 5, 6}))
+ if u1 != u2 {
+ panic("U{} != U{}")
+ }
}
h(a, b)
diff --git a/test/blank1.go b/test/blank1.go
index 4edb2db70..f46a50051 100644
--- a/test/blank1.go
+++ b/test/blank1.go
@@ -13,9 +13,16 @@ var t struct {
_ int
}
+type T struct {
+ _ []int
+}
+
func main() {
_() // ERROR "cannot use _ as value"
x := _+1 // ERROR "cannot use _ as value"
_ = x
_ = t._ // ERROR "cannot refer to blank field"
+
+ var v1, v2 T
+ _ = v1 == v2 // ERROR "cannot be compared|non-comparable"
}
diff --git a/test/cmp.go b/test/cmp.go
index 5be64561d..7183f0207 100644
--- a/test/cmp.go
+++ b/test/cmp.go
@@ -296,7 +296,7 @@ func main() {
{
var x = struct {
x int
- _ []int
+ _ string
y float64
_ float64
z int
diff --git a/test/cmp6.go b/test/cmp6.go
index 7d99aae18..839c274bc 100644
--- a/test/cmp6.go
+++ b/test/cmp6.go
@@ -53,7 +53,7 @@ func main() {
// Comparison of structs should have a good message
use(t3 == t3) // ERROR "struct|expected"
- use(t4 == t4) // ok; the []int is a blank field
+ use(t4 == t4) // ERROR "cannot be compared|non-comparable"
// Slices, functions, and maps too.
var x []int
diff --git a/test/fixedbugs/issue5698.go b/test/fixedbugs/issue5698.go
new file mode 100644
index 000000000..035bbd35d
--- /dev/null
+++ b/test/fixedbugs/issue5698.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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 5698: can define a key type with slices.
+
+package main
+
+type Key struct {
+ a int16 // the compiler was confused by the padding.
+ b []int
+}
+
+type Val struct{}
+
+type Map map[Key]Val // ERROR "invalid map key type"