diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2014-06-19 09:22:53 +0200 |
---|---|---|
committer | Michael Stapelberg <stapelberg@debian.org> | 2014-06-19 09:22:53 +0200 |
commit | 8a39ee361feb9bf46d728ff1ba4f07ca1d9610b1 (patch) | |
tree | 4449f2036cccf162e8417cc5841a35815b3e7ac5 /src/cmd/gc/sinit.c | |
parent | c8bf49ef8a92e2337b69c14b9b88396efe498600 (diff) | |
download | golang-8a39ee361feb9bf46d728ff1ba4f07ca1d9610b1.tar.gz |
Imported Upstream version 1.3upstream/1.3
Diffstat (limited to 'src/cmd/gc/sinit.c')
-rw-r--r-- | src/cmd/gc/sinit.c | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index 446b1110a..59804cd8d 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -286,8 +286,8 @@ staticcopy(Node *l, Node *r, NodeList **out) if(r->op != ONAME || r->class != PEXTERN || r->sym->pkg != localpkg) return 0; - if(r->defn == N) // zeroed - return 1; + if(r->defn == N) // probably zeroed but perhaps supplied externally and of unknown value + return 0; if(r->defn->op != OAS) return 0; orig = r; @@ -354,11 +354,13 @@ staticcopy(Node *l, Node *r, NodeList **out) else { ll = nod(OXXX, N, N); *ll = n1; + ll->orig = ll; // completely separate copy if(!staticassign(ll, e->expr, out)) { // Requires computation, but we're // copying someone else's computation. rr = nod(OXXX, N, N); *rr = *orig; + rr->orig = rr; // completely separate copy rr->type = ll->type; rr->xoffset += e->xoffset; *out = list(*out, nod(OAS, ll, rr)); @@ -378,6 +380,7 @@ staticassign(Node *l, Node *r, NodeList **out) InitPlan *p; InitEntry *e; int i; + Strlit *sval; switch(r->op) { default: @@ -426,6 +429,14 @@ staticassign(Node *l, Node *r, NodeList **out) } break; + case OSTRARRAYBYTE: + if(l->class == PEXTERN && r->left->op == OLITERAL) { + sval = r->left->val.u.sval; + slicebytes(l, sval->s, sval->len); + return 1; + } + break; + case OARRAYLIT: initplan(r); if(isslice(r->type)) { @@ -459,6 +470,7 @@ staticassign(Node *l, Node *r, NodeList **out) else { a = nod(OXXX, N, N); *a = n1; + a->orig = a; // completely separate copy if(!staticassign(a, e->expr, out)) *out = list(*out, nod(OAS, a, e->expr)); } @@ -756,11 +768,24 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) vauto = temp(ptrto(t)); // set auto to point at new temp or heap (3 assign) - if(n->esc == EscNone) { - a = nod(OAS, temp(t), N); - typecheck(&a, Etop); - *init = list(*init, a); // zero new temp - a = nod(OADDR, a->left, N); + if(n->alloc != N) { + // temp allocated during order.c for dddarg + n->alloc->type = t; + if(vstat == N) { + a = nod(OAS, n->alloc, N); + typecheck(&a, Etop); + *init = list(*init, a); // zero new temp + } + a = nod(OADDR, n->alloc, N); + } else if(n->esc == EscNone) { + a = temp(t); + if(vstat == N) { + a = nod(OAS, temp(t), N); + typecheck(&a, Etop); + *init = list(*init, a); // zero new temp + a = a->left; + } + a = nod(OADDR, a, N); } else { a = nod(ONEW, N, N); a->list = list1(typenod(t)); @@ -827,7 +852,7 @@ maplit(int ctxt, Node *n, Node *var, NodeList **init) int nerr; int64 b; Type *t, *tk, *tv, *t1; - Node *vstat, *index, *value; + Node *vstat, *index, *value, *key, *val; Sym *syma, *symb; USED(ctxt); @@ -846,7 +871,7 @@ ctxt = 0; r = l->n; if(r->op != OKEY) - fatal("slicelit: rhs not OKEY: %N", r); + fatal("maplit: rhs not OKEY: %N", r); index = r->left; value = r->right; @@ -890,7 +915,7 @@ ctxt = 0; r = l->n; if(r->op != OKEY) - fatal("slicelit: rhs not OKEY: %N", r); + fatal("maplit: rhs not OKEY: %N", r); index = r->left; value = r->right; @@ -941,8 +966,7 @@ ctxt = 0; a->ninit = list1(nod(OAS, index, nodintconst(0))); a->ntest = nod(OLT, index, nodintconst(t->bound)); - a->nincr = nod(OASOP, index, nodintconst(1)); - a->nincr->etype = OADD; + a->nincr = nod(OAS, index, nod(OADD, index, nodintconst(1))); typecheck(&a, Etop); walkstmt(&a); @@ -950,25 +974,49 @@ ctxt = 0; } // put in dynamic entries one-at-a-time + key = nil; + val = nil; for(l=n->list; l; l=l->next) { r = l->n; if(r->op != OKEY) - fatal("slicelit: rhs not OKEY: %N", r); + fatal("maplit: rhs not OKEY: %N", r); index = r->left; value = r->right; if(isliteral(index) && isliteral(value)) continue; + + // build list of var[c] = expr. + // use temporary so that mapassign1 can have addressable key, val. + if(key == nil) { + key = temp(var->type->down); + val = temp(var->type->type); + } + a = nod(OAS, key, r->left); + typecheck(&a, Etop); + walkstmt(&a); + *init = list(*init, a); + a = nod(OAS, val, r->right); + typecheck(&a, Etop); + walkstmt(&a); + *init = list(*init, a); - // build list of var[c] = expr - a = nod(OINDEX, var, r->left); - a = nod(OAS, a, r->right); + a = nod(OAS, nod(OINDEX, var, key), val); typecheck(&a, Etop); - walkexpr(&a, init); + walkstmt(&a); + *init = list(*init, a); + if(nerr != nerrors) break; - + } + + if(key != nil) { + a = nod(OVARKILL, key, N); + typecheck(&a, Etop); + *init = list(*init, a); + a = nod(OVARKILL, val, N); + typecheck(&a, Etop); *init = list(*init, a); } } @@ -988,12 +1036,16 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init) if(!isptr[t->etype]) fatal("anylit: not ptr"); - r = nod(ONEW, N, N); - r->typecheck = 1; - r->type = t; - r->esc = n->esc; + if(n->right != N) { + r = nod(OADDR, n->right, N); + typecheck(&r, Erv); + } else { + r = nod(ONEW, N, N); + r->typecheck = 1; + r->type = t; + r->esc = n->esc; + } walkexpr(&r, init); - a = nod(OAS, var, r); typecheck(&a, Etop); |