Control-Flow: Generate instruction for left-hand side of invalid assignments

#KT-8390 Fixed
This commit is contained in:
Alexey Sedunov
2015-07-10 02:33:08 +03:00
parent d2dc44379e
commit df07a61a08
8 changed files with 43 additions and 39 deletions
@@ -585,7 +585,15 @@ public class JetControlFlowProcessor {
accessTarget = getDeclarationAccessTarget(left);
}
recordWrite(left, accessTarget, rhsDeferredValue.invoke(), receiverValues, parentExpression);
if (accessTarget == AccessTarget.BlackBox.INSTANCE$ && !(left instanceof JetProperty)) {
generateInstructions(left);
createSyntheticValue(left, MagicKind.VALUE_CONSUMER, left);
}
PseudoValue rightValue = rhsDeferredValue.invoke();
PseudoValue rValue =
rightValue != null ? rightValue : createSyntheticValue(parentExpression, MagicKind.UNRECOGNIZED_WRITE_RHS);
builder.write(parentExpression, left, rValue, accessTarget, receiverValues);
}
private void generateArrayAssignment(
@@ -663,24 +671,6 @@ public class JetControlFlowProcessor {
return argumentValues;
}
private void recordWrite(
@NotNull JetExpression left,
@NotNull AccessTarget target,
@Nullable PseudoValue rightValue,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues,
@NotNull JetExpression parentExpression
) {
if (target == AccessTarget.BlackBox.INSTANCE$) {
List<PseudoValue> values = ContainerUtil.createMaybeSingletonList(rightValue);
builder.magic(parentExpression, parentExpression, values, defaultTypeMap(values), MagicKind.UNSUPPORTED_ELEMENT);
}
else {
PseudoValue rValue =
rightValue != null ? rightValue : createSyntheticValue(parentExpression, MagicKind.UNRECOGNIZED_WRITE_RHS);
builder.write(parentExpression, left, rValue, target, receiverValues);
}
}
private void generateArrayAccess(JetArrayAccessExpression arrayAccessExpression, @Nullable ResolvedCall<?> resolvedCall) {
if (builder.getBoundValue(arrayAccessExpression) != null) return;
mark(arrayAccessExpression);
@@ -9,12 +9,14 @@ L0:
magic[FAKE_INITIALIZER](c: C) -> <v0>
w(c|<v0>)
2 mark({ this = c })
r(c) -> <v1>
magic[UNSUPPORTED_ELEMENT](this = c|<v1>) -> <v2>
r(this, <this>) -> <v1>
magic[VALUE_CONSUMER](this|<v1>) -> <v2>
r(c) -> <v3>
w(this|<v3>)
L1:
1 <END> NEXT:[<SINK>]
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
<SINK> PREV:[<ERROR>, <END>]
=====================
+6 -3
View File
@@ -4,7 +4,10 @@ fun Int.bar(c: C) {
}
---------------------
<v0>: {<: [ERROR : C]} NEW: magic[FAKE_INITIALIZER](c: C) -> <v0>
c <v1>: * NEW: r(c) -> <v1>
this = c <v2>: * NEW: magic[UNSUPPORTED_ELEMENT](this = c|<v1>) -> <v2>
{ this = c } <v2>: * COPY
<v2>: * NEW: magic[VALUE_CONSUMER](this|<v1>) -> <v2>
this <v1>: * COPY
this <v1>: * NEW: r(this, <this>) -> <v1>
c <v3>: * NEW: r(c) -> <v3>
this = c !<v4>: *
{ this = c } !<v4>: * COPY
=====================
@@ -6,13 +6,15 @@ fun foo() {
L0:
1 <START>
2 mark({ x = "" })
magic[UNRESOLVED_CALL](x) -> <v0>
magic[VALUE_CONSUMER](x|<v0>) -> <v1>
mark("")
r("") -> <v0>
magic[UNSUPPORTED_ELEMENT](x = ""|<v0>) -> <v1>
r("") -> <v2>
w(x|<v2>)
L1:
1 <END> NEXT:[<SINK>]
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -3,7 +3,9 @@ fun foo() {
x = ""
}
---------------------
"" <v0>: * NEW: r("") -> <v0>
x = "" <v1>: * NEW: magic[UNSUPPORTED_ELEMENT](x = ""|<v0>) -> <v1>
{ x = "" } <v1>: * COPY
<v1>: * NEW: magic[VALUE_CONSUMER](x|<v0>) -> <v1>
x <v0>: * NEW: magic[UNRESOLVED_CALL](x) -> <v0>
"" <v2>: * NEW: r("") -> <v2>
x = "" !<v3>: *
{ x = "" } !<v3>: * COPY
=====================
+2 -2
View File
@@ -39,7 +39,7 @@ class D() {
fun foo(): Unit {}
fun cannotBe() {
var <!UNUSED_VARIABLE!>i<!>: Int = 5
var i: Int = 5
<!UNRESOLVED_REFERENCE!>z<!> = 30;
<!VARIABLE_EXPECTED!>""<!> = "";
@@ -135,4 +135,4 @@ fun Array<Int>.checkThis() {
abstract class Ab {
abstract fun getArray() : Array<Int>
}
}
@@ -26,3 +26,7 @@ fun get(p: Any) {
fun set(p: Any) {
}
fun foo(s: String) {
s.<!UNRESOLVED_REFERENCE!>xxx<!> = 1
}
@@ -1,6 +1,7 @@
package
internal fun f(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int, /*2*/ c: kotlin.Int = ...): kotlin.Unit
internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
internal fun get(/*0*/ p: kotlin.Any): kotlin.Unit
internal fun set(/*0*/ p: kotlin.Any): kotlin.Unit
internal fun kotlin.Any.get(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.PropertyMetadata): kotlin.String