JVM_IR: add $assertionsDisabled when an inlined function uses it

NOTE: jvmCrossinlineLambdaDeclarationSite.kt is muted because the
inliner does not remap references to an anonymous object's parent
class after regenerating it. Unlike the JVM backend, JVM_IR uses the
top level named class' assertion status for all inner classes. (The
test used to pass because the lambda in `inline fun call` read the
`$assertionsDisabled` field of `CrossinlineLambdaContainer`, which
was not reloaded after changing the assertion status of package `test`.)
This commit is contained in:
pyos
2019-10-14 10:35:41 +02:00
committed by Ilmir Usmanov
parent e89aabbba1
commit 847e287bd6
18 changed files with 333 additions and 38 deletions
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
// FILE: inline.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
// WITH_RUNTIME
@@ -28,6 +26,7 @@ class Dummy
fun enableAssertions(): CheckerJvmAssertInlineFunctionAssertionsEnabled {
val loader = Dummy::class.java.classLoader
loader.setClassAssertionStatus("CheckerJvmAssertInlineFunctionAssertionsEnabled", true)
loader.setClassAssertionStatus("InlineKt", false)
val c = loader.loadClass("CheckerJvmAssertInlineFunctionAssertionsEnabled")
return c.newInstance() as CheckerJvmAssertInlineFunctionAssertionsEnabled
}
@@ -1,6 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
// FILE: inline.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
// WITH_RUNTIME
@@ -1,6 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
// FILE: inline.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
// WITH_RUNTIME
@@ -1,4 +1,6 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
// FILE: inline.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
// WITH_RUNTIME
@@ -0,0 +1,73 @@
// TARGET_BACKEND: JVM
// FILE: inline.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
// WITH_RUNTIME
// NO_CHECK_LAMBDA_INLINING
package test
object CrossinlineLambdaContainer {
inline fun call(crossinline c: () -> Boolean) {
val l = { assert(c()) }
l()
}
}
// FILE: inlineSite.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
import test.CrossinlineLambdaContainer.call
interface Checker {
fun checkTrue(): Boolean
fun checkFalse(): Boolean
}
class ShouldBeDisabled : Checker {
override fun checkTrue(): Boolean {
var hit = false
call { hit = true; true }
return hit
}
override fun checkFalse(): Boolean {
var hit = false
call { hit = true; false }
return hit
}
}
class ShouldBeEnabled : Checker {
override fun checkTrue(): Boolean {
var hit = false
call { hit = true; true }
return hit
}
override fun checkFalse(): Boolean {
var hit = false
call { hit = true; false }
return hit
}
}
fun setDesiredAssertionStatus(v: Boolean): Checker {
val loader = Checker::class.java.classLoader
loader.setDefaultAssertionStatus(v)
val c = loader.loadClass(if (v) "ShouldBeEnabled" else "ShouldBeDisabled")
return c.newInstance() as Checker
}
fun box(): String {
var c = setDesiredAssertionStatus(false)
if (c.checkTrue()) return "FAIL 0"
if (c.checkFalse()) return "FAIL 2"
c = setDesiredAssertionStatus(true)
if (!c.checkTrue()) return "FAIL 4"
try {
c.checkFalse()
return "FAIL 6"
} catch (ignore: AssertionError) {
}
return "OK"
}
@@ -0,0 +1,72 @@
// TARGET_BACKEND: JVM
// FILE: inline.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
// WITH_RUNTIME
// NO_CHECK_LAMBDA_INLINING
package test
object CrossinlineLambdaContainer {
inline fun call(crossinline c: () -> Boolean) {
Runnable { assert(c()) }.run()
}
}
// FILE: inlineSite.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
import test.CrossinlineLambdaContainer.call
interface Checker {
fun checkTrue(): Boolean
fun checkFalse(): Boolean
}
class ShouldBeDisabled : Checker {
override fun checkTrue(): Boolean {
var hit = false
call { hit = true; true }
return hit
}
override fun checkFalse(): Boolean {
var hit = false
call { hit = true; false }
return hit
}
}
class ShouldBeEnabled : Checker {
override fun checkTrue(): Boolean {
var hit = false
call { hit = true; true }
return hit
}
override fun checkFalse(): Boolean {
var hit = false
call { hit = true; false }
return hit
}
}
fun setDesiredAssertionStatus(v: Boolean): Checker {
val loader = Checker::class.java.classLoader
loader.setDefaultAssertionStatus(v)
val c = loader.loadClass(if (v) "ShouldBeEnabled" else "ShouldBeDisabled")
return c.newInstance() as Checker
}
fun box(): String {
var c = setDesiredAssertionStatus(false)
if (c.checkTrue()) return "FAIL 0"
if (c.checkFalse()) return "FAIL 2"
c = setDesiredAssertionStatus(true)
if (!c.checkTrue()) return "FAIL 4"
try {
c.checkFalse()
return "FAIL 6"
} catch (ignore: AssertionError) {
}
return "OK"
}
@@ -1,6 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_MULTI_MODULE: JVM_IR
// FILE: inline.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
// WITH_RUNTIME
@@ -0,0 +1,27 @@
// Not a multi-module test.
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_IR
// FILE: A.kt
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
// WITH_RUNTIME
// FULL_JDK
class A {
inline fun inlineMe(crossinline c : () -> String) = {
assert(true)
c()
}
}
// FILE: B.java
import kotlin.jvm.functions.Function0;
public class B {
public static String check() {
return new A().inlineMe(new Function0<String>() {
@Override public String invoke() { return "OK"; }
}).invoke();
}
}
// FILE: box.kt
fun box(): String = B.check()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
inline fun inlineMe() = assert(true)