diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2016-11-08 11:58:01 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2016-11-08 11:58:01 +0100 |
commit | f297ca8d1f06086316ff3746250092e36ef9f74e (patch) | |
tree | 90755ce5098f1f6fee54d7611ae24311646a0822 /test/files/run/t10032.check | |
parent | 10c609e750a7089055b126e6231e5ddb2f2e8623 (diff) | |
download | scala-f297ca8d1f06086316ff3746250092e36ef9f74e.tar.gz scala-f297ca8d1f06086316ff3746250092e36ef9f74e.tar.bz2 scala-f297ca8d1f06086316ff3746250092e36ef9f74e.zip |
SI-10032 Fix code gen with returns in nested try-finally blocks
Return statements within `try` or `catch` blocks need special treatement
if there's also a `finally`
try { return 1 } finally { println() }
For the return, the code generator emits a store to a local and a jump
to a "cleanup" version of the finally block. There will be 3 versions
of the finally block:
- One reached through a handler, if the code in the try block
throws; re-throws at the end
- A "cleanup" version reached from returns within the try; reads the
local and returns the value at the end
- One reached for ordinary control flow, if there's no return and no
exception within the try
If there are multiple enclosing finally blocks, a "cleanup" version is
emitted for each of them. The nested ones jump to the enclosing ones,
the outermost one reads the local and returns.
A global variable `shouldEmitCleanup` stores whether cleanup versions
are required for the curren finally blocks. By mistake, this variable
was not reset to `false` when emitting a `try-finally` nested within a
`finally`:
try {
try { return 1 }
finally { println() } // need cleanup version
} finally { // need cleanup version
try { println() }
finally { println() } // no cleanup version needed!
}
In this commit we ensure that the variable is reset when emitting
nested `try-finally` blocks.
Diffstat (limited to 'test/files/run/t10032.check')
-rw-r--r-- | test/files/run/t10032.check | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/test/files/run/t10032.check b/test/files/run/t10032.check new file mode 100644 index 0000000000..c8f0bdf034 --- /dev/null +++ b/test/files/run/t10032.check @@ -0,0 +1,49 @@ +t10032.scala:72: warning: Return statement found in finally-clause, discarding its return-value in favor of that of a more deeply nested return. + finally { return i2 } + ^ +t1 + i1 + a1 +t2 + i1 + a1 + a2 + a3 +t3 + i1 + a1 + a3 +t3 + e1 + a1 + i2 + a2 + a3 +t4 + i1 + i2 +t5 + i1 + a1 + a3 +t5 + e1 + a1 + i2 + a3 +t6 + i1 + i2 + i3 +t7 + i1 + a1 +t7 + e1 + i2 + a1 +t8 + i1 + i2 + a1 + a2 |