Also generate a fatal error if a collision occurs in zend_compile.
This is not perfect, because collisions might still be introduced
via opcache, if one file is included multiple times during a request,
invalidate in the meantime and recompiled by different processes.
This still needs to be addressed, but this patch fixes the much
more common case of collisions occuring when opcache is not used.
Fixes bug #78903.
We need to make sure that trait methods with static variables
allocate a separate MAP slot for the static variables pointer,
rather than working in-place.
I wasn't able to create a simple reproducer for this. General approach
is the same as for anonymous classes: If the key is already used, reuse
the old definition.
During preloading, check that all classes that have been included
as part of the preload script itself (rather than through opcache_compile_file)
can actually be preloaded, i.e. satisfy Windows restrictions, have
resolved initializers and resolved property types. When resolving
initializers and property types, also autoload additional classes.
Because of this, the resolution runs in a loop.
* PHP-7.4:
Call zend_unregister_ini_entries() when unload extension loaded through dl() without MSHUTDOWN callback. Extensions with MSHUTDOWN should use UNREGISTER_INI_ENTRIES().
When we change back the bucket key on a class linking failure,
make sure to reload the bucket pointer, as the class table may
have been reallocated in the meantime.
Also remove a bogus bucket key change in anon class registration:
We don't actually rename the class in this case anymore, the RTD
key is already the final name.
We already changed the behavior for __set() in f1848a4. However, it
seems that this is also a problem for all the other property magic,
see bug #78904.
This commit makes the behavior of all the property magic consistent:
Magic will not be triggered for uninitialized typed properties, only
explicitly unset() ones. This brings behavior more in line how
non-typed properties behave and avoids WTF.
Closes GH-4974.
The "return" in the for loop should have been a break on the switch,
otherwise the result is just ignored... but because it prevents
evaluation of the other operand, it also violates the invariant that
everything has been constant evaluated, resulting in an assertion
failure.
The for loop isn't correct in any case though, because it's not legal
to determine the result based on just the second operand, as the
first one may have a side-effect that cannot be optimized away.