28469, "DanilaFe", "[Bug]: copy-elision doesn't consider 'deferred' statements properly", "2026-02-27T20:57:52Z"
As far as I can tell:
When doing copy elision, we do not treat defer with any special understanding of its semantics. Thus, the defer block is considered a "regular" statement. During the same pass, we lower defer statements (inserting them at the end of the control flow). At this point, subsequent analyses can be confused by the results of copy elision, since variable mentions in the defer block, which were previously followed by the elided copies, now come AFTER the eliding copies. This leads to add errors, like this:
class MyClass2 {}
proc foo() {
var a = new shared MyClass2();
defer {
writeln(a);
}
var b = a;
return;
}
foo();
tmpdebug.chpl:3: In function 'foo':
tmpdebug.chpl:6: error: Illegal use of dead value
tmpdebug.chpl:8: note: 'a' is dead due to copy elision here
The real answer is that the above code is not eligible for copy-elision. This is because the last use of a is a mention, not a copy. I think a relatively straightforward change to doFindCopyElisionPoints in splitInit.cpp can fix this.