summaryrefslogtreecommitdiff
path: root/Zend/zend_compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r--Zend/zend_compile.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 70359123c4..ac10a2ad74 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5538,12 +5538,30 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
zend_compile_expr(&right_node, right_ast);
if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) {
- result->op_type = IS_CONST;
- zend_ct_eval_binary_op(&result->u.constant, opcode,
- &left_node.u.constant, &right_node.u.constant);
- zval_ptr_dtor(&left_node.u.constant);
- zval_ptr_dtor(&right_node.u.constant);
- return;
+ do {
+ /* don't evaluate divsion by zero at compile-time */
+ if (opcode == ZEND_DIV) {
+ zval *op2 = &right_node.u.constant;
+
+ convert_scalar_to_number(op2);
+ if (Z_TYPE_P(op2) == IS_LONG) {
+ if (Z_LVAL_P(op2) == 0) {
+ break;
+ }
+ } else if (Z_TYPE_P(op2) == IS_DOUBLE) {
+ if (Z_DVAL_P(op2) == 0.0) {
+ break;
+ }
+ }
+ }
+
+ result->op_type = IS_CONST;
+ zend_ct_eval_binary_op(&result->u.constant, opcode,
+ &left_node.u.constant, &right_node.u.constant);
+ zval_ptr_dtor(&left_node.u.constant);
+ zval_ptr_dtor(&right_node.u.constant);
+ return;
+ } while (0);
}
do {
@@ -6937,6 +6955,22 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
return;
}
+ /* don't evaluate divsion by zero at compile-time */
+ if (ast->attr == ZEND_DIV) {
+ zval *op2 = zend_ast_get_zval(ast->child[1]);
+
+ convert_scalar_to_number(op2);
+ if (Z_TYPE_P(op2) == IS_LONG) {
+ if (Z_LVAL_P(op2) == 0) {
+ return;
+ }
+ } else if (Z_TYPE_P(op2) == IS_DOUBLE) {
+ if (Z_DVAL_P(op2) == 0.0) {
+ return;
+ }
+ }
+ }
+
zend_ct_eval_binary_op(&result, ast->attr,
zend_ast_get_zval(ast->child[0]), zend_ast_get_zval(ast->child[1]));
break;