]> Cypherpunks repositories - gostls13.git/commitdiff
5g/6g/8g: fix double function call in slice
authorRuss Cox <rsc@golang.org>
Mon, 8 Mar 2010 22:19:28 +0000 (14:19 -0800)
committerRuss Cox <rsc@golang.org>
Mon, 8 Mar 2010 22:19:28 +0000 (14:19 -0800)
Fixes #654.

R=ken2
CC=golang-dev
https://golang.org/cl/310041

src/cmd/5g/ggen.c
src/cmd/6g/ggen.c
src/cmd/8g/gg.h
src/cmd/8g/ggen.c
src/cmd/gc/subr.c
src/cmd/gc/walk.c
test/fixedbugs/bug261.go [new file with mode: 0644]

index 758e140dcec5ea15aa6b0fa503d9c09ddc8d84fe..e2313d85b660ac407107a34b7ad1c9481e1c2338 100644 (file)
@@ -810,9 +810,9 @@ int
 cgen_inline(Node *n, Node *res)
 {
        Node nodes[5];
-       Node n1, n2, n3, nres, nnode0, ntemp;
+       Node n1, n2, n3, nres, ntemp;
        vlong v;
-       int i, narg, bad;
+       int i, narg;
 
        if(n->op != OCALLFUNC)
                goto no;
@@ -926,47 +926,39 @@ slicearray:
        return 1;
 
 sliceslice:
-       getargs(n->list, nodes, narg);
-
-       nres = *res;            // result
-       nnode0 = nodes[0];      // input slice
-       if(!sleasy(res) || !sleasy(&nodes[0])) {
-               bad = 0;
-               if(res->ullman >= UINF)
-                       bad = 1;
-               for(i=0; i<narg; i++) {
-                       if(nodes[i].ullman >= UINF)
-                               bad = 1;
-                       if(nodes[i].op == OREGISTER)
-                               regfree(&nodes[i]);
-               }
-
-               if(bad)
-                       goto no;
-
+       ntemp.op = OXXX;
+       if(!sleasy(n->list->n->right)) {
+               Node *n0;
+               
+               n0 = n->list->n->right;
                tempname(&ntemp, res->type);
-               if(!sleasy(&nodes[0])) {
-                       cgen(&nodes[0], &ntemp);
-                       nnode0 = ntemp;
-               }
+               cgen(n0, &ntemp);
+               n->list->n->right = &ntemp;
+               getargs(n->list, nodes, narg);
+               n->list->n->right = n0;
+       } else
                getargs(n->list, nodes, narg);
-               if(!sleasy(res))
-                       nres = ntemp;
+
+       nres = *res;            // result
+       if(!sleasy(res)) {
+               if(ntemp.op == OXXX)
+                       tempname(&ntemp, res->type);
+               nres = ntemp;
        }
-       
+
        if(narg == 3) { // old[lb:]
                // move width to where it would be for old[lb:hb]
                nodes[3] = nodes[2];
                nodes[2].op = OXXX;
                
                // if(lb[1] > old.nel[0]) goto throw;
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.xoffset += Array_nel;
                n2.type = types[TUINT32];
                cmpandthrow(&nodes[1], &n2);
 
                // ret.nel = old.nel[0]-lb[1];
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.type = types[TUINT32];
                n2.xoffset += Array_nel;
        
@@ -982,7 +974,7 @@ sliceslice:
                regfree(&n1);
        } else {        // old[lb:hb]
                // if(hb[2] > old.cap[0]) goto throw;
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.xoffset += Array_cap;
                n2.type = types[TUINT32];
                cmpandthrow(&nodes[2], &n2);
@@ -1011,7 +1003,7 @@ sliceslice:
        }
 
        // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
-       n2 = nnode0;
+       n2 = nodes[0];
        n2.type = types[TUINT32];
        n2.xoffset += Array_cap;
 
@@ -1027,7 +1019,7 @@ sliceslice:
        regfree(&n1);
 
        // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
-       n2 = nnode0;
+       n2 = nodes[0];
        n2.type = types[tptr];
        n2.xoffset += Array_array;
        regalloc(&n3, types[tptr], N);
index 45fd17b27ee605194e51a1f2f08007940d8a9792..99a4aea0454e896b1b99a429775fe8af3235a339 100644 (file)
@@ -1138,9 +1138,9 @@ int
 cgen_inline(Node *n, Node *res)
 {
        Node nodes[5];
-       Node n1, n2, nres, nnode0, ntemp;
+       Node n1, n2, nres, ntemp;
        vlong v;
-       int i, narg, bad;
+       int i, narg;
 
        if(n->op != OCALLFUNC)
                goto no;
@@ -1245,46 +1245,38 @@ slicearray:
        return 1;
 
 sliceslice:
-       getargs(n->list, nodes, narg);
-
-       nres = *res;            // result
-       nnode0 = nodes[0];      // input slice
-       if(!sleasy(res) || !sleasy(&nodes[0])) {
-               bad = 0;
-               if(res->ullman >= UINF)
-                       bad = 1;
-               for(i=0; i<narg; i++) {
-                       if(nodes[i].ullman >= UINF)
-                               bad = 1;
-                       if(nodes[i].op == OREGISTER)
-                               regfree(&nodes[i]);
-               }
-
-               if(bad)
-                       goto no;
-
+       ntemp.op = OXXX;
+       if(!sleasy(n->list->n->right)) {
+               Node *n0;
+               
+               n0 = n->list->n->right;
                tempname(&ntemp, res->type);
-               if(!sleasy(&nodes[0])) {
-                       cgen(&nodes[0], &ntemp);
-                       nnode0 = ntemp;
-               }
+               cgen(n0, &ntemp);
+               n->list->n->right = &ntemp;
+               getargs(n->list, nodes, narg);
+               n->list->n->right = n0;
+       } else
                getargs(n->list, nodes, narg);
-               if(!sleasy(res))
-                       nres = ntemp;
+
+       nres = *res;            // result
+       if(!sleasy(res)) {
+               if(ntemp.op == OXXX)
+                       tempname(&ntemp, res->type);
+               nres = ntemp;
        }
-       
+
        if(narg == 3) { // old[lb:]
                // move width to where it would be for old[lb:hb]
                nodes[3] = nodes[2];
                nodes[2].op = OXXX;
                
                // if(lb[1] > old.nel[0]) goto throw;
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.xoffset += Array_nel;
                cmpandthrow(&nodes[1], &n2);
 
                // ret.nel = old.nel[0]-lb[1];
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.xoffset += Array_nel;
        
                regalloc(&n1, types[TUINT32], N);
@@ -1298,7 +1290,7 @@ sliceslice:
                regfree(&n1);
        } else {        // old[lb:hb]
                // if(hb[2] > old.cap[0]) goto throw;
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.xoffset += Array_cap;
                cmpandthrow(&nodes[2], &n2);
 
@@ -1325,7 +1317,7 @@ sliceslice:
        }
 
        // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
-       n2 = nnode0;
+       n2 = nodes[0];
        n2.xoffset += Array_cap;
 
        regalloc(&n1, types[TUINT32], &nodes[2]);
@@ -1339,7 +1331,7 @@ sliceslice:
        regfree(&n1);
 
        // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
-       n2 = nnode0;
+       n2 = nodes[0];
        n2.xoffset += Array_array;
 
        regalloc(&n1, types[tptr], &nodes[1]);
index c8d4ad613221c7cd4b00a8c469e98452b8dcaef3..81c2658213dc9d6c7d48a80b6dfa40fe982cf211 100644 (file)
@@ -109,6 +109,8 @@ void        naddr(Node*, Addr*, int);
 void   cgen_aret(Node*, Node*);
 int    cgen_inline(Node*, Node*);
 Node*  ncon(uint32);
+void   mgen(Node*, Node*, Node*);
+void   mfree(Node*);
 
 /*
  * cgen64.c
index f6fa7da0b023fa68df186fba4121619dfc515a9e..23177c2408f1c6f8e6b228154b0200cfa1fcb908 100644 (file)
@@ -843,9 +843,9 @@ int
 cgen_inline(Node *n, Node *res)
 {
        Node nodes[5];
-       Node n1, n2, nres, nnode0, ntemp;
+       Node n1, n2, nres, ntemp;
        vlong v;
-       int i, narg, bad;
+       int i, narg;
 
        if(n->op != OCALLFUNC)
                goto no;
@@ -950,47 +950,38 @@ slicearray:
        return 1;
 
 sliceslice:
-       getargs(n->list, nodes, narg);
-
-       nres = *res;            // result
-       nnode0 = nodes[0];      // input slice
        ntemp.op = OXXX;
-       if(!sleasy(res) || !sleasy(&nodes[0])) {
-               bad = 0;
-               if(res->ullman >= UINF)
-                       bad = 1;
-               for(i=0; i<narg; i++) {
-                       if(nodes[i].ullman >= UINF)
-                               bad = 1;
-                       if(nodes[i].op == OREGISTER)
-                               regfree(&nodes[i]);
-               }
-
-               if(bad)
-                       goto no;
-
+       if(!sleasy(n->list->n->right)) {
+               Node *n0;
+               
+               n0 = n->list->n->right;
                tempname(&ntemp, res->type);
-               if(!sleasy(&nodes[0])) {
-                       cgen(&nodes[0], &ntemp);
-                       nnode0 = ntemp;
-               }
+               cgen(n0, &ntemp);
+               n->list->n->right = &ntemp;
+               getargs(n->list, nodes, narg);
+               n->list->n->right = n0;
+       } else
                getargs(n->list, nodes, narg);
-               if(!sleasy(res))
-                       nres = ntemp;
+
+       nres = *res;            // result
+       if(!sleasy(res)) {
+               if(ntemp.op == OXXX)
+                       tempname(&ntemp, res->type);
+               nres = ntemp;
        }
-       
+
        if(narg == 3) { // old[lb:]
                // move width to where it would be for old[lb:hb]
                nodes[3] = nodes[2];
                nodes[2].op = OXXX;
                
                // if(lb[1] > old.nel[0]) goto throw;
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.xoffset += Array_nel;
                cmpandthrow(&nodes[1], &n2);
 
                // ret.nel = old.nel[0]-lb[1];
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.xoffset += Array_nel;
        
                regalloc(&n1, types[TUINT32], N);
@@ -1004,7 +995,7 @@ sliceslice:
                regfree(&n1);
        } else {        // old[lb:hb]
                // if(hb[2] > old.cap[0]) goto throw;
-               n2 = nnode0;
+               n2 = nodes[0];
                n2.xoffset += Array_cap;
                cmpandthrow(&nodes[2], &n2);
 
@@ -1031,7 +1022,7 @@ sliceslice:
        }
 
        // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
-       n2 = nnode0;
+       n2 = nodes[0];
        n2.xoffset += Array_cap;
 
        regalloc(&n1, types[TUINT32], &nodes[2]);
@@ -1045,7 +1036,7 @@ sliceslice:
        regfree(&n1);
 
        // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
-       n2 = nnode0;
+       n2 = nodes[0];
        n2.xoffset += Array_array;
 
        regalloc(&n1, types[tptr], &nodes[1]);
index 2cfca1985c6526299608fb5830284a5ca993a414..eaf673f7492d149cb9652d7dcec108707b728afe 100644 (file)
@@ -2476,6 +2476,9 @@ safeexpr(Node *n, NodeList **init)
        Node *r;
        Node *a;
 
+       if(n == N)
+               return N;
+
        switch(n->op) {
        case ONAME:
        case OLITERAL:
index fded073a378a7e044c1ed27d1179b57923b22f67..ab4f946bdf6db28fdc23da3b10b0e946056c5f31 100644 (file)
@@ -900,8 +900,11 @@ walkexpr(Node **np, NodeList **init)
 
        case OSLICE:
                walkexpr(&n->left, init);
+               n->left = safeexpr(n->left, init);
                walkexpr(&n->right->left, init);
+               n->right->left = safeexpr(n->right->left, init);
                walkexpr(&n->right->right, init);
+               n->right->right = safeexpr(n->right->right, init);
                // dynamic slice
                // sliceslice(old []any, lb int, hb int, width int) (ary []any)
                // sliceslice1(old []any, lb int, width int) (ary []any)
@@ -928,8 +931,11 @@ walkexpr(Node **np, NodeList **init)
 
        case OSLICEARR:
                walkexpr(&n->left, init);
+               n->left = safeexpr(n->left, init);
                walkexpr(&n->right->left, init);
+               n->right->left = safeexpr(n->right->left, init);
                walkexpr(&n->right->right, init);
+               n->right->right = safeexpr(n->right->right, init);
                // static slice
                // slicearray(old *any, nel int, lb int, hb int, width int) (ary []any)
                t = n->type;
diff --git a/test/fixedbugs/bug261.go b/test/fixedbugs/bug261.go
new file mode 100644 (file)
index 0000000..8c3fda1
--- /dev/null
@@ -0,0 +1,23 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var n int
+
+func f() int {
+       n++
+       return n
+}
+
+func main() {
+       x := []int{0,1,2,3,4,5,6,7,8,9,10}
+       n = 5
+       y := x[f():f()]
+       if len(y) != 1 || y[0] != 6 {
+               println("BUG bug261", len(y), y[0])
+       }
+}