[Chapel Merge] Avoid double-deinit upon throws from a forall loop

Branch: refs/heads/main
Revision: 7a870bd
Author: vasslitvinov
Link: Avoid double-deinit upon throws from a forall loop by vasslitvinov · Pull Request #19479 · chapel-lang/chapel · GitHub
Log Message:

Merge pull request #19479 from vasslitvinov/error-double-delete

Avoid double-deinit upon throws from a forall loop

Resolves #18773.

This PR changes the iterator deinitialization actions performed upon a yield
when the yield occurs inside a forall. Formerly these actions included
everything needed to be deinitialized upon returning from the iterator.
Now they include everything upon exiting the forall loop. The impact is
observable when the loop that is using the iterator throws exceptions
in multiple tasks. Before the iterator variables outside the forall loop
would be deinitialized by each task, i.e., multiple times. Now they are
deinitialized just once after the forall loop completed. In this example:

iterator IT() { // assume it is the standalone iterator
  var D: domain(1);
  forall i in IT2() {
yield i;
  }
  writeln();
}

forall idx in IT() {
  throwingFunction();
}

the forall loop would be lowered into:

var D: domain(1)
forall i in IT2() {
  throwingFunction();
  if it threw an error {
deinit D;
goto end_IT;
  }
}
writeln();
deinit D;
end_IT:;

now it is lowered into:

var D: domain(1)
forall i in IT2() {
  throwingFunction();
  if it threw an error {
goto forall_IBB_break_label;
  }
}
forall_IBB_break_label:
if there was an error {
  deinit D;
  goto end_IT;
}
deinit D;
writeln();
end_IT:;

Note: this PR defuturizes a test that now leaks memory.
This test is from #18773. Prior to this PR it had invalid memory accesses.
This PR adds a prediff to squash the output of --memLeaks for this test.
test/errhandling/parallel/forall-calls-throwing-fn2.chpl

r: @mppf

Modified Files:
A test/errhandling/parallel/forall-calls-throwing-fn2.prediff

R test/errhandling/parallel/forall-calls-throwing-fn2.future
R test/errhandling/parallel/forall-calls-throwing-fn2.skipif
M compiler/AST/iterator.cpp
M compiler/include/errorHandling.h
M compiler/passes/errorHandling.cpp
M compiler/resolution/lowerIterators.cpp

Compare: https://github.com/chapel-lang/chapel/compare/e728af4b7be8...7a870bd8f485