From a3acba863cf7a7e408576369773c24689b18da3b Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:29:29 +0100 Subject: [PATCH 1/5] Export visibility for promoted property --- Zend/zend_ast.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index d33747412ef0..ddfc798ae6eb 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2558,6 +2558,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio if (ast->child[3]) { zend_ast_export_attributes(str, ast->child[3], indent, 0); } + zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CPP); if (ast->child[0]) { zend_ast_export_type(str, ast->child[0], indent); smart_str_appendc(str, ' '); From 45f47d25eb7f668bfc7473323fd0c5758419f2a1 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:29:51 +0100 Subject: [PATCH 2/5] Extract hook export code --- Zend/zend_ast.c | 89 +++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index ddfc798ae6eb..d2551ddfb4dc 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1744,6 +1744,51 @@ static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int in zend_ast_export_ns_name(str, ast, 0, indent); } +static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *hook_list, int indent) +{ + smart_str_appends(str, " {"); + smart_str_appendc(str, '\n'); + indent++; + zend_ast_export_indent(str, indent); + + for (uint32_t i = 0; i < hook_list->children; i++) { + zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i]; + zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY); + if (hook->flags & ZEND_ACC_FINAL) { + smart_str_appends(str, "final "); + } + switch (i) { + case ZEND_PROPERTY_HOOK_GET: + smart_str_appends(str, "get"); + break; + case ZEND_PROPERTY_HOOK_SET: + smart_str_appends(str, "set"); + break; + } + zend_ast *body = hook->child[2]; + if (body == NULL) { + smart_str_appendc(str, ';'); + } else if (body->kind == ZEND_AST_PROPERTY_HOOK_SHORT_BODY) { + smart_str_appends(str, " => "); + zend_ast_export_ex(str, body->child[0], 0, indent); + smart_str_appendc(str, ';'); + } else { + smart_str_appends(str, " {\n"); + zend_ast_export_stmt(str, body, indent + 1); + zend_ast_export_indent(str, indent); + smart_str_appendc(str, '}'); + } + if (i < (hook_list->children - 1)) { + smart_str_appendc(str, '\n'); + zend_ast_export_indent(str, indent); + } + } + smart_str_appendc(str, '\n'); + indent--; + zend_ast_export_indent(str, indent); + smart_str_appendc(str, '}'); +} + #define BINARY_OP(_op, _p, _pl, _pr) do { \ op = _op; \ p = _p; \ @@ -2389,49 +2434,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } if (ast->child[3]) { - zend_ast_list *hook_list = zend_ast_get_list(ast->child[3]); - - smart_str_appends(str, " {"); - smart_str_appendc(str, '\n'); - indent++; - zend_ast_export_indent(str, indent); - - for (uint32_t i = 0; i < hook_list->children; i++) { - zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i]; - zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY); - if (hook->flags & ZEND_ACC_FINAL) { - smart_str_appends(str, "final "); - } - switch (i) { - case ZEND_PROPERTY_HOOK_GET: - smart_str_appends(str, "get"); - break; - case ZEND_PROPERTY_HOOK_SET: - smart_str_appends(str, "set"); - break; - } - zend_ast *body = hook->child[2]; - if (body == NULL) { - smart_str_appendc(str, ';'); - } else if (body->kind == ZEND_AST_PROPERTY_HOOK_SHORT_BODY) { - smart_str_appends(str, " => "); - zend_ast_export_ex(str, body->child[0], 0, indent); - smart_str_appendc(str, ';'); - } else { - smart_str_appends(str, " {\n"); - zend_ast_export_stmt(str, body, indent + 1); - zend_ast_export_indent(str, indent); - smart_str_appendc(str, '}'); - } - if (i < (hook_list->children - 1)) { - smart_str_appendc(str, '\n'); - zend_ast_export_indent(str, indent); - } - } - smart_str_appendc(str, '\n'); - indent--; - zend_ast_export_indent(str, indent); - smart_str_appendc(str, '}'); + zend_ast_export_hook_list(str, zend_ast_get_list(ast->child[3]), indent); } break; case ZEND_AST_CONST_ELEM: From ca3013b504329f569dbebcfc4ad0d30482ad4adf Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:31:26 +0100 Subject: [PATCH 3/5] Fix property hook name mismatch --- Zend/zend_ast.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index d2551ddfb4dc..30b067a5ba73 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1757,14 +1757,7 @@ static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *h if (hook->flags & ZEND_ACC_FINAL) { smart_str_appends(str, "final "); } - switch (i) { - case ZEND_PROPERTY_HOOK_GET: - smart_str_appends(str, "get"); - break; - case ZEND_PROPERTY_HOOK_SET: - smart_str_appends(str, "set"); - break; - } + smart_str_append(str, hook->name); zend_ast *body = hook->child[2]; if (body == NULL) { smart_str_appendc(str, ';'); From 225847fb015ff3c6ec1fdb7ca8fbf6405fc8a7d3 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:43:23 +0100 Subject: [PATCH 4/5] Print hooks in parameter exports --- Zend/zend_ast.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 30b067a5ba73..29b825024851 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2567,7 +2567,14 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } smart_str_appendc(str, '$'); zend_ast_export_name(str, ast->child[1], 0, indent); - APPEND_DEFAULT_VALUE(2); + if (ast->child[2]) { + smart_str_appends(str, " = "); + zend_ast_export_ex(str, ast->child[2], 0, indent); + } + if (ast->child[5]) { + zend_ast_export_hook_list(str, zend_ast_get_list(ast->child[5]), indent); + } + break; case ZEND_AST_ENUM_CASE: if (ast->child[3]) { zend_ast_export_attributes(str, ast->child[3], indent, 1); From bb5e96024befd33bbbbd1a5926206eea80edb58b Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:43:38 +0100 Subject: [PATCH 5/5] Add test for GH-17101 --- Zend/tests/property_hooks/gh17101.phpt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Zend/tests/property_hooks/gh17101.phpt diff --git a/Zend/tests/property_hooks/gh17101.phpt b/Zend/tests/property_hooks/gh17101.phpt new file mode 100644 index 000000000000..3ab53fb75da0 --- /dev/null +++ b/Zend/tests/property_hooks/gh17101.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-17101 (AST->string does not reproduce constructor property promotion correctly) +--FILE-- + $this->boolVal = 1;} ) {} + }); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +assert(false && new class { + public function __construct(#[Foo] public private(set) bool $boolVal = false { + final set => $this->boolVal = 1; + }) { + } + +})