diff options
Diffstat (limited to 'src/cmd/gc/range.c')
| -rw-r--r-- | src/cmd/gc/range.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c index 5ce693ae3..9bcd833a7 100644 --- a/src/cmd/gc/range.c +++ b/src/cmd/gc/range.c @@ -6,6 +6,8 @@ * range */ +#include <u.h> +#include <libc.h> #include "go.h" void @@ -30,7 +32,7 @@ typecheckrange(Node *n) switch(t->etype) { default: - yyerror("cannot range over %+N", n->right); + yyerror("cannot range over %lN", n->right); goto out; case TARRAY: @@ -44,6 +46,10 @@ typecheckrange(Node *n) break; case TCHAN: + if(!(t->chan & Crecv)) { + yyerror("invalid operation: range %N (receive from send-only type %T)", n->right, n->right->type); + goto out; + } t1 = t->type; t2 = nil; if(count(n->list) == 2) @@ -52,7 +58,7 @@ typecheckrange(Node *n) case TSTRING: t1 = types[TINT]; - t2 = types[TINT]; + t2 = runetype; break; } @@ -69,12 +75,12 @@ typecheckrange(Node *n) if(v1->defn == n) v1->type = t1; else if(v1->type != T && assignop(t1, v1->type, &why) == 0) - yyerror("cannot assign type %T to %+N in range%s", t1, v1, why); + yyerror("cannot assign type %T to %lN in range%s", t1, v1, why); if(v2) { if(v2->defn == n) v2->type = t2; else if(v2->type != T && assignop(t2, v2->type, &why) == 0) - yyerror("cannot assign type %T to %+N in range%s", t2, v2, why); + yyerror("cannot assign type %T to %lN in range%s", t2, v2, why); } out: @@ -111,8 +117,6 @@ walkrange(Node *n) } v1 = n->list->n; - hv1 = N; - v2 = N; if(n->list->next) v2 = n->list->next->n; @@ -123,8 +127,7 @@ walkrange(Node *n) // no need to make a potentially expensive copy. ha = a; } else { - ha = nod(OXXX, N, N); - tempname(ha, a->type); + ha = temp(a->type); init = list(init, nod(OAS, ha, a)); } @@ -133,17 +136,14 @@ walkrange(Node *n) fatal("walkrange"); case TARRAY: - hv1 = nod(OXXX, N, n); - tempname(hv1, types[TINT]); - hn = nod(OXXX, N, N); - tempname(hn, types[TINT]); + hv1 = temp(types[TINT]); + hn = temp(types[TINT]); hp = nil; init = list(init, nod(OAS, hv1, N)); init = list(init, nod(OAS, hn, nod(OLEN, ha, N))); if(v2) { - hp = nod(OXXX, N, N); - tempname(hp, ptrto(n->type->type)); + hp = temp(ptrto(n->type->type)); tmp = nod(OINDEX, ha, nodintconst(0)); tmp->etype = 1; // no bounds check init = list(init, nod(OAS, hp, nod(OADDR, tmp, N))); @@ -167,9 +167,10 @@ walkrange(Node *n) case TMAP: th = typ(TARRAY); th->type = ptrto(types[TUINT8]); - th->bound = (sizeof(struct Hiter) + widthptr - 1) / widthptr; - hit = nod(OXXX, N, N); - tempname(hit, th); + // see ../../pkg/runtime/hashmap.h:/hash_iter + // Size in words. + th->bound = 5 + 4*3 + 4*4/widthptr; + hit = temp(th); fn = syslook("mapiterinit", 1); argtype(fn, t->down); @@ -200,10 +201,8 @@ walkrange(Node *n) break; case TCHAN: - hv1 = nod(OXXX, N, n); - tempname(hv1, t->type); - hb = nod(OXXX, N, N); - tempname(hb, types[TBOOL]); + hv1 = temp(t->type); + hb = temp(types[TBOOL]); n->ntest = nod(ONE, hb, nodbool(0)); a = nod(OAS2RECV, N, N); @@ -215,18 +214,15 @@ walkrange(Node *n) break; case TSTRING: - ohv1 = nod(OXXX, N, N); - tempname(ohv1, types[TINT]); + ohv1 = temp(types[TINT]); - hv1 = nod(OXXX, N, N); - tempname(hv1, types[TINT]); + hv1 = temp(types[TINT]); init = list(init, nod(OAS, hv1, N)); if(v2 == N) a = nod(OAS, hv1, mkcall("stringiter", types[TINT], nil, ha, hv1)); else { - hv2 = nod(OXXX, N, N); - tempname(hv2, types[TINT]); + hv2 = temp(runetype); a = nod(OAS2, N, N); a->list = list(list1(hv1), hv2); fn = syslook("stringiter2", 0); |
