FIR CFG: add one more test case

This commit is contained in:
pyos
2022-06-15 11:20:48 +02:00
committed by Dmitriy Novozhilov
parent 7d945d9bdc
commit 82731802ee
3 changed files with 153 additions and 2 deletions
@@ -339,4 +339,114 @@ digraph flowFromTwoInplaceLambdas_kt {
120 -> {94} [color=red];
120 -> {97} [color=green];
subgraph cluster_25 {
color=red
121 [label="Enter class I1" style="filled" fillcolor=red];
122 [label="Exit class I1" style="filled" fillcolor=red];
}
121 -> {122} [color=green];
subgraph cluster_26 {
color=red
123 [label="Enter class I2" style="filled" fillcolor=red];
124 [label="Exit class I2" style="filled" fillcolor=red];
}
123 -> {124} [color=green];
subgraph cluster_27 {
color=red
125 [label="Enter function test4" style="filled" fillcolor=red];
subgraph cluster_28 {
color=blue
126 [label="Enter block"];
127 [label="Access variable R|<local>/x|"];
128 [label="Access variable <Unresolved name: x>#"];
129 [label="Access variable R|<local>/x|"];
130 [label="Access variable <Unresolved name: y>#"];
131 [label="Postponed enter to lambda"];
subgraph cluster_29 {
color=blue
143 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_30 {
color=blue
144 [label="Enter block"];
145 [label="Access variable R|<local>/x|"];
146 [label="Type operator: (R|<local>/x| as R|I1|)"];
147 [label="Access variable R|<local>/x|"];
148 [label="Access variable <Unresolved name: y>#"];
149 [label="Function call: R|/n|<R|kotlin/Int?|>()"];
150 [label="Exit block"];
}
151 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
133 [label="Postponed exit from lambda"];
134 [label="Postponed enter to lambda"];
subgraph cluster_31 {
color=blue
152 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_32 {
color=blue
153 [label="Enter block"];
154 [label="Access variable R|<local>/x|"];
155 [label="Type operator: (R|<local>/x| as R|I2|)"];
156 [label="Access variable R|<local>/x|"];
157 [label="Access variable <Unresolved name: x>#"];
158 [label="Const: Int(123)"];
159 [label="Exit block"];
}
160 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
132 [label="Call arguments union" style="filled" fillcolor=yellow];
135 [label="Postponed exit from lambda"];
136 [label="Function call: R|/run2|<R|kotlin/Int?|>(...)"];
137 [label="Access variable R|<local>/x|"];
138 [label="Access variable R|/I1.x|"];
139 [label="Access variable R|<local>/x|"];
140 [label="Access variable R|/I2.y|"];
141 [label="Exit block"];
}
142 [label="Exit function test4" style="filled" fillcolor=red];
}
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {143};
131 -> {133} [color=red];
131 -> {143} [style=dashed];
132 -> {136} [color=red];
133 -> {134};
134 -> {152};
134 -> {135} [color=red];
134 -> {152} [style=dashed];
135 -> {136} [color=green];
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {147};
147 -> {148};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {132} [color=red];
151 -> {133} [color=green];
152 -> {153};
153 -> {154};
154 -> {155};
155 -> {156};
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {132} [color=red];
160 -> {135} [color=green];
}
@@ -61,3 +61,30 @@ FILE: flowFromTwoInplaceLambdas.kt
R|<local>/p|.<Inapplicable(UNSAFE_CALL): kotlin/String.length>#
R|<local>/p|?.{ $subj$.R|kotlin/String.length| }
}
public abstract interface I1 : R|kotlin/Any| {
public abstract val x: R|kotlin/Int|
public get(): R|kotlin/Int|
}
public abstract interface I2 : R|kotlin/Any| {
public abstract val y: R|kotlin/Int|
public get(): R|kotlin/Int|
}
public final fun test4(x: R|kotlin/Any?|): R|kotlin/Unit| {
R|<local>/x|.<Unresolved name: x>#
R|<local>/x|.<Unresolved name: y>#
R|/run2|<R|kotlin/Int?|>(run2@fun <anonymous>(): R|kotlin/Int?| <inline=NoInline, kind=EXACTLY_ONCE> {
(R|<local>/x| as R|I1|)
R|<local>/x|.<Unresolved name: y>#
^ R|/n|<R|kotlin/Int?|>()
}
, run2@fun <anonymous>(): R|kotlin/Int?| <inline=NoInline, kind=EXACTLY_ONCE> {
(R|<local>/x| as R|I2|)
R|<local>/x|.<Unresolved name: x>#
^ Int(123)
}
)
R|<local>/x|.R|/I1.x|
R|<local>/x|.R|/I2.y|
}
@@ -28,7 +28,7 @@ fun test2(x: Any?) {
p.<!UNRESOLVED_REFERENCE!>length<!> // Bad
run2({ p = null; n() }, { p as String; 123 })
p<!UNSAFE_CALL!>.<!>length // Bad: p can be null
p?.length // OK: p is either null or String
p?.length // OK: p is String | Nothing? = String?
}
fun test3(x: Any?) {
@@ -36,5 +36,19 @@ fun test3(x: Any?) {
p.<!UNRESOLVED_REFERENCE!>length<!> // Bad
run2({ p = null; n() }, { p = ""; 123 })
p<!UNSAFE_CALL!>.<!>length // Bad: p can be null
p?.length // OK: p is either null or String
p?.length // OK: p is String | Nothing? = String?
}
interface I1 { val x: Int }
interface I2 { val y: Int }
fun test4(x: Any?) {
x.<!UNRESOLVED_REFERENCE!>x<!> // Bad
x.<!UNRESOLVED_REFERENCE!>y<!> // Bad
run2(
{ x as I1; x.<!UNRESOLVED_REFERENCE!>y<!>; n() }, // Bad: may or may not be called first
{ x as I2; x.<!UNRESOLVED_REFERENCE!>x<!>; 123 } // Bad: may or may not be called first
)
x.x // OK: x is I1 & I2
x.y // OK: x is I1 & I2
}