Fixed bug in inliner + test

This commit is contained in:
Igor Chevdar
2018-06-08 17:18:10 +03:00
parent 4bc12573f2
commit b92fbe7f42
3 changed files with 42 additions and 2 deletions
@@ -275,6 +275,11 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
if (irCallableReference !is IrCallableReference) return false // Second statement of the block must be CallableReference.
return true // The expression represents lambda.
}
val isImmutableVariableLoad: Boolean
get() = argumentExpression.let {
it is IrGetValue && !it.descriptor.let { it is VariableDescriptor && it.isVar }
}
}
//-------------------------------------------------------------------------//
@@ -366,8 +371,13 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
parameterToArgumentOld.forEach {
val parameterDescriptor = it.parameterDescriptor
if (it.isInlinableLambda || it.argumentExpression is IrGetValue) { // If argument is inlinable lambda. IrGetValue is skipped because of recursive inline.
substituteMap[parameterDescriptor] = it.argumentExpression // Associate parameter with lambda argument.
/*
* We need to create temporary variable for each argument except inlinable lambdas.
* For simplicity and to produce simpler IR we don't create temporaries for every immutable variable,
* not only for those referring to inlinable lambdas.
*/
if (it.isInlinableLambda || it.isImmutableVariableLoad) {
substituteMap[parameterDescriptor] = it.argumentExpression
return@forEach
}
+5
View File
@@ -2373,6 +2373,11 @@ task inline_returnLocalClassFromBlock(type: RunKonanTest) {
source = "codegen/inline/returnLocalClassFromBlock.kt"
}
task inline_changingCapturedLocal(type: RunKonanTest) {
goldValue = "OK\n"
source = "codegen/inline/changingCapturedLocal.kt"
}
task deserialized_inline0(type: RunKonanTest) {
source = "serialization/deserialized_inline0.kt"
}
@@ -0,0 +1,25 @@
package codegen.inline.changingCapturedLocal
import kotlin.test.*
var log = ""
inline fun foo(x: Int, action: (Int) -> Unit) = action(x)
fun box(): String {
var x = 23
foo(x) {
log += "$it;"
x++
log += "$it;"
}
if (log != "23;23;") return "fail1: $log"
if (x != 24) return "fail2: $x"
return "OK"
}
@Test fun runTest() {
println(box())
}