You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Regression: final class constants can be overridden by child class (re-#4455, Zend/zend_inheritance.c) #22329
bug · php-src-strict · language · final class constants
Problem
PHP 8.1+ final const on a class must refuse child redeclaration. After #4455, parse accepts final const, but inheritance still allows override — Zend fatals at compile/eval time.
Verified 2026-07-22 on af276f464 (host PHP 8.2.32 Zend vs php bin/vm.php):
Repro
Zend 8.2
VM
class A { final public const X = 'a'; } eval('class B extends A { public const X = \"b\"; }')
lib/Compiler.php / inheritance checks — reject child const when parent const is final (compile-time)
lib/VM.php class-entry merge — same guard if constants register at runtime/eval
Prefer PHP-in-PHP; no new runtime/*.c
Repro
./script/docker-exec.sh -- bash -lc 'php bin/vm.php -r '"'"'class A { final public const X = \"a\"; } eval(\"class B extends A { public const X = \\"b\\"; }\"); echo B::X, \"\n\";'"'"''
Done when
Child redeclaration of final const fatals like Zend (cannot override final constant)
Works for eval and normal compile; ReflectionClassConstant::isFinal() stays true
Compliance .phpt under test/compliance/cases/; php-src-strict; no php-compiler-strict shortcut
Verification:eval('class B extends A { public const X = "b"; }') after final public const X now fatals with B::X cannot override final constant A::X (exit 255). ReflectionClassConstant::isFinal() remains true. Guard lives in VM inheritFromParent / inheritFromInterfaces (rejectChildOverrideOfFinalClassConst). Compliance: final_class_const_eval_override.phpt; unit: FinalClassConstCheckTest::testEvalCannotOverrideFinalClassConstant.
Pre-triage: release-readiness --json → user_release_ready: yes; AOT smoke red on master independently (not this change).
Activity
PurHur commentedon Jul 22, 2026
claim: Worker lane A — starting this run
Pre-triage gates (this workspace):
Language: reject eval override of final class constants (#22329) (#22342
PurHur commentedon Jul 22, 2026
Merged via #22342
Verification:
eval('class B extends A { public const X = "b"; }')afterfinal public const Xnow fatals withB::X cannot override final constant A::X(exit 255).ReflectionClassConstant::isFinal()remains true. Guard lives in VMinheritFromParent/inheritFromInterfaces(rejectChildOverrideOfFinalClassConst). Compliance:final_class_const_eval_override.phpt; unit:FinalClassConstCheckTest::testEvalCannotOverrideFinalClassConstant.Pre-triage:
release-readiness --json→user_release_ready: yes; AOT smoke red on master independently (not this change).