-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Avoid early-binding on unresolved types #4137
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
Fixes bug #76451, and more importantly lays necessary groundwork for covariant/contravariant types. Bug #76451 is just an edge case, but once covariance is introduced this will become a common problem instead.
@dstogov Please have a look at this. Once this issue is resolved, the actual covariance implementation will be simple. |
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 patch affects preloading. Fixing it may disclose other problems.
make test TESTS="--preload Zend/tests/bug76451.phpt"
More optimal solution (without double-checks) would be great.
I'm not sure, if covariant/contravariant types may work without run-time checks, and how this patch would help them.
if ((ce = zend_lookup_class_ex(Z_STR_P(parent_name), Z_STR_P(parent_name + 1), 0)) != NULL) { | ||
do_bind_class(RT_CONSTANT(&op_array->opcodes[opline_num], op_array->opcodes[opline_num].op1), ce); | ||
zend_class_entry *ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(lcname + 1)); | ||
zend_class_entry *parent_ce = zend_lookup_class_ex(Z_STR_P(parent_name), Z_STR_P(parent_name + 1), 0); |
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.
Do we need this lookup. if "ce" is NULL? We didn't do it before.
) { | ||
continue; | ||
} | ||
if (zend_do_perform_implementation_check(func, parent_func) == INHERITANCE_UNRESOLVED) { |
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.
In case we need this only for methods with "class" type hints, we may set special fn_flag to avoid duplicate check for others. We may also reuse the same flag for classes to completely eliminate this loop. (At least we may reuse ZEND_ACC_HAS_TYPE_HINTS & ZEND_ACC_HAS_RETURN_TYPE for methods).
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.
On the other hand, if we check everything in zend_can_early_bind() and everything is fine (INHERITANCE_SUCCESS), we may avoid the same checks in do_bind_class(). If zend_do_perform_implementation_check() returns INHERITANCE_ERROR, we may throw error immediately.
Part of #4185 now. |
Fixes bug #76451, and more importantly lays necessary groundwork for covariant/contravariant types. Bug #76451 is just an edge case, but once covariance is introduced this will become a common problem instead.
The core problem is that the inheritance code currently simply uses
zend_lookup_class
when checking whether two types (that are not string equal) are the same due to aliasing (or in the future: compatible through variance) and treats non-existing classes as an error. This has two problems:This PR solves the problem by