]> Cypherpunks repositories - gostls13.git/commitdiff
gc: fix div bug
authorRuss Cox <rsc@golang.org>
Tue, 30 Aug 2011 12:47:28 +0000 (08:47 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 30 Aug 2011 12:47:28 +0000 (08:47 -0400)
R=ken2
CC=golang-dev
https://golang.org/cl/4950052

src/cmd/6g/ggen.c
src/cmd/8g/ggen.c
test/fixedbugs/bug366.go [new file with mode: 0644]

index 48e2588ded692db4e15486d5769c01129c5917d4..2f68885bd368bb3079f0b7abe40d2147ecf96e36 100644 (file)
@@ -448,8 +448,8 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
 {
        int a, check;
        Node n3, n4, n5;
-       Type *t;
-       Node ax, dx, oldax, olddx;
+       Type *t, *t0;
+       Node ax, dx, ax1, n31, oldax, olddx;
        Prog *p1, *p2, *p3;
 
        // Have to be careful about handling
@@ -461,6 +461,7 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
        // For int32 and int64, use explicit test.
        // Could use int64 hw for int32.
        t = nl->type;
+       t0 = t;
        check = 0;
        if(issigned[t->etype]) {
                check = 1;
@@ -478,18 +479,28 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
        }
        a = optoas(op, t);
 
-       regalloc(&n3, t, N);
+       regalloc(&n3, t0, N);
        if(nl->ullman >= nr->ullman) {
-               savex(D_AX, &ax, &oldax, res, t);
+               savex(D_AX, &ax, &oldax, res, t0);
                cgen(nl, &ax);
-               regalloc(&ax, t, &ax);  // mark ax live during cgen
+               regalloc(&ax, t0, &ax); // mark ax live during cgen
                cgen(nr, &n3);
                regfree(&ax);
        } else {
                cgen(nr, &n3);
-               savex(D_AX, &ax, &oldax, res, t);
+               savex(D_AX, &ax, &oldax, res, t0);
                cgen(nl, &ax);
        }
+       if(t != t0) {
+               // Convert
+               ax1 = ax;
+               n31 = n3;
+               ax.type = t;
+               n3.type = t;
+               gmove(&ax1, &ax);
+               gmove(&n31, &n3);
+       }
+
        p3 = P;
        if(check) {
                nodconst(&n4, t, -1);
index 3490a7bd020c0a15f6ca1e9ef897542418a5a18c..c4f28236808e5d2534d5aabfe87b6facb34660a3 100644 (file)
@@ -484,8 +484,8 @@ void
 dodiv(int op, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
 {
        int check;
-       Node n1, t1, t2, n4, nz;
-       Type *t;
+       Node n1, t1, t2, t3, t4, n4, nz;
+       Type *t, *t0;
        Prog *p1, *p2, *p3;
 
        // Have to be careful about handling
@@ -497,6 +497,7 @@ dodiv(int op, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
        // For int32 and int64, use explicit test.
        // Could use int64 hw for int32.
        t = nl->type;
+       t0 = t;
        check = 0;
        if(issigned[t->etype]) {
                check = 1;
@@ -515,8 +516,18 @@ dodiv(int op, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
 
        tempname(&t1, t);
        tempname(&t2, t);
-       cgen(nl, &t1);
-       cgen(nr, &t2);
+       if(t0 != t) {
+               tempname(&t3, t0);
+               tempname(&t4, t0);
+               cgen(nl, &t3);
+               cgen(nr, &t4);
+               // Convert.
+               gmove(&t3, &t1);
+               gmove(&t4, &t2);
+       } else {
+               cgen(nl, &t1);
+               cgen(nr, &t2);
+       }
 
        if(!samereg(ax, res) && !samereg(dx, res))
                regalloc(&n1, t, res);
diff --git a/test/fixedbugs/bug366.go b/test/fixedbugs/bug366.go
new file mode 100644 (file)
index 0000000..8c000f5
--- /dev/null
@@ -0,0 +1,37 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2011 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 2206.  Incorrect sign extension of div arguments.
+
+package main
+
+func five(x int64) {
+       if x != 5 {
+               panic(x)
+       }
+}
+
+func main() {
+       // 5
+       five(int64(5 / (5 / 3)))
+
+       // 5
+       five(int64(byte(5) / (byte(5) / byte(3))))
+
+       // 5
+       var a, b byte = 5, 3
+       five(int64(a / (a / b)))
+       
+       // integer divide by zero in golang.org sandbox
+       // 0 on windows/amd64
+       x := [3]byte{2, 3, 5}
+       five(int64(x[2] / (x[2] / x[1])))
+
+       // integer divide by zero in golang.org sandbox
+       // crash on windows/amd64
+       y := x[1:3]
+       five(int64(y[1] / (y[1] / y[0])))
+}
\ No newline at end of file