1
0
mirror of https://github.com/golang/go synced 2024-11-21 15:14:43 -07:00

gc: fix div bug

R=ken2
CC=golang-dev
https://golang.org/cl/4950052
This commit is contained in:
Russ Cox 2011-08-30 08:47:28 -04:00
parent c586b5b96b
commit 4fb3c4f765
3 changed files with 69 additions and 10 deletions

View 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);

View 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);

37
test/fixedbugs/bug366.go Normal file
View File

@ -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])))
}