Warn on "parent" without parent at compile-time#3404
Warn on "parent" without parent at compile-time#3404morrisonlevi wants to merge 1 commit intophp:masterfrom
Conversation
|
|
||
| ?> | ||
| --EXPECTF-- | ||
| Strict Standards: Cannot use "parent" when no class scope is active in %s on line %d |
There was a problem hiding this comment.
This message is wrong, isn't it? Class scope is active, there is just no parent.
There was a problem hiding this comment.
Oops, I copied the wrong line. Will fix.
2180d20 to
4443e98
Compare
Zend/zend_compile.c
Outdated
| && !CG(active_class_entry_parent_name)) | ||
| { | ||
| zend_error_noreturn( | ||
| E_STRICT, |
There was a problem hiding this comment.
We no longer introduce E_STRICT warnings, please use E_WARNING instead.
There was a problem hiding this comment.
E_WARNING does not mean this will get changed in a future release. E_DEPRECATED seems odd. I think E_STRICT is the best choice, and unless my memory is failing me we never voted on not adding new E_STRICT; only to remove existing ones.
There was a problem hiding this comment.
We decided to remove the E_STRICT category in https://wiki.php.net/rfc/reclassify_e_strict. If you'd like to go against this prior decision, this change is going to need an RFC.
Imho either E_DEPRECATED or E_WARNING are sensible choices.
There was a problem hiding this comment.
This does not match my memory. I was pretty certain we only voted to reclassify existing ones, not remove the category entirely. I will choose E_DEPRECATED.
Zend/zend_compile.c
Outdated
| CG(active_class_entry) = ce; | ||
| if (extends_ast) { | ||
| zend_string *extends_name = zend_ast_get_str(extends_ast); | ||
| CG(active_class_entry_parent_name) = zend_string_copy(extends_name); |
There was a problem hiding this comment.
This assigns the non-resolved class name. Either this should assign the correct class name, or should just be a boolean for whether it has a parent, to prevent confusion when other code wants to use this member in the future.
There was a problem hiding this comment.
I think other code will need the name of the parent; for instance we reject string $parent = parent::class in parameters but there's no need to actually do this now. Will investigate resolving the class name.
There was a problem hiding this comment.
Just to check, what do you mean by "non-resolved"? I assume Bar in use Foo as Bar; class Baz extends Bar {} or something?
There was a problem hiding this comment.
Yes, that's right. You can either use zend_resolve_class_name, or try to get the already resolved name from above, though extracting it from literals might be a bit inconvenient.
There was a problem hiding this comment.
Dmitry has changed this code recently; it should be easy to use now.
| if (extends_ast) { | ||
| zend_string *extends_name = zend_ast_get_str(extends_ast); | ||
| CG(active_class_entry_parent_name) = zend_string_copy(extends_name); | ||
| } |
There was a problem hiding this comment.
Shouldn't it be NULLed out in the else case? I think it will currently not behave correctly if you have an outer class with parent and an inner (anonymous) class without.
There was a problem hiding this comment.
That sounds right. Will investigate.
|
I've fixed a number of issues and rebased on latest master. I have supposedly enabled support for There is still an annoyance: for compile-time expressions that use |
|
Just a question: "Warn on "parent" without parent at compile-time" compile-time: Do we have it here in the interpreter? |
|
Yes. |
|
The debug build failed on Travis, but it works for me locally. I adjusted a few more tests, including some for This still needs entries in NEWS/UPGRADING but aside from that can anyone spot issues, or would like more tests in certain areas? |
|
Comment on behalf of carusogabriel at php.net: Labelling |
> - Core > Using "parent" inside a class without parent is deprecated, and will throw > a compile-time error in the future. Currently an error will only be > generated if/when the parent is accessed at run-time. Refs: * https://github.com/php/php-src/blob/42cc58ff7b2fee1c17a00dc77a4873552ffb577f/UPGRADING#L303 * php/php-src#3404 * php/php-src#3564 * php/php-src@a9e6667 (originally committed as hard compile time error) * php/php-src@deb44d4 (reverted back to deprecation error)
This adds a compile-time warning of level
E_STRICTto usages ofparentin class-scope where the class does not have a parent, e.g.This currently has two test failures where the
E_STRICTis emitted twice. I was not sure if the check was always redundant or if in some cases it isn't. I am hoping a reviewer will know better than me.If a method definition like this is executed it generates a runtime error, so this should not be a controversial change. In PHP 8.0 we should change this from
E_STRICTto anE_COMPILE_ERROR.