]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/gc: accept cases with same value but different types in switch.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 25 Feb 2013 23:45:43 +0000 (00:45 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 25 Feb 2013 23:45:43 +0000 (00:45 +0100)
Fixes #4781.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7365056

src/cmd/gc/swt.c
test/switch.go

index 6112b0426f460af20b1e8124cac49d66a2198286..a497b86222a9450c03afb1245d46adf7a798c1fe 100644 (file)
@@ -117,12 +117,15 @@ exprcmp(Case *c1, Case *c2)
        n1 = c1->node->left;
        n2 = c2->node->left;
 
+       // sort by type (for switches on interface)
        ct = n1->val.ctype;
-       if(ct != n2->val.ctype) {
-               // invalid program, but return a sort
-               // order so that we can give a better
-               // error later.
+       if(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
@@ -379,6 +382,7 @@ mkcaselist(Node *sw, int arg)
                case Strue:
                case Sfalse:
                        c->type = Texprvar;
+                       c->hash = typehash(n->left->type);
                        switch(consttype(n->left)) {
                        case CTFLT:
                        case CTINT:
index c6a0ebc74ae869c0189cd6e01ba3d19bf91c6518..bcbde68e468bd039811c4828103a9911bb3a19be 100644 (file)
@@ -305,6 +305,35 @@ func main() {
                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 ar := [3]int{1, 2, 3}; ar {
        case [3]int{1, 2, 3}: