From 0159ddbc499421bf9b480d08839b5680d42f919b Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 2 Nov 2016 15:33:41 +0300 Subject: [PATCH] Control-Flow Analysis: Do not skip pseudocode for value arguments if they are matched with errors --- .../kotlin/cfg/ControlFlowProcessor.kt | 4 +- .../cfg/bugs/setWithTypeMismatch.instructions | 56 +++++++++++++++++++ .../testData/cfg/bugs/setWithTypeMismatch.kt | 9 +++ .../cfg/bugs/setWithTypeMismatch.values | 23 ++++++++ .../kotlin/cfg/ControlFlowTestGenerated.java | 6 ++ .../kotlin/cfg/PseudoValueTestGenerated.java | 6 ++ 6 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/cfg/bugs/setWithTypeMismatch.instructions create mode 100644 compiler/testData/cfg/bugs/setWithTypeMismatch.kt create mode 100644 compiler/testData/cfg/bugs/setWithTypeMismatch.values diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt index e16ce3c408c..9a42dc76e6b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt @@ -459,9 +459,7 @@ class ControlFlowProcessor(private val trace: BindingTrace) { val rhsArgument = valueArguments.lastOrNull() var argumentValues = SmartFMap.emptyMap() 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) diff --git a/compiler/testData/cfg/bugs/setWithTypeMismatch.instructions b/compiler/testData/cfg/bugs/setWithTypeMismatch.instructions new file mode 100644 index 00000000000..d0abe8d2368 --- /dev/null +++ b/compiler/testData/cfg/bugs/setWithTypeMismatch.instructions @@ -0,0 +1,56 @@ +== A == +class A +--------------------- +L0: + 1 +L1: + NEXT:[] +error: + PREV:[] +sink: + PREV:[, ] +===================== +== set == +fun A.set(n: Int, m: Int) { + +} +--------------------- +L0: + 1 + v(n: Int) + magic[FAKE_INITIALIZER](n: Int) -> + w(n|) + v(m: Int) + magic[FAKE_INITIALIZER](m: Int) -> + w(m|) + 2 mark({ }) + read (Unit) +L1: + 1 NEXT:[] +error: + PREV:[] +sink: + PREV:[, ] +===================== +== test == +fun test() { + A()["1"] = 2 +} +--------------------- +L0: + 1 + 2 mark({ A()["1"] = 2 }) + mark(A()["1"]) + mark(A()) + call(A(), ) -> + mark("1") + r("1") -> + r(2) -> + call(A()["1"] = 2, set|, , ) -> +L1: + 1 NEXT:[] +error: + PREV:[] +sink: + PREV:[, ] +===================== diff --git a/compiler/testData/cfg/bugs/setWithTypeMismatch.kt b/compiler/testData/cfg/bugs/setWithTypeMismatch.kt new file mode 100644 index 00000000000..6f33ba11e82 --- /dev/null +++ b/compiler/testData/cfg/bugs/setWithTypeMismatch.kt @@ -0,0 +1,9 @@ +class A + +fun A.set(n: Int, m: Int) { + +} + +fun test() { + A()["1"] = 2 +} \ No newline at end of file diff --git a/compiler/testData/cfg/bugs/setWithTypeMismatch.values b/compiler/testData/cfg/bugs/setWithTypeMismatch.values new file mode 100644 index 00000000000..a37d2d59491 --- /dev/null +++ b/compiler/testData/cfg/bugs/setWithTypeMismatch.values @@ -0,0 +1,23 @@ +== A == +class A +--------------------- +===================== +== set == +fun A.set(n: Int, m: Int) { + +} +--------------------- + : Int NEW: magic[FAKE_INITIALIZER](n: Int) -> + : Int NEW: magic[FAKE_INITIALIZER](m: Int) -> +===================== +== test == +fun test() { + A()["1"] = 2 +} +--------------------- +A() : A NEW: call(A(), ) -> +"1" : Int NEW: r("1") -> +2 : Int NEW: r(2) -> +A()["1"] = 2 : * NEW: call(A()["1"] = 2, set|, , ) -> +{ A()["1"] = 2 } : * COPY +===================== diff --git a/compiler/tests/org/jetbrains/kotlin/cfg/ControlFlowTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cfg/ControlFlowTestGenerated.java index 8cbfc851efb..6243e434868 100644 --- a/compiler/tests/org/jetbrains/kotlin/cfg/ControlFlowTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cfg/ControlFlowTestGenerated.java @@ -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") diff --git a/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java index 1379de24f51..ca6d6094a77 100644 --- a/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java @@ -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")