The comment was incorrect. Zval ASTs store their lineno in u2, but u2 does not
get copied in ZVAL_COPY. This triggers use-of-uninitialized errors with MSAN.
Unfortunately, I don't have a simple reproducer.
The output of token_get_all is unaffected, so projects such as the userland
nikic/php-parser are unaffected.
Extensions such as nikic/php-ast which expose the internal php ast would see
literals be flattened, though.
This makes php significantly faster at parsing code such as
`$x = eval('return ' . var_export(str_repeat("\0", 100), true) . ';');`
and avoids the stack overflow from recursing 100000 times in
zend_eval_const_expr to process `'' . "\0" . '' . "\0" . ...`
Closes GH-7946
* Don't create binary op if unnecessary
* Update Zend/zend_ast.c
Co-authored-by: Nikita Popov <nikita.ppv@googlemail.com>
When dumping default values in ReflectionXXX::__toString(), for
expression initializers print the AST export instead of trying to
evaluate the expression. With the introduction of "new in
initializers" the result of the evaluation will commonly not be
printable at all, and "__toString" will throw an exception, which
is not particularly useful. Using the AST export also provides more
information on how the parameter was originally declared, e.g. it
preserves the fact that a certain constant was used.
Closes GH-7540.
zend_double_to_str() converts a double to string in the way that
(string) would (using %.*H using precision).
smart_str_append_double() provides some more fine control over
the precision, and whether a zero fraction should be appeneded
for whole numbers.
A caveat here is that raw calls to zend_gcvt and going through
s*printf has slightly different behavior for the degenarate
precision=0 case. zend_gcvt will add a dummy E+0 in that case,
while s*printf convert this to precision=1 and will not. I'm
going with the s*printf behavior here, which is more common,
but does result in a minor change to the precision.phpt test.
When resolving constants on a dynamically declared class during
preloading, the enum class may not be available. Fail gracefully
in that case.
Possibly we shouldn't be trying to evaluate constants on
non-linked classes at all?
This adds support for internal enums with the same basic approach
as userland enums. Enum values are stored as CONSTANT_AST and
objects created during constant updating at runtime. This means
that we need to use mutable_data for internal enums.
This just adds basic support and APIs, it does not include the
stubs integration from #7212.
Closes GH-7302.
Add support for readonly properties, for which only a single
initializing assignment from the declaring scope is allowed.
RFC: https://wiki.php.net/rfc/readonly_properties_v2
Closes GH-7089.
This is going to result in a compile-time error, but AST printing
is invoked first and should handle it gracefully. Handle it by
falling back to more generic printing code.
Fixes oss-fuzz #36264.
Support acquiring a Closure to a callable using the syntax
func(...), $obj->method(...), etc. This is essentially a
shortcut for Closure::fromCallable().
RFC: https://wiki.php.net/rfc/first_class_callable_syntax
Closes GH-7019.
Co-Authored-By: Nikita Popov <nikita.ppv@gmail.com>
Add support for new expressions inside parameter default values,
static variable initializers, global constant initializers and
attribute arguments.
RFC: https://wiki.php.net/rfc/new_in_initializers
Closes GH-7153.
Because php supports doc comments on class constants, I believe it would also
make sense to support them on enum cases.
I don't have strong opinions about whether attributes should be moved to be the
last element or whether the doc comment should go after the attribute,
but the ast will likely change again before php 8.1 is stable.
So far, all attributes are the last ast child node.
I didn't notice that doc comments weren't implemented due to
https://github.com/php/php-src/pull/6489 being a large change.
https://wiki.php.net/rfc/enumerations
did not mention whether or not doc comments were meant to be supported
We're starting to see a mix between uses of zend_bool and bool.
Replace all usages with the standard bool type everywhere.
Of course, zend_bool is retained as an alias.