diff options
Diffstat (limited to 'src/cmd/6g/gsubr.c')
-rw-r--r-- | src/cmd/6g/gsubr.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index fc5407a1f..55864c34e 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -555,6 +555,7 @@ ismem(Node *n) case OINDREG: case ONAME: case OPARAM: + case OCLOSUREVAR: return 1; case OADDR: if(flag_largemodel) @@ -1057,11 +1058,11 @@ gins(int as, Node *f, Node *t) // Generate an instruction referencing *n // to force segv on nil pointer dereference. void -checkref(Node *n) +checkref(Node *n, int force) { Node m; - if(n->type->type->width < unmappedzero) + if(!force && isptr[n->type->etype] && n->type->type->width < unmappedzero) return; regalloc(&m, types[TUINTPTR], n); @@ -1098,8 +1099,6 @@ checkoffset(Addr *a, int canemitcode) void naddr(Node *n, Addr *a, int canemitcode) { - Prog *p; - a->scale = 0; a->index = D_NONE; a->type = D_NONE; @@ -1148,6 +1147,8 @@ naddr(Node *n, Addr *a, int canemitcode) a->type = n->val.u.reg+D_INDIR; a->sym = n->sym; a->offset = n->xoffset; + if(a->offset != (int32)a->offset) + yyerror("offset %lld too large for OINDREG", a->offset); checkoffset(a, canemitcode); break; @@ -1163,14 +1164,9 @@ naddr(Node *n, Addr *a, int canemitcode) break; case OCLOSUREVAR: - if(!canemitcode) - fatal("naddr OCLOSUREVAR cannot emit code"); - p = gins(AMOVQ, N, N); - p->from.type = D_DX+D_INDIR; - p->from.offset = n->xoffset; - p->to.type = D_BX; - a->type = D_BX; + a->type = D_DX+D_INDIR; a->sym = S; + a->offset = n->xoffset; break; case OCFUNC: @@ -1953,9 +1949,9 @@ sudoclean(void) int sudoaddable(int as, Node *n, Addr *a) { - int o, i, w; - int oary[10]; - int64 v; + int o, i; + int64 oary[10]; + int64 v, w; Node n1, n2, n3, n4, *nn, *l, *r; Node *reg, *reg1; Prog *p1; |