Commit 71b3b460 authored by Rémy Oudompheng's avatar Rémy Oudompheng

cmd/gc: accept cases with same value but different types in switch.

Fixes #4781.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7365056
parent 9e66ee45
...@@ -117,12 +117,15 @@ exprcmp(Case *c1, Case *c2) ...@@ -117,12 +117,15 @@ exprcmp(Case *c1, Case *c2)
n1 = c1->node->left; n1 = c1->node->left;
n2 = c2->node->left; n2 = c2->node->left;
// sort by type (for switches on interface)
ct = n1->val.ctype; ct = n1->val.ctype;
if(ct != n2->val.ctype) { if(ct != n2->val.ctype)
// invalid program, but return a sort
// order so that we can give a better
// error later.
return ct - n2->val.ctype; return ct - n2->val.ctype;
if(!eqtype(n1->type, n2->type)) {
if(n1->type->vargen > n2->type->vargen)
return +1;
else
return -1;
} }
// sort by constant value // sort by constant value
...@@ -379,6 +382,7 @@ mkcaselist(Node *sw, int arg) ...@@ -379,6 +382,7 @@ mkcaselist(Node *sw, int arg)
case Strue: case Strue:
case Sfalse: case Sfalse:
c->type = Texprvar; c->type = Texprvar;
c->hash = typehash(n->left->type);
switch(consttype(n->left)) { switch(consttype(n->left)) {
case CTFLT: case CTFLT:
case CTINT: case CTINT:
......
...@@ -305,6 +305,35 @@ func main() { ...@@ -305,6 +305,35 @@ func main() {
assert(false, "i should be true") assert(false, "i should be true")
} }
// switch on interface with constant cases differing by type.
// was rejected by compiler: see issue 4781
type T int
type B bool
type F float64
type S string
switch i := interface{}(float64(1.0)); i {
case nil:
assert(false, "i should be float64(1.0)")
case (*int)(nil):
assert(false, "i should be float64(1.0)")
case 1:
assert(false, "i should be float64(1.0)")
case T(1):
assert(false, "i should be float64(1.0)")
case F(1.0):
assert(false, "i should be float64(1.0)")
case 1.0:
assert(true, "true")
case "hello":
assert(false, "i should be float64(1.0)")
case S("hello"):
assert(false, "i should be float64(1.0)")
case true, B(false):
assert(false, "i should be float64(1.0)")
case false, B(true):
assert(false, "i should be float64(1.0)")
}
// switch on array. // switch on array.
switch ar := [3]int{1, 2, 3}; ar { switch ar := [3]int{1, 2, 3}; ar {
case [3]int{1, 2, 3}: case [3]int{1, 2, 3}:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment