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:
parent
8ddd6c4181
commit
4f89dcdf99
@ -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);
|
||||||
|
@ -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]);
|
||||||
|
@ -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
|
||||||
|
@ -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]);
|
||||||
|
@ -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:
|
||||||
|
@ -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
23
test/fixedbugs/bug261.go
Normal 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])
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user