]> granicus.if.org Git - php/commitdiff
Fix bug #70804
authorAndrea Faulds <ajf@ajf.me>
Sat, 19 Dec 2015 02:25:44 +0000 (02:25 +0000)
committerAndrea Faulds <ajf@ajf.me>
Sat, 19 Dec 2015 02:25:44 +0000 (02:25 +0000)
This follows on from a4648ded430985e019b446939c4ff5bef36c0b91 and
4e01269082d20f5598c481f122b3eea10a586e2b.
Both -(+0.0) and +(-0.0) behaved incorrectly for the same reason.

NEWS
Zend/tests/bug70804.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/NEWS b/NEWS
index baca4f29e3d6cf53a3602300f731eecb82c95ccc..0d744835d7fdde5dce9b44b1aeb8471ea9032a11 100644 (file)
--- 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 (file)
index 0000000..d7fd18d
--- /dev/null
@@ -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)
index eb4db6add16cabbc582977c639270889910823ac..f65f2ed7b18911284ebe5e62a722244373236e2b 100644 (file)
@@ -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);
 }
 /* }}} */