diff --git a/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll b/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll index b663f336d0a..af42bb755e3 100644 --- a/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll @@ -187,6 +187,13 @@ private predicate boundFlowStepSsa( guard.controls(op2.getUse().getBlock(), testIsTrue) and reason = TCondReason(guard) ) + or + exists(IRGuardCondition guard, boolean testIsTrue, SafeCastInstruction cast | + valueNumberOfOperand(op2) = valueNumber(cast.getUnary()) and + guard = boundFlowCond(valueNumber(cast), op1, delta, upper, testIsTrue) and + guard.controls(op2.getUse().getBlock(), testIsTrue) and + reason = TCondReason(guard) + ) } /** @@ -259,7 +266,7 @@ private predicate safeCast(IntegralType fromtyp, IntegralType totyp) { private class SafeCastInstruction extends ConvertInstruction { SafeCastInstruction() { - safeCast(getResultType(), getUnary().getResultType()) + safeCast(getUnary().getResultType(), getResultType()) or getResultType() instanceof PointerType and getUnary().getResultType() instanceof PointerType diff --git a/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected b/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected index a7d7a6684e3..c5cc8315c6e 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected +++ b/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected @@ -59,3 +59,6 @@ | test.cpp:183:10:183:10 | Load: i | test.cpp:175:23:175:23 | InitializeParameter: x | -1 | true | CompareLT: ... < ... | test.cpp:182:9:182:13 | test.cpp:182:9:182:13 | | test.cpp:185:10:185:10 | Load: i | test.cpp:175:23:175:23 | InitializeParameter: x | 0 | true | CompareLT: ... < ... | test.cpp:176:7:176:11 | test.cpp:176:7:176:11 | | test.cpp:187:10:187:10 | Store: i | test.cpp:175:23:175:23 | InitializeParameter: x | 0 | false | CompareLT: ... < ... | test.cpp:182:9:182:13 | test.cpp:182:9:182:13 | +| test.cpp:199:10:199:10 | Load: i | test.cpp:197:25:197:25 | InitializeParameter: l | -1 | true | CompareLT: ... < ... | test.cpp:198:7:198:11 | test.cpp:198:7:198:11 | +| test.cpp:202:11:202:11 | Load: i | test.cpp:197:25:197:25 | InitializeParameter: l | -3 | true | CompareLT: ... < ... | test.cpp:201:7:201:15 | test.cpp:201:7:201:15 | +| test.cpp:208:10:208:10 | Load: x | test.cpp:206:24:206:24 | InitializeParameter: y | -3 | true | CompareLT: ... < ... | test.cpp:207:7:207:15 | test.cpp:207:7:207:15 | diff --git a/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/test.cpp b/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/test.cpp index bb0f23cea1b..c5b625da7e7 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/test.cpp +++ b/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/test.cpp @@ -186,3 +186,25 @@ int test15(int i, int x) { } return i; } + +// safe integer type conversion +int test16(int i) { + long l; + l = i; +} + +// implicit integer casts +void test17(int i, long l) { + if (i < l) { + sink(i); + } + if (i < l - 2) { + sink (i); + } +} + +void test18(int x, int y) { + if (x < y - 2) { + sink(x); + } +}