aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-04-30 14:04:34 -0700
committerRuss Cox <rsc@golang.org>2010-04-30 14:04:34 -0700
commitc66b49845c2b8915a033f9957bdcea4a57223125 (patch)
treecd4c616b3628840bcb6a40a21c18ed8706ffd9a5
parent253fd30e667efc34f25be4e65ac0f451b712da5a (diff)
downloadgo-c66b49845c2b8915a033f9957bdcea4a57223125.tar.gz
go-c66b49845c2b8915a033f9957bdcea4a57223125.zip
8g: bug272
Fixes #589. R=ken2 CC=golang-dev https://golang.org/cl/1043042
-rw-r--r--src/cmd/8g/cgen.c50
-rw-r--r--test/fixedbugs/bug272.go25
2 files changed, 62 insertions, 13 deletions
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
index d7a5ab33ab..9ebbc4b4f7 100644
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -431,6 +431,33 @@ flt2: // binary
}
/*
+ * generate array index into res.
+ * n might be any size; res is 32-bit.
+ * returns Prog* to patch to panic call.
+ */
+Prog*
+cgenindex(Node *n, Node *res)
+{
+ Node tmp, lo, hi, zero;
+ Prog *p;
+
+ if(!is64(n->type)) {
+ cgen(n, res);
+ return nil;
+ }
+
+ tempname(&tmp, types[TINT64]);
+ cgen(n, &tmp);
+ split64(&tmp, &lo, &hi);
+ gmove(&lo, res);
+ if(debug['B'])
+ return nil;
+ nodconst(&zero, types[TINT32], 0);
+ gins(ACMPL, &hi, &zero);
+ return gbranch(AJNE, T);
+}
+
+/*
* address gen
* res = &n;
*/
@@ -442,7 +469,7 @@ agen(Node *n, Node *res)
Type *t;
uint32 w;
uint64 v;
- Prog *p1;
+ Prog *p1, *p2;
if(debug['g']) {
dump("\nagen-res", res);
@@ -489,20 +516,20 @@ agen(Node *n, Node *res)
break;
case OINDEX:
- // TODO(rsc): uint64 indices
+ p2 = nil; // to be patched to panicindex.
w = n->type->width;
if(nr->addable) {
agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]);
- cgen(nr, &tmp);
+ p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
} else if(nl->addable) {
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]);
- cgen(nr, &tmp);
+ p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
@@ -510,7 +537,7 @@ agen(Node *n, Node *res)
agen(nl, &n3);
} else {
tempname(&tmp, types[TINT32]);
- cgen(nr, &tmp);
+ p2 = cgenindex(nr, &tmp);
nr = &tmp;
agenr(nl, &n3, res);
regalloc(&n1, tmp.type, N);
@@ -575,12 +602,7 @@ agen(Node *n, Node *res)
break;
}
- // type of the index
- t = types[TUINT32];
- if(issigned[n1.type->etype])
- t = types[TINT32];
-
- regalloc(&n2, t, &n1); // i
+ regalloc(&n2, types[TINT32], &n1); // i
gmove(&n1, &n2);
regfree(&n1);
@@ -595,6 +617,8 @@ agen(Node *n, Node *res)
nodconst(&n1, types[TUINT32], nl->type->bound);
gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
p1 = gbranch(optoas(OLT, types[TUINT32]), T);
+ if(p2)
+ patch(p2, pc);
ginscall(panicindex, 0);
patch(p1, pc);
}
@@ -613,8 +637,8 @@ agen(Node *n, Node *res)
p1->from.index = p1->from.type;
p1->from.type = p1->to.type + D_INDIR;
} else {
- nodconst(&n1, t, w);
- gins(optoas(OMUL, t), &n1, &n2);
+ nodconst(&n1, types[TUINT32], w);
+ gins(optoas(OMUL, types[TUINT32]), &n1, &n2);
gins(optoas(OADD, types[tptr]), &n2, &n3);
gmove(&n3, res);
}
diff --git a/test/fixedbugs/bug272.go b/test/fixedbugs/bug272.go
new file mode 100644
index 0000000000..3b7c466748
--- /dev/null
+++ b/test/fixedbugs/bug272.go
@@ -0,0 +1,25 @@
+// $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.
+
+// http://code.google.com/p/go/issues/detail?id=589
+
+package main
+
+func main() {
+ n := int64(100)
+ x := make([]int, n)
+ x[99] = 234;
+ z := x[n-1]
+ if z != 234 {
+ println("BUG")
+ }
+ n |= 1<<32
+ defer func() {
+ recover()
+ }()
+ z = x[n-1]
+ println("BUG2")
+}