Fixed bug in inliner with recursive inline

Return type of a returnable block should be substituted as well as other types
This commit is contained in:
Igor Chevdar
2018-06-29 12:20:12 +03:00
parent 5cc6baf8c3
commit 6a07322f62
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
import org.jetbrains.kotlin.backend.konan.descriptors.propertyIfAccessor
import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride
import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver
import org.jetbrains.kotlin.backend.konan.irasdescriptors.getClass
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
@@ -44,6 +45,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.getArguments
import org.jetbrains.kotlin.ir.util.irCall
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.FqName
@@ -138,7 +140,6 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
fun inline(irCall: IrCall): IrReturnableBlockImpl { // Call to be substituted.
val inlineFunctionBody = inlineFunction(irCall, functionDeclaration)
copyIrElement.addCurrentSubstituteMap(globalSubstituteMap)
return inlineFunctionBody
}
@@ -181,9 +182,21 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
}
}
val returnType = copyFunctionDeclaration.returnType // Substituted return type.
val sourceFileName = context.ir.originalModuleIndex.declarationToFile[caller.descriptor.original]?:""
val inlineFunctionBody = IrReturnableBlockImpl( // Create new IR element to replace "call".
// Update globalSubstituteMap before computing return type.
// This is needed because of nested inlining.
copyIrElement.addCurrentSubstituteMap(globalSubstituteMap)
val transformer = ParameterSubstitutor()
statements.transform { it.transform(transformer, data = null) }
statements.addAll(0, evaluationStatements)
val oldDescriptor = copyFunctionDeclaration.returnType.getClass()?.descriptor
val substitutedDescriptor = oldDescriptor?.let { globalSubstituteMap[it] }
val returnType = substitutedDescriptor?.let { context.ir.translateErased((it.descriptor as ClassDescriptor).defaultType) }
?: copyFunctionDeclaration.returnType
return IrReturnableBlockImpl( // Create new IR element to replace "call".
startOffset = startOffset,
endOffset = endOffset,
type = returnType,
@@ -192,11 +205,6 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
statements = statements,
sourceFileName = sourceFileName
)
val transformer = ParameterSubstitutor()
inlineFunctionBody.transformChildrenVoid(transformer) // Replace value parameters with arguments.
inlineFunctionBody.statements.addAll(0, evaluationStatements) // Insert evaluation statements.
return inlineFunctionBody // Replace call site with InlineFunctionBody.
}
//---------------------------------------------------------------------//