mirror of
https://github.com/golang/go
synced 2024-11-13 14:10:22 -07:00
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:
parent
c6a41a3559
commit
3072df5c1d
@ -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
|
||||||
|
30
test/fixedbugs/issue7214.go
Normal file
30
test/fixedbugs/issue7214.go
Normal 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"
|
Loading…
Reference in New Issue
Block a user