mirror of
https://github.com/github/codeql.git
synced 2026-04-24 00:05:14 +02:00
Merge pull request #14742 from aschackmull/rangeanalysis/share-util-3
Java/C++/Rangeanalysis: Share more range analysis utility predicates.
This commit is contained in:
@@ -26,11 +26,6 @@ module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
|
||||
*/
|
||||
predicate hasBound(SemExpr e, SemExpr bound, float delta, boolean upper) { none() }
|
||||
|
||||
/**
|
||||
* Holds if the value of `dest` is known to be `src + delta`.
|
||||
*/
|
||||
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, float delta) { none() }
|
||||
|
||||
/**
|
||||
* Gets the type that range analysis should use to track the result of the specified expression,
|
||||
* if a type other than the original type of the expression is to be used.
|
||||
|
||||
@@ -94,6 +94,8 @@ module Sem implements Semantic {
|
||||
|
||||
class SsaExplicitUpdate = SemSsaExplicitUpdate;
|
||||
|
||||
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, int delta) { none() }
|
||||
|
||||
predicate conversionCannotOverflow(Type fromType, Type toType) {
|
||||
SemanticType::conversionCannotOverflow(fromType, toType)
|
||||
}
|
||||
|
||||
@@ -58,11 +58,6 @@ module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
|
||||
*/
|
||||
predicate hasBound(SemExpr e, SemExpr bound, float delta, boolean upper) { none() }
|
||||
|
||||
/**
|
||||
* Holds if the value of `dest` is known to be `src + delta`.
|
||||
*/
|
||||
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, float delta) { none() }
|
||||
|
||||
/**
|
||||
* Gets the type that range analysis should use to track the result of the specified expression,
|
||||
* if a type other than the original type of the expression is to be used.
|
||||
|
||||
@@ -9,107 +9,6 @@ private import RangeAnalysisImpl
|
||||
private import ConstantAnalysis
|
||||
|
||||
module RangeUtil<DeltaSig D, LangSig<Sem, D> Lang> implements UtilSig<Sem, D> {
|
||||
/**
|
||||
* Gets an expression that equals `v - d`.
|
||||
*/
|
||||
private SemExpr semSsaRead(SemSsaVariable v, D::Delta delta) {
|
||||
// There are various language-specific extension points that can be removed once we no longer
|
||||
// expect to match the original Java implementation's results exactly.
|
||||
result = v.getAUse() and delta = D::fromInt(0)
|
||||
or
|
||||
exists(D::Delta d1, SemConstantIntegerExpr c |
|
||||
result.(SemAddExpr).hasOperands(semSsaRead(v, d1), c) and
|
||||
delta = D::fromFloat(D::toFloat(d1) - c.getIntValue())
|
||||
)
|
||||
or
|
||||
exists(SemSubExpr sub, D::Delta d1, SemConstantIntegerExpr c |
|
||||
result = sub and
|
||||
sub.getLeftOperand() = semSsaRead(v, d1) and
|
||||
sub.getRightOperand() = c and
|
||||
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue())
|
||||
)
|
||||
or
|
||||
result = v.(SemSsaExplicitUpdate).getSourceExpr() and
|
||||
delta = D::fromFloat(0)
|
||||
or
|
||||
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta)
|
||||
or
|
||||
result.(SemStoreExpr).getOperand() = semSsaRead(v, delta)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a condition that tests whether `v` equals `e + delta`.
|
||||
*
|
||||
* If the condition evaluates to `testIsTrue`:
|
||||
* - `isEq = true` : `v == e + delta`
|
||||
* - `isEq = false` : `v != e + delta`
|
||||
*/
|
||||
pragma[nomagic]
|
||||
SemGuard semEqFlowCond(
|
||||
SemSsaVariable v, SemExpr e, D::Delta delta, boolean isEq, boolean testIsTrue
|
||||
) {
|
||||
exists(boolean eqpolarity |
|
||||
result.isEquality(semSsaRead(v, delta), e, eqpolarity) and
|
||||
(testIsTrue = true or testIsTrue = false) and
|
||||
eqpolarity.booleanXor(testIsTrue).booleanNot() = isEq
|
||||
)
|
||||
or
|
||||
exists(boolean testIsTrue0 |
|
||||
semImplies_v2(result, testIsTrue, semEqFlowCond(v, e, delta, isEq, testIsTrue0), testIsTrue0)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `v` is an `SsaExplicitUpdate` that equals `e + delta`.
|
||||
*/
|
||||
predicate semSsaUpdateStep(SemSsaExplicitUpdate v, SemExpr e, D::Delta delta) {
|
||||
exists(SemExpr defExpr | defExpr = v.getSourceExpr() |
|
||||
defExpr.(SemCopyValueExpr).getOperand() = e and delta = D::fromFloat(0)
|
||||
or
|
||||
defExpr.(SemStoreExpr).getOperand() = e and delta = D::fromFloat(0)
|
||||
or
|
||||
defExpr.(SemAddOneExpr).getOperand() = e and delta = D::fromFloat(1)
|
||||
or
|
||||
defExpr.(SemSubOneExpr).getOperand() = e and delta = D::fromFloat(-1)
|
||||
or
|
||||
e = defExpr and
|
||||
not (
|
||||
defExpr instanceof SemCopyValueExpr or
|
||||
defExpr instanceof SemStoreExpr or
|
||||
defExpr instanceof SemAddOneExpr or
|
||||
defExpr instanceof SemSubOneExpr
|
||||
) and
|
||||
delta = D::fromFloat(0)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e1 + delta` equals `e2`.
|
||||
*/
|
||||
predicate semValueFlowStep(SemExpr e2, SemExpr e1, D::Delta delta) {
|
||||
e2.(SemCopyValueExpr).getOperand() = e1 and delta = D::fromFloat(0)
|
||||
or
|
||||
e2.(SemStoreExpr).getOperand() = e1 and delta = D::fromFloat(0)
|
||||
or
|
||||
e2.(SemAddOneExpr).getOperand() = e1 and delta = D::fromFloat(1)
|
||||
or
|
||||
e2.(SemSubOneExpr).getOperand() = e1 and delta = D::fromFloat(-1)
|
||||
or
|
||||
Lang::additionalValueFlowStep(e2, e1, delta)
|
||||
or
|
||||
exists(SemExpr x | e2.(SemAddExpr).hasOperands(e1, x) |
|
||||
D::fromInt(x.(SemConstantIntegerExpr).getIntValue()) = delta
|
||||
)
|
||||
or
|
||||
exists(SemExpr x, SemSubExpr sub |
|
||||
e2 = sub and
|
||||
sub.getLeftOperand() = e1 and
|
||||
sub.getRightOperand() = x
|
||||
|
|
||||
D::fromInt(-x.(SemConstantIntegerExpr).getIntValue()) = delta
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type used to track the specified expression's range information.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user