From b0c3c7463bb82fd362db4e2c64aa68179fca7574 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Wed, 25 Jan 2017 17:17:31 +0300 Subject: [PATCH] Fix internal compiler error about arithmetic exception #KT-8264 Fixed --- .../evaluate/ConstantExpressionEvaluator.kt | 8 +++++- .../tests/modifiers/const/applicability.kt | 13 +++++++++- .../tests/modifiers/const/applicability.txt | 11 ++++++++ .../const/noDivisionByZeroFeature.kt | 10 +++++++ .../const/noDivisionByZeroFeature.txt | 10 +++++++ .../evaluate/constant/divideByZero.kt | 26 ++++++++++++++++++- 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index eb8643a9127..110336754f3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.* @@ -242,6 +243,11 @@ class ConstantExpressionEvaluator( } } +private val DIVISION_OPERATION_NAMES = + listOf(OperatorNameConventions.DIV, OperatorNameConventions.REM, OperatorNameConventions.MOD) + .map(Name::asString) + .toSet() + private class ConstantExpressionEvaluatorVisitor( private val constantExpressionEvaluator: ConstantExpressionEvaluator, private val trace: BindingTrace @@ -545,7 +551,7 @@ private class ConstantExpressionEvaluatorVisitor( binaryOperations[BinaryOperationKey(receiver.ctcType, parameter.ctcType, name)] private fun isDivisionByZero(name: String, parameter: Any?): Boolean { - if (name == OperatorConventions.BINARY_OPERATION_NAMES[KtTokens.DIV]!!.asString()) { + if (name in DIVISION_OPERATION_NAMES) { if (isIntegerType(parameter)) { return (parameter as Number).toLong() == 0.toLong() } diff --git a/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt b/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt index 5d10c919f39..8f2e23cd075 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt +++ b/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt @@ -42,7 +42,7 @@ const val delegated: Int by Delegate() const val withGetter: Int -get() = 13 + get() = 13 const val withExplicitDefaultGetter: Int = 1 get @@ -80,6 +80,11 @@ const val nonConstInitializer7 = -1/0 const val nonConstInitializer8 = 1/0 - 1/0 const val nonConstInitializer9 = 1.0/0.0 - 1/0 const val nonConstInitializer10 = 0/0 +const val nonConstInitializer11 = 1 % 0 +const val nonConstInitializer12 = 0 % 0 +const val nonConstInitializer13 = 0.mod(0) +const val nonConstInitializer14 = 0.rem(0) +const val nonConstInitializer15 = 0.div(0) const val constInitializer1 = 1.0/0 const val constInitializer2 = 1/0.0 @@ -90,6 +95,12 @@ const val constInitializer6 = 42 + 1.0/0 const val constInitializer7 = 42 - 1.0/0 const val constInitializer8 = 1.0/0 - 1.0/0 const val constInitializer9 = 0.0/0 + 1.0/0 +const val constInitializer10 = 1.0 % 0 +const val constInitializer11 = 0.0 % 0 +const val constInitializer12 = (-1.0) % 0 +const val constInitializer13 = 1.0.rem(0) +const val constInitializer14 = 1.0.mod(0) +const val constInitializer15 = 1.0.div(0) // ------------------ class Delegate { diff --git a/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt b/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt index 815a225cc83..bcd81797ade 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt +++ b/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt @@ -1,6 +1,12 @@ package public const val constInitializer1: kotlin.Double = Infinity.toDouble() +public const val constInitializer10: kotlin.Double = NaN.toDouble() +public const val constInitializer11: kotlin.Double = NaN.toDouble() +public const val constInitializer12: kotlin.Double = NaN.toDouble() +public const val constInitializer13: kotlin.Double = NaN.toDouble() +public const val constInitializer14: kotlin.Double = NaN.toDouble() +public const val constInitializer15: kotlin.Double = Infinity.toDouble() public const val constInitializer2: kotlin.Double = Infinity.toDouble() public const val constInitializer3: kotlin.Double = Infinity.toDouble() public const val constInitializer4: kotlin.Double = -Infinity.toDouble() @@ -13,6 +19,11 @@ public const val defaultGetter: kotlin.Int = 19 public const val delegated: kotlin.Int public const val nonConstInitializer1: kotlin.Int public const val nonConstInitializer10: kotlin.Int +public const val nonConstInitializer11: kotlin.Int +public const val nonConstInitializer12: kotlin.Int +public const val nonConstInitializer13: kotlin.Int +public const val nonConstInitializer14: kotlin.Int +public const val nonConstInitializer15: kotlin.Int public const val nonConstInitializer2: kotlin.String public const val nonConstInitializer3: kotlin.String public const val nonConstInitializer4: kotlin.Double diff --git a/compiler/testData/diagnostics/tests/modifiers/const/noDivisionByZeroFeature.kt b/compiler/testData/diagnostics/tests/modifiers/const/noDivisionByZeroFeature.kt index 208ce8a8a1d..94a073c6eff 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/noDivisionByZeroFeature.kt +++ b/compiler/testData/diagnostics/tests/modifiers/const/noDivisionByZeroFeature.kt @@ -4,8 +4,18 @@ const val a = 1 / 0.0 const val b = 1.0 / 0 const val c = 0.0 / 0 +const val d = 1.0 % 0 +const val e = 0.0 % 0 +const val f = 0.0.mod(0) +const val g = 0.0.rem(0) +const val h = 0.0.div(0) const val i = 1 / 0 val nonConst1 = 1.0 / 0 val nonConst2 = 1 / 0 +val nonConst3 = 1.0 % 0 +val nonConst4 = 1 % 0 +val nonConst5 = 1.mod(0) +val nonConst6 = 1.rem(0) +val nonConst7 = 1.div(0) diff --git a/compiler/testData/diagnostics/tests/modifiers/const/noDivisionByZeroFeature.txt b/compiler/testData/diagnostics/tests/modifiers/const/noDivisionByZeroFeature.txt index bcd14134351..630c7b89902 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/noDivisionByZeroFeature.txt +++ b/compiler/testData/diagnostics/tests/modifiers/const/noDivisionByZeroFeature.txt @@ -3,6 +3,16 @@ package public const val a: kotlin.Double public const val b: kotlin.Double public const val c: kotlin.Double +public const val d: kotlin.Double +public const val e: kotlin.Double +public const val f: kotlin.Double +public const val g: kotlin.Double +public const val h: kotlin.Double public const val i: kotlin.Int public val nonConst1: kotlin.Double public val nonConst2: kotlin.Int +public val nonConst3: kotlin.Double +public val nonConst4: kotlin.Int +public val nonConst5: kotlin.Int +public val nonConst6: kotlin.Int +public val nonConst7: kotlin.Int diff --git a/compiler/testData/evaluate/constant/divideByZero.kt b/compiler/testData/evaluate/constant/divideByZero.kt index 71293e89d45..bc10afb1e79 100644 --- a/compiler/testData/evaluate/constant/divideByZero.kt +++ b/compiler/testData/evaluate/constant/divideByZero.kt @@ -55,4 +55,28 @@ val prop17 = -0.0 / 0 val prop18 = 1.0 / 0 - 1.0 / 0 // val prop19: NaN.toFloat() -val prop19 = 1f / 0 - 1f / 0 \ No newline at end of file +val prop19 = 1f / 0 - 1f / 0 + +// val prop20: NaN.toDouble() +val prop20 = 1.0 % 0 + +// val prop21: NaN.toDouble() +val prop21 = 0.0 % 0 + +// val prop22: NaN.toFloat() +val prop22 = 1f % 0 + +// val prop23: NaN.toDouble() +val prop23 = -1.0 % 0 + +// val prop24: NaN.toDouble() +val prop24 = -0.0 % 0 + +// val prop25: NaN.toDouble() +val prop25 = 1.0.mod(0) + +// val prop26: NaN.toDouble() +val prop26 = 1.0.rem(0) + +// val prop27: Infinity.toDouble() +val prop27 = 1.0.div(0) \ No newline at end of file