From b036ce409c2dbf60b0b3fc3c54c778ab5b03b41e Mon Sep 17 00:00:00 2001 From: Alexey Menshutin Date: Thu, 23 Mar 2023 16:14:36 +0300 Subject: [PATCH] Fix casts in overflow checking function --- .../examples/math/OverflowAsErrorTest.kt | 16 +++++++ .../main/kotlin/org/utbot/engine/Traverser.kt | 43 +++++++++++++------ .../utbot/examples/math/OverflowExamples.java | 3 ++ 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/examples/math/OverflowAsErrorTest.kt b/utbot-framework-test/src/test/kotlin/org/utbot/examples/math/OverflowAsErrorTest.kt index 982c5ceaa7..8b08299e3b 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/examples/math/OverflowAsErrorTest.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/examples/math/OverflowAsErrorTest.kt @@ -69,6 +69,22 @@ internal class OverflowAsErrorTest : UtValueTestCaseChecker( } } + @Test + fun testByteWithIntOverflow() { + withTreatingOverflowAsError { + checkWithException( + OverflowExamples::byteWithIntOverflow, + eq(2), + { x, y, r -> + runCatching { + Math.addExact(x.toInt(), y) + }.isFailure && r.isException() + }, + { x, y, r -> Math.addExact(x.toInt(), y).toByte() == r.getOrThrow() } + ) + } + } + @Test fun testByteSubOverflow() { withTreatingOverflowAsError { diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt index a82de5812f..35d77d9a0f 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt @@ -3767,21 +3767,40 @@ class Traverser( private fun TraversalContext.intOverflowCheck(op: BinopExpr, leftRaw: PrimitiveValue, rightRaw: PrimitiveValue) { // cast to the bigger type val sort = simpleMaxSort(leftRaw, rightRaw) as UtPrimitiveSort - val left = leftRaw.expr.toPrimitiveValue(sort.type) - val right = rightRaw.expr.toPrimitiveValue(sort.type) + val left = UtCastExpression(leftRaw, sort.type) + val right = UtCastExpression(rightRaw, sort.type) + + val leftPrimValue = left.toPrimitiveValue(left.type) + val rightPrimValue = right.toPrimitiveValue(right.type) val overflow = when (op) { - is JAddExpr -> { - mkNot(UtAddNoOverflowExpression(left.expr, right.expr)) - } - is JSubExpr -> { - mkNot(UtSubNoOverflowExpression(left.expr, right.expr)) - } + is JAddExpr -> mkNot(UtAddNoOverflowExpression(left, right)) + is JSubExpr -> mkNot(UtSubNoOverflowExpression(left, right)) is JMulExpr -> when (sort.type) { - is ByteType -> lowerIntMulOverflowCheck(left, right, Byte.MIN_VALUE.toInt(), Byte.MAX_VALUE.toInt()) - is ShortType -> lowerIntMulOverflowCheck(left, right, Short.MIN_VALUE.toInt(), Short.MAX_VALUE.toInt()) - is IntType -> higherIntMulOverflowCheck(left, right, Int.SIZE_BITS, Int.MIN_VALUE.toLong()) { it: UtExpression -> it.toIntValue() } - is LongType -> higherIntMulOverflowCheck(left, right, Long.SIZE_BITS, Long.MIN_VALUE) { it: UtExpression -> it.toLongValue() } + is ByteType -> lowerIntMulOverflowCheck( + leftPrimValue, + rightPrimValue, + Byte.MIN_VALUE.toInt(), + Byte.MAX_VALUE.toInt() + ) + is ShortType -> lowerIntMulOverflowCheck( + leftPrimValue, + rightPrimValue, + Short.MIN_VALUE.toInt(), + Short.MAX_VALUE.toInt() + ) + is IntType -> higherIntMulOverflowCheck( + leftPrimValue, + rightPrimValue, + Int.SIZE_BITS, + Int.MIN_VALUE.toLong() + ) { it: UtExpression -> it.toIntValue() } + is LongType -> higherIntMulOverflowCheck( + leftPrimValue, + rightPrimValue, + Long.SIZE_BITS, + Long.MIN_VALUE + ) { it: UtExpression -> it.toLongValue() } else -> null } else -> null diff --git a/utbot-sample/src/main/java/org/utbot/examples/math/OverflowExamples.java b/utbot-sample/src/main/java/org/utbot/examples/math/OverflowExamples.java index b1cc7fd4f7..271139ab2e 100644 --- a/utbot-sample/src/main/java/org/utbot/examples/math/OverflowExamples.java +++ b/utbot-sample/src/main/java/org/utbot/examples/math/OverflowExamples.java @@ -4,6 +4,9 @@ public class OverflowExamples { public byte byteAddOverflow(byte x, byte y) { return (byte) (x + y); } + public byte byteWithIntOverflow(byte x, int y) { + return (byte) (x + y); + } public byte byteMulOverflow(byte x, byte y) { return (byte) (x * y); }