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 cd26f630547..143b39aaad9 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 @@ -556,7 +556,7 @@ private class ConstantExpressionEvaluatorVisitor( assert(isIntegerType(receiver.value)) { "Only integer constants should be checked for overflow" } assert(name == "minus" || name == "unaryMinus") { "Only negation should be checked for overflow" } - if (receiver.value == result) { + if (receiver.value == result && !isZero(receiver.value)) { trace.report(Errors.INTEGER_OVERFLOW.on(callExpression.getStrictParentOfType() ?: callExpression)) } return result @@ -598,15 +598,15 @@ private class ConstantExpressionEvaluatorVisitor( binaryOperations[BinaryOperationKey(receiver.ctcType, parameter.ctcType, name)] private fun isDivisionByZero(name: String, parameter: Any?): Boolean { - if (name in DIVISION_OPERATION_NAMES) { - if (isIntegerType(parameter)) { - return (parameter as Number).toLong() == 0.toLong() - } - else if (parameter is Float || parameter is Double) { - return (parameter as Number).toDouble() == 0.0 - } + return name in DIVISION_OPERATION_NAMES && isZero(parameter) + } + + private fun isZero(value: Any?): Boolean { + return when { + isIntegerType(value) -> (value as Number).toLong() == 0L + value is Float || value is Double -> (value as Number).toDouble() == 0.0 + else -> false } - return false } override fun visitUnaryExpression(expression: KtUnaryExpression, expectedType: KotlinType?): CompileTimeConstant<*>? { diff --git a/compiler/testData/diagnostics/tests/evaluate/noOverflowWithZero.kt b/compiler/testData/diagnostics/tests/evaluate/noOverflowWithZero.kt new file mode 100644 index 00000000000..0e97797cf5e --- /dev/null +++ b/compiler/testData/diagnostics/tests/evaluate/noOverflowWithZero.kt @@ -0,0 +1,11 @@ +val zero = 0 + +fun test() { + -0 + -0L + -0.0 + -(1 - 1) + -zero + + +0 +} diff --git a/compiler/testData/diagnostics/tests/evaluate/noOverflowWithZero.txt b/compiler/testData/diagnostics/tests/evaluate/noOverflowWithZero.txt new file mode 100644 index 00000000000..02c97459600 --- /dev/null +++ b/compiler/testData/diagnostics/tests/evaluate/noOverflowWithZero.txt @@ -0,0 +1,4 @@ +package + +public val zero: kotlin.Int = 0 +public fun test(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 7b5484e91d0..7b37596199f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -7561,6 +7561,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("noOverflowWithZero.kt") + public void testNoOverflowWithZero() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/evaluate/noOverflowWithZero.kt"); + doTest(fileName); + } + @TestMetadata("numberBinaryOperations.kt") public void testNumberBinaryOperations() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/evaluate/numberBinaryOperations.kt");