Skip to content

Commit 1c733c8

Browse files
authored
Use zend_ast_apply in zend_eval_const_expr (#11261)
Supporting new constant expressions requires remembering to add them to zend_eval_const_expr, even if it only evalutes its children. This is routinely forgotten, at least by me. Use zend_ast_apply to solve this generically.
1 parent a59c933 commit 1c733c8

File tree

1 file changed

+24
-46
lines changed

1 file changed

+24
-46
lines changed

Zend/zend_compile.c

Lines changed: 24 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10557,7 +10557,7 @@ static zend_op *zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t
1055710557
}
1055810558
/* }}} */
1055910559

10560-
static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
10560+
static void zend_eval_const_expr_inner(zend_ast **ast_ptr, void *ctx) /* {{{ */
1056110561
{
1056210562
zend_ast *ast = *ast_ptr;
1056310563
zval result;
@@ -10566,10 +10566,25 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1056610566
return;
1056710567
}
1056810568

10569+
/* Set isset fetch indicator here, opcache disallows runtime altering of the AST */
10570+
if (ast->kind == ZEND_AST_DIM
10571+
&& (ast->attr & ZEND_DIM_IS)
10572+
&& ast->child[0]->kind == ZEND_AST_DIM) {
10573+
ast->child[0]->attr |= ZEND_DIM_IS;
10574+
}
10575+
10576+
/* We don't want to evaluate the class name of ZEND_AST_CLASS_NAME nodes. We need to be able to
10577+
* differenciate between literal class names and expressions that evaluate to strings. Strings
10578+
* are not actually allowed in ::class expressions.
10579+
*
10580+
* ZEND_AST_COALESCE and ZEND_AST_CONDITIONAL will manually evaluate only the children for the
10581+
* taken paths. */
10582+
if (ast->kind != ZEND_AST_CLASS_NAME && ast->kind != ZEND_AST_COALESCE && ast->kind != ZEND_AST_CONDITIONAL) {
10583+
zend_ast_apply(ast, zend_eval_const_expr_inner, ctx);
10584+
}
10585+
1056910586
switch (ast->kind) {
1057010587
case ZEND_AST_BINARY_OP:
10571-
zend_eval_const_expr(&ast->child[0]);
10572-
zend_eval_const_expr(&ast->child[1]);
1057310588
if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
1057410589
return;
1057510590
}
@@ -10582,8 +10597,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1058210597
break;
1058310598
case ZEND_AST_GREATER:
1058410599
case ZEND_AST_GREATER_EQUAL:
10585-
zend_eval_const_expr(&ast->child[0]);
10586-
zend_eval_const_expr(&ast->child[1]);
1058710600
if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
1058810601
return;
1058910602
}
@@ -10595,8 +10608,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1059510608
case ZEND_AST_OR:
1059610609
{
1059710610
bool child0_is_true, child1_is_true;
10598-
zend_eval_const_expr(&ast->child[0]);
10599-
zend_eval_const_expr(&ast->child[1]);
1060010611
if (ast->child[0]->kind != ZEND_AST_ZVAL) {
1060110612
return;
1060210613
}
@@ -10620,7 +10631,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1062010631
break;
1062110632
}
1062210633
case ZEND_AST_UNARY_OP:
10623-
zend_eval_const_expr(&ast->child[0]);
1062410634
if (ast->child[0]->kind != ZEND_AST_ZVAL) {
1062510635
return;
1062610636
}
@@ -10631,7 +10641,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1063110641
break;
1063210642
case ZEND_AST_UNARY_PLUS:
1063310643
case ZEND_AST_UNARY_MINUS:
10634-
zend_eval_const_expr(&ast->child[0]);
1063510644
if (ast->child[0]->kind != ZEND_AST_ZVAL) {
1063610645
return;
1063710646
}
@@ -10702,13 +10711,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1070210711
zend_error(E_COMPILE_ERROR, "Array and string offset access syntax with curly braces is no longer supported");
1070310712
}
1070410713

10705-
/* Set isset fetch indicator here, opcache disallows runtime altering of the AST */
10706-
if ((ast->attr & ZEND_DIM_IS) && ast->child[0]->kind == ZEND_AST_DIM) {
10707-
ast->child[0]->attr |= ZEND_DIM_IS;
10708-
}
10709-
10710-
zend_eval_const_expr(&ast->child[0]);
10711-
zend_eval_const_expr(&ast->child[1]);
1071210714
if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
1071310715
return;
1071410716
}
@@ -10786,9 +10788,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1078610788
zend_ast *name_ast;
1078710789
zend_string *resolved_name;
1078810790

10789-
zend_eval_const_expr(&ast->child[0]);
10790-
zend_eval_const_expr(&ast->child[1]);
10791-
1079210791
if (UNEXPECTED(ast->child[1]->kind != ZEND_AST_ZVAL
1079310792
|| Z_TYPE_P(zend_ast_get_zval(ast->child[1])) != IS_STRING)) {
1079410793
return;
@@ -10818,33 +10817,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1081810817
}
1081910818
break;
1082010819
}
10821-
// TODO: We should probably use zend_ast_apply to recursively walk nodes without
10822-
// special handling. It is required that all nodes that are part of a const expr
10823-
// are visited. Probably we should be distinguishing evaluation of const expr and
10824-
// normal exprs here.
10825-
case ZEND_AST_ARG_LIST:
10826-
{
10827-
zend_ast_list *list = zend_ast_get_list(ast);
10828-
for (uint32_t i = 0; i < list->children; i++) {
10829-
zend_eval_const_expr(&list->child[i]);
10830-
}
10831-
return;
10832-
}
10833-
case ZEND_AST_NEW:
10834-
zend_eval_const_expr(&ast->child[0]);
10835-
zend_eval_const_expr(&ast->child[1]);
10836-
return;
10837-
case ZEND_AST_NAMED_ARG:
10838-
zend_eval_const_expr(&ast->child[1]);
10839-
return;
10840-
case ZEND_AST_CONST_ENUM_INIT:
10841-
zend_eval_const_expr(&ast->child[2]);
10842-
return;
10843-
case ZEND_AST_PROP:
10844-
case ZEND_AST_NULLSAFE_PROP:
10845-
zend_eval_const_expr(&ast->child[0]);
10846-
zend_eval_const_expr(&ast->child[1]);
10847-
return;
1084810820
default:
1084910821
return;
1085010822
}
@@ -10853,3 +10825,9 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1085310825
*ast_ptr = zend_ast_create_zval(&result);
1085410826
}
1085510827
/* }}} */
10828+
10829+
10830+
static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
10831+
{
10832+
zend_eval_const_expr_inner(ast_ptr, NULL);
10833+
}

0 commit comments

Comments
 (0)