summaryrefslogtreecommitdiff
path: root/src/cmd/6g/gsubr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6g/gsubr.c')
-rw-r--r--src/cmd/6g/gsubr.c24
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;