-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix enum to bool comparison #17031
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
Fix enum to bool comparison #17031
Conversation
@IMSoP I decided only to handle |
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 affects many internal classes.
I think this change is too dangerous especially for stable branch.
May be this should be done for enums only?
I don't see a lot of sense in comparison bools with objects, that can't be cast to bool.
@dstogov
None of our extensions prevent casting to
I'm happy merging this for |
I don't care about this a lot and I won't object against merging this into PHP-8.3. |
@bwoebi @arnaud-lb @nielsdos Maybe one of you has some opinions. 🙂 |
I think the proposed behaviour is right, but I'm a bit worried as well for stable branches. |
I'm happy postponing for master and documenting the change accordingly. |
The proposed behavior also looks good to me as it's consistent with the current behavior when the boolean operand is a literal. It also matches the documented behavior of One possible concern is that having a special case in I agree that postponing for master is less risky. |
I agree with the proposed behaviour. I think it would be fine to change in PHP 8.4 given its recency, but 8.3 is probably too risky. |
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.
If this is merged into 8.4 please amend the migration guide and/or open an issue on doc-en.
The compiler compiles $enum == true to ZEND_BOOL, which always returns true for objects (with the default cast_object handler). However, when compared to a statically unknown value $enum == $true, the resulting opcode ZEND_IS_EQUAL would call the objects compare handler. The zend_objects_not_comparable() handler, which is installed for enums and other internal classes, blanketly returns false. This does not match the ZEND_BOOL semantics. We now handle bools in zend_objects_not_comparable() explicitly. Fixes phpGH-16954
Suggested by Arnaud. This avoids handling boolean semantics in each compare handler, as they should be consistent across the language.
@arnaud-lb I added a new commit implementing your suggestion. In synthetic benchmarks, object comparison gets slightly slower, while other comparisons (that don't go through the fast path) get slightly faster (e.g. numeric string to int comparison). My intuition is that the latter is more common, so I'm happy going with your solution. |
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.
Thank you! This looks good to me.
The compiler compiles $enum == true to ZEND_BOOL, which always returns true for objects (with the default cast_object handler). However, when compared to a statically unknown value $enum == $true, the resulting opcode ZEND_IS_EQUAL would call the objects compare handler.
The zend_objects_not_comparable() handler, which is installed for enums and other internal classes, blanketly returns false. This does not match the ZEND_BOOL semantics.
We now handle bools in zend_objects_not_comparable() explicitly.
Fixes GH-16954