From 76285213b8a453ed0825d98e9a6bb3e044d20022 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 20 Oct 2015 14:45:36 -0700 Subject: [PATCH] cmd/compile/internal/gc: there are no -0 floating-point constants Fixes #12577. Change-Id: Id469cd92f5f9436b0ef948ee1a252ed1842bc7aa Reviewed-on: https://go-review.googlesource.com/16133 Run-TryBot: Robert Griesemer TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/compile/internal/gc/mparith3.go | 24 ++++++--- test/fixedbugs/issue12577.go | 66 +++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 test/fixedbugs/issue12577.go diff --git a/src/cmd/compile/internal/gc/mparith3.go b/src/cmd/compile/internal/gc/mparith3.go index f91a64b42d..4aa283fe33 100644 --- a/src/cmd/compile/internal/gc/mparith3.go +++ b/src/cmd/compile/internal/gc/mparith3.go @@ -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 index 0000000000..249b4f2432 --- /dev/null +++ b/test/fixedbugs/issue12577.go @@ -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) +} -- 2.48.1