[FIR] Ignore CFA-only edges in DFA even if they are dead
^KT-53920 Fixed
This commit is contained in:
committed by
Space Team
parent
0eb34983cb
commit
fa9f0bcf84
+6
@@ -1075,6 +1075,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("anonymousObjectInUnreachableCode.kt")
|
||||||
|
public void testAnonymousObjectInUnreachableCode() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/anonymousObjectInUnreachableCode.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("binaryOperations.kt")
|
@TestMetadata("binaryOperations.kt")
|
||||||
public void testBinaryOperations() throws Exception {
|
public void testBinaryOperations() throws Exception {
|
||||||
|
|||||||
+5
@@ -931,6 +931,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("anonymousObjectInUnreachableCode.kt")
|
||||||
|
public void testAnonymousObjectInUnreachableCode() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/anonymousObjectInUnreachableCode.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("binaryOperations.kt")
|
@TestMetadata("binaryOperations.kt")
|
||||||
public void testBinaryOperations() throws Exception {
|
public void testBinaryOperations() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/binaryOperations.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/binaryOperations.kt");
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
FILE: anonymousObjectInUnreachableCode.kt
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
^test Unit
|
||||||
|
object : R|kotlin/Any| {
|
||||||
|
private constructor(): R|<anonymous>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// ISSUE: KT-53920
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
return
|
||||||
|
object {}
|
||||||
|
}
|
||||||
+6
@@ -1075,6 +1075,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("anonymousObjectInUnreachableCode.kt")
|
||||||
|
public void testAnonymousObjectInUnreachableCode() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/anonymousObjectInUnreachableCode.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("binaryOperations.kt")
|
@TestMetadata("binaryOperations.kt")
|
||||||
public void testBinaryOperations() throws Exception {
|
public void testBinaryOperations() throws Exception {
|
||||||
|
|||||||
+6
@@ -1075,6 +1075,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("anonymousObjectInUnreachableCode.kt")
|
||||||
|
public void testAnonymousObjectInUnreachableCode() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/anonymousObjectInUnreachableCode.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("binaryOperations.kt")
|
@TestMetadata("binaryOperations.kt")
|
||||||
public void testBinaryOperations() throws Exception {
|
public void testBinaryOperations() throws Exception {
|
||||||
|
|||||||
+4
-5
@@ -355,7 +355,6 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun exitAnonymousObject(anonymousObject: FirAnonymousObject): ControlFlowGraph {
|
fun exitAnonymousObject(anonymousObject: FirAnonymousObject): ControlFlowGraph {
|
||||||
// TODO: support capturing of mutable properties, KT-44877
|
|
||||||
val (node, controlFlowGraph) = graphBuilder.exitAnonymousObject(anonymousObject)
|
val (node, controlFlowGraph) = graphBuilder.exitAnonymousObject(anonymousObject)
|
||||||
node.mergeIncomingFlow()
|
node.mergeIncomingFlow()
|
||||||
return controlFlowGraph
|
return controlFlowGraph
|
||||||
@@ -1555,13 +1554,13 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
var deadForwardCount = 0
|
var deadForwardCount = 0
|
||||||
for (previousNode in previousNodes) {
|
for (previousNode in previousNodes) {
|
||||||
val incomingEdgeKind = incomingEdges.getValue(previousNode).kind
|
val incomingEdgeKind = incomingEdges.getValue(previousNode).kind
|
||||||
if (isDead) {
|
|
||||||
if (!incomingEdgeKind.isBack) {
|
if (isDead && incomingEdgeKind.usedInDeadDfa) {
|
||||||
previousFlows += previousNode.flow
|
previousFlows += previousNode.flow
|
||||||
}
|
|
||||||
} else if (incomingEdgeKind.usedInDfa) {
|
} else if (incomingEdgeKind.usedInDfa) {
|
||||||
previousFlows += previousNode.flow
|
previousFlows += previousNode.flow
|
||||||
}
|
}
|
||||||
|
|
||||||
if (incomingEdgeKind == EdgeKind.DeadForward) {
|
if (incomingEdgeKind == EdgeKind.DeadForward) {
|
||||||
deadForwardCount++
|
deadForwardCount++
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-7
@@ -157,17 +157,18 @@ class ReturnPath(
|
|||||||
) : EdgeLabel(label = "\"return@${returnTargetSymbol.callableId}\"")
|
) : EdgeLabel(label = "\"return@${returnTargetSymbol.callableId}\"")
|
||||||
|
|
||||||
enum class EdgeKind(
|
enum class EdgeKind(
|
||||||
val usedInDfa: Boolean,
|
val usedInDfa: Boolean, // propagate flow to alive nodes
|
||||||
|
val usedInDeadDfa: Boolean, // propagate flow to dead nodes
|
||||||
val usedInCfa: Boolean,
|
val usedInCfa: Boolean,
|
||||||
val isBack: Boolean,
|
val isBack: Boolean,
|
||||||
val isDead: Boolean
|
val isDead: Boolean
|
||||||
) {
|
) {
|
||||||
Forward(usedInDfa = true, usedInCfa = true, isBack = false, isDead = false),
|
Forward(usedInDfa = true, usedInDeadDfa = true, usedInCfa = true, isBack = false, isDead = false),
|
||||||
DeadForward(usedInDfa = false, usedInCfa = true, isBack = false, isDead = true),
|
DeadForward(usedInDfa = false, usedInDeadDfa = true, usedInCfa = true, isBack = false, isDead = true),
|
||||||
DfgForward(usedInDfa = true, usedInCfa = false, isBack = false, isDead = false),
|
DfgForward(usedInDfa = true, usedInDeadDfa = true, usedInCfa = false, isBack = false, isDead = false),
|
||||||
CfgForward(usedInDfa = false, usedInCfa = true, isBack = false, isDead = false),
|
CfgForward(usedInDfa = false, usedInDeadDfa = false, usedInCfa = true, isBack = false, isDead = false),
|
||||||
CfgBackward(usedInDfa = false, usedInCfa = true, isBack = true, isDead = false),
|
CfgBackward(usedInDfa = false, usedInDeadDfa = false, usedInCfa = true, isBack = true, isDead = false),
|
||||||
DeadBackward(usedInDfa = false, usedInCfa = true, isBack = true, isDead = true)
|
DeadBackward(usedInDfa = false, usedInDeadDfa = false, usedInCfa = true, isBack = true, isDead = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalStdlibApi::class)
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
|||||||
Reference in New Issue
Block a user