Skip to content

Commit c06bdb0

Browse files
committed
Detect simplifiable comparison of subtraction
1 parent eb83257 commit c06bdb0

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

codeql-custom-queries-java/queries/lib/Expressions.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ predicate comparesWithConstant(ComparisonExpr compExpr, Expr operand, int value,
202202
and compExpr.getGreaterOperand() = operand
203203
and compExpr.getLesserOperand().(CompileTimeConstantExpr).getIntValue() = value - 1
204204
and equalOrGreater = true
205+
// ignore floating point types because `1.5 >= 2` is not the same as `1.5 > 1`
206+
and not operand.getType() instanceof FloatingPointType
205207
)
206208
// operand >= value
207209
or (
@@ -223,5 +225,7 @@ predicate comparesWithConstant(ComparisonExpr compExpr, Expr operand, int value,
223225
and compExpr.getLesserOperand() = operand
224226
and compExpr.getGreaterOperand().(CompileTimeConstantExpr).getIntValue() = value - 1
225227
and equalOrGreater = false
228+
// ignore floating point types because `1.5 < 2` is not the same as `1.5 <= 1`
229+
and not operand.getType() instanceof FloatingPointType
226230
)
227231
}

codeql-custom-queries-java/queries/recommendations/simplifiable-comparison-or-equality-test.ql

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*
66
* The following shows some examples which can be simplified:
77
* - `-x == -y` → `x == y`
8+
* - `x - y > 0` → `x > y`
89
* - `x + 1 < 4` → `x < 3`
910
* - `x - 1 > 0` → `x > 1`
1011
* - `x * 2 > 4` → `x > 2`
@@ -13,9 +14,13 @@
1314
* However, there can be cases where the verbose expression reported by
1415
* this query is desired to make the intention clearer, for example
1516
* `index + 1` to indicate an increment of `index` in the subsequent lines.
17+
*
18+
* @id todo
19+
* @kind problem
1620
*/
1721

1822
import java
23+
import lib.Expressions
1924
import lib.Literals
2025

2126
class ComparisonOrEqualityTest extends BinaryExpr {
@@ -39,6 +44,36 @@ where
3944
and simplifiableExpr.getRightOperand() instanceof Negated
4045
and action = "Remove negation from both operands"
4146
)
47+
or exists(SubExpr subExpr, int compared, boolean equalOrGreater, string recommendedCmpOp |
48+
comparesWithConstant(simplifiableExpr, subExpr, compared, equalOrGreater)
49+
and (
50+
recommendedCmpOp = ">="
51+
// compares `>= 0`
52+
and compared = 0
53+
and equalOrGreater = true
54+
or
55+
recommendedCmpOp = ">"
56+
// compares `>= 1`
57+
and compared = 1
58+
and equalOrGreater = true
59+
// ignore floating point values because it can have results between 0 and 1
60+
and subExpr.getType() instanceof IntegralType
61+
or
62+
recommendedCmpOp = "<"
63+
// compares `< 0`
64+
and compared = 0
65+
and equalOrGreater = false
66+
or
67+
recommendedCmpOp = "<="
68+
// compares `< 1`
69+
and compared = 1
70+
and equalOrGreater = false
71+
// ignore floating point values because it can have results between 0 and 1
72+
and subExpr.getType() instanceof IntegralType
73+
)
74+
|
75+
action = "Remove subtraction and directly compare values: `a " + recommendedCmpOp + " b`"
76+
)
4277
or exists(Literal literalOperand, BinaryExpr simplifiableOperand, Literal removableLiteral |
4378
literalOperand = simplifiableExpr.getAnOperand()
4479
and simplifiableOperand = simplifiableExpr.getAnOperand()

0 commit comments

Comments
 (0)