From 8aa4acee8844aae7a84af89b783c73ce6f20de92 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Mon, 19 Feb 2018 17:52:37 +0300 Subject: [PATCH] Bug fix: explicitly initialize lateinit properties/variables with null --- .../backend/konan/lower/LateinitLowering.kt | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/LateinitLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/LateinitLowering.kt index 7e39e5d263e..c2038671e47 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/LateinitLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/LateinitLowering.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl @@ -43,6 +44,24 @@ class LateinitLowering( override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitVariable(declaration: IrVariable): IrStatement { + declaration.transformChildrenVoid(this) + + val symbol = declaration.symbol + val descriptor = declaration.descriptor + if (!descriptor.isLateInit) return declaration + + assert(declaration.initializer == null, { "'lateinit' modifier is not allowed for variables with initializer" }) + assert(!KotlinBuiltIns.isPrimitiveType(descriptor.type), { "'lateinit' modifier is not allowed on primitive types" }) + val startOffset = declaration.startOffset + val endOffset = declaration.endOffset + val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset) + irBuilder.run { + declaration.initializer = irNull() + } + return declaration + } + override fun visitGetValue(expression: IrGetValue): IrExpression { val symbol = expression.symbol val descriptor = symbol.descriptor as? VariableDescriptor @@ -67,8 +86,19 @@ class LateinitLowering( override fun visitProperty(declaration: IrProperty): IrStatement { declaration.transformChildrenVoid(this) - if (declaration.descriptor.isLateInit && declaration.descriptor.kind.isReal) - transformGetter(declaration.backingField!!.symbol, declaration.getter!!) + if (!declaration.descriptor.isLateInit || !declaration.descriptor.kind.isReal) + return declaration + + val backingField = declaration.backingField!! + transformGetter(backingField.symbol, declaration.getter!!) + + assert(backingField.initializer == null, { "'lateinit' modifier is not allowed for properties with initializer" }) + val startOffset = declaration.startOffset + val endOffset = declaration.endOffset + val irBuilder = context.createIrBuilder(backingField.symbol, startOffset, endOffset) + irBuilder.run { + backingField.initializer = irExprBody(irNull()) + } return declaration }