Even if we can't actually pass by reference, we still need to
create the REFERENCE wrapper to satisfy the calling convention.
The particular test case would crash with JIT, because the existence
of the reference was assumed.
Fixes oss-fuzz #39440.
This would end up taking the successors_count=2 case, even though
we need to treat SWITCH and MATCH differently. This incorrectly
marked a block as FOLLOW, resulting in incorrect block pass
optimization.
Fixes oss-fuzz #39380.
This was doing a plain copy of JMPZNZ, even though it encodes
offsets relative to the opline. As such, the offsets would be
relative to target, while they should be relative to opline.
Fix this by recomputing them.
Fixes oss-fuzz #39295.
This ensures that code directly before the loop var free is
separated out (and will generally be eliminated as unreachable).
This fixes some assumptions we have that unreachable loop var free
blocks start with the loop var free.
Fixes oss-fuzz #39395.
We can't remove a trivial phi of the form x = phi(x), because we
don't have a replacement value. We could drop the whole block
though. SCCP would normally do this, but in this particular case
we only determine non-reachability based on type information.
Fixes oss-fuzz #39316.
If we're removing a predecessor because it already exists during
replacement, we should also drop pi nodes for that predecessor.
Fixes oss-fuzz #39276.
We shouldn't try to load further classes if one autoload throws.
This fixes oss-fuzz #38881, though I believe there are still two
deeper issues here: 1) Why do we allow autoloading with an active
exception? 2) Exception save & restore should probably also save
and restore the exception opline.
Even though the input is not a reference (or not treated as such),
we still need to create a reference to satisfy the function
signature. Various code relies on reference arguments actually
being references. In this particular case, it would result in
a JIT crash.
The zend_call_function() implementation already handled this
correctly.
We'd have usually converted it into a PRE_INC if there is no use,
but that's not guaranteed. If there is no use at this point, make
sure we don't try to use the sentinel value.
In this case we should use the original internal handler. Otherwise
the trampoline will attempt to free the closure, but the function
being used is not actually part of a closure anymore.
While parent:: should inherit the called scope, it should only do
so if it is compatible. If there is no called scope, or it is not
a subtype of the scope, we should fall back to the scope.
For a particular assignment, a non-coerced constant assignment
value will remain valid. However, opcache merges cache slots for
all identical property references, which means that this
optimization also disables property type checks for all other
operands on the property that occur in the same functions.
This could be addressed by blocking cache slot merging in opcache,
but I prefer dropping it entirely instead. It does not seem
important enough to warrant doing that.
Updating based on the properties info HT will miss private parent
properties that have been shadowed in the child class. Instead,
perform updating directly on the default properties table.
We can't do the same for static properties, because those don't
have a convenient way to look up the property type from the
property offset. However, I don't believe the problem exists for
static properties, because we're always going to be using the
property on the class it was declared on, while children only hold
INDIRECT references. As such, this should be covered by parent
class const updating.
Fixes oss-fuzz #35906.
We can't destroy the result operand early, because the division
might fail, in which case we need to preserve the original value.
Place the division result in a temporary zval, and only copy it
on success.
Fixes oss-fuzz #35876.
The analysis in the bug report wasn't correct (at least not in
this case -- there may still be a more general problem here),
the issue was that write_property returned the original variable_ptr
rather than the zend_assign_to_variable() return value, which will
DEREF the variable before overwriting it.
In this case we ended up creating an ASSIGN_OBJ_REF with VAR
result operand, which was not freed.
Fix this by implementing assign_ref_znode the same was as
assign_znode, i.e. performing an assignment with result and
then freeing the result, which will result mark the result as
UNUSED. This is more robust than the special handling for
result == NULL that was used before.
This fixes one of the issues reported in bug #81190.
The result == op1 check did not work properly here, because op1
was &op1_copy at this point. Move the division by zero reporting
out of the _base function, so it can check the original op1.
When the memory limit is restored during shutdown, we may still
be using a lot of memory. Ignore the failure at that point and
set it again after the MM is shut down, at which point memory
usage should be at its lowest point.
When the memory limit is reduced using an `ini_set("memory_limit", ..)`
below the currently allocated memory, the out-of-memory check overflowed.
Instead of implementing additional checks during allocation,
`zend_set_memory_limit()` now validates the new memory limit. When
below the current memory usage the ini_set call will fail and throw
a warning.
This is part of GH-7040.
While the specified restriction was checked, the #[Attribute]
attribute did not specify the flags parameter, so that Reflection
returned incorrect information.
In particular, Attribute itself has a CLASS target, not an ALL
target.
mixed should be behaving the same way as no type here, and not
require X to be autoloaded. Everything apart from "void" is trivially
covariant to "mixed".
Only reset the uninitialized property flag once the type check
has succeeded. Previously the property was treated as unset rather
than uninitialized after a failed assignment.
Noticed this edge-case while working on accessors...