From eb744cc9e14f6055da89911b06553661b90f4bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Fri, 4 Oct 2019 15:00:51 +0200 Subject: [PATCH] JVM IR: Fix constant folding for unsigned toString --- .../backend/jvm/lower/FoldConstantLowering.kt | 24 ++++++++++++++----- ...unsignedTypeValuesInsideStringTemplates.kt | 1 - 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FoldConstantLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FoldConstantLowering.kt index cdc6ac275f4..9da5035b4c4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FoldConstantLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FoldConstantLowering.kt @@ -10,14 +10,12 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns -import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrConst -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable +import org.jetbrains.kotlin.ir.util.isUnsigned import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.resolve.constants.evaluate.evaluateBinary @@ -161,6 +159,7 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr return buildIrConstant(call, evaluated) } + @ExperimentalUnsignedTypes override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitCall(expression: IrCall): IrExpression { @@ -175,6 +174,19 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr } } + // Unsigned constants are represented through signed constants with a different IrType. + private fun constToString(const: IrConst<*>): String { + if (const.type.isUnsigned()) { + when (val kind = const.kind) { + is IrConstKind.Byte -> return kind.valueOf(const).toUByte().toString() + is IrConstKind.Short -> return kind.valueOf(const).toUShort().toString() + is IrConstKind.Int -> return kind.valueOf(const).toUInt().toString() + is IrConstKind.Long -> return kind.valueOf(const).toULong().toString() + } + } + return const.value.toString() + } + override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression { expression.transformChildrenVoid(this) val folded = mutableListOf() @@ -183,11 +195,11 @@ class FoldConstantLowering(private val context: JvmBackendContext) : IrElementTr when { next !is IrConst<*> -> folded += next last !is IrConst<*> -> folded += IrConstImpl.string( - next.startOffset, next.endOffset, context.irBuiltIns.stringType, next.value.toString() + next.startOffset, next.endOffset, context.irBuiltIns.stringType, constToString(next) ) else -> folded[folded.size - 1] = IrConstImpl.string( last.startOffset, next.endOffset, context.irBuiltIns.stringType, - last.value.toString() + next.value.toString() + constToString(last) + constToString(next) ) } } diff --git a/compiler/testData/codegen/box/unsignedTypes/unsignedTypeValuesInsideStringTemplates.kt b/compiler/testData/codegen/box/unsignedTypes/unsignedTypeValuesInsideStringTemplates.kt index ec620f3fb69..12bb49a4795 100644 --- a/compiler/testData/codegen/box/unsignedTypes/unsignedTypeValuesInsideStringTemplates.kt +++ b/compiler/testData/codegen/box/unsignedTypes/unsignedTypeValuesInsideStringTemplates.kt @@ -1,6 +1,5 @@ // KJS_WITH_FULL_RUNTIME // WITH_RUNTIME -// IGNORE_BACKEND: JVM_IR const val MAX_BYTE: UByte = 0xFFu const val HUNDRED: UByte = 100u