summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCholerae Hu <choleraehyq@gmail.com>2019-07-26 13:22:08 +0800
committerMatthew Dempsky <mdempsky@google.com>2019-08-28 19:45:44 +0000
commit52cff70100b5c382339ea3ba9c262f7831d2a965 (patch)
tree9bef04792567ba65fafc4d334901dee04417b3b1
parent25ebf015f62c7e3ec8d1eaa56ba7c73c510fc040 (diff)
downloadgo-git-52cff70100b5c382339ea3ba9c262f7831d2a965.tar.gz
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 <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
-rw-r--r--src/cmd/compile/internal/gc/const.go12
-rw-r--r--test/const.go39
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")