Commit f4d3d22a authored by Russ Cox's avatar Russ Cox

enforce channel direction

R=ken
OCL=29209
CL=29216
parent a3c17d58
...@@ -48,16 +48,16 @@ char *sysimport = ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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); ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment