-
-
Notifications
You must be signed in to change notification settings - Fork 606
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 issue 6226 - detect impossible cases when switching on integral t… #10603
base: master
Are you sure you want to change the base?
Conversation
Thanks for your pull request and interest in making D better, @StianGulpen! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#10603" |
Hmm, look like there are a couple of phobos fixes needed first. |
And the buidlkite CI shows that user code would be affected too. This changes probably requires discussions. Not sure if people are ready for another disruptive deprecation. |
is it possible to deprecate the behaviour under switch while keeping it an error elsewhere? |
@@ -2510,7 +2510,7 @@ else | |||
ss.condition.type = ss.condition.type.constOf(); | |||
break; | |||
} | |||
ss.condition = integralPromotions(ss.condition, sc); | |||
|
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.
The error messages produced indicate that these checks are backwards, and it is a mistake to move the integralPromotions from here.
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 the first message I explained that promotion is kept only to prevent a problem with the code produced by the DMD backend. For example you can test this code when the promotion is completely removed:
string test(char a)
{
version (none) asm
{
xor EAX, EAX;
}
switch (a) // mov AL, byte ptr[...], but RAX is garbage, then cmp EAX result are randomly wrong
{
case 'a': return "a";
case 'b': return "b";
default: assert(false); // will take this path because of the garbages in EAX, despite of AL being correct.
}
}
void main(string[] args)
{
assert(test('a') == "a");
assert(test('b') == "b");
}
Without the BE issue the promotion would be removed. Why do you want to promote a byte
to an int
if the goal is to test the different values that a byte
can have ?
Impossible cases are accepted because of the promotion that happened before the semantic check of the case and that is based on the promoted target type, i.e ss.condition.type
.
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.
You are indeed correct that:
"The case expressions must all evaluate to a constant value or array, or a runtime initialized const or immutable variable of integral type. They must be implicitly convertible to the type of the switch Expression."
https://dlang.org/spec/statement.html#switch-statement
I had that backwards.
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.
yeah but nothing says in the specs that the type of the condition has to be promoted. Of course if it gets promoted before processing the cases that then it's obvious why the errors are not issued...
So I'm not sure if I understand. Do you agree on the fact that there's a bug ?
The bug to me is like if enum byte a = ubyte(-1);
would be accepted just because we are in a switch, while everywhere else that fails.
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.
The integral promotion of the switch value is not the source of the problem, and moving it causes failures in existing code. The correct fix would be to check if the case values could be produced by the integral promotion of the switch value.
In |
It's unnecessary to support anything but 32 or 64 bits. Just promote the switch value to an |
So this is what is done with the PR but this time not too early.
The plan now that everybody understands why and how things are done is to keep track of the original type somewhere and use it while the Of course as an option a special case could be added to spec, preventing the compiler change. |
It needs to pass the tests, then I'll have another look. |
…ypes
While making testing this change I've discovered that when the
switch
is generated the CPU register that's tested is not cleaned up. This was not a problem until promotion was deactivated. So the promotion is still there but happens after the semantic on theswitch
body.