diff options
author | Andrea Faulds <ajf@ajf.me> | 2015-12-17 22:36:14 +0000 |
---|---|---|
committer | Andrea Faulds <ajf@ajf.me> | 2015-12-17 22:39:29 +0000 |
commit | a4648ded430985e019b446939c4ff5bef36c0b91 (patch) | |
tree | 13dfc9c71de3557a351dea7918b4e63f686c2491 | |
parent | a917840f38a4743020e0d8a16fcaf23826a87500 (diff) | |
download | php-git-a4648ded430985e019b446939c4ff5bef36c0b91.tar.gz |
Fix bug #52355
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | Zend/tests/bug52355.phpt | 20 | ||||
-rw-r--r-- | Zend/zend_compile.c | 36 | ||||
-rw-r--r-- | ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt | bin | 4553 -> 4554 bytes | |||
-rw-r--r-- | ext/standard/tests/general_functions/print_r_64bit.phpt | 12 | ||||
-rw-r--r-- | ext/standard/tests/general_functions/var_dump_64bit.phpt | 6 |
6 files changed, 56 insertions, 19 deletions
@@ -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 Binary files differindex 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 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]=> |