[FIR-TEST] Add new testdata generated after changes in previous commit
This commit is contained in:
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
fun checkJump(x: Int?, y: Int?) {
|
||||
while (true) {
|
||||
if (x ?: break == 0) {
|
||||
y!!
|
||||
} else {
|
||||
y!!
|
||||
}
|
||||
// Ok
|
||||
y.hashCode()
|
||||
}
|
||||
// Smart cast here is erroneous: y is nullable
|
||||
y.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
public fun foo(x: String?, y: String?): Int {
|
||||
while (true) {
|
||||
val z = x ?: if (y == null) break else y
|
||||
// z is not null in both branches
|
||||
z.length
|
||||
// y is nullable if x != null
|
||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
// y is null because of the break
|
||||
return y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// !CHECK_TYPE
|
||||
|
||||
public fun foo(x: String?): Int {
|
||||
var y: Any
|
||||
loop@ while (true) {
|
||||
y = when (x) {
|
||||
null -> break@loop
|
||||
"abc" -> return 0
|
||||
"xyz" -> return 1
|
||||
else -> x.length
|
||||
}
|
||||
// y is always Int after when
|
||||
checkSubtype<Int>(y)
|
||||
}
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun gav(w: String, arg: Any, z: String): String
|
||||
{ return if (arg is String) arg else if (z != "") z else w }
|
||||
|
||||
public fun foo(x: String?, z: String?, w: String?): Int {
|
||||
do {
|
||||
gav(w!!, if (x == null) break else x, z!!)
|
||||
} while (bar())
|
||||
// w is not null because of w!!
|
||||
w.length
|
||||
// z is nullable despite of z!!
|
||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun gav(arg: Any, z: String): String { return if (arg is String) arg else z }
|
||||
|
||||
public fun foo(x: String?, z: String?): Int {
|
||||
do {
|
||||
gav(if (x == null) break else x, z!!)
|
||||
} while (bar())
|
||||
// z is nullable despite of z!!
|
||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun gav(arg: Any): String { return if (arg is String) arg else "" }
|
||||
|
||||
public fun foo(x: String?): Int {
|
||||
var y: Any
|
||||
do {
|
||||
y = ""
|
||||
y = gav(if (x == null) break else x)
|
||||
} while (bar())
|
||||
y.hashCode()
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun gav(z: String, arg: Any): String { return if (arg is String) arg else z }
|
||||
|
||||
public fun foo(x: String?, z: String?): Int {
|
||||
do {
|
||||
gav(z!!, if (x == null) break else x)
|
||||
} while (bar())
|
||||
// z is not null because of z!!
|
||||
z.length
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun gav(z: String, w: String, arg: Any): String
|
||||
{ return if (arg is String) arg else if (z != "") z else w }
|
||||
|
||||
public fun foo(x: String?, z: String?, w: String?): Int {
|
||||
do {
|
||||
gav(z!!, w!!, if (x == null) break else x)
|
||||
} while (bar())
|
||||
// w is not null because of w!!
|
||||
w.length
|
||||
// z is not null because of z!!
|
||||
z.length
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
// See KT-6283
|
||||
do {
|
||||
p!!.length
|
||||
} while (!x())
|
||||
// Do-while loop is executed at least once, so
|
||||
// p should be not null here
|
||||
return p.length
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
// See KT-6283
|
||||
do {
|
||||
p!!.length
|
||||
if (p == "abc") break
|
||||
} while (!x())
|
||||
// p should be smart casted despite of break
|
||||
return p.length
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
// See KT-6283
|
||||
do {
|
||||
p!!.length
|
||||
if (p == "abc") continue
|
||||
} while (!x())
|
||||
// p should be smart casted despite of continue
|
||||
return p.length
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
fun y(): Boolean { return false }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
do {
|
||||
if (y()) break
|
||||
// We do not always reach this statement
|
||||
p!!.length
|
||||
} while (!x())
|
||||
// Here we have do while loop but p is still nullable due to break before
|
||||
return p.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
fun y(): Boolean { return false }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
do {
|
||||
if (y()) continue
|
||||
// We do not always reach this statement
|
||||
p!!.length
|
||||
} while (!x())
|
||||
// Here we have do while loop but p is still nullable due to continue before
|
||||
return p.length
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
fun foo(s: String?): Int {
|
||||
do {
|
||||
} while (s!!.length > 0)
|
||||
return s.length
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun foo(s: String?): Int {
|
||||
do {
|
||||
if (bar()) break
|
||||
} while (s!!.length > 0)
|
||||
// This call is unsafe due to break
|
||||
return s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
// Exotic variant with unused literal
|
||||
do { ->
|
||||
p!!.length
|
||||
} while (!x())
|
||||
// Literal is not called so p.length is unsafe
|
||||
return p.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
// See KT-6283
|
||||
do {
|
||||
if (p != null) break
|
||||
} while (!x())
|
||||
// p can be null despite of the break
|
||||
return p.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun foo(s: String?): Int {
|
||||
do {
|
||||
} while (s==null)
|
||||
return s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun foo(s: String?): Int {
|
||||
do {
|
||||
if (bar()) break
|
||||
} while (s==null)
|
||||
// This call is unsafe due to break
|
||||
return s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public fun foo(x: String?): Int {
|
||||
do {
|
||||
// After the check, smart cast should work
|
||||
x ?: break
|
||||
// x is not null in both branches
|
||||
x.length
|
||||
} while (true)
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public fun foo(x: String?, y: String?): Int {
|
||||
while (true) {
|
||||
x ?: if (y == null) break
|
||||
// y is nullable if x != null
|
||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
// y is null because of the break
|
||||
return y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public fun foo(x: String?): Int {
|
||||
do {
|
||||
// After the check, smart cast should work
|
||||
x ?: x!!.length
|
||||
// x is not null in both branches
|
||||
if (x.length == 0) break
|
||||
} while (true)
|
||||
return x.length
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public fun foo(x: String?, y: String?): Int {
|
||||
while (true) {
|
||||
(if (x != null) break else y) ?: y!!
|
||||
// y is not null in both branches but it's hard to determine
|
||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
// y can be null because of the break
|
||||
return y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
public fun foo(p: String?, y: String?): Int {
|
||||
do {
|
||||
// After the check, smart cast should work
|
||||
if (y == null) {
|
||||
"null".toString()
|
||||
break
|
||||
}
|
||||
y.length
|
||||
p!!.length
|
||||
} while (true)
|
||||
return y?.length ?: -1
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
public fun foo(x: String?): Int {
|
||||
var y: Any
|
||||
do {
|
||||
// This and hashCode() below are needed just to prevent
|
||||
// UNINITIALIZED_VARIABLE, UNUSED_VALUE, ...
|
||||
y = ""
|
||||
y = if (x == null) break else x
|
||||
} while (bar())
|
||||
y.hashCode()
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public fun foo(x: String?): Int {
|
||||
var y: Any
|
||||
while (true) {
|
||||
y = if (x == null) break else x
|
||||
}
|
||||
// In future we can infer this initialization
|
||||
y.hashCode()
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public fun foo(x: String?): Int {
|
||||
while (true) {
|
||||
// After the check, smart cast should work
|
||||
val y = if (x == null) break else x
|
||||
// y is not null in both branches
|
||||
y.length
|
||||
}
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
public fun foo(x: String?, y: String?): Int {
|
||||
do {
|
||||
// After the check, smart cast should work
|
||||
if (x != null) {
|
||||
if (x == "abc") break
|
||||
y!!.length
|
||||
} else {
|
||||
y!!.length
|
||||
}
|
||||
// y!! in both branches
|
||||
y.length
|
||||
} while (true)
|
||||
// break is possible before so !! is necessary
|
||||
return y!!.length
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public fun foo(p: String?, y: String?): Int {
|
||||
do {
|
||||
// After the check, smart cast should work
|
||||
if (y == null) break
|
||||
y.length
|
||||
p!!.length
|
||||
} while (true)
|
||||
return y?.length ?: -1
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
public fun foo(x: String?, y: String?): Int {
|
||||
while (true) {
|
||||
val z = (if (y == null) break else x) ?: y
|
||||
// z is not null in both branches
|
||||
z.length
|
||||
// y is not null in both branches
|
||||
y.length
|
||||
}
|
||||
// y is null because of the break
|
||||
return y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?, r: String?): Int {
|
||||
do {
|
||||
do {
|
||||
p!!.length
|
||||
} while (r == null)
|
||||
} while (!x())
|
||||
// Auto cast possible
|
||||
r.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
// Auto cast possible
|
||||
return p.length
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?, r: String?): Int {
|
||||
outer@ do {
|
||||
do {
|
||||
p!!.length
|
||||
if (!x()) continue@outer
|
||||
} while (r == null)
|
||||
} while (!x())
|
||||
// Auto cast NOT possible due to long continue
|
||||
r.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
// Auto cast possible
|
||||
return p.length
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?, r: String?, q: String?): Int {
|
||||
while(true) {
|
||||
q!!.length
|
||||
do {
|
||||
do {
|
||||
p!!.length
|
||||
} while (!x())
|
||||
} while (r == null)
|
||||
if (!x()) break
|
||||
}
|
||||
// Smart cast is possible everywhere
|
||||
r.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
q.length
|
||||
return p.length
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?, r: String?, q: String?): Int {
|
||||
while(true) {
|
||||
q!!.length
|
||||
do {
|
||||
p!!.length
|
||||
} while (r == null)
|
||||
if (!x()) break
|
||||
}
|
||||
// Smart cast is possible everywhere
|
||||
r.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
q.length
|
||||
return p.length
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?, r: String?, q: String?): Int {
|
||||
while(true) {
|
||||
q!!.length
|
||||
do {
|
||||
while(true) {
|
||||
p!!.length
|
||||
if (x()) break
|
||||
}
|
||||
} while (r == null)
|
||||
if (!x()) break
|
||||
}
|
||||
// Smart cast is possible everywhere
|
||||
r.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
q.length
|
||||
return p.length
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
fun x(p: String): Boolean { return p == "abc" }
|
||||
|
||||
public fun foo(p: String?, r: String?, q: String?): Int {
|
||||
while(true) {
|
||||
q!!.length
|
||||
loop@ do {
|
||||
while(true) {
|
||||
p!!.length
|
||||
if (x(p)) break@loop
|
||||
if (x(q)) break
|
||||
}
|
||||
} while (r == null)
|
||||
if (!x(p)) break
|
||||
}
|
||||
// Long break allows r == null
|
||||
r.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
// Smart cast is possible
|
||||
q.length
|
||||
return p.length
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?, r: String?, q: String?): Int {
|
||||
outer@ while(true) {
|
||||
q!!.length
|
||||
do {
|
||||
if (x()) continue@outer
|
||||
do {
|
||||
p!!.length
|
||||
} while (!x())
|
||||
} while (r == null)
|
||||
if (!x()) break
|
||||
}
|
||||
// Smart cast is possible only for q
|
||||
q.length
|
||||
// But not possible for the others
|
||||
r.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
return p.length
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// !CHECK_TYPE
|
||||
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
public fun foo(x: String?): Int {
|
||||
var y: Int?
|
||||
y = 0
|
||||
loop@ do {
|
||||
y += when (x) {
|
||||
null -> break@loop
|
||||
"abc" -> return 0
|
||||
"xyz" -> return 1
|
||||
else -> x.length
|
||||
}
|
||||
// y is always Int after when
|
||||
checkSubtype<Int>(y)
|
||||
} while (bar())
|
||||
// y is always Int even here
|
||||
checkSubtype<Int>(y)
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
fun foo(x: String): String? = x
|
||||
|
||||
fun calc(x: String?, y: String?): Int {
|
||||
do {
|
||||
// Smart cast because of x!! in receiver
|
||||
foo(x!!)?.subSequence(0, if (x.length > 0) 5 else break)
|
||||
y!!.length
|
||||
// x is not null in condition but we do not see it yet
|
||||
} while (x.length > 0)
|
||||
// y is nullable because of break
|
||||
y.length
|
||||
// x is not null, at least in theory
|
||||
return x.length
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fun foo(x: String): String? = x
|
||||
|
||||
fun calc(x: String?): Int {
|
||||
do {
|
||||
// Smart cast because of x!! in receiver
|
||||
foo(x!!)?.subSequence(0, x.length)
|
||||
// Smart cast because of x!! in receiver
|
||||
if (x.length == 0) break
|
||||
} while (true)
|
||||
// Here x is also not null
|
||||
return x.length
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public fun foo(p: String?, y: String?): Int {
|
||||
do {
|
||||
// After this !!, y. should be smartcasted in loop as well as outside
|
||||
y!!.length
|
||||
if (p == null) break
|
||||
y.length
|
||||
} while (true)
|
||||
return y.length
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
public fun foo(x: String?): Int {
|
||||
loop@ while (true) {
|
||||
when (x) {
|
||||
null -> break@loop
|
||||
"abc" -> return 0
|
||||
"xyz" -> return 1
|
||||
else -> x.length
|
||||
}
|
||||
}
|
||||
// x is null because of the break
|
||||
return x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
public fun foo(x: String?): Int {
|
||||
loop@ while (true) {
|
||||
when (x) {
|
||||
null -> return -1
|
||||
"abc" -> return 0
|
||||
"xyz" -> return 1
|
||||
else -> break@loop
|
||||
}
|
||||
}
|
||||
// x is not null because of the break
|
||||
// but we are not able to detect it
|
||||
return x.length
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
fun foo(s: String?): Int {
|
||||
while (s!!.length > 0) {
|
||||
s.length
|
||||
}
|
||||
return s.length
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun foo(s: String?): Int {
|
||||
while (s!!.length > 0) {
|
||||
s.length
|
||||
if (bar()) break
|
||||
}
|
||||
return s.length
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun foo(s: String?): Int {
|
||||
while (s==null) {
|
||||
}
|
||||
return s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fun main() {
|
||||
var result: String? = null
|
||||
var i = 0
|
||||
while (result == null) {
|
||||
if (i == 10) result = "non null"
|
||||
else i++
|
||||
}
|
||||
result.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fun bar(): Boolean { return true }
|
||||
|
||||
fun foo(s: String?): Int {
|
||||
while (s==null) {
|
||||
if (bar()) break
|
||||
}
|
||||
// Call is unsafe due to break
|
||||
return s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
while(x()) {
|
||||
p!!.length
|
||||
if (x()) break
|
||||
}
|
||||
// p is nullable because it's possible loop body is not executed at all
|
||||
return p.length
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
// Like whileTrue but 2 == 2 is in use
|
||||
while(2 == 2) {
|
||||
p!!.length
|
||||
if (x()) break
|
||||
}
|
||||
// Smart cast should not work in this case, see KT-6284
|
||||
return p.length
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
// KT-6284
|
||||
while(true) {
|
||||
p!!.length
|
||||
if (x()) break
|
||||
}
|
||||
// while (true) loop body is executed at least once
|
||||
// so p is not null here
|
||||
return p.length
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
while(true) {
|
||||
if (x()) break
|
||||
if (p==null) return -1
|
||||
// p is not null
|
||||
p.length
|
||||
}
|
||||
// p can be null because break is earlier than return
|
||||
return p.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
while(true) {
|
||||
if (x()) break
|
||||
// We do not always reach this statement
|
||||
p!!.length
|
||||
}
|
||||
// Here we have while (true) loop but p is nullable due to break before
|
||||
return p.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fun x(): Boolean { return true }
|
||||
|
||||
public fun foo(p: String?): Int {
|
||||
while(true) {
|
||||
if (p==null) return -1
|
||||
if (x()) break
|
||||
// p is not null
|
||||
p.length
|
||||
}
|
||||
// while (true) loop body with return is executed at least once
|
||||
// so p is not null here
|
||||
return p.length
|
||||
}
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
// !LANGUAGE: +SoundSmartcastFromLoopConditionForLoopAssignedVariables
|
||||
|
||||
fun foo() {
|
||||
var x: String? = "123"
|
||||
while (x!!.length < 42) {
|
||||
x = null
|
||||
break
|
||||
|
||||
}
|
||||
// TODO: this testdata fixates undesired behavior (it should be an unsafe call)
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!> // 'x' is unsoundly smartcasted here
|
||||
}
|
||||
|
||||
fun bar() {
|
||||
var x: List<Int>? = ArrayList<Int>(1)
|
||||
for (i in x!!) {
|
||||
x = null
|
||||
break
|
||||
|
||||
}
|
||||
// TODO: this testdata fixates undesired behavior (it should be an unsafe call)
|
||||
x.<!UNRESOLVED_REFERENCE!>size<!> // 'x' is unsoundly smartcasted here
|
||||
}
|
||||
compiler/testData/diagnostics/tests/smartCasts/loops/whileWithAssertInConditionAndBreakBefore.fir.kt
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// !LANGUAGE: -SoundSmartcastFromLoopConditionForLoopAssignedVariables
|
||||
|
||||
fun foo() {
|
||||
var x: String? = "123"
|
||||
while (x!!.length < 42) {
|
||||
x = null
|
||||
break
|
||||
|
||||
}
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!> // 'x' is unsoundly smartcasted here
|
||||
}
|
||||
|
||||
fun bar() {
|
||||
var x: List<Int>? = ArrayList<Int>(1)
|
||||
for (i in x!!) {
|
||||
x = null
|
||||
break
|
||||
|
||||
}
|
||||
x.<!UNRESOLVED_REFERENCE!>size<!> // 'x' is unsoundly smartcasted here
|
||||
}
|
||||
Reference in New Issue
Block a user