ControlFlowBuilder.getExitPoint() now can return null if nothing was found #KT-10823 Fixed
Also #EA-73355 Fixed
This commit is contained in:
@@ -39,7 +39,7 @@ interface ControlFlowBuilder {
|
||||
|
||||
fun exitLexicalScope(element: KtElement)
|
||||
|
||||
fun getExitPoint(labelElement: KtElement): Label
|
||||
fun getExitPoint(labelElement: KtElement): Label?
|
||||
fun getConditionEntryPoint(labelElement: KtElement): Label
|
||||
|
||||
// Declarations
|
||||
|
||||
@@ -123,7 +123,7 @@ abstract class ControlFlowBuilderAdapter : ControlFlowBuilder {
|
||||
delegateBuilder.throwException(throwExpression, thrownValue)
|
||||
}
|
||||
|
||||
override fun getExitPoint(labelElement: KtElement): Label {
|
||||
override fun getExitPoint(labelElement: KtElement): Label? {
|
||||
return delegateBuilder.getExitPoint(labelElement)
|
||||
}
|
||||
|
||||
|
||||
@@ -785,7 +785,7 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
||||
val loop = getCorrespondingLoop(expression)
|
||||
if (loop != null) {
|
||||
checkJumpDoesNotCrossFunctionBoundary(expression, loop)
|
||||
builder.jump(builder.getExitPoint(loop), expression)
|
||||
builder.getExitPoint(loop)?.let { builder.jump(it, expression) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -171,9 +171,9 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
||||
return (blockInfo as LoopInfo).conditionEntryPoint
|
||||
}
|
||||
|
||||
override fun getExitPoint(labelElement: KtElement): Label {
|
||||
val blockInfo = elementToBlockInfo[labelElement] ?: error(labelElement.text)
|
||||
return blockInfo.exitPoint
|
||||
override fun getExitPoint(labelElement: KtElement): Label? {
|
||||
// It's quite possible to have null here, e.g. for non-local returns (see KT-10823)
|
||||
return elementToBlockInfo[labelElement]?.exitPoint
|
||||
}
|
||||
|
||||
private val currentScope: LexicalScope
|
||||
@@ -217,7 +217,7 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
||||
}
|
||||
|
||||
override fun exitSubroutine(subroutine: KtElement): Pseudocode {
|
||||
bindLabel(getExitPoint(subroutine))
|
||||
getExitPoint(subroutine)?.let { bindLabel(it) }
|
||||
pseudocode.addExitInstruction(SubroutineExitInstruction(subroutine, currentScope, false))
|
||||
bindLabel(error)
|
||||
pseudocode.addErrorInstruction(SubroutineExitInstruction(subroutine, currentScope, true))
|
||||
@@ -245,13 +245,13 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
||||
}
|
||||
|
||||
override fun returnValue(returnExpression: KtExpression, returnValue: PseudoValue, subroutine: KtElement) {
|
||||
val exitPoint = getExitPoint(subroutine)
|
||||
val exitPoint = getExitPoint(subroutine) ?: return
|
||||
handleJumpInsideTryFinally(exitPoint)
|
||||
add(ReturnValueInstruction(returnExpression, currentScope, exitPoint, returnValue))
|
||||
}
|
||||
|
||||
override fun returnNoValue(returnExpression: KtReturnExpression, subroutine: KtElement) {
|
||||
val exitPoint = getExitPoint(subroutine)
|
||||
val exitPoint = getExitPoint(subroutine) ?: return
|
||||
handleJumpInsideTryFinally(exitPoint)
|
||||
add(ReturnNoValueInstruction(returnExpression, currentScope, exitPoint))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
fun find2(): Any? {
|
||||
fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find2 element<!>
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// For find(): AssertionError at ControlFlowInstructionsGeneratorWorker.getExitPoint()
|
||||
|
||||
fun find(): Any? {
|
||||
object : Any() {
|
||||
fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find element<!>
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun find4(): Any? {
|
||||
<!NOT_YET_SUPPORTED_IN_INLINE!>inline fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find4 element<!>
|
||||
}<!>
|
||||
return null
|
||||
}
|
||||
|
||||
fun find3(): Any? {
|
||||
object : Any() {
|
||||
<!NOTHING_TO_INLINE!>inline<!> fun visit(element: Any) {
|
||||
<!RETURN_NOT_ALLOWED!>return@find3 element<!>
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package
|
||||
|
||||
public fun find(): kotlin.Any?
|
||||
public fun find2(): kotlin.Any?
|
||||
public fun find3(): kotlin.Any?
|
||||
public fun find4(): kotlin.Any?
|
||||
@@ -2889,6 +2889,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt10823.kt")
|
||||
public void testKt10823() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt10823.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1156.kt")
|
||||
public void testKt1156() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt1156.kt");
|
||||
|
||||
Reference in New Issue
Block a user