Control-Flow Analysis: Do not skip pseudocode for value arguments if they are matched with errors

This commit is contained in:
Alexey Sedunov
2016-11-02 15:33:41 +03:00
parent df38c70278
commit 0159ddbc49
6 changed files with 101 additions and 3 deletions
@@ -459,9 +459,7 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
val rhsArgument = valueArguments.lastOrNull()
var argumentValues = SmartFMap.emptyMap<PseudoValue, ValueParameterDescriptor>()
for (valueArgument in valueArguments) {
val argumentMapping = setResolvedCall.getArgumentMapping(valueArgument)
if (argumentMapping.isError() || argumentMapping !is ArgumentMatch) continue
val argumentMapping = setResolvedCall.getArgumentMapping(valueArgument) as? ArgumentMatch ?: continue
val parameterDescriptor = argumentMapping.valueParameter
if (valueArgument !== rhsArgument) {
argumentValues = generateValueArgument(valueArgument, parameterDescriptor, argumentValues)
@@ -0,0 +1,56 @@
== A ==
class A
---------------------
L0:
1 <START>
L1:
<END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
== set ==
fun A.set(n: Int, m: Int) {
}
---------------------
L0:
1 <START>
v(n: Int)
magic[FAKE_INITIALIZER](n: Int) -> <v0>
w(n|<v0>)
v(m: Int)
magic[FAKE_INITIALIZER](m: Int) -> <v1>
w(m|<v1>)
2 mark({ })
read (Unit)
L1:
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
== test ==
fun test() {
A()["1"] = 2
}
---------------------
L0:
1 <START>
2 mark({ A()["1"] = 2 })
mark(A()["1"])
mark(A())
call(A(), <init>) -> <v0>
mark("1")
r("1") -> <v1>
r(2) -> <v2>
call(A()["1"] = 2, set|<v0>, <v1>, <v2>) -> <v3>
L1:
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
+9
View File
@@ -0,0 +1,9 @@
class A
fun A.set(n: Int, m: Int) {
}
fun test() {
A()["1"] = 2
}
+23
View File
@@ -0,0 +1,23 @@
== A ==
class A
---------------------
=====================
== set ==
fun A.set(n: Int, m: Int) {
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](n: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](m: Int) -> <v1>
=====================
== test ==
fun test() {
A()["1"] = 2
}
---------------------
A() <v0>: A NEW: call(A(), <init>) -> <v0>
"1" <v1>: Int NEW: r("1") -> <v1>
2 <v2>: Int NEW: r(2) -> <v2>
A()["1"] = 2 <v3>: * NEW: call(A()["1"] = 2, set|<v0>, <v1>, <v2>) -> <v3>
{ A()["1"] = 2 } <v3>: * COPY
=====================
@@ -156,6 +156,12 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/bugs/kt7761.kt");
doTest(fileName);
}
@TestMetadata("setWithTypeMismatch.kt")
public void testSetWithTypeMismatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/bugs/setWithTypeMismatch.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/cfg/controlStructures")
@@ -158,6 +158,12 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/bugs/kt7761.kt");
doTest(fileName);
}
@TestMetadata("setWithTypeMismatch.kt")
public void testSetWithTypeMismatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/bugs/setWithTypeMismatch.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/cfg/controlStructures")