mirror of
https://github.com/golang/go
synced 2024-11-26 14:46:47 -07:00
enforce channel direction
R=ken OCL=29209 CL=29216
This commit is contained in:
parent
a3c17d58df
commit
f4d3d22a94
@ -48,16 +48,16 @@ char *sysimport =
|
|||||||
"func sys.mapiter1 (hiter *any) (key any)\n"
|
"func sys.mapiter1 (hiter *any) (key any)\n"
|
||||||
"func sys.mapiter2 (hiter *any) (key any, val any)\n"
|
"func sys.mapiter2 (hiter *any) (key any, val any)\n"
|
||||||
"func sys.newchan (elemsize int, elemalg int, hint int) (hchan chan any)\n"
|
"func sys.newchan (elemsize int, elemalg int, hint int) (hchan chan any)\n"
|
||||||
"func sys.chanrecv1 (hchan chan any) (elem any)\n"
|
"func sys.chanrecv1 (hchan <-chan any) (elem any)\n"
|
||||||
"func sys.chanrecv2 (hchan chan any) (elem any, pres bool)\n"
|
"func sys.chanrecv2 (hchan <-chan any) (elem any, pres bool)\n"
|
||||||
"func sys.chanrecv3 (hchan chan any, elem *any) (pres bool)\n"
|
"func sys.chanrecv3 (hchan <-chan any, elem *any) (pres bool)\n"
|
||||||
"func sys.chansend1 (hchan chan any, elem any)\n"
|
"func sys.chansend1 (hchan chan<- any, elem any)\n"
|
||||||
"func sys.chansend2 (hchan chan any, elem any) (pres bool)\n"
|
"func sys.chansend2 (hchan chan<- any, elem any) (pres bool)\n"
|
||||||
"func sys.closechan (hchan chan any)\n"
|
"func sys.closechan (hchan any)\n"
|
||||||
"func sys.closedchan (hchan chan any) (? bool)\n"
|
"func sys.closedchan (hchan any) (? bool)\n"
|
||||||
"func sys.newselect (size int) (sel *uint8)\n"
|
"func sys.newselect (size int) (sel *uint8)\n"
|
||||||
"func sys.selectsend (sel *uint8, hchan chan any, elem any) (selected bool)\n"
|
"func sys.selectsend (sel *uint8, hchan chan<- any, elem any) (selected bool)\n"
|
||||||
"func sys.selectrecv (sel *uint8, hchan chan any, elem *any) (selected bool)\n"
|
"func sys.selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n"
|
||||||
"func sys.selectdefault (sel *uint8) (selected bool)\n"
|
"func sys.selectdefault (sel *uint8) (selected bool)\n"
|
||||||
"func sys.selectgo (sel *uint8)\n"
|
"func sys.selectgo (sel *uint8)\n"
|
||||||
"func sys.newarray (nel int, cap int, width int) (ary []any)\n"
|
"func sys.newarray (nel int, cap int, width int) (ary []any)\n"
|
||||||
|
@ -390,9 +390,9 @@ enum
|
|||||||
{
|
{
|
||||||
/* types of channel */
|
/* types of channel */
|
||||||
Cxxx,
|
Cxxx,
|
||||||
Cboth,
|
Crecv = 1<<0,
|
||||||
Crecv,
|
Csend = 1<<1,
|
||||||
Csend,
|
Cboth = Crecv | Csend,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -1067,6 +1067,8 @@ Tpretty(Fmt *fp, Type *t)
|
|||||||
case Crecv:
|
case Crecv:
|
||||||
return fmtprint(fp, "<-chan %T", t->type);
|
return fmtprint(fp, "<-chan %T", t->type);
|
||||||
case Csend:
|
case Csend:
|
||||||
|
if(t->type != T && t->type->etype == TCHAN)
|
||||||
|
return fmtprint(fp, "chan<- (%T)", t->type);
|
||||||
return fmtprint(fp, "chan<- %T", t->type);
|
return fmtprint(fp, "chan<- %T", t->type);
|
||||||
}
|
}
|
||||||
return fmtprint(fp, "chan %T", t->type);
|
return fmtprint(fp, "chan %T", t->type);
|
||||||
@ -1704,6 +1706,11 @@ eqtype1(Type *t1, Type *t2, int d, int names)
|
|||||||
if(t1->bound == t2->bound)
|
if(t1->bound == t2->bound)
|
||||||
break;
|
break;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case TCHAN:
|
||||||
|
if(t1->chan == t2->chan)
|
||||||
|
break;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return eqtype1(t1->type, t2->type, d+1, names);
|
return eqtype1(t1->type, t2->type, d+1, names);
|
||||||
}
|
}
|
||||||
|
@ -62,17 +62,17 @@ func mapiter1(hiter *any) (key any);
|
|||||||
func mapiter2(hiter *any) (key any, val any);
|
func mapiter2(hiter *any) (key any, val any);
|
||||||
|
|
||||||
func newchan(elemsize int, elemalg int, hint int) (hchan chan any);
|
func newchan(elemsize int, elemalg int, hint int) (hchan chan any);
|
||||||
func chanrecv1(hchan chan any) (elem any);
|
func chanrecv1(hchan <-chan any) (elem any);
|
||||||
func chanrecv2(hchan chan any) (elem any, pres bool);
|
func chanrecv2(hchan <-chan any) (elem any, pres bool);
|
||||||
func chanrecv3(hchan chan any, elem *any) (pres bool);
|
func chanrecv3(hchan <-chan any, elem *any) (pres bool);
|
||||||
func chansend1(hchan chan any, elem any);
|
func chansend1(hchan chan<- any, elem any);
|
||||||
func chansend2(hchan chan any, elem any) (pres bool);
|
func chansend2(hchan chan<- any, elem any) (pres bool);
|
||||||
func closechan(hchan chan any);
|
func closechan(hchan any);
|
||||||
func closedchan(hchan chan any) bool;
|
func closedchan(hchan any) bool;
|
||||||
|
|
||||||
func newselect(size int) (sel *byte);
|
func newselect(size int) (sel *byte);
|
||||||
func selectsend(sel *byte, hchan chan any, elem any) (selected bool);
|
func selectsend(sel *byte, hchan chan<- any, elem any) (selected bool);
|
||||||
func selectrecv(sel *byte, hchan chan any, elem *any) (selected bool);
|
func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool);
|
||||||
func selectdefault(sel *byte) (selected bool);
|
func selectdefault(sel *byte) (selected bool);
|
||||||
func selectgo(sel *byte);
|
func selectgo(sel *byte);
|
||||||
|
|
||||||
|
@ -1335,6 +1335,11 @@ selcase(Node *n, Node *var)
|
|||||||
if(t == T)
|
if(t == T)
|
||||||
return N;
|
return N;
|
||||||
|
|
||||||
|
if(!(t->chan & Csend)) {
|
||||||
|
yyerror("cannot send on %T", t);
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
convlit(c->right, t->type);
|
convlit(c->right, t->type);
|
||||||
if(!ascompat(t->type, c->right->type)) {
|
if(!ascompat(t->type, c->right->type)) {
|
||||||
badtype(c->op, t->type, c->right->type);
|
badtype(c->op, t->type, c->right->type);
|
||||||
@ -1365,6 +1370,11 @@ recv:
|
|||||||
if(t == T)
|
if(t == T)
|
||||||
return N;
|
return N;
|
||||||
|
|
||||||
|
if(!(t->chan & Crecv)) {
|
||||||
|
yyerror("cannot receive from %T", t);
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
|
// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
|
||||||
on = syslook("selectrecv", 1);
|
on = syslook("selectrecv", 1);
|
||||||
argtype(on, t->type);
|
argtype(on, t->type);
|
||||||
@ -1389,6 +1399,11 @@ recv2:
|
|||||||
if(t == T)
|
if(t == T)
|
||||||
return N;
|
return N;
|
||||||
|
|
||||||
|
if(!(t->chan & Crecv)) {
|
||||||
|
yyerror("cannot receive from %T", t);
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
walktype(c->left, Elv); // elem
|
walktype(c->left, Elv); // elem
|
||||||
convlit(c->left, t->type);
|
convlit(c->left, t->type);
|
||||||
if(!ascompat(t->type, c->left->type)) {
|
if(!ascompat(t->type, c->left->type)) {
|
||||||
@ -2103,6 +2118,14 @@ ascompat(Type *dst, Type *src)
|
|||||||
if(dst == T || src == T)
|
if(dst == T || src == T)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if(dst->etype == TCHAN && src->etype == TCHAN) {
|
||||||
|
if(!eqtype(dst->type, src->type))
|
||||||
|
return 0;
|
||||||
|
if(dst->chan & ~src->chan)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(isslice(dst)
|
if(isslice(dst)
|
||||||
&& isptr[src->etype]
|
&& isptr[src->etype]
|
||||||
&& isfixedarray(src->type)
|
&& isfixedarray(src->type)
|
||||||
@ -2634,7 +2657,7 @@ chanop(Node *n, int top)
|
|||||||
r = a;
|
r = a;
|
||||||
|
|
||||||
on = syslook("closechan", 1);
|
on = syslook("closechan", 1);
|
||||||
argtype(on, t->type); // any-1
|
argtype(on, t); // any-1
|
||||||
|
|
||||||
r = nod(OCALL, on, r);
|
r = nod(OCALL, on, r);
|
||||||
walktype(r, top);
|
walktype(r, top);
|
||||||
@ -2651,7 +2674,7 @@ chanop(Node *n, int top)
|
|||||||
r = a;
|
r = a;
|
||||||
|
|
||||||
on = syslook("closedchan", 1);
|
on = syslook("closedchan", 1);
|
||||||
argtype(on, t->type); // any-1
|
argtype(on, t); // any-1
|
||||||
|
|
||||||
r = nod(OCALL, on, r);
|
r = nod(OCALL, on, r);
|
||||||
walktype(r, top);
|
walktype(r, top);
|
||||||
@ -2704,6 +2727,11 @@ chanop(Node *n, int top)
|
|||||||
if(t == T)
|
if(t == T)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if(!(t->chan & Crecv)) {
|
||||||
|
yyerror("cannot receive from %T", t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
a = n->right->left; // chan
|
a = n->right->left; // chan
|
||||||
r = a;
|
r = a;
|
||||||
|
|
||||||
@ -2727,6 +2755,11 @@ chanop(Node *n, int top)
|
|||||||
if(t == T)
|
if(t == T)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if(!(t->chan & Crecv)) {
|
||||||
|
yyerror("cannot receive from %T", t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
a = n->left; // chan
|
a = n->left; // chan
|
||||||
r = a;
|
r = a;
|
||||||
|
|
||||||
@ -2769,14 +2802,15 @@ chanop(Node *n, int top)
|
|||||||
t = fixchan(n->left->type);
|
t = fixchan(n->left->type);
|
||||||
if(t == T)
|
if(t == T)
|
||||||
break;
|
break;
|
||||||
|
if(!(t->chan & Csend)) {
|
||||||
|
yyerror("cannot send to %T", t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(top != Etop)
|
if(top != Etop)
|
||||||
goto send2;
|
goto send2;
|
||||||
|
|
||||||
// chansend1(hchan *chan any, elem any);
|
// chansend1(hchan *chan any, elem any);
|
||||||
t = fixchan(n->left->type);
|
|
||||||
if(t == T)
|
|
||||||
break;
|
|
||||||
|
|
||||||
a = n->right; // e
|
a = n->right; // e
|
||||||
r = a;
|
r = a;
|
||||||
a = n->left; // chan
|
a = n->left; // chan
|
||||||
@ -2791,10 +2825,6 @@ chanop(Node *n, int top)
|
|||||||
|
|
||||||
send2:
|
send2:
|
||||||
// chansend2(hchan *chan any, val any) (pres bool);
|
// chansend2(hchan *chan any, val any) (pres bool);
|
||||||
t = fixchan(n->left->type);
|
|
||||||
if(t == T)
|
|
||||||
break;
|
|
||||||
|
|
||||||
a = n->right; // e
|
a = n->right; // e
|
||||||
r = a;
|
r = a;
|
||||||
a = n->left; // chan
|
a = n->left; // chan
|
||||||
@ -4144,7 +4174,6 @@ maplit(Node *n, Node *var)
|
|||||||
if(r != N && r->op == OEMPTY)
|
if(r != N && r->op == OEMPTY)
|
||||||
r = N;
|
r = N;
|
||||||
|
|
||||||
loop:
|
|
||||||
while(r != N) {
|
while(r != N) {
|
||||||
if(r == N)
|
if(r == N)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user