Control-Flow: Generate instruction for left-hand side of invalid assignments
#KT-8390 Fixed
This commit is contained in:
@@ -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>]
|
||||
=====================
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user