diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ieee754.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/ieee754.kt index 5ada2ef3cb4..cdd1b9f8165 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ieee754.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ieee754.kt @@ -10,9 +10,9 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore -import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactoryImpl import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils @@ -28,20 +28,26 @@ fun calcProperTypeForIeee754ArithmeticIfNeeded( typeMapper: KotlinTypeMapper ): TypeAndNullability? { if (inferredPrimitiveType == null) return null - val ktType = expression.kotlinType(bindingContext) ?: return null + val ktType = expression.getKotlinTypeForComparison(bindingContext) ?: return null val isNullable = TypeUtils.isNullableType(ktType) val asmType = typeMapper.mapType(inferredPrimitiveType) if (!AsmUtil.isPrimitive(asmType)) return null return TypeAndNullability(asmType, isNullable) } +private fun KtExpression.getKotlinTypeForComparison(bindingContext: BindingContext): KotlinType? = + when { + this is KtProperty -> bindingContext[BindingContext.VARIABLE, this]?.type + else -> kotlinType(bindingContext) + } + fun legacyCalcTypeForIeee754ArithmeticIfNeeded( expression: KtExpression?, bindingContext: BindingContext, descriptor: DeclarationDescriptor, languageVersionSettings: LanguageVersionSettings ): TypeAndNullability? { - val ktType = expression.kotlinType(bindingContext) ?: return null + val ktType = expression?.getKotlinTypeForComparison(bindingContext) ?: return null if (KotlinBuiltIns.isDoubleOrNullableDouble(ktType)) { return TypeAndNullability( @@ -59,7 +65,7 @@ fun legacyCalcTypeForIeee754ArithmeticIfNeeded( // NB. Using DataFlowValueFactoryImpl is a hack, but it is ok for 'legacy' val dataFlow = DataFlowValueFactoryImpl().createDataFlowValue( - expression!!, + expression, ktType, bindingContext, descriptor diff --git a/compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt b/compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt new file mode 100644 index 00000000000..49e4b5678f2 --- /dev/null +++ b/compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +VariableDeclarationInWhenSubject +// IGNORE_BACKEND: JS + +val dz = -0.0 + +fun box(): String { + when (val y = dz) { + 0.0 -> {} + else -> throw AssertionError() + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt b/compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt new file mode 100644 index 00000000000..56dca102979 --- /dev/null +++ b/compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +VariableDeclarationInWhenSubject +ProperIeee754Comparisons +// IGNORE_BACKEND: JS + +val az: Any = -0.0 + +fun box(): String { + when (val y = az) { + !is Double -> throw AssertionError() + 0.0 -> {} + else -> throw AssertionError() + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 8f1d6201ecf..3f1ad85a3c9 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -21673,6 +21673,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt"); } + @TestMetadata("ieee754Equality.kt") + public void testIeee754Equality() throws Exception { + runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt"); + } + + @TestMetadata("ieee754EqualityWithSmartCast.kt") + public void testIeee754EqualityWithSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt"); + } + @TestMetadata("isCheckOnSubjectVariable.kt") public void testIsCheckOnSubjectVariable() throws Exception { runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 01ceccda028..78c24942760 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -21673,6 +21673,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt"); } + @TestMetadata("ieee754Equality.kt") + public void testIeee754Equality() throws Exception { + runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt"); + } + + @TestMetadata("ieee754EqualityWithSmartCast.kt") + public void testIeee754EqualityWithSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt"); + } + @TestMetadata("isCheckOnSubjectVariable.kt") public void testIsCheckOnSubjectVariable() throws Exception { runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 78208a8ecf8..2826f4b8bd2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -21673,6 +21673,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt"); } + @TestMetadata("ieee754Equality.kt") + public void testIeee754Equality() throws Exception { + runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt"); + } + + @TestMetadata("ieee754EqualityWithSmartCast.kt") + public void testIeee754EqualityWithSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt"); + } + @TestMetadata("isCheckOnSubjectVariable.kt") public void testIsCheckOnSubjectVariable() throws Exception { runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 4c453c75692..97d2f007ed4 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -19566,6 +19566,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt"); } + @TestMetadata("ieee754Equality.kt") + public void testIeee754Equality() throws Exception { + runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt"); + } + + @TestMetadata("ieee754EqualityWithSmartCast.kt") + public void testIeee754EqualityWithSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt"); + } + @TestMetadata("isCheckOnSubjectVariable.kt") public void testIsCheckOnSubjectVariable() throws Exception { runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");