From 52cff70100b5c382339ea3ba9c262f7831d2a965 Mon Sep 17 00:00:00 2001 From: Cholerae Hu Date: Fri, 26 Jul 2019 13:22:08 +0800 Subject: [PATCH] cmd/compile: truncate constant arithmetic result with typed complex numbers Fixes #33285 Change-Id: Idd125e3342058051216be3f105330aef987320c3 Reviewed-on: https://go-review.googlesource.com/c/go/+/187697 Run-TryBot: Matthew Dempsky TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/const.go | 12 ++++++--- test/const.go | 39 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index 504f8f0ec3..6d39417ba5 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -1042,9 +1042,15 @@ func setconst(n *Node, v Val) { overflow(v, n.Type) lineno = lno - // Truncate precision for non-ideal float. - if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL { - n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) + if !n.Type.IsUntyped() { + switch v.Ctype() { + // Truncate precision for non-ideal float. + case CTFLT: + n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) + // Truncate precision for non-ideal complex. + case CTCPLX: + n.SetVal(Val{trunccmplxlit(v.U.(*Mpcplx), n.Type)}) + } } } diff --git a/test/const.go b/test/const.go index f8e0a753cb..3f4956497e 100644 --- a/test/const.go +++ b/test/const.go @@ -157,10 +157,49 @@ func interfaces() { "for interface{}==int comipiler == runtime") } +// Test that typed floating-point and complex arithmetic +// is computed with correct precision. +func truncate() { + const ( + x30 = 1 << 30 + x60 = 1 << 60 + + staticF32 = float32(x30) + 1 - x30 + staticF64 = float64(x60) + 1 - x60 + staticC64 = complex64(x30) + 1 - x30 + staticC128 = complex128(x60) + 1 - x60 + ) + dynamicF32 := float32(x30) + dynamicF32 += 1 + dynamicF32 -= x30 + + dynamicF64 := float64(x60) + dynamicF64 += 1 + dynamicF64 -= x60 + + dynamicC64 := complex64(x30) + dynamicC64 += 1 + dynamicC64 -= x30 + + dynamicC128 := complex128(x60) + dynamicC128 += 1 + dynamicC128 -= x60 + + assert(staticF32 == 0, "staticF32 == 0") + assert(staticF64 == 0, "staticF64 == 0") + assert(dynamicF32 == 0, "dynamicF32 == 0") + assert(dynamicF64 == 0, "dynamicF64 == 0") + assert(staticC64 == 0, "staticC64 == 0") + assert(staticC128 == 0, "staticC128 == 0") + assert(dynamicC64 == 0, "dynamicC64 == 0") + assert(dynamicC128 == 0, "dynamicC128 == 0") +} + func main() { ints() floats() interfaces() + truncate() assert(ctrue == true, "ctrue == true") assert(cfalse == false, "cfalse == false") -- 2.48.1