mirror of https://github.com/golang/go.git
cmd/6g: fix use of large integers as indexes or array sizes.
A check for smallintconst was missing before generating the comparisons. Fixes #4348. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/6815088
This commit is contained in:
parent
3e80f9ce7b
commit
1e233ad075
|
|
@ -566,6 +566,7 @@ agenr(Node *n, Node *a, Node *res)
|
||||||
Type *t;
|
Type *t;
|
||||||
uint32 w;
|
uint32 w;
|
||||||
uint64 v;
|
uint64 v;
|
||||||
|
int freelen;
|
||||||
|
|
||||||
if(debug['g']) {
|
if(debug['g']) {
|
||||||
dump("\nagenr-n", n);
|
dump("\nagenr-n", n);
|
||||||
|
|
@ -576,6 +577,7 @@ agenr(Node *n, Node *a, Node *res)
|
||||||
|
|
||||||
switch(n->op) {
|
switch(n->op) {
|
||||||
case OINDEX:
|
case OINDEX:
|
||||||
|
freelen = 0;
|
||||||
w = n->type->width;
|
w = n->type->width;
|
||||||
// Generate the non-addressable child first.
|
// Generate the non-addressable child first.
|
||||||
if(nr->addable)
|
if(nr->addable)
|
||||||
|
|
@ -587,6 +589,7 @@ agenr(Node *n, Node *a, Node *res)
|
||||||
agenr(nl, &n3, res);
|
agenr(nl, &n3, res);
|
||||||
} else {
|
} else {
|
||||||
igen(nl, &nlen, res);
|
igen(nl, &nlen, res);
|
||||||
|
freelen = 1;
|
||||||
nlen.type = types[tptr];
|
nlen.type = types[tptr];
|
||||||
nlen.xoffset += Array_array;
|
nlen.xoffset += Array_array;
|
||||||
regalloc(&n3, types[tptr], res);
|
regalloc(&n3, types[tptr], res);
|
||||||
|
|
@ -612,6 +615,7 @@ agenr(Node *n, Node *a, Node *res)
|
||||||
nl = &tmp2;
|
nl = &tmp2;
|
||||||
}
|
}
|
||||||
igen(nl, &nlen, res);
|
igen(nl, &nlen, res);
|
||||||
|
freelen = 1;
|
||||||
nlen.type = types[tptr];
|
nlen.type = types[tptr];
|
||||||
nlen.xoffset += Array_array;
|
nlen.xoffset += Array_array;
|
||||||
regalloc(&n3, types[tptr], res);
|
regalloc(&n3, types[tptr], res);
|
||||||
|
|
@ -651,7 +655,14 @@ agenr(Node *n, Node *a, Node *res)
|
||||||
if(isslice(nl->type) || nl->type->etype == TSTRING) {
|
if(isslice(nl->type) || nl->type->etype == TSTRING) {
|
||||||
if(!debug['B'] && !n->bounded) {
|
if(!debug['B'] && !n->bounded) {
|
||||||
nodconst(&n2, types[simtype[TUINT]], v);
|
nodconst(&n2, types[simtype[TUINT]], v);
|
||||||
|
if(smallintconst(nr)) {
|
||||||
gins(optoas(OCMP, types[simtype[TUINT]]), &nlen, &n2);
|
gins(optoas(OCMP, types[simtype[TUINT]]), &nlen, &n2);
|
||||||
|
} else {
|
||||||
|
regalloc(&tmp, types[simtype[TUINT]], N);
|
||||||
|
gmove(&n2, &tmp);
|
||||||
|
gins(optoas(OCMP, types[simtype[TUINT]]), &nlen, &tmp);
|
||||||
|
regfree(&tmp);
|
||||||
|
}
|
||||||
p1 = gbranch(optoas(OGT, types[simtype[TUINT]]), T, +1);
|
p1 = gbranch(optoas(OGT, types[simtype[TUINT]]), T, +1);
|
||||||
ginscall(panicindex, -1);
|
ginscall(panicindex, -1);
|
||||||
patch(p1, pc);
|
patch(p1, pc);
|
||||||
|
|
@ -690,6 +701,12 @@ agenr(Node *n, Node *a, Node *res)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nodconst(&nlen, t, nl->type->bound);
|
nodconst(&nlen, t, nl->type->bound);
|
||||||
|
if(!smallintconst(&nlen)) {
|
||||||
|
regalloc(&n5, t, N);
|
||||||
|
gmove(&nlen, &n5);
|
||||||
|
nlen = n5;
|
||||||
|
freelen = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gins(optoas(OCMP, t), &n2, &nlen);
|
gins(optoas(OCMP, t), &n2, &nlen);
|
||||||
p1 = gbranch(optoas(OLT, t), T, +1);
|
p1 = gbranch(optoas(OLT, t), T, +1);
|
||||||
|
|
@ -721,7 +738,7 @@ agenr(Node *n, Node *a, Node *res)
|
||||||
indexdone:
|
indexdone:
|
||||||
*a = n3;
|
*a = n3;
|
||||||
regfree(&n2);
|
regfree(&n2);
|
||||||
if(!isconst(nl, CTSTR) && !isfixedarray(nl->type))
|
if(freelen)
|
||||||
regfree(&nlen);
|
regfree(&nlen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
// compile
|
||||||
|
|
||||||
|
// Copyright 2012 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.
|
||||||
|
|
||||||
|
// Issue 4238. After switch to 64-bit ints the compiler generates
|
||||||
|
// illegal instructions when using large array bounds or indexes.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
// 1<<32 on a 64-bit machine, 1 otherwise.
|
||||||
|
const LARGE = ^uint(0)>>32 + 1
|
||||||
|
|
||||||
|
func A() int {
|
||||||
|
var a []int
|
||||||
|
return a[LARGE]
|
||||||
|
}
|
||||||
|
|
||||||
|
func B(i int) int {
|
||||||
|
var b [LARGE]int
|
||||||
|
return b[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
n := A()
|
||||||
|
B(n)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue