diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 5087605fccb..ce6c04d9708 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -1584,8 +1584,33 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) return false + return when (value.kind) { + IrConstKind.Null -> true + IrConstKind.Boolean -> (value.value as Boolean) == false + IrConstKind.Byte -> (value.value as Byte) == 0.toByte() + IrConstKind.Char -> (value.value as Char) == 0.toChar() + IrConstKind.Short -> (value.value as Short) == 0.toShort() + IrConstKind.Int -> (value.value as Int) == 0 + IrConstKind.Long -> (value.value as Long) == 0L + IrConstKind.Float -> (value.value as Float).toRawBits() == 0 + IrConstKind.Double -> (value.value as Double).toRawBits() == 0L + IrConstKind.String -> false + } + } + private fun evaluateSetField(value: IrSetField): LLVMValueRef { context.log{"evaluateSetField : ${ir2string(value)}"} + if (value.origin == IrStatementOrigin.INITIALIZE_FIELD + && isZeroConstValue(value.value)) { + check(value.receiver is IrGetValue) { "Only IrGetValue expected for receiver of a field initializer" } + // All newly allocated objects are zeroed out, so it is redundant to initialize their + // fields with the default values. This is also aligned with the Kotlin/JVM behavior. + // See https://youtrack.jetbrains.com/issue/KT-39100 for details. + return codegen.theUnitInstanceRef.llvm + } + val valueToAssign = evaluateExpression(value.value) val store = if (!value.symbol.owner.isStatic) { val thisPtr = evaluateExpression(value.receiver!!) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt index 21df4b2bc0b..522da3d8f27 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt @@ -69,7 +69,7 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo val initExpression = initializer.expression initializers.add(IrBlockImpl(startOffset, endOffset, context.irBuiltIns.unitType, - STATEMENT_ORIGIN_ANONYMOUS_INITIALIZER, + IrStatementOrigin.INITIALIZE_FIELD, listOf( IrSetFieldImpl(startOffset, endOffset, declaration.symbol, IrGetValueImpl( @@ -78,7 +78,7 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo ), initExpression, context.irBuiltIns.unitType, - STATEMENT_ORIGIN_ANONYMOUS_INITIALIZER))) + IrStatementOrigin.INITIALIZE_FIELD))) ) // We shall keep initializer for constants for compile-time instantiation.