cmd/gc: check duplicate keys in maps with interface{} key type

Fixes #7214

LGTM=rsc
R=golang-codereviews, bradfitz, rsc
CC=golang-codereviews, minux.ma
https://golang.org/cl/82080044
This commit is contained in:
Jan Ziak 2014-04-04 16:46:23 +02:00
parent c6a41a3559
commit 3072df5c1d
2 changed files with 51 additions and 6 deletions

View file

@ -2304,10 +2304,13 @@ keydup(Node *n, Node *hash[], ulong nhash)
ulong b; ulong b;
double d; double d;
int i; int i;
Node *a; Node *a, *orign;
Node cmp; Node cmp;
char *s; char *s;
orign = n;
if(n->op == OCONVIFACE)
n = n->left;
evconst(n); evconst(n);
if(n->op != OLITERAL) if(n->op != OLITERAL)
return; // we dont check variables 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) { for(a=hash[h]; a!=N; a=a->ntest) {
cmp.op = OEQ; cmp.op = OEQ;
cmp.left = n; cmp.left = n;
cmp.right = a; if(a->op == OCONVIFACE && orign->op == OCONVIFACE) {
evconst(&cmp); if(a->left->type == n->type) {
b = cmp.val.u.bval; 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) { if(b) {
// too lazy to print the literal // too lazy to print the literal
yyerror("duplicate key %N in map literal", n); yyerror("duplicate key %N in map literal", n);
return; return;
} }
} }
n->ntest = hash[h]; orign->ntest = hash[h];
hash[h] = n; hash[h] = orign;
} }
static void static void

View file

@ -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"