Always null detection

This commit is contained in:
Mikhail Glukhikh
2015-11-06 17:54:05 +03:00
parent ed1c94d0f9
commit 2d9fbf5696
40 changed files with 140 additions and 75 deletions
@@ -0,0 +1,11 @@
fun foo(): String {
var s: String?
s = null
<!ALWAYS_NULL!>s<!>?.length
if (<!ALWAYS_NULL!>s<!> == null) s = "z"
var t: String? = "y"
if (t == null) t = "x"
var x: Int? = null
if (x == null) <!TYPE_MISMATCH!><!DEBUG_INFO_SMARTCAST!>x<!> += null<!>
return <!DEBUG_INFO_SMARTCAST!>t<!> + s
}
@@ -0,0 +1,3 @@
package
public fun foo(): kotlin.String
@@ -8,19 +8,19 @@ fun foo(x : String?, y : String?) {
x<!UNSAFE_CALL!>.<!>length
y<!UNSAFE_CALL!>.<!>length
}
if (y != null || x == y) {
if (y != null || x == <!ALWAYS_NULL!>y<!>) {
x<!UNSAFE_CALL!>.<!>length
y<!UNSAFE_CALL!>.<!>length
}
else {
// y == null but x != y
<!DEBUG_INFO_SMARTCAST!>x<!>.length
y<!UNSAFE_CALL!>.<!>length
<!ALWAYS_NULL!>y<!><!UNSAFE_CALL!>.<!>length
}
if (y == null && x != y) {
if (y == null && x != <!ALWAYS_NULL!>y<!>) {
// y == null but x != y
<!DEBUG_INFO_SMARTCAST!>x<!>.length
y<!UNSAFE_CALL!>.<!>length
<!ALWAYS_NULL!>y<!><!UNSAFE_CALL!>.<!>length
}
else {
x<!UNSAFE_CALL!>.<!>length
@@ -3,10 +3,10 @@ fun foo(x: String?, y: String?, z: String?, w: String?) {
<!DEBUG_INFO_SMARTCAST!>z<!>.length
else
z<!UNSAFE_CALL!>.<!>length
if (x != null || y != null || (x != z && y != z))
if (x != null || y != null || (<!ALWAYS_NULL!>x<!> != z && <!ALWAYS_NULL!>y<!> != z))
z<!UNSAFE_CALL!>.<!>length
else
z<!UNSAFE_CALL!>.<!>length
<!ALWAYS_NULL!>z<!><!UNSAFE_CALL!>.<!>length
if (x == null || y == null || (x != z && y != z))
z<!UNSAFE_CALL!>.<!>length
else
@@ -0,0 +1,10 @@
class IncDec {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(): Unit {}
}
fun foo(): IncDec {
var x = IncDec()
x = <!UNUSED_CHANGED_VALUE!>x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!><!>
x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>
return x
}
@@ -0,0 +1,11 @@
package
public fun foo(): IncDec
public final class IncDec {
public constructor IncDec()
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 final operator fun inc(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1,6 +1,6 @@
fun bar(x: Int?): Int {
if (x != null) return -1
if (<!SENSELESS_COMPARISON!>x == null<!>) return -2
if (<!ALWAYS_NULL!>x<!> == null) return -2
// Should be unreachable
return 2 + 2
}
@@ -4,7 +4,7 @@ fun foo() {
v = "abc"
<!DEBUG_INFO_SMARTCAST!>v<!>.length
v = null
v<!UNSAFE_CALL!>.<!>length
<!ALWAYS_NULL!>v<!><!UNSAFE_CALL!>.<!>length
v = "abc"
<!DEBUG_INFO_SMARTCAST!>v<!>.length
}
@@ -3,5 +3,5 @@ fun foo() {
// It is possible in principle to provide smart cast here
v<!UNSAFE_CALL!>.<!>length
v = null
v<!UNSAFE_CALL!>.<!>length
<!ALWAYS_NULL!>v<!><!UNSAFE_CALL!>.<!>length
}
@@ -1,5 +1,5 @@
fun foo(): Int {
var i: Int? = <!VARIABLE_WITH_REDUNDANT_INITIALIZER!>42<!>
i = null
return i <!UNSAFE_INFIX_CALL!>+<!> 1
return <!ALWAYS_NULL!>i<!> <!UNSAFE_INFIX_CALL!>+<!> 1
}
@@ -1,5 +1,5 @@
fun foo(): Int {
var s: String? = <!VARIABLE_WITH_REDUNDANT_INITIALIZER!>"abc"<!>
s = null
return s<!UNSAFE_CALL!>.<!>length
return <!ALWAYS_NULL!>s<!><!UNSAFE_CALL!>.<!>length
}