1
0
mirror of https://github.com/golang/go synced 2024-11-22 13:45:00 -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); Node* safeexpr(Node *n, NodeList **init);
void saveerrors(void); void saveerrors(void);
Node* cheapexpr(Node *n, NodeList **init); Node* cheapexpr(Node *n, NodeList **init);
Node* localexpr(Node *n, NodeList **init); Node* localexpr(Node *n, Type *t, NodeList **init);
int32 setlineno(Node *n); int32 setlineno(Node *n);
void setmaxarg(Type *t); void setmaxarg(Type *t);
Type* shallow(Type *t); Type* shallow(Type *t);

View File

@ -311,7 +311,7 @@ walkselect(Node *sel)
case OSEND: case OSEND:
// selectsend(sel *byte, hchan *chan any, elem *any) (selected bool); // selectsend(sel *byte, hchan *chan any, elem *any) (selected bool);
n->left = safeexpr(n->left, &r->ninit); 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 = nod(OADDR, n->right, N);
n->right->etype = 1; // pointer does not escape n->right->etype = 1; // pointer does not escape
typecheck(&n->right, Erv); typecheck(&n->right, Erv);

View File

@ -2728,12 +2728,12 @@ safeexpr(Node *n, NodeList **init)
} }
static Node* static Node*
copyexpr(Node *n, NodeList **init) copyexpr(Node *n, Type *t, NodeList **init)
{ {
Node *a, *l; Node *a, *l;
l = nod(OXXX, N, N); l = nod(OXXX, N, N);
tempname(l, n->type); tempname(l, t);
a = nod(OAS, l, n); a = nod(OAS, l, n);
typecheck(&a, Etop); typecheck(&a, Etop);
walkexpr(&a, init); walkexpr(&a, init);
@ -2754,20 +2754,21 @@ cheapexpr(Node *n, NodeList **init)
return n; 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* Node*
localexpr(Node *n, NodeList **init) localexpr(Node *n, Type *t, NodeList **init)
{ {
if(n->op == ONAME && 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 n;
return copyexpr(n, init); return copyexpr(n, t, init);
} }
void void

View File

@ -10,6 +10,22 @@ import (
"testing" "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) { func BenchmarkSelectUncontended(b *testing.B) {
const CallsPerSched = 1000 const CallsPerSched = 1000
procs := runtime.GOMAXPROCS(-1) procs := runtime.GOMAXPROCS(-1)