diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/Pseudocode.java b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/Pseudocode.java index fb206a7b945..561f97f594f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/Pseudocode.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/Pseudocode.java @@ -66,4 +66,6 @@ public interface Pseudocode { List getUsages(@Nullable PseudoValue value); boolean isSideEffectFree(@NotNull Instruction instruction); + + Pseudocode copy(); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/PseudocodeImpl.java b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/PseudocodeImpl.java index 533507e75aa..91aa44a7055 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/PseudocodeImpl.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/PseudocodeImpl.java @@ -458,6 +458,41 @@ public class PseudocodeImpl implements Pseudocode { return mutableInstructionList.get(targetPosition); } + @Override + public PseudocodeImpl copy() { + PseudocodeImpl result = new PseudocodeImpl(correspondingElement); + result.repeatWhole(this); + return result; + } + + private void repeatWhole(PseudocodeImpl originalPseudocode) { + Map originalToCopy = Maps.newLinkedHashMap(); + Multimap originalLabelsForInstruction = HashMultimap.create(); + int labelCount = 0; + for (PseudocodeLabel label : originalPseudocode.labels) { + originalToCopy.put(label, label.copy(labelCount++)); + originalLabelsForInstruction.put(getJumpTarget(label), label); + } + for (Label label : originalToCopy.values()) { + labels.add((PseudocodeLabel) label); + } + for (Instruction originalInstruction : originalPseudocode.mutableInstructionList) { + repeatLabelsBindingForInstruction(originalInstruction, originalToCopy, originalLabelsForInstruction); + Instruction copy = copyInstruction(originalInstruction, originalToCopy); + addInstruction(copy); + if (originalInstruction == originalPseudocode.errorInstruction && copy instanceof SubroutineExitInstruction) { + errorInstruction = (SubroutineExitInstruction) copy; + } + if (originalInstruction == originalPseudocode.exitInstruction && copy instanceof SubroutineExitInstruction) { + exitInstruction = (SubroutineExitInstruction) copy; + } + if (originalInstruction == originalPseudocode.sinkInstruction && copy instanceof SubroutineSinkInstruction) { + sinkInstruction = (SubroutineSinkInstruction) copy; + } + } + parent = originalPseudocode.parent; + } + public int repeatPart(@NotNull Label startLabel, @NotNull Label finishLabel, int labelCount) { PseudocodeImpl originalPseudocode = ((PseudocodeLabel) startLabel).getPseudocode(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/LocalFunctionDeclarationInstruction.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/LocalFunctionDeclarationInstruction.kt index f923aa57cce..8069f779ece 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/LocalFunctionDeclarationInstruction.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/LocalFunctionDeclarationInstruction.kt @@ -57,5 +57,5 @@ public class LocalFunctionDeclarationInstruction( override fun toString(): String = "d(${render(element)})" override fun createCopy(): InstructionImpl = - LocalFunctionDeclarationInstruction(element, body, lexicalScope) + LocalFunctionDeclarationInstruction(element, body.copy(), lexicalScope) } diff --git a/compiler/testData/diagnostics/tests/regressions/kt10243.kt b/compiler/testData/diagnostics/tests/regressions/kt10243.kt new file mode 100644 index 00000000000..fd5c9d63067 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/kt10243.kt @@ -0,0 +1,16 @@ +val f: Boolean = true +private fun doUpdateRegularTasks() { + try { + while (f) { + val xmlText = getText() + if (xmlText == null) {} + else { + xmlText.value = 0 // !!! + } + } + + } + finally { + fun execute() {} + } +} diff --git a/compiler/testData/diagnostics/tests/regressions/kt10243.txt b/compiler/testData/diagnostics/tests/regressions/kt10243.txt new file mode 100644 index 00000000000..ef3ec620e55 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/kt10243.txt @@ -0,0 +1,4 @@ +package + +public val f: kotlin.Boolean = true +private fun doUpdateRegularTasks(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index ea17b9bd5be..f0aec570e1b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -12552,6 +12552,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("kt10243.kt") + public void testKt10243() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/kt10243.kt"); + doTest(fileName); + } + @TestMetadata("kt127.kt") public void testKt127() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/kt127.kt");