mirror of
https://github.com/github/codeql.git
synced 2026-01-30 14:52:57 +01:00
45 lines
1.2 KiB
Plaintext
45 lines
1.2 KiB
Plaintext
/**
|
|
* Provides classes and predicates for recognizing floating point expressions which cannot be NaN.
|
|
*/
|
|
|
|
import cpp
|
|
private import semmle.code.cpp.rangeanalysis.RangeSSA
|
|
|
|
/**
|
|
* Holds if `guard` won't return the value `polarity` when either
|
|
* operand is NaN.
|
|
*/
|
|
predicate nanExcludingComparison(ComparisonOperation guard, boolean polarity) {
|
|
polarity = true and
|
|
(
|
|
guard instanceof LTExpr or
|
|
guard instanceof LEExpr or
|
|
guard instanceof GTExpr or
|
|
guard instanceof GEExpr or
|
|
guard instanceof EQExpr
|
|
)
|
|
or
|
|
polarity = false and
|
|
guard instanceof NEExpr
|
|
}
|
|
|
|
/**
|
|
* Holds if `v` is a use of an SSA definition in `def` which cannot be NaN,
|
|
* by virtue of the guard in `def`.
|
|
*/
|
|
private predicate excludesNan(RangeSsaDefinition def, VariableAccess v) {
|
|
exists(VariableAccess inCond, ComparisonOperation guard, boolean branch, StackVariable lsv |
|
|
def.isGuardPhi(lsv, inCond, guard, branch) and
|
|
v = def.getAUse(lsv) and
|
|
guard.getAnOperand() = inCond and
|
|
nanExcludingComparison(guard, branch)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* A variable access which cannot be NaN.
|
|
*/
|
|
class NonNanVariableAccess extends VariableAccess {
|
|
NonNanVariableAccess() { excludesNan(_, this) }
|
|
}
|