Merge pull request #14656 from aschackmull/shared/range-utils

Rangeanalysis: Share ssaRead predicate
This commit is contained in:
Anders Schack-Mulligen
2023-11-01 15:57:52 +01:00
committed by GitHub
10 changed files with 128 additions and 192 deletions

View File

@@ -23,6 +23,8 @@ class SemSsaExplicitUpdate extends SemSsaVariable {
SemSsaExplicitUpdate() { Specific::explicitUpdate(this, sourceExpr) }
final SemExpr getSourceExpr() { result = sourceExpr }
final SemExpr getDefiningExpr() { result = sourceExpr }
}
class SemSsaPhiNode extends SemSsaVariable {

View File

@@ -151,7 +151,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
) {
exists(Bounds::SemSsaBound phibound, int v, int m |
edge.phiInput(phi, inp) and
phibound.getAVariable() = phi and
phibound.getVariable() = phi and
ssaModulus(inp, edge, phibound, v, m) and
mod = m.gcd(v) and
mod != 1
@@ -233,7 +233,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
) {
phiModulus(v, b, val, mod) and pos.hasReadOfVar(v)
or
b.(Bounds::SemSsaBound).getAVariable() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
b.(Bounds::SemSsaBound).getVariable() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
or
exists(SemExpr e, int val0, int delta |
semExprModulus(e, b, val0, mod) and

View File

@@ -8,14 +8,6 @@ private import RangeAnalysisImpl
private import codeql.rangeanalysis.RangeAnalysis
module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadCopy(SemExpr e) { none() }
/**
* Ignore the bound on this expression.
*
@@ -24,40 +16,6 @@ module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
*/
predicate ignoreExprBound(SemExpr e) { none() }
/**
* Ignore any inferred zero lower bound on this expression.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreZeroLowerBound(SemExpr e) { none() }
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadArithmeticExpr(SemExpr e) { none() }
/**
* Holds if the specified variable should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadAssignment(SemSsaVariable v) { none() }
/**
* Adds additional results to `ssaRead()` that are specific to Java.
*
* This predicate handles propagation of offsets for post-increment and post-decrement expressions
* in exactly the same way as the old Java implementation. Once the new implementation matches the
* old one, we should remove this predicate and propagate deltas for all similar patterns, whether
* or not they come from a post-increment/decrement expression.
*/
SemExpr specificSsaRead(SemSsaVariable v, float delta) { none() }
/**
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
*/

View File

@@ -52,9 +52,21 @@ module Sem implements Semantic {
class NegateExpr = SemNegateExpr;
class AddOneExpr = SemAddOneExpr;
class PreIncExpr = SemAddOneExpr;
class SubOneExpr = SemSubOneExpr;
class PreDecExpr = SemSubOneExpr;
class PostIncExpr extends SemUnaryExpr {
PostIncExpr() { none() }
}
class PostDecExpr extends SemUnaryExpr {
PostDecExpr() { none() }
}
class CopyValueExpr extends SemUnaryExpr {
CopyValueExpr() { this instanceof SemCopyValueExpr or this instanceof SemStoreExpr }
}
class ConditionalExpr = SemConditionalExpr;
@@ -116,7 +128,7 @@ module ConstantBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}
@@ -134,7 +146,7 @@ module RelativeBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}
@@ -150,7 +162,7 @@ module AllBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}

View File

@@ -9,14 +9,6 @@ private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
private import codeql.rangeanalysis.RangeAnalysis
module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadCopy(SemExpr e) { none() }
/**
* Ignore the bound on this expression.
*
@@ -56,40 +48,6 @@ module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
t instanceof SemFloatingPointType and lb = -(1.0 / 0.0) and ub = 1.0 / 0.0
}
/**
* Ignore any inferred zero lower bound on this expression.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreZeroLowerBound(SemExpr e) { none() }
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadArithmeticExpr(SemExpr e) { none() }
/**
* Holds if the specified variable should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadAssignment(SemSsaVariable v) { none() }
/**
* Adds additional results to `ssaRead()` that are specific to Java.
*
* This predicate handles propagation of offsets for post-increment and post-decrement expressions
* in exactly the same way as the old Java implementation. Once the new implementation matches the
* old one, we should remove this predicate and propagate deltas for all similar patterns, whether
* or not they come from a post-increment/decrement expression.
*/
SemExpr specificSsaRead(SemSsaVariable v, float delta) { none() }
/**
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
*/

View File

@@ -12,33 +12,27 @@ module RangeUtil<DeltaSig D, LangSig<Sem, D> Lang> implements UtilSig<Sem, D> {
/**
* Gets an expression that equals `v - d`.
*/
SemExpr semSsaRead(SemSsaVariable v, D::Delta delta) {
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()) and
not Lang::ignoreSsaReadArithmeticExpr(result)
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()) and
not Lang::ignoreSsaReadArithmeticExpr(result)
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue())
)
or
result = v.(SemSsaExplicitUpdate).getSourceExpr() and
delta = D::fromFloat(0) and
not Lang::ignoreSsaReadAssignment(v)
delta = D::fromFloat(0)
or
result = Lang::specificSsaRead(v, delta)
or
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta) and
not Lang::ignoreSsaReadCopy(result)
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta)
or
result.(SemStoreExpr).getOperand() = semSsaRead(v, delta)
}

View File

@@ -15,6 +15,8 @@ private import RangeUtils
private import Sign
module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
private import codeql.rangeanalysis.internal.RangeUtils::MakeUtils<Sem, D>
/**
* An SSA definition for which the analysis can compute the sign.
*
@@ -297,12 +299,12 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
|
testIsTrue = true and
comp.getLesserOperand() = lowerbound and
comp.getGreaterOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
comp.getGreaterOperand() = ssaRead(v, D::fromInt(0)) and
(if comp.isStrict() then isStrict = true else isStrict = false)
or
testIsTrue = false and
comp.getGreaterOperand() = lowerbound and
comp.getLesserOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
comp.getLesserOperand() = ssaRead(v, D::fromInt(0)) and
(if comp.isStrict() then isStrict = false else isStrict = true)
)
}
@@ -321,12 +323,12 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
|
testIsTrue = true and
comp.getGreaterOperand() = upperbound and
comp.getLesserOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
comp.getLesserOperand() = ssaRead(v, D::fromInt(0)) and
(if comp.isStrict() then isStrict = true else isStrict = false)
or
testIsTrue = false and
comp.getLesserOperand() = upperbound and
comp.getGreaterOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
comp.getGreaterOperand() = ssaRead(v, D::fromInt(0)) and
(if comp.isStrict() then isStrict = false else isStrict = true)
)
}
@@ -342,7 +344,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
exists(SemGuard guard, boolean testIsTrue, boolean polarity, SemExpr e |
pos.hasReadOfVar(pragma[only_bind_into](v)) and
semGuardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and
e = Utils::semSsaRead(pragma[only_bind_into](v), D::fromInt(0)) and
e = ssaRead(pragma[only_bind_into](v), D::fromInt(0)) and
guard.isEquality(eqbound, e, polarity) and
isEq = polarity.booleanXor(testIsTrue).booleanNot() and
not unknownSign(eqbound)