FIR DFA: generate more correct implications on as/as?
^KT-54851 Fixed
This commit is contained in:
+15
-10
@@ -446,22 +446,27 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
if (operandVariable.isReal()) {
|
if (operandVariable.isReal()) {
|
||||||
flow.addTypeStatement(operandVariable typeEq type)
|
flow.addTypeStatement(operandVariable typeEq type)
|
||||||
}
|
}
|
||||||
logicSystem.approveStatementsInsideFlow(
|
if (!type.canBeNull) {
|
||||||
flow,
|
logicSystem.approveStatementsInsideFlow(
|
||||||
operandVariable notEq null,
|
flow,
|
||||||
shouldRemoveSynthetics = true,
|
operandVariable notEq null,
|
||||||
shouldForkFlow = false
|
shouldRemoveSynthetics = true,
|
||||||
)
|
shouldForkFlow = false
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val expressionVariable = variableStorage.createSyntheticVariable(typeOperatorCall)
|
||||||
|
flow.addImplication((expressionVariable notEq null) implies (operandVariable notEq null))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FirOperation.SAFE_AS -> {
|
FirOperation.SAFE_AS -> {
|
||||||
val expressionVariable = variableStorage.createSyntheticVariable(typeOperatorCall)
|
val expressionVariable = variableStorage.createSyntheticVariable(typeOperatorCall)
|
||||||
|
flow.addImplication((expressionVariable notEq null) implies (operandVariable notEq null))
|
||||||
if (operandVariable.isReal()) {
|
if (operandVariable.isReal()) {
|
||||||
flow.addImplication((expressionVariable notEq null) implies (operandVariable typeEq type))
|
flow.addImplication((expressionVariable notEq null) implies (operandVariable typeEq type))
|
||||||
flow.addImplication((expressionVariable eq null) implies (operandVariable typeNotEq type))
|
if (!type.canBeNull) {
|
||||||
}
|
flow.addImplication((expressionVariable eq null) implies (operandVariable typeNotEq type))
|
||||||
if (type.nullability == ConeNullability.NOT_NULL) {
|
}
|
||||||
flow.addImplication((expressionVariable notEq null) implies (operandVariable notEq null))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ fun case_2(x: Class?) {
|
|||||||
*/
|
*/
|
||||||
fun case_3(x: Any?) {
|
fun case_3(x: Any?) {
|
||||||
if ((x as Class?)?.prop_8?.prop_8?.prop_8?.prop_8 == null) else {
|
if ((x as Class?)?.prop_8?.prop_8?.prop_8?.prop_8 == null) else {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class?")!>x<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class")!>x<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class?")!>x<!><!UNSAFE_CALL!>.<!>prop_8
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class")!>x<!>.prop_8
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class?")!>x<!><!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class")!>x<!>.prop_8<!UNSAFE_CALL!>.<!>prop_8
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class?")!>x<!><!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class")!>x<!>.prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class?")!>x<!><!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class")!>x<!>.prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ fun case_6(x: Class?) {
|
|||||||
<!DEBUG_INFO_EXPRESSION_TYPE("Class? & Class")!>x<!>.prop_8
|
<!DEBUG_INFO_EXPRESSION_TYPE("Class? & Class")!>x<!>.prop_8
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("Class? & Class")!>x<!>.prop_8.prop_8
|
<!DEBUG_INFO_EXPRESSION_TYPE("Class? & Class")!>x<!>.prop_8.prop_8
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("Class? & Class")!>x<!>.prop_8.prop_8.prop_8
|
<!DEBUG_INFO_EXPRESSION_TYPE("Class? & Class")!>x<!>.prop_8.prop_8.prop_8
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("Class? & Class")!>x<!>.prop_8.prop_8.prop_8<!UNSAFE_CALL!>.<!>prop_8<!UNSAFE_CALL!>.<!>prop_8
|
<!DEBUG_INFO_EXPRESSION_TYPE("Class? & Class")!>x<!>.prop_8.prop_8.prop_8.prop_8<!UNSAFE_CALL!>.<!>prop_8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ fun case_12(x: Any?) {
|
|||||||
*/
|
*/
|
||||||
fun case_13(x: Any?) {
|
fun case_13(x: Any?) {
|
||||||
if (x as Boolean? ?: x!!) {
|
if (x as Boolean? ?: x!!) {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Boolean?")!>x<!><!UNSAFE_CALL!>.<!>not()
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Boolean")!>x<!>.not()
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean?")!>select(x)<!><!UNSAFE_CALL!>.<!>not()
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean")!>select(x)<!>.not()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,24 +20,24 @@ fun case_2(x: Any?) {
|
|||||||
// TESTCASE NUMBER: 3
|
// TESTCASE NUMBER: 3
|
||||||
fun case_3(x: Any?) {
|
fun case_3(x: Any?) {
|
||||||
if (x as Number? is Int) {
|
if (x as Number? is Int) {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Number?")!>x<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Number")!>x<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Number?")!>x<!>.<!UNRESOLVED_REFERENCE!>inv<!>()
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Number")!>x<!>.<!UNRESOLVED_REFERENCE!>inv<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 4
|
// TESTCASE NUMBER: 4
|
||||||
fun case_4(x: Any?) {
|
fun case_4(x: Any?) {
|
||||||
if (x as Class? is Class) {
|
if (x as Class? is Class) {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class?")!>x<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class")!>x<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class?")!>x<!><!UNSAFE_CALL!>.<!>prop_1
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & Class")!>x<!><!UNSAFE_CALL{LT}!>.<!>prop_1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 5
|
// TESTCASE NUMBER: 5
|
||||||
fun case_5(x: Any?) {
|
fun case_5(x: Any?) {
|
||||||
if (x as Nothing? is Nothing) {
|
if (x as Nothing? is Nothing) {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Nothing?")!>x<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Nothing")!>x<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Nothing?")!>x<!><!UNSAFE_CALL!>.<!><!UNRESOLVED_REFERENCE{LT}!>inv<!>()
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.Nothing")!>x<!><!UNSAFE_CALL{LT}!>.<!><!UNRESOLVED_REFERENCE{LT}!>inv<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,8 +51,8 @@ fun case_6(x: Any?) {
|
|||||||
// TESTCASE NUMBER: 7
|
// TESTCASE NUMBER: 7
|
||||||
fun case_7(x: Any?) {
|
fun case_7(x: Any?) {
|
||||||
if (x as String? != null) {
|
if (x as String? != null) {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.String?")!>x<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.String")!>x<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.String?")!>x<!><!UNSAFE_CALL!>.<!>length
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & kotlin.String")!>x<!><!UNSAFE_CALL{LT}!>.<!>length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ fun case_2(x: Any?) {
|
|||||||
// TESTCASE NUMBER: 3
|
// TESTCASE NUMBER: 3
|
||||||
fun case_3(x: Any?) {
|
fun case_3(x: Any?) {
|
||||||
if (x as ClassLevel1? is ClassLevel1) {
|
if (x as ClassLevel1? is ClassLevel1) {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & ClassLevel1?")!>x<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & ClassLevel1")!>x<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & ClassLevel1?")!>x<!><!UNSAFE_CALL!>.<!>test1()
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & ClassLevel1")!>x<!>.test1()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user