From 2115d55e1c06be76d96cd89f6ebad5cd59118214 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Thu, 15 Jun 2023 18:09:14 +0200 Subject: [PATCH] [IR] Forbid to interpret expressions that involves unsigned numbers We want to forbid expressions of type `Unsigned == Unsigned` or similar. Working with unsigned numbers we can only inline them on the call site or use in `String.plus` expression. This commit fixes problem in test `unsignedTypesInAnnotations`. Here interpreter thinks that expression `ONE_UINT != 1u` can be evaluated, but fails to do it. This fail prevent us from inlining `ONE_UINT` and on runtime we get error about missing getter. Earlier this property would have been inlined by `ConstLowering`, but we got rid of it. --- .../ir/interpreter/checker/EvaluationMode.kt | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt index 6dac264d170..0bf3c58c0b9 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt @@ -7,10 +7,14 @@ package org.jetbrains.kotlin.ir.interpreter.checker import org.jetbrains.kotlin.ir.BuiltInOperatorNames import org.jetbrains.kotlin.ir.IrBuiltIns -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.interpreter.* import org.jetbrains.kotlin.ir.interpreter.hasAnnotation +import org.jetbrains.kotlin.ir.interpreter.intrinsicConstEvaluationAnnotation +import org.jetbrains.kotlin.ir.interpreter.property import org.jetbrains.kotlin.ir.types.isPrimitiveType import org.jetbrains.kotlin.ir.types.isString import org.jetbrains.kotlin.ir.types.isUnsignedType @@ -74,7 +78,15 @@ enum class EvaluationMode { } override fun canEvaluateBlock(block: IrBlock): Boolean = block.statements.size == 1 - override fun canEvaluateExpression(expression: IrExpression): Boolean = expression is IrCall + override fun canEvaluateExpression(expression: IrExpression): Boolean { + if (expression !is IrCall) return false + + if (expression.getAllArgumentsWithIr().any { it.second?.type?.isUnsigned() == true }) { + return expression.symbol.owner.fqNameWhenAvailable?.asString() == "kotlin.String.plus" + } + + return true + } }, ONLY_INTRINSIC_CONST { @@ -88,7 +100,10 @@ enum class EvaluationMode { } override fun canEvaluateBlock(block: IrBlock): Boolean = block.origin == IrStatementOrigin.WHEN || block.statements.size == 1 - override fun canEvaluateExpression(expression: IrExpression): Boolean = expression is IrCall || expression is IrWhen + + override fun canEvaluateExpression(expression: IrExpression): Boolean { + return ONLY_BUILTINS.canEvaluateExpression(expression) || expression is IrWhen + } }; open fun canEvaluateFunction(function: IrFunction): Boolean = false