1
0
mirror of https://github.com/golang/go synced 2024-11-21 20:34:40 -07:00

runtime: fix compilation of send select cases

Fixes #2102.

R=fullung, rsc
CC=golang-dev
https://golang.org/cl/4825043
This commit is contained in:
Dmitriy Vyukov 2011-07-25 12:25:37 -04:00 committed by Russ Cox
parent 770543107d
commit 33ff947cac
4 changed files with 26 additions and 9 deletions

View 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);

View 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);

View 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

View 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)