mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Merge remote-tracking branch 'origin/PHP-7.0'
This commit is contained in:
commit
36202ef056
45
Zend/tests/constant_expressions_coalesce.phpt
Normal file
45
Zend/tests/constant_expressions_coalesce.phpt
Normal file
@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
Constant expressions with null coalescing operator ??
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
const A = [1 => [[]]];
|
||||
|
||||
const T_1 = null ?? A[1]['undefined']['index'] ?? 1;
|
||||
const T_2 = null ?? A['undefined']['index'] ?? 2;
|
||||
const T_3 = null ?? A[1][0][2] ?? 3;
|
||||
const T_4 = A[1][0][2] ?? 4;
|
||||
|
||||
var_dump(T_1);
|
||||
var_dump(T_2);
|
||||
var_dump(T_3);
|
||||
var_dump(T_4);
|
||||
|
||||
var_dump((function(){ static $var = null ?? A[1]['undefined']['index'] ?? 1; return $var; })());
|
||||
var_dump((function(){ static $var = null ?? A['undefined']['index'] ?? 2; return $var; })());
|
||||
var_dump((function(){ static $var = null ?? A[1][0][2] ?? 3; return $var; })());
|
||||
var_dump((function(){ static $var = A[1][0][2] ?? 4; return $var; })());
|
||||
|
||||
var_dump((new class { public $var = null ?? A[1]['undefined']['index'] ?? 1; })->var);
|
||||
var_dump((new class { public $var = null ?? A['undefined']['index'] ?? 2; })->var);
|
||||
var_dump((new class { public $var = null ?? A[1][0][2] ?? 3; })->var);
|
||||
var_dump((new class { public $var = A[1][0][2] ?? 4; })->var);
|
||||
|
||||
const D = [][] ?? 1;
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(4)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(4)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(4)
|
||||
|
||||
Fatal error: Cannot use [] for reading in %s.php on line 25
|
@ -337,6 +337,30 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc
|
||||
zval_dtor(&op1);
|
||||
}
|
||||
break;
|
||||
case ZEND_AST_COALESCE:
|
||||
if (ast->child[0]->kind == ZEND_AST_DIM) {
|
||||
ast->child[0]->attr = ZEND_DIM_IS;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
if (Z_TYPE(op1) > IS_NULL) {
|
||||
*result = op1;
|
||||
} else {
|
||||
if (ast->child[1]->kind == ZEND_AST_DIM) {
|
||||
ast->child[1]->attr = ZEND_DIM_IS;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) {
|
||||
zval_dtor(&op1);
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
zval_dtor(&op1);
|
||||
}
|
||||
break;
|
||||
case ZEND_AST_UNARY_PLUS:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
@ -385,6 +409,14 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc
|
||||
}
|
||||
break;
|
||||
case ZEND_AST_DIM:
|
||||
if (ast->child[1] == NULL) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
|
||||
if (ast->attr == ZEND_DIM_IS && ast->child[0]->kind == ZEND_AST_DIM) {
|
||||
ast->child[0]->attr = ZEND_DIM_IS;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
} else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
|
||||
@ -393,7 +425,12 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc
|
||||
} else {
|
||||
zval tmp;
|
||||
|
||||
zend_fetch_dimension_by_zval(&tmp, &op1, &op2);
|
||||
if (ast->attr == ZEND_DIM_IS) {
|
||||
zend_fetch_dimension_by_zval_is(&tmp, &op1, &op2, IS_CONST);
|
||||
} else {
|
||||
zend_fetch_dimension_by_zval(&tmp, &op1, &op2);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(Z_ISREF(tmp))) {
|
||||
ZVAL_DUP(result, Z_REFVAL(tmp));
|
||||
} else {
|
||||
|
@ -7314,7 +7314,7 @@ zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */
|
||||
|| kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM
|
||||
|| kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
|
||||
|| kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
|
||||
|| kind == ZEND_AST_MAGIC_CONST;
|
||||
|| kind == ZEND_AST_MAGIC_CONST || kind == ZEND_AST_COALESCE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -896,6 +896,8 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
|
||||
#define ZEND_SEND_BY_REF 1
|
||||
#define ZEND_SEND_PREFER_REF 2
|
||||
|
||||
#define ZEND_DIM_IS 1
|
||||
|
||||
static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, uint32_t arg_num, uint32_t mask)
|
||||
{
|
||||
arg_num--;
|
||||
|
@ -1938,6 +1938,12 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *
|
||||
zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR);
|
||||
}
|
||||
|
||||
ZEND_API void zend_fetch_dimension_by_zval_is(zval *result, zval *container, zval *dim, int dim_type)
|
||||
{
|
||||
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1);
|
||||
}
|
||||
|
||||
|
||||
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type)
|
||||
{
|
||||
if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
|
||||
|
@ -294,6 +294,7 @@ ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, con
|
||||
void zend_verify_abstract_class(zend_class_entry *ce);
|
||||
|
||||
ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim);
|
||||
ZEND_API void zend_fetch_dimension_by_zval_is(zval *result, zval *container, zval *dim, int dim_type);
|
||||
|
||||
ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user