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:
parent
770543107d
commit
33ff947cac
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user