Skip to content

Commit 72a7300

Browse files
committed
Use zend_ast_apply in zend_eval_const_expr
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 bd03c03 commit 72a7300

File tree

1 file changed

+25
-46
lines changed

1 file changed

+25
-46
lines changed

Zend/zend_compile.c

Lines changed: 25 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,26 @@ 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+
*/
10583+
if (ast->kind != ZEND_AST_CLASS_NAME && ast->kind != ZEND_AST_COALESCE && ast->kind != ZEND_AST_CONDITIONAL) {
10584+
zend_ast_apply(ast, zend_eval_const_expr_inner, ctx);
10585+
}
10586+
1056910587
switch (ast->kind) {
1057010588
case ZEND_AST_BINARY_OP:
10571-
zend_eval_const_expr(&ast->child[0]);
10572-
zend_eval_const_expr(&ast->child[1]);
1057310589
if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
1057410590
return;
1057510591
}
@@ -10582,8 +10598,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1058210598
break;
1058310599
case ZEND_AST_GREATER:
1058410600
case ZEND_AST_GREATER_EQUAL:
10585-
zend_eval_const_expr(&ast->child[0]);
10586-
zend_eval_const_expr(&ast->child[1]);
1058710601
if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
1058810602
return;
1058910603
}
@@ -10595,8 +10609,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1059510609
case ZEND_AST_OR:
1059610610
{
1059710611
bool child0_is_true, child1_is_true;
10598-
zend_eval_const_expr(&ast->child[0]);
10599-
zend_eval_const_expr(&ast->child[1]);
1060010612
if (ast->child[0]->kind != ZEND_AST_ZVAL) {
1060110613
return;
1060210614
}
@@ -10620,7 +10632,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1062010632
break;
1062110633
}
1062210634
case ZEND_AST_UNARY_OP:
10623-
zend_eval_const_expr(&ast->child[0]);
1062410635
if (ast->child[0]->kind != ZEND_AST_ZVAL) {
1062510636
return;
1062610637
}
@@ -10631,7 +10642,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1063110642
break;
1063210643
case ZEND_AST_UNARY_PLUS:
1063310644
case ZEND_AST_UNARY_MINUS:
10634-
zend_eval_const_expr(&ast->child[0]);
1063510645
if (ast->child[0]->kind != ZEND_AST_ZVAL) {
1063610646
return;
1063710647
}
@@ -10702,13 +10712,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1070210712
zend_error(E_COMPILE_ERROR, "Array and string offset access syntax with curly braces is no longer supported");
1070310713
}
1070410714

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]);
1071210715
if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
1071310716
return;
1071410717
}
@@ -10786,9 +10789,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1078610789
zend_ast *name_ast;
1078710790
zend_string *resolved_name;
1078810791

10789-
zend_eval_const_expr(&ast->child[0]);
10790-
zend_eval_const_expr(&ast->child[1]);
10791-
1079210792
if (UNEXPECTED(ast->child[1]->kind != ZEND_AST_ZVAL
1079310793
|| Z_TYPE_P(zend_ast_get_zval(ast->child[1])) != IS_STRING)) {
1079410794
return;
@@ -10818,33 +10818,6 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1081810818
}
1081910819
break;
1082010820
}
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;
1084810821
default:
1084910822
return;
1085010823
}
@@ -10853,3 +10826,9 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
1085310826
*ast_ptr = zend_ast_create_zval(&result);
1085410827
}
1085510828
/* }}} */
10829+
10830+
10831+
static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
10832+
{
10833+
zend_eval_const_expr_inner(ast_ptr, NULL);
10834+
}

0 commit comments

Comments
 (0)