From 28acbcb2197d5d58b9960f4221d17042a30d2215 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 3 Dec 2013 18:08:51 +0400 Subject: [PATCH] Using call for set on an indexed expression in lvalue position --- .../jet/lang/cfg/JetControlFlowProcessor.java | 14 +++++++---- .../testData/cfg/ArrayAccess.instructions | 7 +++--- .../cfg/arraySetPlusAssign.instructions | 25 +++++++++++++++++++ compiler/testData/cfg/arraySetPlusAssign.kt | 3 +++ .../jet/cfg/ControlFlowTestGenerated.java | 5 ++++ 5 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/cfg/arraySetPlusAssign.instructions create mode 100644 compiler/testData/cfg/arraySetPlusAssign.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index 850fd2a0477..abae820b925 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -352,7 +352,8 @@ public class JetControlFlowProcessor { } if (left instanceof JetArrayAccessExpression) { - generateArrayAccess((JetArrayAccessExpression) left); + ResolvedCall setResolvedCall = trace.get(BindingContext.INDEXED_LVALUE_SET, left); + generateArrayAccess((JetArrayAccessExpression) left, setResolvedCall); recordWrite(left, parentExpression); return; } @@ -382,8 +383,8 @@ public class JetControlFlowProcessor { } } - private void generateArrayAccess(JetArrayAccessExpression arrayAccessExpression) { - if (!generateCall(arrayAccessExpression)) { + private void generateArrayAccess(JetArrayAccessExpression arrayAccessExpression, @Nullable ResolvedCall setResolvedCall) { + if (!checkAndGenerateCall(arrayAccessExpression, setResolvedCall)) { for (JetExpression index : arrayAccessExpression.getIndexExpressions()) { generateInstructions(index, false); } @@ -859,7 +860,7 @@ public class JetControlFlowProcessor { @Override public void visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression) { if (!generateCall(expression)) { - generateArrayAccess(expression); + generateArrayAccess(expression, getResolvedCall(expression)); } } @@ -1017,7 +1018,10 @@ public class JetControlFlowProcessor { } private boolean generateCall(JetExpression calleeExpression) { - ResolvedCall resolvedCall = getResolvedCall(calleeExpression); + return checkAndGenerateCall(calleeExpression, getResolvedCall(calleeExpression)); + } + + private boolean checkAndGenerateCall(JetExpression calleeExpression, @Nullable ResolvedCall resolvedCall) { if (resolvedCall == null) { builder.compilationError(calleeExpression, "No resolved call"); return false; diff --git a/compiler/testData/cfg/ArrayAccess.instructions b/compiler/testData/cfg/ArrayAccess.instructions index 76cbbb0a89e..74b22740849 100644 --- a/compiler/testData/cfg/ArrayAccess.instructions +++ b/compiler/testData/cfg/ArrayAccess.instructions @@ -30,10 +30,11 @@ L0: r(1) NEXT:[call(+=, plus)] PREV:[call(a[10], get)] call(+=, plus) NEXT:[r(a)] PREV:[r(1)] r(a) NEXT:[r(10)] PREV:[call(+=, plus)] - r(10) NEXT:[call(a[10], set)] PREV:[r(a)] - call(a[10], get) NEXT:[] PREV:[r(10)] + r(10) NEXT:[r(1)] PREV:[r(a)] + r(1) NEXT:[call(a[10], set)] PREV:[r(10)] + call(a[10], set) NEXT:[] PREV:[r(1)] L1: - NEXT:[] PREV:[call(a[10], get)] + NEXT:[] PREV:[call(a[10], set)] error: NEXT:[] PREV:[] sink: diff --git a/compiler/testData/cfg/arraySetPlusAssign.instructions b/compiler/testData/cfg/arraySetPlusAssign.instructions new file mode 100644 index 00000000000..83ecd8180a5 --- /dev/null +++ b/compiler/testData/cfg/arraySetPlusAssign.instructions @@ -0,0 +1,25 @@ +== foo == +fun foo(a: Array) { + a[0] += 1 +} +--------------------- +L0: + NEXT:[v(a: Array)] PREV:[] + v(a: Array) NEXT:[w(a)] PREV:[] + w(a) NEXT:[r(a)] PREV:[v(a: Array)] + r(a) NEXT:[r(0)] PREV:[w(a)] + r(0) NEXT:[call(a[0], get)] PREV:[r(a)] + call(a[0], get) NEXT:[r(1)] PREV:[r(0)] + r(1) NEXT:[call(+=, plus)] PREV:[call(a[0], get)] + call(+=, plus) NEXT:[r(a)] PREV:[r(1)] + r(a) NEXT:[r(0)] PREV:[call(+=, plus)] + r(0) NEXT:[r(1)] PREV:[r(a)] + r(1) NEXT:[call(a[0], set)] PREV:[r(0)] + call(a[0], set) NEXT:[] PREV:[r(1)] +L1: + NEXT:[] PREV:[call(a[0], set)] +error: + NEXT:[] PREV:[] +sink: + NEXT:[] PREV:[, ] +===================== diff --git a/compiler/testData/cfg/arraySetPlusAssign.kt b/compiler/testData/cfg/arraySetPlusAssign.kt new file mode 100644 index 00000000000..2afef4b774f --- /dev/null +++ b/compiler/testData/cfg/arraySetPlusAssign.kt @@ -0,0 +1,3 @@ +fun foo(a: Array) { + a[0] += 1 +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java b/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java index bd039da6a13..5c2a32dab38 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java @@ -56,6 +56,11 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest { doTest("compiler/testData/cfg/arraySet.kt"); } + @TestMetadata("arraySetPlusAssign.kt") + public void testArraySetPlusAssign() throws Exception { + doTest("compiler/testData/cfg/arraySetPlusAssign.kt"); + } + @TestMetadata("Assignments.kt") public void testAssignments() throws Exception { doTest("compiler/testData/cfg/Assignments.kt");