]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/gc: there are no -0 floating-point constants
authorRobert Griesemer <gri@golang.org>
Tue, 20 Oct 2015 21:45:36 +0000 (14:45 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 20 Oct 2015 22:11:11 +0000 (22:11 +0000)
Fixes #12577.

Change-Id: Id469cd92f5f9436b0ef948ee1a252ed1842bc7aa
Reviewed-on: https://go-review.googlesource.com/16133
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/mparith3.go
test/fixedbugs/issue12577.go [new file with mode: 0644]

index f91a64b42d82310b70b7a0c99286e3a541f98aa4..4aa283fe33aa2c806c056e6f78565e963e29d16e 100644 (file)
@@ -113,7 +113,7 @@ func mpgetflt(a *Mpflt) float64 {
                Yyerror("mpgetflt ovf")
        }
 
-       return x
+       return x + 0 // avoid -0 (should not be needed, but be conservative)
 }
 
 func mpgetflt32(a *Mpflt) float64 {
@@ -125,7 +125,7 @@ func mpgetflt32(a *Mpflt) float64 {
                Yyerror("mpgetflt32 ovf")
        }
 
-       return x
+       return x + 0 // avoid -0 (should not be needed, but be conservative)
 }
 
 func Mpmovecflt(a *Mpflt, c float64) {
@@ -133,6 +133,10 @@ func Mpmovecflt(a *Mpflt, c float64) {
                fmt.Printf("\nconst %g", c)
        }
 
+       // convert -0 to 0
+       if c == 0 {
+               c = 0
+       }
        a.Val.SetFloat64(c)
 
        if Mpdebug {
@@ -141,7 +145,10 @@ func Mpmovecflt(a *Mpflt, c float64) {
 }
 
 func mpnegflt(a *Mpflt) {
-       a.Val.Neg(&a.Val)
+       // avoid -0
+       if a.Val.Sign() != 0 {
+               a.Val.Neg(&a.Val)
+       }
 }
 
 //
@@ -163,15 +170,20 @@ func mpatoflt(a *Mpflt, as string) {
                // - decimal point and binary point in constant
                // TODO(gri) use different conversion function or check separately
                Yyerror("malformed constant: %s", as)
-               a.Val.SetUint64(0)
+               a.Val.SetFloat64(0)
                return
        }
 
        if f.IsInf() {
                Yyerror("constant too large: %s", as)
-               a.Val.SetUint64(0)
+               a.Val.SetFloat64(0)
                return
        }
+
+       // -0 becomes 0
+       if f.Sign() == 0 && f.Signbit() {
+               a.Val.SetFloat64(0)
+       }
 }
 
 func (f *Mpflt) String() string {
@@ -188,7 +200,7 @@ func Fconv(fvp *Mpflt, flag int) string {
        // determine sign
        f := &fvp.Val
        var sign string
-       if fvp.Val.Signbit() {
+       if f.Sign() < 0 {
                sign = "-"
                f = new(big.Float).Abs(f)
        } else if flag&obj.FmtSign != 0 {
diff --git a/test/fixedbugs/issue12577.go b/test/fixedbugs/issue12577.go
new file mode 100644 (file)
index 0000000..249b4f2
--- /dev/null
@@ -0,0 +1,66 @@
+// run
+
+// Copyright 2015 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 12577: Test that there are no -0 floating-point constants.
+
+package main
+
+import "math"
+
+const (
+       z0 = 0.0
+       z1 = -0.0
+       z2 = -z0
+       z3 = -z2
+)
+
+var (
+       x0 float32 = z0
+       x1 float32 = z1
+       x2 float32 = z2
+       x3 float32 = z3
+
+       y0 float64 = z0
+       y1 float64 = z1
+       y2 float64 = z2
+       y3 float64 = z3
+)
+
+func test32(f float32) {
+       if f != 0 || math.Signbit(float64(f)) {
+               println("BUG: got", f, "want 0.0")
+               return
+       }
+}
+
+func test64(f float64) {
+       if f != 0 || math.Signbit(f) {
+               println("BUG: got", f, "want 0.0")
+               return
+       }
+}
+
+func main() {
+       if f := -x0; f != 0 || !math.Signbit(float64(f)) {
+               println("BUG: got", f, "want -0.0")
+       }
+
+       test32(-0.0)
+       test32(x0)
+       test32(x1)
+       test32(x2)
+       test32(x3)
+
+       if f := -y0; f != 0 || !math.Signbit(f) {
+               println("BUG: got", f, "want -0.0")
+       }
+
+       test64(-0.0)
+       test64(y0)
+       test64(y1)
+       test64(y2)
+       test64(y3)
+}