]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: truncate constant arithmetic result with typed complex numbers
authorCholerae Hu <choleraehyq@gmail.com>
Fri, 26 Jul 2019 05:22:08 +0000 (13:22 +0800)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 28 Aug 2019 19:45:44 +0000 (19:45 +0000)
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>
src/cmd/compile/internal/gc/const.go
test/const.go

index 504f8f0ec3cc56b4427503dae1d5e514a4de4a28..6d39417ba5ab326a5056796a5227d70974643602 100644 (file)
@@ -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)})
+               }
        }
 }
 
index f8e0a753cbcb4db7d0e9626cab2fc80f4a5b8875..3f4956497ebd332df4385ce0db22687bc5e44672 100644 (file)
@@ -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")