]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix compilation of send select cases
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 25 Jul 2011 16:25:37 +0000 (12:25 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 25 Jul 2011 16:25:37 +0000 (12:25 -0400)
Fixes #2102.

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

src/cmd/gc/go.h
src/cmd/gc/select.c
src/cmd/gc/subr.c
src/pkg/runtime/chan_test.go

index c61e8a994248ab2ae4b9d8e405042e8d07098c25..ee4ee6c89ba99a4afb6551a51f17373247169654 100644 (file)
@@ -1136,7 +1136,7 @@ Sym*      restrictlookup(char *name, Pkg *pkg);
 Node*  safeexpr(Node *n, NodeList **init);
 void   saveerrors(void);
 Node*  cheapexpr(Node *n, NodeList **init);
-Node*  localexpr(Node *n, NodeList **init);
+Node*  localexpr(Node *n, Type *t, NodeList **init);
 int32  setlineno(Node *n);
 void   setmaxarg(Type *t);
 Type*  shallow(Type *t);
index 14ec015f2db0825f612f1c21a0da97006e301a7e..095c764159d09bcbaf18baeaa0774b9c449133de 100644 (file)
@@ -311,7 +311,7 @@ walkselect(Node *sel)
                        case OSEND:
                                // selectsend(sel *byte, hchan *chan any, elem *any) (selected bool);
                                n->left = safeexpr(n->left, &r->ninit);
-                               n->right = localexpr(n->right, &r->ninit);
+                               n->right = localexpr(n->right, n->left->type->type, &r->ninit);
                                n->right = nod(OADDR, n->right, N);
                                n->right->etype = 1;  // pointer does not escape
                                typecheck(&n->right, Erv);
index 9ec630bcf28a06dda041ac6ad0354f0181fc5b17..96675be3fd6240a7a8b99faeaa4740360f304869 100644 (file)
@@ -2728,12 +2728,12 @@ safeexpr(Node *n, NodeList **init)
 }
 
 static Node*
-copyexpr(Node *n, NodeList **init)
+copyexpr(Node *n, Type *t, NodeList **init)
 {
        Node *a, *l;
        
        l = nod(OXXX, N, N);
-       tempname(l, n->type);
+       tempname(l, t);
        a = nod(OAS, l, n);
        typecheck(&a, Etop);
        walkexpr(&a, init);
@@ -2754,20 +2754,21 @@ cheapexpr(Node *n, NodeList **init)
                return n;
        }
 
-       return copyexpr(n, init);
+       return copyexpr(n, n->type, init);
 }
 
 /*
- * return n in a local variable if it is not already.
+ * return n in a local variable of type t if it is not already.
  */
 Node*
-localexpr(Node *n, NodeList **init)
+localexpr(Node *n, Type *t, NodeList **init)
 {
        if(n->op == ONAME &&
-                (n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT))
+               (n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT) &&
+               convertop(n->type, t, nil) == OCONVNOP)
                return n;
        
-       return copyexpr(n, init);
+       return copyexpr(n, t, init);
 }
 
 void
index 31f6856e77fd90c4ab6e4f866e6adbf27ba9e662..c5ffe93acc29074c4082bbd95220aaff1b85de9e 100644 (file)
@@ -10,6 +10,22 @@ import (
        "testing"
 )
 
+func TestChanSendInterface(t *testing.T) {
+       type mt struct{}
+       m := &mt{}
+       c := make(chan interface{}, 1)
+       c <- m
+       select {
+       case c <- m:
+       default:
+       }
+       select {
+       case c <- m:
+       case c <- &mt{}:
+       default:
+       }
+}
+
 func BenchmarkSelectUncontended(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)