-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Warn on "parent" without parent at compile-time #3404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message is wrong, isn't it? Class scope is active, there is just no parent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We no longer introduce E_STRICT warnings, please use E_WARNING instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -6453,6 +6467,10 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ | |||
} | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dmitry has changed this code recently; it should be easy to use now.
Zend/zend_compile.c
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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_STRICT
to usages ofparent
in class-scope where the class does not have a parent, e.g.This currently has two test failures where the
E_STRICT
is 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_STRICT
to anE_COMPILE_ERROR
.