Fix bogus integer overflow warning for 'mod' operator
#KT-15875 Fixed
This commit is contained in:
+13
-3
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -510,7 +510,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateBinaryAndCheck(receiver: OperationArgument, parameter: OperationArgument, name: String, callExpression: KtExpression): Any? {
|
private fun evaluateBinaryAndCheck(receiver: OperationArgument, parameter: OperationArgument, name: String, callExpression: KtExpression): Any? {
|
||||||
val functions = binaryOperations[BinaryOperationKey(receiver.ctcType, parameter.ctcType, name)] ?: return null
|
val functions = getBinaryOperation(receiver, parameter, name) ?: return null
|
||||||
|
|
||||||
val (function, checker) = functions
|
val (function, checker) = functions
|
||||||
val actualResult = try {
|
val actualResult = try {
|
||||||
@@ -526,7 +526,14 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
|
|
||||||
fun toBigInteger(value: Any?) = BigInteger.valueOf((value as Number).toLong())
|
fun toBigInteger(value: Any?) = BigInteger.valueOf((value as Number).toLong())
|
||||||
|
|
||||||
val resultInBigIntegers = checker(toBigInteger(receiver.value), toBigInteger(parameter.value))
|
val refinedChecker = if (name == OperatorNameConventions.MOD.asString()) {
|
||||||
|
getBinaryOperation(receiver, parameter, OperatorNameConventions.REM.asString())?.second ?: return null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
checker
|
||||||
|
}
|
||||||
|
|
||||||
|
val resultInBigIntegers = refinedChecker(toBigInteger(receiver.value), toBigInteger(parameter.value))
|
||||||
|
|
||||||
if (toBigInteger(actualResult) != resultInBigIntegers) {
|
if (toBigInteger(actualResult) != resultInBigIntegers) {
|
||||||
trace.report(Errors.INTEGER_OVERFLOW.on(callExpression.getStrictParentOfType<KtExpression>() ?: callExpression))
|
trace.report(Errors.INTEGER_OVERFLOW.on(callExpression.getStrictParentOfType<KtExpression>() ?: callExpression))
|
||||||
@@ -534,6 +541,9 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
return actualResult
|
return actualResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getBinaryOperation(receiver: OperationArgument, parameter: OperationArgument, name: String) =
|
||||||
|
binaryOperations[BinaryOperationKey(receiver.ctcType, parameter.ctcType, name)]
|
||||||
|
|
||||||
private fun isDivisionByZero(name: String, parameter: Any?): Boolean {
|
private fun isDivisionByZero(name: String, parameter: Any?): Boolean {
|
||||||
if (name == OperatorConventions.BINARY_OPERATION_NAMES[KtTokens.DIV]!!.asString()) {
|
if (name == OperatorConventions.BINARY_OPERATION_NAMES[KtTokens.DIV]!!.asString()) {
|
||||||
if (isIntegerType(parameter)) {
|
if (isIntegerType(parameter)) {
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ val l20: Int = <!INTEGER_OVERFLOW!>30 * 24 * 60 * 60 * 1000<!>
|
|||||||
val l21: Int = intMinValue - intMinValue
|
val l21: Int = intMinValue - intMinValue
|
||||||
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
||||||
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||||
|
val l24: Int = (-1).<!DEPRECATION!>mod<!>(5)
|
||||||
|
val l25: Int = (-1).rem(5)
|
||||||
|
val l26: Int = (-1) % 5
|
||||||
|
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val a3: Int = <!INTEGER_OVERFLOW!><!INTEGER_OVERFLOW!>intMaxValue + 1<!> - 10<!>
|
val a3: Int = <!INTEGER_OVERFLOW!><!INTEGER_OVERFLOW!>intMaxValue + 1<!> - 10<!>
|
||||||
@@ -41,6 +45,9 @@ fun foo() {
|
|||||||
val l21: Int = intMinValue - intMinValue
|
val l21: Int = intMinValue - intMinValue
|
||||||
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
||||||
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||||
|
val l24: Int = (-1).<!DEPRECATION!>mod<!>(5)
|
||||||
|
val l25: Int = (-1).rem(5)
|
||||||
|
val l26: Int = (-1) % 5
|
||||||
}
|
}
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
@@ -63,5 +70,8 @@ class A {
|
|||||||
val l21: Int = intMinValue - intMinValue
|
val l21: Int = intMinValue - intMinValue
|
||||||
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
||||||
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||||
|
val l24: Int = (-1).<!DEPRECATION!>mod<!>(5)
|
||||||
|
val l25: Int = (-1).rem(5)
|
||||||
|
val l26: Int = (-1) % 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,9 @@ public val l20: kotlin.Int = -1702967296
|
|||||||
public val l21: kotlin.Int = 0
|
public val l21: kotlin.Int = 0
|
||||||
public val l22: kotlin.Int = 0
|
public val l22: kotlin.Int = 0
|
||||||
public val l23: kotlin.Int = -1
|
public val l23: kotlin.Int = -1
|
||||||
|
public val l24: kotlin.Int = -1
|
||||||
|
public val l25: kotlin.Int = -1
|
||||||
|
public val l26: kotlin.Int = -1
|
||||||
public fun foo(): kotlin.Unit
|
public fun foo(): kotlin.Unit
|
||||||
|
|
||||||
public final class A {
|
public final class A {
|
||||||
|
|||||||
@@ -22,3 +22,7 @@ fun local() {
|
|||||||
<!UNSUPPORTED_FEATURE!>operator<!> fun Int.rem(x: Int) {}
|
<!UNSUPPORTED_FEATURE!>operator<!> fun Int.rem(x: Int) {}
|
||||||
<!UNSUPPORTED_FEATURE!>operator<!> fun String.remAssign(x: Int) {}
|
<!UNSUPPORTED_FEATURE!>operator<!> fun String.remAssign(x: Int) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun noOverflow() {
|
||||||
|
(-1).<!DEPRECATION!>mod<!>(5)
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public fun local(): kotlin.Unit
|
public fun local(): kotlin.Unit
|
||||||
|
public fun noOverflow(): kotlin.Unit
|
||||||
public operator fun Baz.rem(/*0*/ x: kotlin.Int): kotlin.Unit
|
public operator fun Baz.rem(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||||
|
|
||||||
public final class Bar {
|
public final class Bar {
|
||||||
|
|||||||
Reference in New Issue
Block a user