KT-5863: Inlined try/catch/finally block with non-local return doesn't work properly
#KT-5863 Fixed
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
+6
@@ -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");
|
||||
|
||||
+6
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user