Commit 1e233ad0 authored by Rémy Oudompheng's avatar Rémy Oudompheng

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
parent 3e80f9ce
...@@ -566,6 +566,7 @@ agenr(Node *n, Node *a, Node *res) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
gins(optoas(OCMP, types[simtype[TUINT]]), &nlen, &n2); if(smallintconst(nr)) {
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) ...@@ -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) ...@@ -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;
......
// 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)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment