Fixed bug in inliner + test
This commit is contained in:
+12
-2
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
Reference in New Issue
Block a user