Commit 0bd41e2f authored by Russ Cox's avatar Russ Cox

gc: bug242

R=ken2
CC=golang-dev
https://golang.org/cl/198053
parent 810def84
...@@ -875,8 +875,7 @@ int isselect(Node*); ...@@ -875,8 +875,7 @@ int isselect(Node*);
Node* staticname(Type*); Node* staticname(Type*);
int iscomposite(Type*); int iscomposite(Type*);
Node* callnew(Type*); Node* callnew(Type*);
Node* saferef(Node*, NodeList**); Node* safeexpr(Node*, NodeList**);
Node* safeval(Node*, NodeList**);
int is64(Type*); int is64(Type*);
int noconv(Type*, Type*); int noconv(Type*, Type*);
NodeList* list1(Node*); NodeList* list1(Node*);
...@@ -1073,6 +1072,7 @@ void typecheckrange(Node*); ...@@ -1073,6 +1072,7 @@ void typecheckrange(Node*);
Node* typecheckconv(Node*, Node*, Type*, int, char*); Node* typecheckconv(Node*, Node*, Type*, int, char*);
int checkconv(Type*, Type*, int, int*, int*, char*); int checkconv(Type*, Type*, int, int*, int*, char*);
Node* typecheck(Node**, int); Node* typecheck(Node**, int);
int islvalue(Node*);
/* /*
* const.c * const.c
......
...@@ -2410,10 +2410,11 @@ staticname(Type *t) ...@@ -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* Node*
saferef(Node *n, NodeList **init) safeexpr(Node *n, NodeList **init)
{ {
Node *l; Node *l;
Node *r; Node *r;
...@@ -2421,9 +2422,11 @@ saferef(Node *n, NodeList **init) ...@@ -2421,9 +2422,11 @@ saferef(Node *n, NodeList **init)
switch(n->op) { switch(n->op) {
case ONAME: case ONAME:
case OLITERAL:
return n; return n;
case ODOT: case ODOT:
l = saferef(n->left, init); l = safeexpr(n->left, init);
if(l == n->left) if(l == n->left)
return n; return n;
r = nod(OXXX, N, N); r = nod(OXXX, N, N);
...@@ -2433,41 +2436,34 @@ saferef(Node *n, NodeList **init) ...@@ -2433,41 +2436,34 @@ saferef(Node *n, NodeList **init)
walkexpr(&r, init); walkexpr(&r, init);
return r; return r;
case OINDEX:
case ODOTPTR: case ODOTPTR:
case OIND: case OIND:
l = nod(OXXX, N, N); l = safeexpr(n->left, init);
tempname(l, ptrto(n->type)); if(l == n->left)
a = nod(OAS, l, nod(OADDR, n, N)); return n;
typecheck(&a, Etop); a = nod(OXXX, N, N);
*a = *n;
a->left = l;
walkexpr(&a, init); walkexpr(&a, init);
*init = list(*init, a); return 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;
// is this a local variable or a dot of a local variable? case OINDEX:
for(l=n; l->op == ODOT; l=l->left) case OINDEXMAP:
if(l->left->type != T && isptr[l->left->type->etype]) l = safeexpr(n->left, init);
goto copy; r = safeexpr(n->right, init);
if(l->op == ONAME && (l->class == PAUTO || l->class == PPARAM)) if(l == n->left && r == n->right)
return n; 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); l = nod(OXXX, N, N);
tempname(l, n->type); tempname(l, n->type);
a = nod(OAS, l, n); a = nod(OAS, l, n);
......
...@@ -31,7 +31,6 @@ static void typecheckfunc(Node*); ...@@ -31,7 +31,6 @@ static void typecheckfunc(Node*);
static void checklvalue(Node*, char*); static void checklvalue(Node*, char*);
static void checkassign(Node*); static void checkassign(Node*);
static void checkassignlist(NodeList*); static void checkassignlist(NodeList*);
static int islvalue(Node*);
static void toslice(Node**); static void toslice(Node**);
void void
...@@ -1940,7 +1939,7 @@ addrescapes(Node *n) ...@@ -1940,7 +1939,7 @@ addrescapes(Node *n)
/* /*
* lvalue etc * lvalue etc
*/ */
static int int
islvalue(Node *n) islvalue(Node *n)
{ {
switch(n->op) { switch(n->op) {
......
...@@ -457,6 +457,15 @@ walkexprlist(NodeList *l, NodeList **init) ...@@ -457,6 +457,15 @@ walkexprlist(NodeList *l, NodeList **init)
walkexpr(&l->n, init); walkexpr(&l->n, init);
} }
void
walkexprlistsafe(NodeList *l, NodeList **init)
{
for(; l; l=l->next) {
l->n = safeexpr(l->n, init);
walkexpr(&l->n, init);
}
}
void void
walkexpr(Node **np, NodeList **init) walkexpr(Node **np, NodeList **init)
{ {
...@@ -610,6 +619,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -610,6 +619,7 @@ walkexpr(Node **np, NodeList **init)
*init = concat(*init, n->ninit); *init = concat(*init, n->ninit);
n->ninit = nil; n->ninit = nil;
walkexpr(&n->left, init); walkexpr(&n->left, init);
n->left = safeexpr(n->left, init);
if(oaslit(n, init)) if(oaslit(n, init))
goto ret; goto ret;
walkexpr(&n->right, init); walkexpr(&n->right, init);
...@@ -626,8 +636,8 @@ walkexpr(Node **np, NodeList **init) ...@@ -626,8 +636,8 @@ walkexpr(Node **np, NodeList **init)
as2: as2:
*init = concat(*init, n->ninit); *init = concat(*init, n->ninit);
n->ninit = nil; n->ninit = nil;
walkexprlist(n->list, init); walkexprlistsafe(n->list, init);
walkexprlist(n->rlist, init); walkexprlistsafe(n->rlist, init);
ll = ascompatee(OAS, n->list, n->rlist, init); ll = ascompatee(OAS, n->list, n->rlist, init);
ll = reorder3(ll); ll = reorder3(ll);
n = liststmt(ll); n = liststmt(ll);
...@@ -639,7 +649,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -639,7 +649,7 @@ walkexpr(Node **np, NodeList **init)
*init = concat(*init, n->ninit); *init = concat(*init, n->ninit);
n->ninit = nil; n->ninit = nil;
r = n->rlist->n; r = n->rlist->n;
walkexprlist(n->list, init); walkexprlistsafe(n->list, init);
walkexpr(&r, init); walkexpr(&r, init);
ll = ascompatet(n->op, n->list, &r->type, 0, init); ll = ascompatet(n->op, n->list, &r->type, 0, init);
n = liststmt(concat(list1(r), ll)); n = liststmt(concat(list1(r), ll));
...@@ -650,7 +660,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -650,7 +660,7 @@ walkexpr(Node **np, NodeList **init)
*init = concat(*init, n->ninit); *init = concat(*init, n->ninit);
n->ninit = nil; n->ninit = nil;
r = n->rlist->n; r = n->rlist->n;
walkexprlist(n->list, init); walkexprlistsafe(n->list, init);
walkexpr(&r->left, init); walkexpr(&r->left, init);
fn = chanfn("chanrecv2", 2, r->left->type); fn = chanfn("chanrecv2", 2, r->left->type);
r = mkcall1(fn, getoutargx(fn->type), init, r->left); r = mkcall1(fn, getoutargx(fn->type), init, r->left);
...@@ -663,7 +673,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -663,7 +673,7 @@ walkexpr(Node **np, NodeList **init)
*init = concat(*init, n->ninit); *init = concat(*init, n->ninit);
n->ninit = nil; n->ninit = nil;
r = n->rlist->n; r = n->rlist->n;
walkexprlist(n->list, init); walkexprlistsafe(n->list, init);
walkexpr(&r->left, init); walkexpr(&r->left, init);
fn = mapfn("mapaccess2", r->left->type); fn = mapfn("mapaccess2", r->left->type);
r = mkcall1(fn, getoutargx(fn->type), init, r->left, r->right); r = mkcall1(fn, getoutargx(fn->type), init, r->left, r->right);
...@@ -676,7 +686,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -676,7 +686,7 @@ walkexpr(Node **np, NodeList **init)
// a,b = m[i]; // a,b = m[i];
*init = concat(*init, n->ninit); *init = concat(*init, n->ninit);
n->ninit = nil; n->ninit = nil;
walkexprlist(n->list, init); walkexprlistsafe(n->list, init);
l = n->list->n; l = n->list->n;
t = l->left->type; t = l->left->type;
n = mkcall1(mapfn("mapassign2", t), T, init, l->left, l->right, n->rlist->n, n->rlist->next->n); n = mkcall1(mapfn("mapassign2", t), T, init, l->left, l->right, n->rlist->n, n->rlist->next->n);
...@@ -687,7 +697,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -687,7 +697,7 @@ walkexpr(Node **np, NodeList **init)
*init = concat(*init, n->ninit); *init = concat(*init, n->ninit);
n->ninit = nil; n->ninit = nil;
r = n->rlist->n; r = n->rlist->n;
walkexprlist(n->list, init); walkexprlistsafe(n->list, init);
walkdottype(r, init); walkdottype(r, init);
et = ifaceas1(r->type, r->left->type, 1); et = ifaceas1(r->type, r->left->type, 1);
switch(et) { switch(et) {
...@@ -744,6 +754,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -744,6 +754,7 @@ walkexpr(Node **np, NodeList **init)
goto ret; goto ret;
case OASOP: case OASOP:
n->left = safeexpr(n->left, init);
walkexpr(&n->left, init); walkexpr(&n->left, init);
l = n->left; l = n->left;
if(l->op == OINDEXMAP) if(l->op == OINDEXMAP)
...@@ -761,7 +772,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -761,7 +772,7 @@ walkexpr(Node **np, NodeList **init)
*/ */
et = n->left->type->etype; et = n->left->type->etype;
if(widthptr == 4 && (et == TUINT64 || et == TINT64)) { if(widthptr == 4 && (et == TUINT64 || et == TINT64)) {
l = saferef(n->left, init); l = safeexpr(n->left, init);
r = nod(OAS, l, nod(n->etype, l, n->right)); r = nod(OAS, l, nod(n->etype, l, n->right));
typecheck(&r, Etop); typecheck(&r, Etop);
walkexpr(&r, init); walkexpr(&r, init);
...@@ -1183,6 +1194,13 @@ ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init) ...@@ -1183,6 +1194,13 @@ ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
* a expression list. called in * a expression list. called in
* expr-list = expr-list * expr-list = expr-list
*/ */
// ensure order of evaluation for function calls
for(ll=nl; ll; ll=ll->next)
ll->n = safeexpr(ll->n, init);
for(lr=nr; lr; lr=lr->next)
lr->n = safeexpr(lr->n, init);
nn = nil; nn = nil;
for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next)
nn = list(nn, ascompatee1(op, ll->n, lr->n, init)); nn = list(nn, ascompatee1(op, ll->n, lr->n, init));
...@@ -1766,8 +1784,8 @@ mapop(Node *n, NodeList **init) ...@@ -1766,8 +1784,8 @@ mapop(Node *n, NodeList **init)
// into tmpi := index; map[tmpi] = map[tmpi] op right // into tmpi := index; map[tmpi] = map[tmpi] op right
// make it ok to double-evaluate map[tmpi] // make it ok to double-evaluate map[tmpi]
n->left->left = safeval(n->left->left, init); n->left->left = safeexpr(n->left->left, init);
n->left->right = safeval(n->left->right, init); n->left->right = safeexpr(n->left->right, init);
a = nod(OXXX, N, N); a = nod(OXXX, N, N);
*a = *n->left; // copy of map[tmpi] *a = *n->left; // copy of map[tmpi]
......
...@@ -151,11 +151,6 @@ panic PC=xxx ...@@ -151,11 +151,6 @@ panic PC=xxx
== bugs/ == bugs/
=========== bugs/bug242.go
bad map check 13 false false
panic PC=xxx
BUG: tuple evaluation order
=========== bugs/bug246.go =========== bugs/bug246.go
bugs/bug246.go:17: cannot convert 0 to type unsafe.Pointer bugs/bug246.go:17: cannot convert 0 to type unsafe.Pointer
bugs/bug246.go:17: cannot convert 0 (type uintptr) to type *int in conversion bugs/bug246.go:17: cannot convert 0 (type uintptr) to type *int in conversion
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment