]> Cypherpunks repositories - gostls13.git/commitdiff
big: handle aliasing correctly for Rat.SetFrac.
authorRobert Griesemer <gri@golang.org>
Tue, 18 Oct 2011 19:40:41 +0000 (12:40 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 18 Oct 2011 19:40:41 +0000 (12:40 -0700)
Fixes #2379.

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

src/pkg/big/rat.go
src/pkg/big/rat_test.go

index 327b9bd9ca72665092dc62634c26428d89065360..f435e637f191a5b3af153de1443e1d8cbd6ab9ec 100644 (file)
@@ -27,9 +27,13 @@ func NewRat(a, b int64) *Rat {
 
 // SetFrac sets z to a/b and returns z.
 func (z *Rat) SetFrac(a, b *Int) *Rat {
-       z.a.Set(a)
        z.a.neg = a.neg != b.neg
-       z.b = z.b.set(b.abs)
+       babs := b.abs
+       if &z.a == b || alias(z.a.abs, babs) {
+               babs = nat(nil).set(babs) // make a copy
+       }
+       z.a.abs = z.a.abs.set(a.abs)
+       z.b = z.b.set(babs)
        return z.norm()
 }
 
index dbc5bb6cca11552c5b32166c3b44ef26f3049cad..a2b905525eed0e65c63f6b637170779b9337621a 100644 (file)
@@ -330,3 +330,43 @@ func TestRatGobEncoding(t *testing.T) {
                }
        }
 }
+
+func TestIssue2379(t *testing.T) {
+       // 1) no aliasing
+       q := NewRat(3, 2)
+       x := new(Rat)
+       x.SetFrac(NewInt(3), NewInt(2))
+       if x.Cmp(q) != 0 {
+               t.Errorf("1) got %s want %s", x, q)
+       }
+
+       // 2) aliasing of numerator
+       x = NewRat(2, 3)
+       x.SetFrac(NewInt(3), x.Num())
+       if x.Cmp(q) != 0 {
+               t.Errorf("2) got %s want %s", x, q)
+       }
+
+       // 3) aliasing of denominator
+       x = NewRat(2, 3)
+       x.SetFrac(x.Denom(), NewInt(2))
+       if x.Cmp(q) != 0 {
+               t.Errorf("3) got %s want %s", x, q)
+       }
+
+       // 4) aliasing of numerator and denominator
+       x = NewRat(2, 3)
+       x.SetFrac(x.Denom(), x.Num())
+       if x.Cmp(q) != 0 {
+               t.Errorf("4) got %s want %s", x, q)
+       }
+
+       // 5) numerator and denominator are the same
+       q = NewRat(1, 1)
+       x = new(Rat)
+       n := NewInt(7)
+       x.SetFrac(n, n)
+       if x.Cmp(q) != 0 {
+               t.Errorf("5) got %s want %s", x, q)
+       }
+}