Skip to content

Commit

Permalink
Add assertions verifying that zend_ast_decl AST nodes are not treated…
Browse files Browse the repository at this point in the history
… as regular zend_ast nodes (#17390)

* zend_compile: Do not traverse children of ZEND_AST_CLOSURE in zend_compile_const_expr()

* Add assertions verifying that zend_ast_decl AST nodes are not treated as regular zend_ast nodes
  • Loading branch information
TimWolla authored Jan 8, 2025
1 parent a091e52 commit fd1eacc
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 2 deletions.
11 changes: 10 additions & 1 deletion Zend/zend_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,9 @@ static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
size += zend_ast_tree_size(list->child[i]);
}
}
} else if (zend_ast_is_decl(ast)) {
/* Not implemented. */
ZEND_UNREACHABLE();
} else {
uint32_t i, children = zend_ast_get_num_children(ast);

Expand Down Expand Up @@ -1141,6 +1144,9 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
ZVAL_COPY(&new->val, &((zend_ast_zval *) ast)->val);
Z_LINENO(new->val) = zend_ast_get_lineno(ast);
buf = (void*)((char*)buf + sizeof(zend_ast_zval));
} else if (zend_ast_is_decl(ast)) {
/* Not implemented. */
ZEND_UNREACHABLE();
} else {
uint32_t i, children = zend_ast_get_num_children(ast);
zend_ast *new = (zend_ast*)buf;
Expand Down Expand Up @@ -1206,7 +1212,7 @@ ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast)
zend_string_release_ex(zend_ast_get_constant_name(ast), 0);
} else if (EXPECTED(ast->kind == ZEND_AST_OP_ARRAY)) {
ZEND_ASSERT(!Z_REFCOUNTED(((zend_ast_zval*)(ast))->val));
} else if (EXPECTED(ast->kind >= ZEND_AST_FUNC_DECL)) {
} else if (EXPECTED(zend_ast_is_decl(ast))) {
zend_ast_decl *decl = (zend_ast_decl *) ast;

if (decl->name) {
Expand Down Expand Up @@ -1237,6 +1243,9 @@ ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn, void *contex
for (i = 0; i < list->children; ++i) {
fn(&list->child[i], context);
}
} else if (zend_ast_is_decl(ast)) {
/* Not implemented. */
ZEND_UNREACHABLE();
} else {
uint32_t i, children = zend_ast_get_num_children(ast);
for (i = 0; i < children; ++i) {
Expand Down
6 changes: 6 additions & 0 deletions Zend/zend_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ static zend_always_inline bool zend_ast_is_special(zend_ast *ast) {
return (ast->kind >> ZEND_AST_SPECIAL_SHIFT) & 1;
}

static zend_always_inline bool zend_ast_is_decl(zend_ast *ast) {
return zend_ast_is_special(ast) && ast->kind >= ZEND_AST_FUNC_DECL;
}

static zend_always_inline bool zend_ast_is_list(zend_ast *ast) {
return (ast->kind >> ZEND_AST_IS_LIST_SHIFT) & 1;
}
Expand All @@ -357,6 +361,8 @@ static zend_always_inline zend_string *zend_ast_get_constant_name(zend_ast *ast)

static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) {
ZEND_ASSERT(!zend_ast_is_list(ast));
ZEND_ASSERT(!zend_ast_is_special(ast));

return ast->kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
}
static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) {
Expand Down
3 changes: 2 additions & 1 deletion Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -11293,7 +11293,8 @@ static void zend_compile_const_expr(zend_ast **ast_ptr, void *context) /* {{{ */
break;
case ZEND_AST_CLOSURE:
zend_compile_const_expr_closure(ast_ptr);
break;
/* Return, because we do not want to traverse the children. */
return;
}

zend_ast_apply(ast, zend_compile_const_expr, context);
Expand Down
6 changes: 6 additions & 0 deletions ext/opcache/zend_file_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,9 @@ static void zend_file_cache_serialize_ast(zend_ast *ast,
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
/* The op_array itself will be serialized as part of the dynamic_func_defs. */
SERIALIZE_PTR(Z_PTR(((zend_ast_zval*)ast)->val));
} else if (zend_ast_is_decl(ast)) {
/* Not implemented. */
ZEND_UNREACHABLE();
} else {
uint32_t children = zend_ast_get_num_children(ast);
for (i = 0; i < children; i++) {
Expand Down Expand Up @@ -1248,6 +1251,9 @@ static void zend_file_cache_unserialize_ast(zend_ast *ast,
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
/* The op_array itself will be unserialized as part of the dynamic_func_defs. */
UNSERIALIZE_PTR(Z_PTR(((zend_ast_zval*)ast)->val));
} else if (zend_ast_is_decl(ast)) {
/* Not implemented. */
ZEND_UNREACHABLE();
} else {
uint32_t children = zend_ast_get_num_children(ast);
for (i = 0; i < children; i++) {
Expand Down
3 changes: 3 additions & 0 deletions ext/opcache/zend_persist.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ static zend_ast *zend_persist_ast(zend_ast *ast)
zend_ast_zval *copy = zend_shared_memdup(ast, sizeof(zend_ast_zval));
zend_persist_op_array(&copy->val);
node = (zend_ast *) copy;
} else if (zend_ast_is_decl(ast)) {
/* Not implemented. */
ZEND_UNREACHABLE();
} else {
uint32_t children = zend_ast_get_num_children(ast);
node = zend_shared_memdup(ast, zend_ast_size(children));
Expand Down
3 changes: 3 additions & 0 deletions ext/opcache/zend_persist_calc.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ static void zend_persist_ast_calc(zend_ast *ast)
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
ADD_SIZE(sizeof(zend_ast_zval));
zend_persist_op_array_calc(&((zend_ast_zval*)(ast))->val);
} else if (zend_ast_is_decl(ast)) {
/* Not implemented. */
ZEND_UNREACHABLE();
} else {
uint32_t children = zend_ast_get_num_children(ast);
ADD_SIZE(zend_ast_size(children));
Expand Down

0 comments on commit fd1eacc

Please sign in to comment.