summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Faulds <ajf@ajf.me>2015-12-19 02:25:44 +0000
committerAndrea Faulds <ajf@ajf.me>2015-12-19 02:25:44 +0000
commit42c8f5e91d4e4ec00d91506e986e3578a3695ee9 (patch)
tree3463787da20e41f05df69162813425c9c4edc847
parent8d217db369d83de22db6c2e6ad9a440d6c59518f (diff)
downloadphp-git-42c8f5e91d4e4ec00d91506e986e3578a3695ee9.tar.gz
Fix bug #70804
This follows on from a4648ded430985e019b446939c4ff5bef36c0b91 and 4e01269082d20f5598c481f122b3eea10a586e2b. Both -(+0.0) and +(-0.0) behaved incorrectly for the same reason.
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug70804.phpt17
-rw-r--r--Zend/zend_compile.c32
3 files changed, 25 insertions, 26 deletions
diff --git a/NEWS b/NEWS
index baca4f29e3..0d744835d7 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@ PHP NEWS
(Nikita)
. Fixed bug #52355 (Negating zero does not produce negative zero). (Andrea)
. Fixed bug #66179 (var_export() exports float as integer). (Andrea)
+ . Fixed bug #70804 (Unary add on negative zero produces positive zero).
+ (Andrea)
. CURL:
. Fixed bug #71144 (Sementation fault when using cURL with ZTS).
diff --git a/Zend/tests/bug70804.phpt b/Zend/tests/bug70804.phpt
new file mode 100644
index 0000000000..d7fd18d98d
--- /dev/null
+++ b/Zend/tests/bug70804.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #70804 (Unary add on negative zero produces positive zero)
+--FILE--
+<?php
+
+var_dump(+(-0.0));
+var_dump(+(float)"-0");
+
+$foo = +(-sin(0));
+
+var_dump($foo);
+
+?>
+--EXPECT--
+float(-0)
+float(-0)
+float(-0)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index eb4db6add1..f65f2ed7b1 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5807,16 +5807,8 @@ 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) /* {{{ */
{
zval left;
- 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);
- }
+ ZVAL_LONG(&left, (kind == ZEND_AST_UNARY_PLUS) ? 1 : -1);
+ mul_function(result, &left, op);
}
/* }}} */
@@ -6007,6 +5999,7 @@ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */
{
zend_ast *expr_ast = ast->child[0];
znode expr_node;
+ znode lefthand_node;
ZEND_ASSERT(ast->kind == ZEND_AST_UNARY_PLUS || ast->kind == ZEND_AST_UNARY_MINUS);
@@ -6019,22 +6012,9 @@ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */
return;
}
- 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, 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);
- }
+ lefthand_node.op_type = IS_CONST;
+ ZVAL_LONG(&lefthand_node.u.constant, (ast->kind == ZEND_AST_UNARY_PLUS) ? 1 : -1);
+ zend_emit_op_tmp(result, ZEND_MUL, &lefthand_node, &expr_node);
}
/* }}} */