Commit ce899c8c681 for php
commit ce899c8c681b77147b7daa5b2729cdbfda194027
Author: Jorg Sowa <jorg.sowa@gmail.com>
Date: Fri Oct 30 22:46:07 2026 +0100
Fix AST printing of final and abstract on class constants and properties
Closes GH-25062
diff --git a/NEWS b/NEWS
index 06945c2b7ba..ab9d9476c5e 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,8 @@ PHP NEWS
(David Carlier)
. Fixed bug GH-24534 (Segfault in zend_try_early_bind when a parent class
autoloads its cached child during linking). (David Carlier)
+ . Fixed AST printing dropping final on class constants and properties, and
+ abstract on properties. (Jorg Sowa)
- CLI:
. Fixed bug GH-24697 (PHP_HTTP_PARSER_STRICT build option doesn't work).
diff --git a/Zend/tests/assert/expect_final_abstract_modifiers.phpt b/Zend/tests/assert/expect_final_abstract_modifiers.phpt
new file mode 100644
index 00000000000..5dd87976faf
--- /dev/null
+++ b/Zend/tests/assert/expect_final_abstract_modifiers.phpt
@@ -0,0 +1,36 @@
+--TEST--
+AST printing of final and abstract modifiers on class constants and properties
+--INI--
+zend.assertions=1
+--FILE--
+<?php
+
+try {
+ assert(false && new class {
+ final public const A = 1;
+ final protected const int B = 2;
+ final public $a;
+ final public static $b;
+ final public readonly int $c;
+ abstract public $d { get; }
+ abstract protected private(set) int $e { set; }
+ });
+} catch (AssertionError $e) {
+ echo $e->getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+assert(false && new class {
+ public final const A = 1;
+ protected final const int B = 2;
+ public final $a;
+ public static final $b;
+ public final readonly int $c;
+ public abstract $d {
+ get;
+ }
+ protected private(set) abstract int $e {
+ set;
+ }
+})
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 4e640a321d1..2d190fc951c 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -2010,6 +2010,12 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
if (ast->attr & ZEND_ACC_STATIC) {
smart_str_appends(str, "static ");
}
+ if (ast->attr & ZEND_ACC_ABSTRACT) {
+ smart_str_appends(str, "abstract ");
+ }
+ if (ast->attr & ZEND_ACC_FINAL) {
+ smart_str_appends(str, "final ");
+ }
if (ast->attr & ZEND_ACC_READONLY) {
smart_str_appends(str, "readonly ");
}
@@ -2032,6 +2038,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
}
zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CONSTANT);
+ if (ast->attr & ZEND_ACC_FINAL) {
+ smart_str_appends(str, "final ");
+ }
smart_str_appends(str, "const ");
if (ast->child[2]) {
zend_ast_export_type(str, ast->child[2], indent);