]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: check duplicate keys in maps with interface{} key type
authorJan Ziak <0xe2.0x9a.0x9b@gmail.com>
Fri, 4 Apr 2014 14:46:23 +0000 (16:46 +0200)
committerJan Ziak <0xe2.0x9a.0x9b@gmail.com>
Fri, 4 Apr 2014 14:46:23 +0000 (16:46 +0200)
Fixes #7214

LGTM=rsc
R=golang-codereviews, bradfitz, rsc
CC=golang-codereviews, minux.ma
https://golang.org/cl/82080044

src/cmd/gc/typecheck.c
test/fixedbugs/issue7214.go [new file with mode: 0644]

index b6e43b759497430353cd6a76db96e2da1c7c783d..2b44cd8202da8975301c240487c7c382a726cbad 100644 (file)
@@ -2304,10 +2304,13 @@ keydup(Node *n, Node *hash[], ulong nhash)
        ulong b;
        double d;
        int i;
-       Node *a;
+       Node *a, *orign;
        Node cmp;
        char *s;
 
+       orign = n;
+       if(n->op == OCONVIFACE)
+               n = n->left;
        evconst(n);
        if(n->op != OLITERAL)
                return; // we dont check variables
@@ -2340,17 +2343,29 @@ keydup(Node *n, Node *hash[], ulong nhash)
        for(a=hash[h]; a!=N; a=a->ntest) {
                cmp.op = OEQ;
                cmp.left = n;
-               cmp.right = a;
-               evconst(&cmp);
-               b = cmp.val.u.bval;
+               if(a->op == OCONVIFACE && orign->op == OCONVIFACE) {
+                       if(a->left->type == n->type) {
+                               cmp.right = a->left;
+                               evconst(&cmp);
+                               b = cmp.val.u.bval;
+                       }
+                       else {
+                               b = 0;
+                       }
+               }
+               else {
+                       cmp.right = a;
+                       evconst(&cmp);
+                       b = cmp.val.u.bval;
+               }
                if(b) {
                        // too lazy to print the literal
                        yyerror("duplicate key %N in map literal", n);
                        return;
                }
        }
-       n->ntest = hash[h];
-       hash[h] = n;
+       orign->ntest = hash[h];
+       hash[h] = orign;
 }
 
 static void
diff --git a/test/fixedbugs/issue7214.go b/test/fixedbugs/issue7214.go
new file mode 100644 (file)
index 0000000..82ddf74
--- /dev/null
@@ -0,0 +1,30 @@
+// errorcheck
+
+// Copyright 2014 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 7214: No duplicate key error for maps with interface{} key type
+
+package p
+
+var _ = map[interface{}]int{2: 1, 2: 1} // ERROR "duplicate key"
+var _ = map[interface{}]int{int(2): 1, int16(2): 1}
+var _ = map[interface{}]int{int16(2): 1, int16(2): 1} // ERROR "duplicate key"
+
+type S string
+
+var _ = map[interface{}]int{"a": 1, "a": 1} // ERROR "duplicate key"
+var _ = map[interface{}]int{"a": 1, S("a"): 1}
+var _ = map[interface{}]int{S("a"): 1, S("a"): 1} // ERROR "duplicate key"
+
+type I interface {
+       f()
+}
+
+type N int
+
+func (N) f() {}
+
+var _ = map[I]int{N(0): 1, N(2): 1}
+var _ = map[I]int{N(2): 1, N(2): 1} // ERROR "duplicate key"