Somewhat reduced test case:
-----
module bug_example;
int f (int n) {
foreach (i; 0..n) {
}
return 10;
}
int c (int a, int b) {
return (f(a) * 1L * f(b)) % 1000;
}
void main () {
auto a = [2];
foreach (n; a) {
int res = c(n - 1, n);
import std.stdio: writeln;
writeln(res);
}
}
-----
Compile with "dmd -O -inline".
With 2.086.0, it produces the correct result (100).
With 2.087.1 and further, the result is wrong (10).
The bug shows with "-m32" and with "-m32mscoff"; no bug seen with "-m64".
The "* 1L *" part is conversion to long for multiplication.
Goes the same with "cast(long) f(a)" instead.
After "% 1000", it is (well, should have been) safe to treat the result as int.
Ivan Kazmenko.
Comment #1 by b2.temp — 2020-06-02T04:50:19Z
reduced w/o phobos, test case is a "runnable" TC:
---
#!dmd -O -inline -m32
int f (int n)
{
foreach (i; 0..n) {}
return 10;
}
int c (int a, int b)
{
return (f(a) * 1L * f(b)) % 1000;
}
void main ()
{
int[] a = [1];
assert(c(2 - 1, 2) == 100);
}
---
Comment #2 by b2.temp — 2020-06-02T05:15:32Z
according to digger, caused by https://github.com/dlang/dmd/pull/9722
full bisection report:
> digger: Finding shortest path between 717f0aba51531c140d1a41ff8da3020443b6d523 > and 2e4afcd30657009f75394aaead63721c5eac0e38...
> digger: 0 commits (about 0 tests) remaining.
> digger: 2e4afcd30657009f75394aaead63721c5eac0e38 is the first bad commit
> commit 2e4afcd30657009f75394aaead63721c5eac0e38
> Author: Walter Bright <[email protected]>
> Date: Sat Apr 27 22:04:40 2019 -0700
>
> dmd: Merge pull request #9722 from WalterBright/cod2-const2
>
> https://github.com/dlang/dmd/pull/9722
>
> cod2.c: improve details a bit pt 2
>
> diff --git a/dmd b/dmd
> index d8d17ee3e..9203ab647 160000
> --- a/dmd
> +++ b/dmd
> @@ -1 +1 @@
> -Subproject commit d8d17ee3efcdd53b39f29530879fde77980ab18b
> +Subproject commit 9203ab6477f4c8e816c60803112a554d19499f4d
> digger: Bisection completed successfully.