diff options
author | GULPF <oscarnihlgard@gmail.com> | 2018-01-31 16:29:42 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-01-31 16:29:42 +0100 |
commit | 94038545bec1bffa9bf045be8a5e52b79e9f217c (patch) | |
tree | e3b9cf0915442772c3405b561e6455b5b36c4957 | |
parent | b5538990a2f0260b1ab04df3c73ecf9a7f927ad2 (diff) | |
download | Nim-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.nim | 16 | ||||
-rw-r--r-- | compiler/rodutils.nim | 16 | ||||
-rw-r--r-- | compiler/semfold.nim | 1 | ||||
-rw-r--r-- | tests/ccgbugs/t7079.nim | 9 |
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 |