diff options
Diffstat (limited to 'src/cmd/gc/subr.c')
-rw-r--r-- | src/cmd/gc/subr.c | 62 |
1 files changed, 29 insertions, 33 deletions
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 40d8b6f9d..3e58415a8 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -2410,10 +2410,11 @@ staticname(Type *t) } /* - * return side effect-free, assignable n, appending side effects to init. + * return side effect-free appending side effects to init. + * result is assignable if n is. */ Node* -saferef(Node *n, NodeList **init) +safeexpr(Node *n, NodeList **init) { Node *l; Node *r; @@ -2421,9 +2422,11 @@ saferef(Node *n, NodeList **init) switch(n->op) { case ONAME: + case OLITERAL: return n; + case ODOT: - l = saferef(n->left, init); + l = safeexpr(n->left, init); if(l == n->left) return n; r = nod(OXXX, N, N); @@ -2433,41 +2436,34 @@ saferef(Node *n, NodeList **init) walkexpr(&r, init); return r; - case OINDEX: case ODOTPTR: case OIND: - l = nod(OXXX, N, N); - tempname(l, ptrto(n->type)); - a = nod(OAS, l, nod(OADDR, n, N)); - typecheck(&a, Etop); + l = safeexpr(n->left, init); + if(l == n->left) + return n; + a = nod(OXXX, N, N); + *a = *n; + a->left = l; walkexpr(&a, init); - *init = list(*init, a); - r = nod(OIND, l, N); - typecheck(&r, Erv); - walkexpr(&r, init); - return r; - } - fatal("saferef %N", n); - return N; -} - -/* - * return side effect-free n, appending side effects to init. - */ -Node* -safeval(Node *n, NodeList **init) -{ - Node *l; - Node *a; + return a; - // is this a local variable or a dot of a local variable? - for(l=n; l->op == ODOT; l=l->left) - if(l->left->type != T && isptr[l->left->type->etype]) - goto copy; - if(l->op == ONAME && (l->class == PAUTO || l->class == PPARAM)) - return n; + case OINDEX: + case OINDEXMAP: + l = safeexpr(n->left, init); + r = safeexpr(n->right, init); + if(l == n->left && r == n->right) + return n; + a = nod(OXXX, N, N); + *a = *n; + a->left = l; + a->right = r; + walkexpr(&a, init); + return a; + } -copy: + // make a copy; must not be used as an lvalue + if(islvalue(n)) + fatal("missing lvalue case in safeexpr: %N", n); l = nod(OXXX, N, N); tempname(l, n->type); a = nod(OAS, l, n); |