1
0
mirror of https://github.com/golang/go synced 2024-11-22 00:54:43 -07:00

5g/6g/8g: fix double function call in slice

Fixes #654.

R=ken2
CC=golang-dev
https://golang.org/cl/310041
This commit is contained in:
Russ Cox 2010-03-08 14:19:28 -08:00
parent 8ddd6c4181
commit 4f89dcdf99
7 changed files with 106 additions and 97 deletions

View File

@ -810,9 +810,9 @@ int
cgen_inline(Node *n, Node *res) cgen_inline(Node *n, Node *res)
{ {
Node nodes[5]; Node nodes[5];
Node n1, n2, n3, nres, nnode0, ntemp; Node n1, n2, n3, nres, ntemp;
vlong v; vlong v;
int i, narg, bad; int i, narg;
if(n->op != OCALLFUNC) if(n->op != OCALLFUNC)
goto no; goto no;
@ -926,47 +926,39 @@ slicearray:
return 1; return 1;
sliceslice: sliceslice:
getargs(n->list, nodes, narg); ntemp.op = OXXX;
if(!sleasy(n->list->n->right)) {
Node *n0;
n0 = n->list->n->right;
tempname(&ntemp, res->type);
cgen(n0, &ntemp);
n->list->n->right = &ntemp;
getargs(n->list, nodes, narg);
n->list->n->right = n0;
} else
getargs(n->list, nodes, narg);
nres = *res; // result nres = *res; // result
nnode0 = nodes[0]; // input slice if(!sleasy(res)) {
if(!sleasy(res) || !sleasy(&nodes[0])) { if(ntemp.op == OXXX)
bad = 0; tempname(&ntemp, res->type);
if(res->ullman >= UINF) nres = ntemp;
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;
tempname(&ntemp, res->type);
if(!sleasy(&nodes[0])) {
cgen(&nodes[0], &ntemp);
nnode0 = ntemp;
}
getargs(n->list, nodes, narg);
if(!sleasy(res))
nres = ntemp;
} }
if(narg == 3) { // old[lb:] if(narg == 3) { // old[lb:]
// move width to where it would be for old[lb:hb] // move width to where it would be for old[lb:hb]
nodes[3] = nodes[2]; nodes[3] = nodes[2];
nodes[2].op = OXXX; nodes[2].op = OXXX;
// if(lb[1] > old.nel[0]) goto throw; // if(lb[1] > old.nel[0]) goto throw;
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
n2.type = types[TUINT32]; n2.type = types[TUINT32];
cmpandthrow(&nodes[1], &n2); cmpandthrow(&nodes[1], &n2);
// ret.nel = old.nel[0]-lb[1]; // ret.nel = old.nel[0]-lb[1];
n2 = nnode0; n2 = nodes[0];
n2.type = types[TUINT32]; n2.type = types[TUINT32];
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
@ -982,7 +974,7 @@ sliceslice:
regfree(&n1); regfree(&n1);
} else { // old[lb:hb] } else { // old[lb:hb]
// if(hb[2] > old.cap[0]) goto throw; // if(hb[2] > old.cap[0]) goto throw;
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
n2.type = types[TUINT32]; n2.type = types[TUINT32];
cmpandthrow(&nodes[2], &n2); cmpandthrow(&nodes[2], &n2);
@ -1011,7 +1003,7 @@ sliceslice:
} }
// ret.cap = old.cap[0]-lb[1]; (uses hb[2]) // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
n2 = nnode0; n2 = nodes[0];
n2.type = types[TUINT32]; n2.type = types[TUINT32];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
@ -1027,7 +1019,7 @@ sliceslice:
regfree(&n1); regfree(&n1);
// ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1]) // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
n2 = nnode0; n2 = nodes[0];
n2.type = types[tptr]; n2.type = types[tptr];
n2.xoffset += Array_array; n2.xoffset += Array_array;
regalloc(&n3, types[tptr], N); regalloc(&n3, types[tptr], N);

View File

@ -1138,9 +1138,9 @@ int
cgen_inline(Node *n, Node *res) cgen_inline(Node *n, Node *res)
{ {
Node nodes[5]; Node nodes[5];
Node n1, n2, nres, nnode0, ntemp; Node n1, n2, nres, ntemp;
vlong v; vlong v;
int i, narg, bad; int i, narg;
if(n->op != OCALLFUNC) if(n->op != OCALLFUNC)
goto no; goto no;
@ -1245,46 +1245,38 @@ slicearray:
return 1; return 1;
sliceslice: sliceslice:
getargs(n->list, nodes, narg); ntemp.op = OXXX;
if(!sleasy(n->list->n->right)) {
Node *n0;
n0 = n->list->n->right;
tempname(&ntemp, res->type);
cgen(n0, &ntemp);
n->list->n->right = &ntemp;
getargs(n->list, nodes, narg);
n->list->n->right = n0;
} else
getargs(n->list, nodes, narg);
nres = *res; // result nres = *res; // result
nnode0 = nodes[0]; // input slice if(!sleasy(res)) {
if(!sleasy(res) || !sleasy(&nodes[0])) { if(ntemp.op == OXXX)
bad = 0; tempname(&ntemp, res->type);
if(res->ullman >= UINF) nres = ntemp;
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;
tempname(&ntemp, res->type);
if(!sleasy(&nodes[0])) {
cgen(&nodes[0], &ntemp);
nnode0 = ntemp;
}
getargs(n->list, nodes, narg);
if(!sleasy(res))
nres = ntemp;
} }
if(narg == 3) { // old[lb:] if(narg == 3) { // old[lb:]
// move width to where it would be for old[lb:hb] // move width to where it would be for old[lb:hb]
nodes[3] = nodes[2]; nodes[3] = nodes[2];
nodes[2].op = OXXX; nodes[2].op = OXXX;
// if(lb[1] > old.nel[0]) goto throw; // if(lb[1] > old.nel[0]) goto throw;
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
cmpandthrow(&nodes[1], &n2); cmpandthrow(&nodes[1], &n2);
// ret.nel = old.nel[0]-lb[1]; // ret.nel = old.nel[0]-lb[1];
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
regalloc(&n1, types[TUINT32], N); regalloc(&n1, types[TUINT32], N);
@ -1298,7 +1290,7 @@ sliceslice:
regfree(&n1); regfree(&n1);
} else { // old[lb:hb] } else { // old[lb:hb]
// if(hb[2] > old.cap[0]) goto throw; // if(hb[2] > old.cap[0]) goto throw;
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
cmpandthrow(&nodes[2], &n2); cmpandthrow(&nodes[2], &n2);
@ -1325,7 +1317,7 @@ sliceslice:
} }
// ret.cap = old.cap[0]-lb[1]; (uses hb[2]) // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
regalloc(&n1, types[TUINT32], &nodes[2]); regalloc(&n1, types[TUINT32], &nodes[2]);
@ -1339,7 +1331,7 @@ sliceslice:
regfree(&n1); regfree(&n1);
// ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1]) // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_array; n2.xoffset += Array_array;
regalloc(&n1, types[tptr], &nodes[1]); regalloc(&n1, types[tptr], &nodes[1]);

View File

@ -109,6 +109,8 @@ void naddr(Node*, Addr*, int);
void cgen_aret(Node*, Node*); void cgen_aret(Node*, Node*);
int cgen_inline(Node*, Node*); int cgen_inline(Node*, Node*);
Node* ncon(uint32); Node* ncon(uint32);
void mgen(Node*, Node*, Node*);
void mfree(Node*);
/* /*
* cgen64.c * cgen64.c

View File

@ -843,9 +843,9 @@ int
cgen_inline(Node *n, Node *res) cgen_inline(Node *n, Node *res)
{ {
Node nodes[5]; Node nodes[5];
Node n1, n2, nres, nnode0, ntemp; Node n1, n2, nres, ntemp;
vlong v; vlong v;
int i, narg, bad; int i, narg;
if(n->op != OCALLFUNC) if(n->op != OCALLFUNC)
goto no; goto no;
@ -950,47 +950,38 @@ slicearray:
return 1; return 1;
sliceslice: sliceslice:
getargs(n->list, nodes, narg); ntemp.op = OXXX;
if(!sleasy(n->list->n->right)) {
Node *n0;
n0 = n->list->n->right;
tempname(&ntemp, res->type);
cgen(n0, &ntemp);
n->list->n->right = &ntemp;
getargs(n->list, nodes, narg);
n->list->n->right = n0;
} else
getargs(n->list, nodes, narg);
nres = *res; // result nres = *res; // result
nnode0 = nodes[0]; // input slice if(!sleasy(res)) {
ntemp.op = OXXX; if(ntemp.op == OXXX)
if(!sleasy(res) || !sleasy(&nodes[0])) { tempname(&ntemp, res->type);
bad = 0; nres = ntemp;
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;
tempname(&ntemp, res->type);
if(!sleasy(&nodes[0])) {
cgen(&nodes[0], &ntemp);
nnode0 = ntemp;
}
getargs(n->list, nodes, narg);
if(!sleasy(res))
nres = ntemp;
} }
if(narg == 3) { // old[lb:] if(narg == 3) { // old[lb:]
// move width to where it would be for old[lb:hb] // move width to where it would be for old[lb:hb]
nodes[3] = nodes[2]; nodes[3] = nodes[2];
nodes[2].op = OXXX; nodes[2].op = OXXX;
// if(lb[1] > old.nel[0]) goto throw; // if(lb[1] > old.nel[0]) goto throw;
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
cmpandthrow(&nodes[1], &n2); cmpandthrow(&nodes[1], &n2);
// ret.nel = old.nel[0]-lb[1]; // ret.nel = old.nel[0]-lb[1];
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
regalloc(&n1, types[TUINT32], N); regalloc(&n1, types[TUINT32], N);
@ -1004,7 +995,7 @@ sliceslice:
regfree(&n1); regfree(&n1);
} else { // old[lb:hb] } else { // old[lb:hb]
// if(hb[2] > old.cap[0]) goto throw; // if(hb[2] > old.cap[0]) goto throw;
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
cmpandthrow(&nodes[2], &n2); cmpandthrow(&nodes[2], &n2);
@ -1031,7 +1022,7 @@ sliceslice:
} }
// ret.cap = old.cap[0]-lb[1]; (uses hb[2]) // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
regalloc(&n1, types[TUINT32], &nodes[2]); regalloc(&n1, types[TUINT32], &nodes[2]);
@ -1045,7 +1036,7 @@ sliceslice:
regfree(&n1); regfree(&n1);
// ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1]) // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
n2 = nnode0; n2 = nodes[0];
n2.xoffset += Array_array; n2.xoffset += Array_array;
regalloc(&n1, types[tptr], &nodes[1]); regalloc(&n1, types[tptr], &nodes[1]);

View File

@ -2476,6 +2476,9 @@ safeexpr(Node *n, NodeList **init)
Node *r; Node *r;
Node *a; Node *a;
if(n == N)
return N;
switch(n->op) { switch(n->op) {
case ONAME: case ONAME:
case OLITERAL: case OLITERAL:

View File

@ -900,8 +900,11 @@ walkexpr(Node **np, NodeList **init)
case OSLICE: case OSLICE:
walkexpr(&n->left, init); walkexpr(&n->left, init);
n->left = safeexpr(n->left, init);
walkexpr(&n->right->left, init); walkexpr(&n->right->left, init);
n->right->left = safeexpr(n->right->left, init);
walkexpr(&n->right->right, init); walkexpr(&n->right->right, init);
n->right->right = safeexpr(n->right->right, init);
// dynamic slice // dynamic slice
// sliceslice(old []any, lb int, hb int, width int) (ary []any) // sliceslice(old []any, lb int, hb int, width int) (ary []any)
// sliceslice1(old []any, lb 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: case OSLICEARR:
walkexpr(&n->left, init); walkexpr(&n->left, init);
n->left = safeexpr(n->left, init);
walkexpr(&n->right->left, init); walkexpr(&n->right->left, init);
n->right->left = safeexpr(n->right->left, init);
walkexpr(&n->right->right, init); walkexpr(&n->right->right, init);
n->right->right = safeexpr(n->right->right, init);
// static slice // static slice
// slicearray(old *any, nel int, lb int, hb int, width int) (ary []any) // slicearray(old *any, nel int, lb int, hb int, width int) (ary []any)
t = n->type; t = n->type;

23
test/fixedbugs/bug261.go Normal file
View File

@ -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])
}
}