]> granicus.if.org Git - php/commitdiff
Fix bug #52355
authorAndrea Faulds <ajf@ajf.me>
Thu, 17 Dec 2015 22:36:14 +0000 (22:36 +0000)
committerAndrea Faulds <ajf@ajf.me>
Thu, 17 Dec 2015 22:39:29 +0000 (22:39 +0000)
NEWS
Zend/tests/bug52355.phpt [new file with mode: 0644]
Zend/zend_compile.c
ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt
ext/standard/tests/general_functions/print_r_64bit.phpt
ext/standard/tests/general_functions/var_dump_64bit.phpt

diff --git a/NEWS b/NEWS
index 4a1f7f6859f9e9c08c56f6a19671d5f3b238fb1f..a82de3b92777ef172d9e9d22c27b92e2289cba2f 100644 (file)
--- 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 (file)
index 0000000..7f46c71
--- /dev/null
@@ -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)
index 1609ba5127f4bde9222c37f16986fa4053da1a08..eb4db6add16cabbc582977c639270889910823ac 100644 (file)
@@ -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);
+       }
 }
 /* }}} */
 
index ee3c31b6e6ab2bc75bda0ab41e39c149a03bb4ff..4fe2f4c95b80137ff8a4210c72d56956ab6bf58d 100644 (file)
Binary files a/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt and b/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt differ
index d62b3f9790292720df67755b887c8be0c226f746..40f44ea1e486777c0c4ae16be8d42afcc99a6e7b 100644 (file)
@@ -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
         (
index 3672357936e3e58f202c7c32acbc2501dd456c23..4545e98372be9b0a23bd880d9edae6771970f367 100644 (file)
@@ -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]=>