Standard data flow analysis results are taken into account during condition analysis #KT-7933 Fixed

This commit is contained in:
Mikhail Glukhikh
2015-10-30 12:00:38 +03:00
parent dd1196ae6b
commit 182cde1e02
6 changed files with 114 additions and 4 deletions
@@ -0,0 +1,55 @@
fun foo(x: String?, y: String?, z: String?) {
if ((x!!.hashCode() == 0 || y!!.hashCode() == 1) && z!!.hashCode() == 2) {
<!DEBUG_INFO_SMARTCAST!>x<!>.length
y<!UNSAFE_CALL!>.<!>length
// condition is true => z!! after and is called
<!DEBUG_INFO_SMARTCAST!>z<!>.length
}
else {
<!DEBUG_INFO_SMARTCAST!>x<!>.length
y<!UNSAFE_CALL!>.<!>length
z<!UNSAFE_CALL!>.<!>length
}
// First element is always analyzed
<!DEBUG_INFO_SMARTCAST!>x<!>.length
var xx = y ?: z
if ((xx!!.hashCode() == 0 && y!!.hashCode() == 1) || z!!.hashCode() == 2) {
<!DEBUG_INFO_SMARTCAST!>xx<!>.length
y<!UNSAFE_CALL!>.<!>length
z<!UNSAFE_CALL!>.<!>length
}
else {
<!DEBUG_INFO_SMARTCAST!>xx<!>.length
y<!UNSAFE_CALL!>.<!>length
// condition is false => z!! after or is called
<!DEBUG_INFO_SMARTCAST!>z<!>.length
}
// First element is always analyzed
<!DEBUG_INFO_SMARTCAST!>x<!>.length
xx = y ?: z
if (xx!!.hashCode() == 0 && y!!.hashCode() == 1 && z!!.hashCode() == 2) {
// all three are called
<!DEBUG_INFO_SMARTCAST!>xx<!>.length
<!DEBUG_INFO_SMARTCAST!>y<!>.length
<!DEBUG_INFO_SMARTCAST!>z<!>.length
}
else {
<!DEBUG_INFO_SMARTCAST!>xx<!>.length
y<!UNSAFE_CALL!>.<!>length
z<!UNSAFE_CALL!>.<!>length
}
// First element is always analyzed
<!DEBUG_INFO_SMARTCAST!>x<!>.length
xx = y ?: z
if (xx!!.hashCode() == 0 || y!!.hashCode() == 1 || z!!.hashCode() == 2) {
<!DEBUG_INFO_SMARTCAST!>xx<!>.length
y<!UNSAFE_CALL!>.<!>length
z<!UNSAFE_CALL!>.<!>length
}
else {
// all three are called
<!DEBUG_INFO_SMARTCAST!>xx<!>.length
<!DEBUG_INFO_SMARTCAST!>y<!>.length
<!DEBUG_INFO_SMARTCAST!>z<!>.length
}
}
@@ -0,0 +1,3 @@
package
public fun foo(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?, /*2*/ z: kotlin.String?): kotlin.Unit
@@ -0,0 +1,13 @@
class D(val a: String, val b: Boolean)
fun foo(p: Boolean, v: D?): String {
if (p && v!!.b) <!DEBUG_INFO_SMARTCAST!>v<!>.a
else v<!UNSAFE_CALL!>.<!>a
if (p && v!! == D("?", false)) <!DEBUG_INFO_SMARTCAST!>v<!>.a
else v<!UNSAFE_CALL!>.<!>a
if (p || v!!.b) v<!UNSAFE_CALL!>.<!>a
else <!DEBUG_INFO_SMARTCAST!>v<!>.a
if (p || v!! == D("?", false)) v<!UNSAFE_CALL!>.<!>a
else <!DEBUG_INFO_SMARTCAST!>v<!>.a
return ""
}
@@ -0,0 +1,12 @@
package
public fun foo(/*0*/ p: kotlin.Boolean, /*1*/ v: D?): kotlin.String
public final class D {
public constructor D(/*0*/ a: kotlin.String, /*1*/ b: kotlin.Boolean)
public final val a: kotlin.String
public final val b: kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}