dmd
dmd copied to clipboard
Inconsistent use-before-initialization behavior for aggregate fields
Follow-up of Issue 15869. The fix is a band-aid and initialization is still extremely fragile depending on which optimization kicks in.
struct S {
bool value;
int a, b, c, d;
}
struct X(int opt) {
S s = S(true);
this(bool) {
s = copyS();
}
static if (opt == 1) { // URVO
S copyS() { return S(s.value); }
}
static if (opt == 2) { // NRVO
S copyS() {
S result;
result.value = s.value;
return result;
}
}
static if (opt == 3) { // No RVO
S copyS() {
S result;
result.value = s.value;
return result;
return S();
}
}
}
void main() {
import std.stdio;
X!1 x1 = X!1(true);
X!2 x2 = X!2(true);
X!3 x3 = X!3(true);
writeln("URVO: ", x1.s.value);
writeln("NRVO: ", x2.s.value);
writeln("No RVO: ", x3.s.value);
}
Output on both DMD 2.111 and master:
$ dmd -run test.d
URVO: false
NRVO: false
No RVO: true
$ dmd -inline -run test.d
URVO: true
NRVO: false
No RVO: true
Adding an unused return statement changes the behavior, which is insane and prevents writing safe code IMO. I actually spent some time keeping the broken inliner behavior intact when working on the inliner.