Support 'break' and 'continue' in expressions

- generate fake jump instructions so that we can always analyze stack depths
- fix stack before break and continue by dropping excessive elements (e.g., *a*.foo(*b*, c?:continue))
- Analyzer rewritten in Kotlin, with more flexible control of CFG traversal

 #Fixed KT-3340
 #Fixed KT-4258
 #Fixed KT-7941
This commit is contained in:
dnpetrov
2015-06-23 12:13:48 +03:00
parent d937f385cd
commit c24e6b5698
21 changed files with 739 additions and 18 deletions
@@ -0,0 +1,12 @@
fun box(): String {
OUTER@while (true) {
var x = ""
try {
do {
x = x + break@OUTER
} while (true)
} finally {
return "OK"
}
}
}
@@ -0,0 +1,9 @@
fun test(str: String): String {
var s = ""
for (i in 1..3) {
s += if (i<2) str else break
}
return s
}
fun box(): String = test("OK")
@@ -0,0 +1,7 @@
fun box(): String {
var s = "OK"
for (i in 1..3) {
s = s + if (i<2) "" else continue
}
return s
}
@@ -0,0 +1,17 @@
inline fun bar(block: () -> String) : String {
return block()
}
inline fun bar2() : String {
while (true) break
return bar { return "def" }
}
fun foobar(x: String, y: String, z: String) = x + y + z
fun box(): String {
val test = foobar("abc", bar2(), "ghi")
return if (test == "abcdefghi")
"OK"
else "Failed, test=$test"
}
@@ -0,0 +1,9 @@
fun box(): String {
var x = "OK"
do {
while (true) {
x = x + break
}
} while (false)
return x
}
@@ -0,0 +1,13 @@
fun foo(x: Long, y: Int, z: Double, s: String) {}
fun box(): String {
while (true) {
try {
foo(0, 0, 0.0, "" + continue)
}
finally {
foo(0, 0, 0.0, "" + break)
}
}
return "OK"
}
@@ -0,0 +1,12 @@
fun box(): String {
var x = "OK"
while (true) {
try {
x = x + continue
}
finally {
x = x + break
}
}
return x
}
@@ -0,0 +1,13 @@
fun box(): String {
var r = ""
for (i in 1..1) {
try {
r += "O"
break
} finally {
r += "K"
continue
}
}
return r
}
@@ -0,0 +1,4 @@
fun box(): String {
while (true) break
return "OK"
}