summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorGULPF <oscarnihlgard@gmail.com>2018-01-31 16:29:42 +0100
committerAndreas Rumpf <rumpf_a@web.de>2018-01-31 16:29:42 +0100
commit94038545bec1bffa9bf045be8a5e52b79e9f217c (patch)
treee3b9cf0915442772c3405b561e6455b5b36c4957
parentb5538990a2f0260b1ab04df3c73ecf9a7f927ad2 (diff)
downloadNim-94038545bec1bffa9bf045be8a5e52b79e9f217c.tar.gz
Fixes codegen bug with literal negative zero, fixes #7079 (#7158)
* Fixes #7079

* Fix handling of neg zero during constant folding
-rw-r--r--compiler/jsgen.nim16
-rw-r--r--compiler/rodutils.nim16
-rw-r--r--compiler/semfold.nim1
-rw-r--r--tests/ccgbugs/t7079.nim9
4 files changed, 31 insertions, 11 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 6f40e7031..75880a15a 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -2284,11 +2284,17 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
     r.kind = resExpr
   of nkFloatLit..nkFloat64Lit:
     let f = n.floatVal
-    if f != f: r.res = rope"NaN"
-    elif f == 0.0: r.res = rope"0.0"
-    elif f == 0.5 * f:
-      if f > 0.0: r.res = rope"Infinity"
-      else: r.res = rope"-Infinity"
+    case classify(f)
+    of fcNaN:
+      r.res = rope"NaN"
+    of fcNegZero:
+      r.res = rope"-0.0"
+    of fcZero:
+      r.res = rope"0.0"
+    of fcInf:
+      r.res = rope"Infinity"
+    of fcNegInf:
+      r.res = rope"-Infinity"
     else: r.res = rope(f.toStrMaxPrecision)
     r.kind = resExpr
   of nkCallKinds:
diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim
index 0456e9349..0d9c7112f 100644
--- a/compiler/rodutils.nim
+++ b/compiler/rodutils.nim
@@ -8,18 +8,22 @@
 #
 
 ## Serialization utilities for the compiler.
-import strutils
+import strutils, math
 
 proc c_snprintf(s: cstring; n:uint; frmt: cstring): cint {.importc: "snprintf", header: "<stdio.h>", nodecl, varargs.}
 
 proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string =
-  if f != f:
+  case classify(f)
+  of fcNaN:
     result = "NAN"
-  elif f == 0.0:
+  of fcNegZero:
+    result = "-0.0" & literalPostfix
+  of fcZero:
     result = "0.0" & literalPostfix
-  elif f == 0.5 * f:
-    if f > 0.0: result = "INF"
-    else: result = "-INF"
+  of fcInf:
+    result = "INF"
+  of fcNegInf:
+    result = "-INF"
   else:
     when defined(nimNoArrayToCstringConversion):
       result = newString(81)
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 55cdc334c..59c55010f 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -225,6 +225,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
   of mDivF64:
     if getFloat(b) == 0.0:
       if getFloat(a) == 0.0: result = newFloatNodeT(NaN, n)
+      elif getFloat(b).classify == fcNegZero: result = newFloatNodeT(-Inf, n)
       else: result = newFloatNodeT(Inf, n)
     else:
       result = newFloatNodeT(getFloat(a) / getFloat(b), n)
diff --git a/tests/ccgbugs/t7079.nim b/tests/ccgbugs/t7079.nim
new file mode 100644
index 000000000..bfa1b77a6
--- /dev/null
+++ b/tests/ccgbugs/t7079.nim
@@ -0,0 +1,9 @@
+discard """
+  action: run
+  targets: '''c js'''
+"""
+
+import math
+let x = -0.0
+doAssert classify(x) == fcNegZero
+doAssert classify(1 / -0.0) == fcNegInf
\ No newline at end of file