FAQ
Reviewers: golang-dev_googlegroups.com,

Message:
Hello golang-dev@googlegroups.com (cc: golang-dev@googlegroups.com),

I'd like you to review this change to
https://code.google.com/p/go


Description:
cmd/5g, cmd/8g: fix internal error on 64-bit indices statically bounded

Fixes issue 4448.

Please review this at http://codereview.appspot.com/6855100/

Affected files:
M src/cmd/5g/cgen.c
M src/cmd/5g/gg.h
M src/cmd/5g/gsubr.c
M src/cmd/8g/cgen.c
A test/fixedbugs/issue4448.go


Index: src/cmd/5g/cgen.c
===================================================================
--- a/src/cmd/5g/cgen.c
+++ b/src/cmd/5g/cgen.c
@@ -521,7 +521,7 @@
* returns Prog* to patch to panic call.
*/
Prog*
-cgenindex(Node *n, Node *res)
+cgenindex(Node *n, Node *res, int bounded)
{
Node tmp, lo, hi, zero, n1, n2;

@@ -534,7 +534,7 @@
cgen(n, &tmp);
split64(&tmp, &lo, &hi);
gmove(&lo, res);
- if(debug['B']) {
+ if(bounded) {
splitclean();
return nil;
}
@@ -889,6 +889,7 @@
Prog *p1, *p2;
uint32 w;
uint64 v;
+ int bounded;

if(debug['g'])
dump("agenr-n", n);
@@ -915,13 +916,14 @@
case OINDEX:
p2 = nil; // to be patched to panicindex.
w = n->type->width;
+ bounded = debug['B'] || n->bounded;
if(nr->addable) {
if(!isconst(nr, CTINT))
tempname(&tmp, types[TINT32]);
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) {
- p2 = cgenindex(nr, &tmp);
+ p2 = cgenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
@@ -929,7 +931,7 @@
if(nl->addable) {
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]);
- p2 = cgenindex(nr, &tmp);
+ p2 = cgenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
@@ -938,7 +940,7 @@
}
} else {
tempname(&tmp, types[TINT32]);
- p2 = cgenindex(nr, &tmp);
+ p2 = cgenindex(nr, &tmp, bounded);
nr = &tmp;
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
Index: src/cmd/5g/gg.h
===================================================================
--- a/src/cmd/5g/gg.h
+++ b/src/cmd/5g/gg.h
@@ -88,7 +88,7 @@
* cgen
*/
void agen(Node*, Node*);
-Prog* cgenindex(Node *, Node *);
+Prog* cgenindex(Node *, Node *, int);
void igen(Node*, Node*, Node*);
void agenr(Node *n, Node *a, Node *res);
vlong fieldoffset(Type*, Node*);
Index: src/cmd/5g/gsubr.c
===================================================================
--- a/src/cmd/5g/gsubr.c
+++ b/src/cmd/5g/gsubr.c
@@ -1937,7 +1937,7 @@
t = types[TINT32];
regalloc(reg1, t, N);
regalloc(&n3, types[TINT32], reg1);
- p2 = cgenindex(r, &n3);
+ p2 = cgenindex(r, &n3, debug['B'] || n->bounded);
gmove(&n3, reg1);
regfree(&n3);

Index: src/cmd/8g/cgen.c
===================================================================
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -464,8 +464,8 @@
* n is an array index, and might be any size; res width is <= 32-bit.
* returns Prog* to patch to panic call.
*/
-Prog*
-igenindex(Node *n, Node *res)
+static Prog*
+igenindex(Node *n, Node *res, int bounded)
{
Node tmp, lo, hi, zero;

@@ -485,7 +485,7 @@
split64(&tmp, &lo, &hi);
tempname(res, types[TUINT32]);
gmove(&lo, res);
- if(debug['B']) {
+ if(bounded) {
splitclean();
return nil;
}
@@ -508,6 +508,7 @@
uint32 w;
uint64 v;
Prog *p1, *p2;
+ int bounded;

if(debug['g']) {
dump("\nagen-res", res);
@@ -584,26 +585,27 @@
case OINDEX:
p2 = nil; // to be patched to panicindex.
w = n->type->width;
+ bounded = debug['B'] || n->bounded;
if(nr->addable) {
// Generate &nl first, and move nr into register.
if(!isconst(nl, CTSTR))
igen(nl, &n3, res);
if(!isconst(nr, CTINT)) {
- p2 = igenindex(nr, &tmp);
+ p2 = igenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
} else if(nl->addable) {
// Generate nr first, and move &nl into register.
if(!isconst(nr, CTINT)) {
- p2 = igenindex(nr, &tmp);
+ p2 = igenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
if(!isconst(nl, CTSTR))
igen(nl, &n3, res);
} else {
- p2 = igenindex(nr, &tmp);
+ p2 = igenindex(nr, &tmp, bounded);
nr = &tmp;
if(!isconst(nl, CTSTR))
igen(nl, &n3, res);
Index: test/fixedbugs/issue4448.go
===================================================================
new file mode 100644
--- /dev/null
+++ b/test/fixedbugs/issue4448.go
@@ -0,0 +1,37 @@
+// run
+
+// 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 4448: 64-bit indices that are statically known
+// to be bounded make 5g and 8g generate a dangling branch.
+
+package main
+
+const b26 uint64 = 0x022fdd63cc95386d
+
+var bitPos [64]int
+
+func init() {
+ for p := uint(0); p < 64; p++ {
+ bitPos[b26<<p>>58] = int(p)
+ }
+}
+
+func MinPos(w uint64) int {
+ if w == 0 {
+ panic("bit: MinPos(0) undefined")
+ }
+ return bitPos[((w&-w)*b26)>>58]
+}
+
+func main() {
+ const one = uint64(1)
+ for i := 0; i < 64; i++ {
+ if MinPos(1<<uint(i)) != i {
+ println("i =", i)
+ panic("MinPos(1<<uint(i)) != i")
+ }
+ }
+}

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-dev @
categoriesgo
postedNov 26, '12 at 11:28p
activeNov 27, '12 at 8:38p
posts3
users2
websitegolang.org

2 users in discussion

Remyoudompheng: 2 posts Rsc: 1 post

People

Translate

site design / logo © 2022 Grokbase