Bug 22988 – no short-circuiting when constant folding ternary operator
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-04-04T21:12:09Z
Last change time
2022-04-07T10:08:10Z
Keywords
pull, rejects-valid
Assigned to
No Owner
Creator
Max Samukha
Comments
Comment #0 by maxsamukha — 2022-04-04T21:12:09Z
enum a = 0;
enum b = a ? 1 << a - 1 : 0;
void main()
{
}
Error: shift by -1 is outside the range `0..31`
Comment #1 by dkorpel — 2022-04-05T07:57:18Z
Because AddExpression has precedence over ShiftExpression, it's parsed as:
```
enum b = a ? 1 << (a - 1) : 0;
```
Since a = 0, it results in a shift by -1, which gives an error. To fix, add parentheses around the shift:
```
enum b = a ? (1 << a) - 1 : 0;
```
Comment #2 by maxsamukha — 2022-04-05T08:15:53Z
The precedence is intended to be (a ? (1 << (a - 1)) : 0).
Since 'a' is 0, the first branch of the conditional shouldn't be evaluated, and the expected result is 0.
Compare that to the runtime version, which behaves as expected:
void main()
{
int a = 0;
int b = a ? 1 << a - 1 : 0;
assert(b == 0);
}
Comment #3 by maxsamukha — 2022-04-05T08:52:48Z
Similar case:
enum l = 0;
enum int[l] a = [];
enum b = l ? a[l] : 0;
Error: array index 0 is out of bounds `a[0 .. 0]`
Or simply:
enum a = 0 ? 1 << -1 : 0;
enum int[0] a = [];
enum b = 0 ? a[0] : 0;
Comment #4 by maxsamukha — 2022-04-05T08:55:10Z
(In reply to Max Samukha from comment #3)
> enum b = l ? a[l] : 0;
Should be:
enum b = l ? a[l - 1] : 0;
Comment #5 by dkorpel — 2022-04-05T09:17:31Z
Ah, thanks for clearing that up. I think this test illustrates the problem best:
```
enum a = false && (1 << -1); // passes
enum b = false ? (1 << -1) : 0; // fails
```
I've updated the title
Comment #6 by maxsamukha — 2022-04-05T09:32:30Z
(In reply to Dennis from comment #5)
> ```
> I've updated the title
Great, thanks!
Comment #7 by dlang-bot — 2022-04-07T08:56:06Z
@BorisCarvajal created dlang/dmd pull request #13961 "Fix Issue 22988 - no short-circuiting when constant folding ternary operator" fixing this issue:
- Fix Issue 22988 - no short-circuiting when constant folding ternary operator
https://github.com/dlang/dmd/pull/13961
Comment #8 by dlang-bot — 2022-04-07T10:08:10Z
dlang/dmd pull request #13961 "Fix Issue 22988 - no short-circuiting when constant folding ternary operator" was merged into master:
- befbc46fd7309ffb6e640822fa74280a750cf65e by Boris Carvajal:
Fix Issue 22988 - no short-circuiting when constant folding ternary operator
https://github.com/dlang/dmd/pull/13961