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);
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);
}
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);
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
"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)