D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 22988 - no short-circuiting when constant folding ternary operator
Summary: no short-circuiting when constant folding ternary operator
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 normal
Assignee: No Owner
URL:
Keywords: pull, rejects-valid
Depends on:
Blocks:
 
Reported: 2022-04-04 21:12 UTC by Max Samukha
Modified: 2022-04-07 10:08 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Max Samukha 2022-04-04 21:12:09 UTC
enum a = 0;
enum b = a ? 1 << a - 1 : 0;

void main()
{
}

Error: shift by -1 is outside the range `0..31`
Comment 1 Dennis 2022-04-05 07:57:18 UTC
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 Max Samukha 2022-04-05 08:15:53 UTC
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 Max Samukha 2022-04-05 08:52:48 UTC
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 Max Samukha 2022-04-05 08:55:10 UTC
(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 Dennis 2022-04-05 09:17:31 UTC
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 Max Samukha 2022-04-05 09:32:30 UTC
(In reply to Dennis from comment #5)

> ```
> I've updated the title

Great, thanks!
Comment 7 Dlang Bot 2022-04-07 08:56:06 UTC
@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 Dlang Bot 2022-04-07 10:08:10 UTC
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