summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Faulds <ajf@ajf.me>2015-12-17 22:36:14 +0000
committerAndrea Faulds <ajf@ajf.me>2015-12-17 22:39:29 +0000
commita4648ded430985e019b446939c4ff5bef36c0b91 (patch)
tree13dfc9c71de3557a351dea7918b4e63f686c2491
parenta917840f38a4743020e0d8a16fcaf23826a87500 (diff)
downloadphp-git-a4648ded430985e019b446939c4ff5bef36c0b91.tar.gz
Fix bug #52355
-rw-r--r--NEWS1
-rw-r--r--Zend/tests/bug52355.phpt20
-rw-r--r--Zend/zend_compile.c36
-rw-r--r--ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phptbin4553 -> 4554 bytes
-rw-r--r--ext/standard/tests/general_functions/print_r_64bit.phpt12
-rw-r--r--ext/standard/tests/general_functions/var_dump_64bit.phpt6
6 files changed, 56 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index 4a1f7f6859..a82de3b927 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,7 @@ PHP NEWS
highlight_string() function). (Nikita)
. Fixed bug #71154 (Incorrect HT iterator invalidation causes iterator reuse).
(Nikita)
+ . Fixed bug #52355 (Negating zero does not produce negative zero). (Andrea)
- DBA:
. Fixed key leak with invalid resource. (Laruence)
diff --git a/Zend/tests/bug52355.phpt b/Zend/tests/bug52355.phpt
new file mode 100644
index 0000000000..7f46c71d46
--- /dev/null
+++ b/Zend/tests/bug52355.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #52355 (Negating zero does not produce negative zero)
+--FILE--
+<?php
+
+var_dump(-0.0);
+var_dump(-(float)"0");
+
+$foo = -sin(0);
+
+var_dump($foo);
+
+var_dump(@(1.0 / -0.0));
+
+?>
+--EXPECT--
+float(-0)
+float(-0)
+float(-0)
+float(-INF)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 1609ba5127..eb4db6add1 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5806,12 +5806,17 @@ static inline void zend_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op
static inline void zend_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */
{
- binary_op_type fn = kind == ZEND_AST_UNARY_PLUS
- ? add_function : sub_function;
-
zval left;
- ZVAL_LONG(&left, 0);
- fn(result, &left, op);
+ if (kind == ZEND_AST_UNARY_PLUS) {
+ ZVAL_LONG(&left, 0);
+ add_function(result, &left, op);
+ } else {
+ /* We use `(-1) * $a` instead of `0 - $a`, because the latter handles
+ * negative zero wrong.
+ */
+ ZVAL_LONG(&left, -1);
+ mul_function(result, &left, op);
+ }
}
/* }}} */
@@ -6001,7 +6006,7 @@ void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */
void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */
{
zend_ast *expr_ast = ast->child[0];
- znode zero_node, expr_node;
+ znode expr_node;
ZEND_ASSERT(ast->kind == ZEND_AST_UNARY_PLUS || ast->kind == ZEND_AST_UNARY_MINUS);
@@ -6014,11 +6019,22 @@ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */
return;
}
- zero_node.op_type = IS_CONST;
- ZVAL_LONG(&zero_node.u.constant, 0);
+ if (ast->kind == ZEND_AST_UNARY_PLUS) {
+ znode zero_node;
+ zero_node.op_type = IS_CONST;
+ ZVAL_LONG(&zero_node.u.constant, 0);
- zend_emit_op_tmp(result, ast->kind == ZEND_AST_UNARY_PLUS ? ZEND_ADD : ZEND_SUB,
- &zero_node, &expr_node);
+ zend_emit_op_tmp(result, ZEND_ADD, &zero_node, &expr_node);
+ } else {
+ /* We use `(-1) * $a` instead of `0 - $a`, because the latter handles
+ * negative zero wrong.
+ */
+ znode neg_one_node;
+ neg_one_node.op_type = IS_CONST;
+ ZVAL_LONG(&neg_one_node.u.constant, -1);
+
+ zend_emit_op_tmp(result, ZEND_MUL, &neg_one_node, &expr_node);
+ }
}
/* }}} */
diff --git a/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt b/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt
index ee3c31b6e6..4fe2f4c95b 100644
--- a/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt
+++ b/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt
Binary files differ
diff --git a/ext/standard/tests/general_functions/print_r_64bit.phpt b/ext/standard/tests/general_functions/print_r_64bit.phpt
index d62b3f9790..40f44ea1e4 100644
--- a/ext/standard/tests/general_functions/print_r_64bit.phpt
+++ b/ext/standard/tests/general_functions/print_r_64bit.phpt
@@ -443,9 +443,9 @@ Array
*** Testing print_r() on float variables ***
-- Iteration 1 --
-0
-0
-0
+-0
+-0
+-0
-- Iteration 2 --
0
0
@@ -1606,7 +1606,7 @@ Array
-- Iteration 4 --
Array
(
- [0] => 0
+ [0] => -0
[1] => Where am I?
[2] => Array
(
@@ -1622,7 +1622,7 @@ Array
Array
(
- [0] => 0
+ [0] => -0
[1] => Where am I?
[2] => Array
(
@@ -1638,7 +1638,7 @@ Array
Array
(
- [0] => 0
+ [0] => -0
[1] => Where am I?
[2] => Array
(
diff --git a/ext/standard/tests/general_functions/var_dump_64bit.phpt b/ext/standard/tests/general_functions/var_dump_64bit.phpt
index 3672357936..4545e98372 100644
--- a/ext/standard/tests/general_functions/var_dump_64bit.phpt
+++ b/ext/standard/tests/general_functions/var_dump_64bit.phpt
@@ -368,7 +368,7 @@ int(-2147483648)
*** Testing var_dump() on float variables ***
-- Iteration 1 --
-float(0)
+float(-0)
-- Iteration 2 --
float(0)
-- Iteration 3 --
@@ -893,7 +893,7 @@ array(4) {
-- Iteration 4 --
array(6) {
[0]=>
- float(0)
+ float(-0)
[1]=>
string(11) "Where am I?"
[2]=>
@@ -1519,7 +1519,7 @@ array(6) {
[3]=>
array(6) {
[0]=>
- float(0)
+ float(-0)
[1]=>
string(11) "Where am I?"
[2]=>