Commit 5300734e3f6 for php
commit 5300734e3f6a268e7c3ee23086e006eb1f91d4c1
Author: Jorg Sowa <jorg.sowa@gmail.com>
Date: Sat Oct 31 16:17:24 2026 +0100
Fix AST export of readonly anonymous classes
Closes GH-25060
diff --git a/NEWS b/NEWS
index 030ea531fd3..4ff44252837 100644
--- a/NEWS
+++ b/NEWS
@@ -40,6 +40,8 @@ PHP NEWS
autoloads its cached child during linking). (David Carlier)
. Fixed AST printing dropping final on class constants and properties, and
abstract on properties. (Jorg Sowa)
+ . Fixed AST export of readonly anonymous classes dropping the readonly
+ modifier. (Jorg Sowa)
- CLI:
. Fixed bug GH-24697 (PHP_HTTP_PARSER_STRICT build option doesn't work).
diff --git a/Zend/tests/assert/expect_readonly_anon_class.phpt b/Zend/tests/assert/expect_readonly_anon_class.phpt
new file mode 100644
index 00000000000..5944475ffc4
--- /dev/null
+++ b/Zend/tests/assert/expect_readonly_anon_class.phpt
@@ -0,0 +1,22 @@
+--TEST--
+AST export of readonly anonymous class
+--INI--
+zend.assertions=1
+--FILE--
+<?php
+try {
+ assert(false && new readonly class {});
+} catch (AssertionError $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+}
+try {
+ assert(false && new #[A] readonly class(1) {});
+} catch (AssertionError $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+AssertionError: assert(false && new readonly class {
+})
+AssertionError: assert(false && new #[A] readonly class(1) {
+})
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 2d190fc951c..abd90dd2234 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -2320,6 +2320,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
if (decl->child[3]) {
zend_ast_export_attributes(str, decl->child[3], indent, 0);
}
+ if (decl->flags & ZEND_ACC_READONLY_CLASS) {
+ smart_str_appends(str, "readonly ");
+ }
smart_str_appends(str, "class");
if (!zend_ast_is_list(ast->child[1])
|| zend_ast_get_list(ast->child[1])->children) {