]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/5g, cmd/8g: fix internal error on 64-bit indices statically bounded
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Tue, 27 Nov 2012 20:37:38 +0000 (21:37 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Tue, 27 Nov 2012 20:37:38 +0000 (21:37 +0100)
Fixes #4448.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6855100

src/cmd/5g/cgen.c
src/cmd/5g/gg.h
src/cmd/5g/gsubr.c
src/cmd/8g/cgen.c
test/fixedbugs/issue4448.go [new file with mode: 0644]

index bd56728bf52bd5d4950214e1255d33ba7c80b0e6..764a2803f53f04636bf6cde98dcba185c79ce353 100644 (file)
@@ -521,7 +521,7 @@ ret:
  * 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 @@ cgenindex(Node *n, Node *res)
        cgen(n, &tmp);
        split64(&tmp, &lo, &hi);
        gmove(&lo, res);
-       if(debug['B']) {
+       if(bounded) {
                splitclean();
                return nil;
        }
@@ -889,6 +889,7 @@ agenr(Node *n, Node *a, Node *res)
        Prog *p1, *p2;
        uint32 w;
        uint64 v;
+       int bounded;
 
        if(debug['g'])
                dump("agenr-n", n);
@@ -915,13 +916,14 @@ agenr(Node *n, Node *a, Node *res)
        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 @@ agenr(Node *n, Node *a, Node *res)
                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 @@ agenr(Node *n, Node *a, Node *res)
                        }
                } 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 370cf6e038483af9bf1292f9c6bea1cdc88a4402..394ca4730bbbb9a755b5ac556e1cb0f957381e10 100644 (file)
@@ -88,7 +88,7 @@ void  ginscall(Node*, int);
  * 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 916d2a7453239fda95c4f459280828a6299d82af..ed0e73b88d0e730f9a91f7d359a21e280d282af3 100644 (file)
@@ -1937,7 +1937,7 @@ oindex:
                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 9716d0616b60fc563c914e9adb58623b1aa2f936..935831d75120ae28d833544d00e65da766c8e06f 100644 (file)
@@ -464,8 +464,8 @@ flt2:       // binary
  * 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 @@ igenindex(Node *n, Node *res)
        split64(&tmp, &lo, &hi);
        tempname(res, types[TUINT32]);
        gmove(&lo, res);
-       if(debug['B']) {
+       if(bounded) {
                splitclean();
                return nil;
        }
@@ -508,6 +508,7 @@ agen(Node *n, Node *res)
        uint32 w;
        uint64 v;
        Prog *p1, *p2;
+       int bounded;
 
        if(debug['g']) {
                dump("\nagen-res", res);
@@ -584,26 +585,27 @@ agen(Node *n, Node *res)
        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);
diff --git a/test/fixedbugs/issue4448.go b/test/fixedbugs/issue4448.go
new file mode 100644 (file)
index 0000000..fa1d9fe
--- /dev/null
@@ -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")
+               }
+       }
+}