Bug 5258 – [CTFE] Stack overflow with struct by ref
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2010-11-22T17:09:00Z
Last change time
2011-06-11T22:33:41Z
Keywords
ice-on-valid-code
Assigned to
nobody
Creator
bearophile_hugs
Comments
Comment #0 by bearophile_hugs — 2010-11-22T17:09:12Z
This D2 program generates a Stack Overflow with DMD 2.050 despite the stack dept is very small:
struct Foo { int x; }
void bar(int n, ref Foo f) {
if (n)
bar(n - 1, f);
else
f.x++;
}
int spam() {
bar(1, Foo());
return 0;
}
enum _ = spam();
void main() {}
Comment #1 by bearophile_hugs — 2011-05-06T02:51:16Z
This CTFE bug is present in DMD v1.068beta still, but it seems absent in DMD v1.042.
A longer example that gives the correct answer with DMD 1.042 but produces stack overflow with DMD v1.068beta:
import std.c.stdio: printf;
bool test(int k, int j, ulong diag45, ulong diag135, ulong cols) {
return ((cols & (1UL << j)) +
(diag135 & (1UL << (j + k))) +
(diag45 & (1UL << (32 + j - k))) ) == 0;
}
void mark(int k, int j, ref ulong diag45, ref ulong diag135, ref ulong cols) {
cols ^= (1UL << j);
diag135 ^= (1UL << (j + k));
diag45 ^= (1UL << (32 + j - k));
}
uint solve(int niv, int dx, ref ulong diag45, ref ulong diag135, ref ulong cols) {
uint solutions_found;
if (niv) {
for (int i = 0; i < dx; i++)
if (test(niv, i, diag45, diag135, cols)) {
mark(niv, i, diag45, diag135, cols);
solutions_found += solve(niv - 1, dx, diag45, diag135, cols);
mark(niv, i, diag45, diag135, cols);
}
} else {
for (int i = 0; i < dx; i++)
solutions_found += test(0, i, diag45, diag135, cols);
}
return solutions_found;
}
ulong nqueen(int n) {
// masques
ulong diag45 = 0; // / diagonal bitboard
ulong diag135 = 0; // \ diagonal bitboard
ulong cols = 0; // column bitboard
return solve(n - 1, n, diag45, diag135, cols);
}
const ulong result = nqueen(9);
void main() {
// NQUEENS: 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2_680, 14_200, 73_712, 365_596
printf("%lld\n", result);
}
Comment #2 by clugdbug — 2011-05-06T04:09:57Z
This is a pseudo-regression: it was never doing what it was supposed to. The test case happened to give the correct results on a previous version, but only because one bug hid another. Slight changes would make it fail.
Ref parameters are not going to work reliably in CTFE until pointers are implemented. Which is not happening in this release.
Comment #3 by clugdbug — 2011-05-17T14:22:02Z
The bug reported in comment 1 is bug 5845, which is a different bug.