KT-5863: Inlined try/catch/finally block with non-local return doesn't work properly

#KT-5863 Fixed
This commit is contained in:
Michael Bogdanov
2014-09-26 11:03:19 +04:00
parent bf368b2bc2
commit b3e075173b
5 changed files with 35 additions and 3 deletions
@@ -354,7 +354,7 @@ public class MethodInliner {
AbstractInsnNode cur = node.instructions.getFirst();
int index = 0;
Set<LabelNode> deadLabels = new HashSet<LabelNode>();
Set<LabelNode> possibleDeadLabels = new HashSet<LabelNode>();
while (cur != null) {
Frame<SourceValue> frame = sources[index];
@@ -414,10 +414,15 @@ public class MethodInliner {
if (frame == null) {
//clean dead code otherwise there is problems in unreachable finally block, don't touch label it cause try/catch/finally problems
if (prevNode.getType() == AbstractInsnNode.LABEL) {
deadLabels.add((LabelNode) prevNode);
possibleDeadLabels.add((LabelNode) prevNode);
} else {
node.instructions.remove(prevNode);
}
} else {
//Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
//but as result all this labels will be merged into one (see KT-5863)
possibleDeadLabels.remove(prevNode.getPrevious());
}
}
@@ -425,7 +430,7 @@ public class MethodInliner {
List<TryCatchBlockNode> blocks = node.tryCatchBlocks;
for (Iterator<TryCatchBlockNode> iterator = blocks.iterator(); iterator.hasNext(); ) {
TryCatchBlockNode block = iterator.next();
if (deadLabels.contains(block.start) && deadLabels.contains(block.end)) {
if (possibleDeadLabels.contains(block.start) && possibleDeadLabels.contains(block.end)) {
iterator.remove();
}
}
@@ -0,0 +1,6 @@
inline fun test2Inline() = performWithFinally { "OK" }
fun box(): String {
return test2Inline()
}
@@ -0,0 +1,9 @@
inline fun <R> performWithFinally(finally: () -> R) : R {
try {
throw RuntimeException("1")
} catch (e: RuntimeException) {
throw RuntimeException("2")
} finally {
return finally()
}
}
@@ -745,6 +745,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxCodegenT
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/tryCatchFinally"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("kt5863.1.kt")
public void testKt5863() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/tryCatchFinally/kt5863.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("tryCatch.1.kt")
public void testTryCatch() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/tryCatchFinally/tryCatch.1.kt");
@@ -745,6 +745,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/tryCatchFinally"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("kt5863.1.kt")
public void testKt5863() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/tryCatchFinally/kt5863.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("tryCatch.1.kt")
public void testTryCatch() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/tryCatchFinally/tryCatch.1.kt");