]> Cypherpunks repositories - gostls13.git/commitdiff
bug196
authorRuss Cox <rsc@golang.org>
Tue, 20 Oct 2009 04:10:29 +0000 (21:10 -0700)
committerRuss Cox <rsc@golang.org>
Tue, 20 Oct 2009 04:10:29 +0000 (21:10 -0700)
R=ken
OCL=35905
CL=35905

src/cmd/gc/go.h
src/cmd/gc/subr.c
src/cmd/gc/walk.c
test/fixedbugs/bug196.go [moved from test/bugs/bug196.go with 100% similarity]
test/golden.out

index 35f90a8f703833b551dd1e1c48cbcb53cc7e7f28..d76bacd1b0b344a2719d6966b40ef9f0afb2af3d 100644 (file)
@@ -847,6 +847,7 @@ Node*       staticname(Type*);
 int    iscomposite(Type*);
 Node*  callnew(Type*);
 Node*  saferef(Node*, NodeList**);
+Node*  safeval(Node*, NodeList**);
 int    is64(Type*);
 int    noconv(Type*, Type*);
 NodeList*      list1(Node*);
index 819ebd51c22cd49bd5772a11a33aa2dd46a750ac..e65ce5551946aee69b078c61bdb6a48e0ddf7ca3 100644 (file)
@@ -2346,7 +2346,7 @@ staticname(Type *t)
 }
 
 /*
- * return side effect-free n, appending side effects to init.
+ * return side effect-free, assignable n, appending side effects to init.
  */
 Node*
 saferef(Node *n, NodeList **init)
@@ -2387,6 +2387,33 @@ saferef(Node *n, NodeList **init)
        return N;
 }
 
+/*
+ * return side effect-free n, appending side effects to init.
+ */
+Node*
+safeval(Node *n, NodeList **init)
+{
+       Node *l;
+       Node *r;
+       Node *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;
+
+copy:
+       l = nod(OXXX, N, N);
+       tempname(l, n->type);
+       a = nod(OAS, l, n);
+       typecheck(&a, Etop);
+       walkexpr(&a, init);
+       *init = list(*init, a);
+       return l;
+}
+
 void
 setmaxarg(Type *t)
 {
index 99c105ba9ad66bb02f17c60a6cc121eb562ffc31..4b6b4ae9accd320794ecdc7deca34228d7f5f3ea 100644 (file)
@@ -1592,7 +1592,6 @@ Node*
 mapop(Node *n, NodeList **init)
 {
        Node *r, *a;
-       Type *t;
 
        r = n;
        switch(n->op) {
@@ -1601,16 +1600,10 @@ mapop(Node *n, NodeList **init)
        case OASOP:
                // rewrite map[index] op= right
                // into tmpi := index; map[tmpi] = map[tmpi] op right
-               // TODO(rsc): does this double-evaluate map?
 
-               t = n->left->left->type;
-               a = nod(OXXX, N, N);
-               tempname(a, t->down);                   // tmpi
-               r = nod(OAS, a, n->left->right);        // tmpi := index
-               n->left->right = a;                     // m[tmpi]
-               typecheck(&r, Etop);
-               walkexpr(&r, init);
-               *init = list(*init, r);
+               // make it ok to double-evaluate map[tmpi]
+               n->left->left = safeval(n->left->left, init);
+               n->left->right = safeval(n->left->right, init);
 
                a = nod(OXXX, N, N);
                *a = *n->left;          // copy of map[tmpi]
similarity index 100%
rename from test/bugs/bug196.go
rename to test/fixedbugs/bug196.go
index 500440af99d98a90726366b2ec85e9b47fc489f9..2f21c1d205bca196484ae9317acbe04781e04d6d 100644 (file)
@@ -146,8 +146,3 @@ BUG: should fail
 
 =========== bugs/bug193.go
 BUG: errchk: bugs/bug193.go:14: missing expected error: 'shift'
-
-=========== bugs/bug196.go
-too many calls: 5
-panic PC=xxx
-BUG: bug196