aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jsifier.js3
-rw-r--r--src/parseTools.js7
-rw-r--r--tests/core/test_literal_negative_zero.in27
-rw-r--r--tests/core/test_literal_negative_zero.out6
-rw-r--r--tests/test_core.py8
5 files changed, 50 insertions, 1 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index a503e90d..726a5eda 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -215,6 +215,9 @@ function JSify(data, functionsOnly) {
function parseConst(value, type, ident) {
var constant = makeConst(value, type);
+ // Sadly, we've thrown away type information in makeConst, so we're not
+ // passing correct type info to parseNumerical which works around this
+ // lack.
constant = flatten(constant).map(function(x) { return parseNumerical(x) })
return constant;
}
diff --git a/src/parseTools.js b/src/parseTools.js
index 4d6d7bd3..b7f97a40 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -962,8 +962,13 @@ function parseNumerical(value, type) {
}
if (isNumber(value)) {
var ret = parseFloat(value); // will change e.g. 5.000000e+01 to 50
+ // type may be undefined here, like when this is called from makeConst with a single argument.
+ // but if it is a number, then we can safely assume that this should handle negative zeros
+ // correctly.
+ if (type === undefined || type === 'double' || type === 'float') {
+ if (value[0] === '-' && ret === 0) { return '-.0'; } // fix negative 0, toString makes it 0
+ }
if (type === 'double' || type === 'float') {
- if (value[0] === '-' && ret === 0) return '-.0'; // fix negative 0, toString makes it 0
if (!RUNNING_JS_OPTS) ret = asmEnsureFloat(ret, type);
}
return ret.toString();
diff --git a/tests/core/test_literal_negative_zero.in b/tests/core/test_literal_negative_zero.in
new file mode 100644
index 00000000..1554fbf5
--- /dev/null
+++ b/tests/core/test_literal_negative_zero.in
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <math.h>
+
+static float XXXf = -0.0f;
+static double XXXd = -0.0;
+
+struct x {
+ float f;
+ double d;
+};
+
+static struct x xx[] = {
+ -0x0p+0,
+ -0x0p+0,
+};
+
+int main(int argc, char ** argv) {
+ float YYYf = -0.0f;
+ float YYYd = -0.0;
+
+ printf("%.2f\n", XXXf);
+ printf("%.2f\n", XXXd);
+ printf("%.2f\n", YYYf);
+ printf("%.2f\n", YYYd);
+ printf("%.2f\n", xx->f);
+ printf("%.2f\n", xx->d);
+}
diff --git a/tests/core/test_literal_negative_zero.out b/tests/core/test_literal_negative_zero.out
new file mode 100644
index 00000000..d1b863b8
--- /dev/null
+++ b/tests/core/test_literal_negative_zero.out
@@ -0,0 +1,6 @@
+-0.00
+-0.00
+-0.00
+-0.00
+-0.00
+-0.00
diff --git a/tests/test_core.py b/tests/test_core.py
index 799e47f0..7fe48977 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -477,6 +477,14 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run_from_file(src, output)
+ def test_literal_negative_zero(self):
+ if self.emcc_args == None: return self.skip('needs emcc')
+
+ test_path = path_from_root('tests', 'core', 'test_literal_negative_zero')
+ src, output = (test_path + s for s in ('.in', '.out'))
+
+ self.do_run_from_file(src, output)
+
def test_llvm_intrinsics(self):
if self.emcc_args == None: return self.skip('needs ta2')