Fix crash when a partial skips a param with a constant default#184
Open
iliaal wants to merge 1 commit into
Open
Fix crash when a partial skips a param with a constant default#184iliaal wants to merge 1 commit into
iliaal wants to merge 1 commit into
Conversation
When a partial leaves an optional parameter unbound (a positional gap from named arguments) and its default is a constant expression, the default AST was compiled into the forwarding call as an uncompilable ZEND_AST_CONSTANT node: an assertion in debug builds, undefined behavior otherwise. For a user function, skip the parameter and pass the following arguments by name so the target applies its own default at call time; this materializes no value and handles every default kind, including enum cases that cannot be a literal. Internal functions still pass an explicit default and error if it is not introspectable.
iliaal
force-pushed
the
fix/pfa-const-default-gap-crash
branch
from
July 19, 2026 00:37
28dbd3c to
c2117da
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A partial that leaves an optional parameter unbound via a named-argument gap, where that parameter's default is a constant expression, crashes the compiler.
f(a: 10, c: ?)forfunction f($a, $b = SOME_CONST, $c = 0)compiled the callee default into the generated forwarding call as aZEND_AST_CONSTANTnode, whichzend_compile_expr_innerhas no case for:ZEND_ASSERT(0)in debug,__builtin_unreachableUB in release. A plain literal default ($b = 5) is unaffected.For a user function, this skips the unbound parameter in the forwarding call and passes the following arguments by name, so the target applies its own default at call time. That matches a normal call exactly (verified for global constants,
self::class constants, and enum cases) and materializes no value, so it is safe under opcache for defaults that cannot be stored as a literal, such as enum cases. Internal functions are unchanged: they still pass an explicit default and error when it is not introspectable.