Control-Flow Analysis: Reuse pseudo-value information for unused expression analysis
This commit is contained in:
@@ -25,7 +25,7 @@ fun f(): Unit {
|
||||
<!TYPE_MISMATCH!>x<!> in 1..2
|
||||
|
||||
val y : Boolean? = true
|
||||
false || <!TYPE_MISMATCH!>y<!>
|
||||
<!TYPE_MISMATCH!>y<!> && true
|
||||
<!TYPE_MISMATCH!>y<!> && <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>
|
||||
}
|
||||
<!UNUSED_EXPRESSION!>false || <!TYPE_MISMATCH!>y<!><!>
|
||||
<!UNUSED_EXPRESSION!><!TYPE_MISMATCH!>y<!> && true<!>
|
||||
<!UNUSED_EXPRESSION!><!TYPE_MISMATCH!>y<!> && <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!><!>
|
||||
}
|
||||
@@ -47,7 +47,7 @@ fun blockReturnValueTypeMatch() : Int {return 1}
|
||||
fun blockReturnValueTypeMismatchUnit() : Int {return <!TYPE_MISMATCH!>Unit<!>}
|
||||
|
||||
fun blockAndAndMismatch() : Int {
|
||||
true && false
|
||||
<!UNUSED_EXPRESSION!>true && false<!>
|
||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
fun blockAndAndMismatch1() : Int {
|
||||
return <!TYPE_MISMATCH!>true && false<!>
|
||||
@@ -57,7 +57,7 @@ fun blockAndAndMismatch2() : Int {
|
||||
}
|
||||
|
||||
fun blockAndAndMismatch3() : Int {
|
||||
true || false
|
||||
<!UNUSED_EXPRESSION!>true || false<!>
|
||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
fun blockAndAndMismatch4() : Int {
|
||||
return <!TYPE_MISMATCH!>true || false<!>
|
||||
@@ -91,18 +91,18 @@ fun blockReturnValueTypeMatch6() : Int {
|
||||
}
|
||||
fun blockReturnValueTypeMatch7() : Int {
|
||||
if (1 > 2)
|
||||
1.0
|
||||
else 2.0
|
||||
<!UNUSED_EXPRESSION!>1.0<!>
|
||||
else <!UNUSED_EXPRESSION!>2.0<!>
|
||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
fun blockReturnValueTypeMatch8() : Int {
|
||||
if (1 > 2)
|
||||
1.0
|
||||
else 2.0
|
||||
<!UNUSED_EXPRESSION!>1.0<!>
|
||||
else <!UNUSED_EXPRESSION!>2.0<!>
|
||||
return 1
|
||||
}
|
||||
fun blockReturnValueTypeMatch9() : Int {
|
||||
if (1 > 2)
|
||||
1.0
|
||||
<!UNUSED_EXPRESSION!>1.0<!>
|
||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
fun blockReturnValueTypeMatch10() : Int {
|
||||
return <!TYPE_MISMATCH!>if (1 > 2)
|
||||
@@ -110,7 +110,7 @@ fun blockReturnValueTypeMatch10() : Int {
|
||||
}
|
||||
fun blockReturnValueTypeMatch11() : Int {
|
||||
if (1 > 2)
|
||||
else 1.0
|
||||
else <!UNUSED_EXPRESSION!>1.0<!>
|
||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
fun blockReturnValueTypeMatch12() : Int {
|
||||
if (1 > 2)
|
||||
|
||||
@@ -12,11 +12,11 @@ fun demo() {
|
||||
<!UNUSED_EXPRESSION!>"$.$.asdf$\t"<!>
|
||||
<!UNUSED_EXPRESSION!>"asd\$"<!>
|
||||
<!UNUSED_EXPRESSION!>"asd$a<!ILLEGAL_ESCAPE!>\x<!>"<!>
|
||||
<!UNUSED_EXPRESSION!>"asd$a$asd$ $<!UNRESOLVED_REFERENCE!>xxx<!>"<!>
|
||||
<!UNUSED_EXPRESSION!>"fosdfasdo${1 + bar + 100}}sdsdfgdsfsdf"<!>
|
||||
<!UNUSED_EXPRESSION!>"foo${bar + map {foo}}sdfsdf"<!>
|
||||
<!UNUSED_EXPRESSION!>"foo${bar + map { "foo" }}sdfsdf"<!>
|
||||
<!UNUSED_EXPRESSION!>"foo${bar + map {
|
||||
"foo$sdf${ buzz{}}" }}sdfsdf"<!>
|
||||
"asd$a$asd$ $<!UNRESOLVED_REFERENCE!>xxx<!>"
|
||||
"fosdfasdo${1 + bar + 100}}sdsdfgdsfsdf"
|
||||
"foo${bar + map {foo}}sdfsdf"
|
||||
"foo${bar + map { "foo" }}sdfsdf"
|
||||
"foo${bar + map {
|
||||
"foo$sdf${ buzz{}}" }}sdfsdf"
|
||||
<!UNUSED_EXPRESSION!>"a<!ILLEGAL_ESCAPE!>\u<!> <!ILLEGAL_ESCAPE!>\u<!>0 <!ILLEGAL_ESCAPE!>\u<!>00 <!ILLEGAL_ESCAPE!>\u<!>000 \u0000 \u0AaA <!ILLEGAL_ESCAPE!>\u<!>0AAz.length( ) + \u0022b"<!>
|
||||
}
|
||||
@@ -3,7 +3,7 @@ fun testIf() {
|
||||
}
|
||||
|
||||
fun testIf1(b: Boolean) {
|
||||
if (b) todo() else 1
|
||||
if (b) todo() else <!UNUSED_EXPRESSION!>1<!>
|
||||
|
||||
bar()
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ package kt1075
|
||||
fun foo(b: String) {
|
||||
if (<!TYPE_MISMATCH!>b<!> in 1..10) {} //type mismatch
|
||||
when (b) {
|
||||
<!TYPE_MISMATCH_IN_RANGE!>in<!> 1..10 -> 1 //no type mismatch, but it should be here
|
||||
else -> 2
|
||||
<!TYPE_MISMATCH_IN_RANGE!>in<!> 1..10 -> <!UNUSED_EXPRESSION!>1<!> //no type mismatch, but it should be here
|
||||
else -> <!UNUSED_EXPRESSION!>2<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ fun foo() : Int {
|
||||
fun fff(): Int {
|
||||
var d = 3
|
||||
when(d) {
|
||||
4 -> 21
|
||||
4 -> <!UNUSED_EXPRESSION!>21<!>
|
||||
return 2 -> <!UNREACHABLE_CODE!>return 47<!>
|
||||
<!UNREACHABLE_CODE!>bar() -> 45<!>
|
||||
<!UNREACHABLE_CODE!>444 -> true<!>
|
||||
|
||||
@@ -21,7 +21,7 @@ fun test1(t : Pair<Int, Int>) : Int {
|
||||
}
|
||||
|
||||
//more tests
|
||||
fun t1(x: Int) = when(x) {
|
||||
fun t1(x: Int) = when(<!UNUSED_EXPRESSION!>x<!>) {
|
||||
else -> 1
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ class BinOp(val operator : String) : Expr
|
||||
fun test(e : Expr) {
|
||||
if (e is BinOp) {
|
||||
when (<!DEBUG_INFO_AUTOCAST!>e<!>.operator) {
|
||||
else -> 0
|
||||
else -> <!UNUSED_EXPRESSION!>0<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,10 @@
|
||||
|
||||
fun foo(s: String?) {
|
||||
when {
|
||||
s == null -> 1
|
||||
<!DEBUG_INFO_AUTOCAST!>s<!>.foo() -> 2
|
||||
else -> 3
|
||||
s == null -> <!UNUSED_EXPRESSION!>1<!>
|
||||
<!DEBUG_INFO_AUTOCAST!>s<!>.foo() -> <!UNUSED_EXPRESSION!>2<!>
|
||||
else -> <!UNUSED_EXPRESSION!>3<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun String.foo() = true
|
||||
|
||||
|
||||
|
||||
fun String.foo() = true
|
||||
@@ -71,5 +71,5 @@ import outer.*
|
||||
val c = Command()
|
||||
c<!UNNECESSARY_SAFE_CALL!>?.<!>equals2(null)
|
||||
|
||||
if (command == null) 1
|
||||
if (command == null) <!UNUSED_EXPRESSION!>1<!>
|
||||
}
|
||||
|
||||
@@ -9,4 +9,4 @@ fun unusedLiteralInDoWhile(){
|
||||
do<!UNUSED_FUNCTION_LITERAL!>{() ->
|
||||
val <!UNUSED_VARIABLE!>i<!> = 1
|
||||
}<!> while(false)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
package d
|
||||
|
||||
trait A<T>
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
fun test(a: Any) {
|
||||
when (a)<!SYNTAX!><!>
|
||||
when (<!UNUSED_EXPRESSION!>a<!>)<!SYNTAX!><!>
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
package d
|
||||
|
||||
fun foo(a : IntArray) {
|
||||
|
||||
@@ -2,21 +2,21 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
||||
(s)(11)
|
||||
(s).invoke(11)
|
||||
(s) invoke 11
|
||||
(<!USAGE_IS_NOT_INLINABLE!>s<!>)
|
||||
(<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>s<!>)
|
||||
}
|
||||
|
||||
inline fun Function1<Int, Unit>.inlineExt() {
|
||||
(this).invoke(11)
|
||||
(this) invoke 11
|
||||
(this)(11)
|
||||
(<!USAGE_IS_NOT_INLINABLE!>this<!>)
|
||||
(<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>this<!>)
|
||||
}
|
||||
|
||||
inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) {
|
||||
(((s)))(11)
|
||||
(((s))).invoke(11)
|
||||
(((s))) invoke 11
|
||||
(((<!USAGE_IS_NOT_INLINABLE!>s<!>)))
|
||||
(((<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>s<!>)))
|
||||
}
|
||||
|
||||
inline fun propagation(s: (p: Int) -> Unit) {
|
||||
|
||||
@@ -51,7 +51,7 @@ inline fun Function1<Int, Unit>.inlineExt() {
|
||||
this invoke 11
|
||||
this(11)
|
||||
|
||||
<!USAGE_IS_NOT_INLINABLE!>this<!>
|
||||
<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>this<!>
|
||||
|
||||
11
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
||||
(s: (p: Int) -> Unit)(11)
|
||||
(s: (p: Int) -> Unit).invoke(11)
|
||||
(s: (p: Int) -> Unit) invoke 11
|
||||
(<!USAGE_IS_NOT_INLINABLE!>s<!>)
|
||||
(<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>s<!>)
|
||||
}
|
||||
|
||||
inline fun Function1<Int, Unit>.inlineExt() {
|
||||
@@ -18,4 +18,4 @@ inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) {
|
||||
(((s: (p: Int) -> Unit): (p: Int) -> Unit): (p: Int) -> Unit).invoke(11)
|
||||
(((s: (p: Int) -> Unit): (p: Int) -> Unit): (p: Int) -> Unit) invoke 11
|
||||
(((<!USAGE_IS_NOT_INLINABLE!>s<!>: (p: Int) -> Unit)))
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
//FILE: foo.kt
|
||||
fun main(args: Array<String>) {
|
||||
val c: Type
|
||||
when (<!UNINITIALIZED_VARIABLE!>c<!>) {
|
||||
when (<!UNINITIALIZED_VARIABLE, UNUSED_EXPRESSION!>c<!>) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fun nonlocals(b : Boolean) {
|
||||
@a{(): Int ->
|
||||
@a<!UNUSED_FUNCTION_LITERAL!>{(): Int ->
|
||||
fun foo() {
|
||||
if (b) {
|
||||
<!RETURN_NOT_ALLOWED!>return@a 1<!> // The label must be resolved, but an error should be reported for a non-local return
|
||||
@@ -7,6 +7,5 @@ fun nonlocals(b : Boolean) {
|
||||
}
|
||||
|
||||
return@a 5
|
||||
}
|
||||
}
|
||||
|
||||
}<!>
|
||||
}
|
||||
+3
-3
@@ -15,11 +15,11 @@ fun B.b() {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
@b { B.() ->
|
||||
@b <!UNUSED_FUNCTION_LITERAL!>{ B.() ->
|
||||
object : A {
|
||||
override fun foo() {
|
||||
this@b.bar()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}<!>
|
||||
}
|
||||
@@ -6,5 +6,5 @@ fun Any.equals(other : Any?) : Boolean = this === other
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val command = parse("")
|
||||
if (command == null) 1 // error on this line, but must be OK
|
||||
}
|
||||
if (command == null) <!UNUSED_EXPRESSION!>1<!> // error on this line, but must be OK
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
fun <T> T.mustBe(t : T) {
|
||||
<!UNUSED_EXPRESSION!>"$this must be$<!SYNTAX!>as<!>$t"<!>
|
||||
}
|
||||
"$this must be$<!SYNTAX!>as<!>$t"
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
fun foo(i: Int) {
|
||||
<!FUNCTION_EXPECTED!>i<!>()
|
||||
<!FUNCTION_EXPECTED!>1<!>()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// FILE: f.kt
|
||||
class A() {
|
||||
fun foo() : Unit {
|
||||
this@A
|
||||
<!UNUSED_EXPRESSION!>this@A<!>
|
||||
this<!UNRESOLVED_REFERENCE!>@a<!>
|
||||
this
|
||||
<!UNUSED_EXPRESSION!>this<!>
|
||||
}
|
||||
|
||||
val x = this@A.foo()
|
||||
|
||||
@@ -5,7 +5,7 @@ fun notAnExpression() {
|
||||
if (<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>) {} else {} // not an expression
|
||||
val <!UNUSED_VARIABLE!>x<!> = <!SUPER_IS_NOT_AN_EXPRESSION!>super<!> // not an expression
|
||||
when (1) {
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!> -> 1 // not an expression
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!> -> <!UNUSED_EXPRESSION!>1<!> // not an expression
|
||||
else -> {}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,15 +4,15 @@ fun foo() : Int {
|
||||
val s = ""
|
||||
val x = 1
|
||||
when (x) {
|
||||
is <!INCOMPATIBLE_TYPES!>String<!> -> 1
|
||||
!is Int -> 1
|
||||
is Any<!USELESS_NULLABLE_CHECK!>?<!> -> 1
|
||||
<!INCOMPATIBLE_TYPES!>s<!> -> 1
|
||||
1 -> 1
|
||||
1 + <!UNRESOLVED_REFERENCE!>a<!> -> 1
|
||||
in 1..<!UNRESOLVED_REFERENCE!>a<!> -> 1
|
||||
!in 1..<!UNRESOLVED_REFERENCE!>a<!> -> 1
|
||||
else -> 1
|
||||
is <!INCOMPATIBLE_TYPES!>String<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
!is Int -> <!UNUSED_EXPRESSION!>1<!>
|
||||
is Any<!USELESS_NULLABLE_CHECK!>?<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
<!INCOMPATIBLE_TYPES!>s<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
1 -> <!UNUSED_EXPRESSION!>1<!>
|
||||
1 + <!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
in 1..<!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
!in 1..<!UNRESOLVED_REFERENCE!>a<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
else -> <!UNUSED_EXPRESSION!>1<!>
|
||||
}
|
||||
|
||||
return 0
|
||||
@@ -25,20 +25,20 @@ fun test() {
|
||||
val s = "";
|
||||
|
||||
when (x) {
|
||||
<!INCOMPATIBLE_TYPES!>s<!> -> 1
|
||||
<!INCOMPATIBLE_TYPES!>""<!> -> 1
|
||||
x -> 1
|
||||
1 -> 1
|
||||
<!INCOMPATIBLE_TYPES!>s<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
<!INCOMPATIBLE_TYPES!>""<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
x -> <!UNUSED_EXPRESSION!>1<!>
|
||||
1 -> <!UNUSED_EXPRESSION!>1<!>
|
||||
}
|
||||
|
||||
val z = 1
|
||||
|
||||
when (z) {
|
||||
<!ELSE_MISPLACED_IN_WHEN!>else<!> -> 1
|
||||
<!ELSE_MISPLACED_IN_WHEN!>else<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||
<!UNREACHABLE_CODE!>1 -> 2<!>
|
||||
}
|
||||
|
||||
when (z) {
|
||||
else -> 1
|
||||
when (<!UNUSED_EXPRESSION!>z<!>) {
|
||||
else -> <!UNUSED_EXPRESSION!>1<!>
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user