diff options
Diffstat (limited to 'Zend/zend_compile.c')
| -rw-r--r-- | Zend/zend_compile.c | 32 | 
1 files changed, 27 insertions, 5 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 18836d6418..20575360c3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6967,14 +6967,16 @@ void zend_const_expr_to_zval(zval *result, zend_ast *ast) /* {{{ */  	zend_compile_const_expr(&ast);  	if (ast->kind == ZEND_AST_ZVAL) {  		ZVAL_COPY_VALUE(result, zend_ast_get_zval(ast)); - -		/* Kill this branch of the original AST, as it was already destroyed. -		 * It would be nice to find a better solution to this problem in the -		 * future. */ -		orig_ast->kind = 0;  	} else {  		ZVAL_NEW_AST(result, zend_ast_copy(ast)); +		/* destroy the ast here, it might have been replaced */ +		zend_ast_destroy(ast);  	} + +	/* Kill this branch of the original AST, as it was already destroyed. +	 * It would be nice to find a better solution to this problem in the +	 * future. */ +	orig_ast->kind = 0;  }  /* }}} */ @@ -7385,6 +7387,26 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */  			zend_ct_eval_unary_pm(&result, ast->kind, zend_ast_get_zval(ast->child[0]));  			break; +		case ZEND_AST_COALESCE: +			zend_eval_const_expr(&ast->child[0]); + +			if (ast->child[0]->kind != ZEND_AST_ZVAL) { +				/* ensure everything was compile-time evaluated at least once */ +				zend_eval_const_expr(&ast->child[1]); +				return; +			} + +			if (Z_TYPE_P(zend_ast_get_zval(ast->child[0])) == IS_NULL) { +				zend_eval_const_expr(&ast->child[1]); +				*ast_ptr = ast->child[1]; +				ast->child[1] = NULL; +				zend_ast_destroy(ast); +			} else { +				*ast_ptr = ast->child[0]; +				ast->child[0] = NULL; +				zend_ast_destroy(ast); +			} +			return;  		case ZEND_AST_CONDITIONAL:  		{  			zend_ast **child, *child_ast;  | 
