mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Merge pull request #12599 from rdmarsh2/rdmarsh2/range-analysis-overflow
C++: add overflow detection to new range analysis
This commit is contained in:
@@ -8,6 +8,8 @@ private import semmle.code.cpp.ir.IR
|
|||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
|
||||||
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisImpl
|
||||||
|
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the lower bound of the expression.
|
* Gets the lower bound of the expression.
|
||||||
@@ -22,8 +24,10 @@ private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.Rang
|
|||||||
* `lowerBound(expr.getFullyConverted())`
|
* `lowerBound(expr.getFullyConverted())`
|
||||||
*/
|
*/
|
||||||
float lowerBound(Expr expr) {
|
float lowerBound(Expr expr) {
|
||||||
exists(Instruction i, SemBound b | i.getAst() = expr and b instanceof SemZeroBound |
|
exists(Instruction i, ConstantBounds::SemBound b |
|
||||||
semBounded(getSemanticExpr(i), b, result, false, _)
|
i.getAst() = expr and b instanceof ConstantBounds::SemZeroBound
|
||||||
|
|
|
||||||
|
ConstantStage::semBounded(getSemanticExpr(i), b, result, false, _)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,8 +44,10 @@ float lowerBound(Expr expr) {
|
|||||||
* `upperBound(expr.getFullyConverted())`
|
* `upperBound(expr.getFullyConverted())`
|
||||||
*/
|
*/
|
||||||
float upperBound(Expr expr) {
|
float upperBound(Expr expr) {
|
||||||
exists(Instruction i, SemBound b | i.getAst() = expr and b instanceof SemZeroBound |
|
exists(Instruction i, ConstantBounds::SemBound b |
|
||||||
semBounded(getSemanticExpr(i), b, result, true, _)
|
i.getAst() = expr and b instanceof ConstantBounds::SemZeroBound
|
||||||
|
|
|
||||||
|
ConstantStage::semBounded(getSemanticExpr(i), b, result, true, _)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +96,15 @@ predicate defMightOverflow(RangeSsaDefinition def, StackVariable v) {
|
|||||||
* does not consider the possibility that the expression might overflow
|
* does not consider the possibility that the expression might overflow
|
||||||
* due to a conversion.
|
* due to a conversion.
|
||||||
*/
|
*/
|
||||||
predicate exprMightOverflowNegatively(Expr expr) { none() }
|
predicate exprMightOverflowNegatively(Expr expr) {
|
||||||
|
lowerBound(expr) < exprMinVal(expr)
|
||||||
|
or
|
||||||
|
exists(SemanticExprConfig::Expr semExpr |
|
||||||
|
semExpr.getUnconverted().getAst() = expr and
|
||||||
|
ConstantStage::potentiallyOverflowingExpr(false, semExpr) and
|
||||||
|
not ConstantStage::initialBounded(semExpr, _, _, false, _, _, _)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the expression might overflow negatively. Conversions
|
* Holds if the expression might overflow negatively. Conversions
|
||||||
@@ -108,7 +122,15 @@ predicate convertedExprMightOverflowNegatively(Expr expr) {
|
|||||||
* does not consider the possibility that the expression might overflow
|
* does not consider the possibility that the expression might overflow
|
||||||
* due to a conversion.
|
* due to a conversion.
|
||||||
*/
|
*/
|
||||||
predicate exprMightOverflowPositively(Expr expr) { none() }
|
predicate exprMightOverflowPositively(Expr expr) {
|
||||||
|
upperBound(expr) > exprMaxVal(expr)
|
||||||
|
or
|
||||||
|
exists(SemanticExprConfig::Expr semExpr |
|
||||||
|
semExpr.getUnconverted().getAst() = expr and
|
||||||
|
ConstantStage::potentiallyOverflowingExpr(true, semExpr) and
|
||||||
|
not ConstantStage::initialBounded(semExpr, _, _, true, _, _, _)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the expression might overflow positively. Conversions
|
* Holds if the expression might overflow positively. Conversions
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
private import RangeAnalysisStage
|
private import RangeAnalysisStage
|
||||||
|
private import RangeAnalysisImpl
|
||||||
|
|
||||||
module FloatDelta implements DeltaSig {
|
module FloatDelta implements DeltaSig {
|
||||||
class Delta = float;
|
class Delta = float;
|
||||||
@@ -18,3 +19,36 @@ module FloatDelta implements DeltaSig {
|
|||||||
bindingset[f]
|
bindingset[f]
|
||||||
Delta fromFloat(float f) { result = f }
|
Delta fromFloat(float f) { result = f }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module FloatOverflow implements OverflowSig<FloatDelta> {
|
||||||
|
predicate semExprDoesNotOverflow(boolean positively, SemExpr expr) {
|
||||||
|
exists(float lb, float ub, float delta |
|
||||||
|
typeBounds(expr.getSemType(), lb, ub) and
|
||||||
|
ConstantStage::initialBounded(expr, any(ConstantBounds::SemZeroBound b), delta, positively, _,
|
||||||
|
_, _)
|
||||||
|
|
|
||||||
|
positively = true and delta < ub
|
||||||
|
or
|
||||||
|
positively = false and delta > lb
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
additional predicate typeBounds(SemType t, float lb, float ub) {
|
||||||
|
exists(SemIntegerType integralType, float limit |
|
||||||
|
integralType = t and limit = 2.pow(8 * integralType.getByteSize())
|
||||||
|
|
|
||||||
|
if integralType instanceof SemBooleanType
|
||||||
|
then lb = 0 and ub = 1
|
||||||
|
else
|
||||||
|
if integralType.isSigned()
|
||||||
|
then (
|
||||||
|
lb = -(limit / 2) and ub = (limit / 2) - 1
|
||||||
|
) else (
|
||||||
|
lb = 0 and ub = limit - 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// This covers all floating point types. The range is (-Inf, +Inf).
|
||||||
|
t instanceof SemFloatingPointType and lb = -(1.0 / 0.0) and ub = 1.0 / 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
import RangeAnalysisImpl
|
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound
|
||||||
|
private import RangeAnalysisImpl as Impl
|
||||||
|
import Impl::Public
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
|||||||
private import RangeAnalysisStage
|
private import RangeAnalysisStage
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
||||||
|
|
||||||
module CppLangImpl implements LangSig<FloatDelta> {
|
module CppLangImplConstant implements LangSig<FloatDelta> {
|
||||||
/**
|
/**
|
||||||
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
|
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
|
||||||
*
|
*
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
private import RangeAnalysisStage
|
private import RangeAnalysisStage
|
||||||
private import RangeAnalysisSpecific
|
private import RangeAnalysisConstantSpecific
|
||||||
|
private import RangeAnalysisRelativeSpecific
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
||||||
private import RangeUtils
|
private import RangeUtils
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound as SemanticBound
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound as SemanticBound
|
||||||
@@ -28,7 +29,7 @@ module ConstantBounds implements BoundSig<FloatDelta> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private module RelativeBounds implements BoundSig<FloatDelta> {
|
module RelativeBounds implements BoundSig<FloatDelta> {
|
||||||
class SemBound instanceof SemanticBound::SemBound {
|
class SemBound instanceof SemanticBound::SemBound {
|
||||||
SemBound() { not this instanceof SemanticBound::SemZeroBound }
|
SemBound() { not this instanceof SemanticBound::SemZeroBound }
|
||||||
|
|
||||||
@@ -46,11 +47,13 @@ private module RelativeBounds implements BoundSig<FloatDelta> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private module ConstantStage =
|
module ConstantStage =
|
||||||
RangeStage<FloatDelta, ConstantBounds, CppLangImpl, RangeUtil<FloatDelta, CppLangImpl>>;
|
RangeStage<FloatDelta, ConstantBounds, FloatOverflow, CppLangImplConstant,
|
||||||
|
RangeUtil<FloatDelta, CppLangImplConstant>>;
|
||||||
|
|
||||||
private module RelativeStage =
|
module RelativeStage =
|
||||||
RangeStage<FloatDelta, RelativeBounds, CppLangImpl, RangeUtil<FloatDelta, CppLangImpl>>;
|
RangeStage<FloatDelta, RelativeBounds, FloatOverflow, CppLangImplRelative,
|
||||||
|
RangeUtil<FloatDelta, CppLangImplRelative>>;
|
||||||
|
|
||||||
private newtype TSemReason =
|
private newtype TSemReason =
|
||||||
TSemNoReason() or
|
TSemNoReason() or
|
||||||
@@ -60,48 +63,52 @@ private newtype TSemReason =
|
|||||||
guard = any(RelativeStage::SemCondReason reason).getCond()
|
guard = any(RelativeStage::SemCondReason reason).getCond()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
ConstantStage::SemReason constantReason(SemReason reason) {
|
||||||
* A reason for an inferred bound. This can either be `CondReason` if the bound
|
|
||||||
* is due to a specific condition, or `NoReason` if the bound is inferred
|
|
||||||
* without going through a bounding condition.
|
|
||||||
*/
|
|
||||||
abstract class SemReason extends TSemReason {
|
|
||||||
/** Gets a textual representation of this reason. */
|
|
||||||
abstract string toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A reason for an inferred bound that indicates that the bound is inferred
|
|
||||||
* without going through a bounding condition.
|
|
||||||
*/
|
|
||||||
class SemNoReason extends SemReason, TSemNoReason {
|
|
||||||
override string toString() { result = "NoReason" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A reason for an inferred bound pointing to a condition. */
|
|
||||||
class SemCondReason extends SemReason, TSemCondReason {
|
|
||||||
/** Gets the condition that is the reason for the bound. */
|
|
||||||
SemGuard getCond() { this = TSemCondReason(result) }
|
|
||||||
|
|
||||||
override string toString() { result = getCond().toString() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConstantStage::SemReason constantReason(SemReason reason) {
|
|
||||||
result instanceof ConstantStage::SemNoReason and reason instanceof SemNoReason
|
result instanceof ConstantStage::SemNoReason and reason instanceof SemNoReason
|
||||||
or
|
or
|
||||||
result.(ConstantStage::SemCondReason).getCond() = reason.(SemCondReason).getCond()
|
result.(ConstantStage::SemCondReason).getCond() = reason.(SemCondReason).getCond()
|
||||||
}
|
}
|
||||||
|
|
||||||
private RelativeStage::SemReason relativeReason(SemReason reason) {
|
RelativeStage::SemReason relativeReason(SemReason reason) {
|
||||||
result instanceof RelativeStage::SemNoReason and reason instanceof SemNoReason
|
result instanceof RelativeStage::SemNoReason and reason instanceof SemNoReason
|
||||||
or
|
or
|
||||||
result.(RelativeStage::SemCondReason).getCond() = reason.(SemCondReason).getCond()
|
result.(RelativeStage::SemCondReason).getCond() = reason.(SemCondReason).getCond()
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate semBounded(
|
import Public
|
||||||
SemExpr e, SemanticBound::SemBound b, float delta, boolean upper, SemReason reason
|
|
||||||
) {
|
module Public {
|
||||||
ConstantStage::semBounded(e, b, delta, upper, constantReason(reason))
|
predicate semBounded(
|
||||||
or
|
SemExpr e, SemanticBound::SemBound b, float delta, boolean upper, SemReason reason
|
||||||
RelativeStage::semBounded(e, b, delta, upper, relativeReason(reason))
|
) {
|
||||||
|
ConstantStage::semBounded(e, b, delta, upper, constantReason(reason))
|
||||||
|
or
|
||||||
|
RelativeStage::semBounded(e, b, delta, upper, relativeReason(reason))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reason for an inferred bound. This can either be `CondReason` if the bound
|
||||||
|
* is due to a specific condition, or `NoReason` if the bound is inferred
|
||||||
|
* without going through a bounding condition.
|
||||||
|
*/
|
||||||
|
abstract class SemReason extends TSemReason {
|
||||||
|
/** Gets a textual representation of this reason. */
|
||||||
|
abstract string toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reason for an inferred bound that indicates that the bound is inferred
|
||||||
|
* without going through a bounding condition.
|
||||||
|
*/
|
||||||
|
class SemNoReason extends SemReason, TSemNoReason {
|
||||||
|
override string toString() { result = "NoReason" }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A reason for an inferred bound pointing to a condition. */
|
||||||
|
class SemCondReason extends SemReason, TSemCondReason {
|
||||||
|
/** Gets the condition that is the reason for the bound. */
|
||||||
|
SemGuard getCond() { this = TSemCondReason(result) }
|
||||||
|
|
||||||
|
override string toString() { result = getCond().toString() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* C++-specific implementation of range analysis.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
||||||
|
private import RangeAnalysisStage
|
||||||
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
||||||
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.IntDelta
|
||||||
|
private import RangeAnalysisImpl
|
||||||
|
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||||
|
|
||||||
|
module CppLangImplRelative implements LangSig<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.
|
||||||
|
*
|
||||||
|
* 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 ignoreExprBound(SemExpr e) {
|
||||||
|
exists(boolean upper, float delta, ConstantBounds::SemZeroBound b, float lb, float ub |
|
||||||
|
ConstantStage::semBounded(e, b, delta, upper, _) and
|
||||||
|
typeBounds(e.getSemType(), lb, ub) and
|
||||||
|
(
|
||||||
|
upper = false and
|
||||||
|
delta < lb
|
||||||
|
or
|
||||||
|
upper = true and
|
||||||
|
delta > ub
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate typeBounds(SemType t, float lb, float ub) {
|
||||||
|
exists(SemIntegerType integralType, float limit |
|
||||||
|
integralType = t and limit = 2.pow(8 * integralType.getByteSize())
|
||||||
|
|
|
||||||
|
if integralType instanceof SemBooleanType
|
||||||
|
then lb = 0 and ub = 1
|
||||||
|
else
|
||||||
|
if integralType.isSigned()
|
||||||
|
then (
|
||||||
|
lb = -(limit / 2) and ub = (limit / 2) - 1
|
||||||
|
) else (
|
||||||
|
lb = 0 and ub = limit - 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// This covers all floating point types. The range is (-Inf, +Inf).
|
||||||
|
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`).
|
||||||
|
*/
|
||||||
|
predicate hasConstantBound(SemExpr e, float bound, boolean upper) { none() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `e >= bound + delta` (if `upper = false`) or `e <= bound + delta` (if `upper = true`).
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* This predicate is commonly used in languages that support immutable "boxed" types that are
|
||||||
|
* actually references but whose values can be tracked as the type contained in the box.
|
||||||
|
*/
|
||||||
|
SemType getAlternateType(SemExpr e) { none() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type that range analysis should use to track the result of the specified source
|
||||||
|
* variable, if a type other than the original type of the expression is to be used.
|
||||||
|
*
|
||||||
|
* This predicate is commonly used in languages that support immutable "boxed" types that are
|
||||||
|
* actually references but whose values can be tracked as the type contained in the box.
|
||||||
|
*/
|
||||||
|
SemType getAlternateTypeForSsaVariable(SemSsaVariable var) { none() }
|
||||||
|
}
|
||||||
@@ -73,6 +73,7 @@ import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticCFG
|
|||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticType
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticType
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticOpcode
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticOpcode
|
||||||
private import ConstantAnalysis
|
private import ConstantAnalysis
|
||||||
|
private import Sign
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -240,11 +241,19 @@ signature module BoundSig<DeltaSig D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<D> UtilParam> {
|
signature module OverflowSig<DeltaSig D> {
|
||||||
|
predicate semExprDoesNotOverflow(boolean positively, SemExpr expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
module RangeStage<
|
||||||
|
DeltaSig D, BoundSig<D> Bounds, OverflowSig<D> OverflowParam, LangSig<D> LangParam,
|
||||||
|
UtilSig<D> UtilParam>
|
||||||
|
{
|
||||||
private import Bounds
|
private import Bounds
|
||||||
private import LangParam
|
private import LangParam
|
||||||
private import UtilParam
|
private import UtilParam
|
||||||
private import D
|
private import D
|
||||||
|
private import OverflowParam
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An expression that does conversion, boxing, or unboxing
|
* An expression that does conversion, boxing, or unboxing
|
||||||
@@ -920,6 +929,81 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
|
|||||||
bounded(cast.getOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
|
bounded(cast.getOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
predicate bounded(
|
||||||
|
SemExpr e, SemBound b, D::Delta delta, boolean upper, boolean fromBackEdge, D::Delta origdelta,
|
||||||
|
SemReason reason
|
||||||
|
) {
|
||||||
|
initialBounded(e, b, delta, upper, fromBackEdge, origdelta, reason) and
|
||||||
|
(
|
||||||
|
semExprDoesNotOverflow(upper.booleanNot(), e)
|
||||||
|
or
|
||||||
|
not potentiallyOverflowingExpr(upper.booleanNot(), e)
|
||||||
|
or
|
||||||
|
exists(D::Delta otherDelta |
|
||||||
|
initialBounded(e, _, otherDelta, upper.booleanNot(), _, _, _) and
|
||||||
|
(
|
||||||
|
upper = true and D::toFloat(otherDelta) >= 0
|
||||||
|
or
|
||||||
|
upper = false and D::toFloat(otherDelta) <= 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate potentiallyOverflowingExpr(boolean positively, SemExpr expr) {
|
||||||
|
(
|
||||||
|
expr.getOpcode() instanceof Opcode::Add or
|
||||||
|
expr.getOpcode() instanceof Opcode::PointerAdd
|
||||||
|
) and
|
||||||
|
(
|
||||||
|
positively = true and
|
||||||
|
(
|
||||||
|
pragma[only_bind_out](semExprSign(expr.(SemBinaryExpr).getLeftOperand())) = TPos() and
|
||||||
|
pragma[only_bind_out](semExprSign(expr.(SemBinaryExpr).getRightOperand())) = TPos()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
positively = false and
|
||||||
|
(
|
||||||
|
pragma[only_bind_out](semExprSign(expr.(SemBinaryExpr).getLeftOperand())) = TNeg() and
|
||||||
|
pragma[only_bind_out](semExprSign(expr.(SemBinaryExpr).getRightOperand())) = TNeg()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
(
|
||||||
|
expr.getOpcode() instanceof Opcode::Sub or
|
||||||
|
expr.getOpcode() instanceof Opcode::PointerSub
|
||||||
|
) and
|
||||||
|
(
|
||||||
|
positively = true and
|
||||||
|
(
|
||||||
|
pragma[only_bind_out](semExprSign(expr.(SemBinaryExpr).getLeftOperand())) = TPos() and
|
||||||
|
pragma[only_bind_out](semExprSign(expr.(SemBinaryExpr).getRightOperand())) = TNeg()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
positively = false and
|
||||||
|
(
|
||||||
|
pragma[only_bind_out](semExprSign(expr.(SemBinaryExpr).getLeftOperand())) = TNeg() and
|
||||||
|
pragma[only_bind_out](semExprSign(expr.(SemBinaryExpr).getRightOperand())) = TPos()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
positively in [true, false] and
|
||||||
|
(
|
||||||
|
expr.getOpcode() instanceof Opcode::Mul or
|
||||||
|
expr.getOpcode() instanceof Opcode::ShiftLeft
|
||||||
|
)
|
||||||
|
or
|
||||||
|
positively = false and
|
||||||
|
(
|
||||||
|
expr.getOpcode() instanceof Opcode::Negate or
|
||||||
|
expr.getOpcode() instanceof Opcode::SubOne or
|
||||||
|
expr.(SemDivExpr).getSemType() instanceof SemFloatingPointType
|
||||||
|
)
|
||||||
|
or
|
||||||
|
positively = true and
|
||||||
|
expr.getOpcode() instanceof Opcode::AddOne
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes a normal form of `x` where -0.0 has changed to +0.0. This can be
|
* Computes a normal form of `x` where -0.0 has changed to +0.0. This can be
|
||||||
* needed on the lesser side of a floating-point comparison or on both sides of
|
* needed on the lesser side of a floating-point comparison or on both sides of
|
||||||
@@ -934,7 +1018,7 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
|
|||||||
* - `upper = true` : `e <= b + delta`
|
* - `upper = true` : `e <= b + delta`
|
||||||
* - `upper = false` : `e >= b + delta`
|
* - `upper = false` : `e >= b + delta`
|
||||||
*/
|
*/
|
||||||
private predicate bounded(
|
predicate initialBounded(
|
||||||
SemExpr e, SemBound b, D::Delta delta, boolean upper, boolean fromBackEdge, D::Delta origdelta,
|
SemExpr e, SemBound b, D::Delta delta, boolean upper, boolean fromBackEdge, D::Delta origdelta,
|
||||||
SemReason reason
|
SemReason reason
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
||||||
private import RangeAnalysisSpecific
|
private import RangeAnalysisRelativeSpecific
|
||||||
private import RangeAnalysisStage as Range
|
private import RangeAnalysisStage as Range
|
||||||
private import ConstantAnalysis
|
private import ConstantAnalysis
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnaly
|
|||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisSpecific
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisRelativeSpecific
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisImpl
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisImpl
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
||||||
import semmle.code.cpp.ir.IR as IR
|
import semmle.code.cpp.ir.IR as IR
|
||||||
import TestUtilities.InlineExpectationsTest
|
import TestUtilities.InlineExpectationsTest
|
||||||
|
|
||||||
module ModulusAnalysisInstantiated =
|
module ModulusAnalysisInstantiated =
|
||||||
ModulusAnalysis<FloatDelta, ConstantBounds, RangeUtil<FloatDelta, CppLangImpl>>;
|
ModulusAnalysis<FloatDelta, ConstantBounds, RangeUtil<FloatDelta, CppLangImplRelative>>;
|
||||||
|
|
||||||
class ModulusAnalysisTest extends InlineExpectationsTest {
|
class ModulusAnalysisTest extends InlineExpectationsTest {
|
||||||
ModulusAnalysisTest() { this = "ModulusAnalysisTest" }
|
ModulusAnalysisTest() { this = "ModulusAnalysisTest" }
|
||||||
|
|||||||
23
cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql
Normal file
23
cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import cpp
|
||||||
|
import semmle.code.cpp.rangeanalysis.new.SimpleRangeAnalysis
|
||||||
|
import TestUtilities.InlineExpectationsTest
|
||||||
|
|
||||||
|
class RangeAnalysisTest extends InlineExpectationsTest {
|
||||||
|
RangeAnalysisTest() { this = "RangeAnalysisTest" }
|
||||||
|
|
||||||
|
override string getARelevantTag() { result = "overflow" }
|
||||||
|
|
||||||
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
|
exists(Expr e |
|
||||||
|
tag = "overflow" and
|
||||||
|
element = e.toString() and
|
||||||
|
location = e.getLocation() and
|
||||||
|
value =
|
||||||
|
strictconcat(string s |
|
||||||
|
s = "+" and exprMightOverflowPositively(e)
|
||||||
|
or
|
||||||
|
s = "-" and exprMightOverflowNegatively(e)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,9 +8,9 @@ int test1(struct List* p) {
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
for (; p; p = p->next) {
|
for (; p; p = p->next) {
|
||||||
count = count+1;
|
count = count+1;
|
||||||
range(count); // $ range===count:p+1 range=>=1
|
range(count); // $ range===count:p+1
|
||||||
}
|
}
|
||||||
range(count); // $ range=>=0
|
range(count);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,13 +40,13 @@ int test4() {
|
|||||||
int total = 0;
|
int total = 0;
|
||||||
for (i = 0; i < 2; i = i+1) {
|
for (i = 0; i < 2; i = i+1) {
|
||||||
range(i); // $ range=<=1 range=>=0
|
range(i); // $ range=<=1 range=>=0
|
||||||
range(total); // $ range=>=0
|
range(total);
|
||||||
total += i;
|
total += i;
|
||||||
range(total); // $ range=<=i+1 range=<=i+1 range=>=0 range=>=i+0
|
range(total); // $ range=<=i+1 range=<=i+1 MISSING: range=>=0 range=>=i+0
|
||||||
}
|
}
|
||||||
range(total); // $ range=>=0
|
range(total); // $ MISSING: range=>=0
|
||||||
range(i); // $ range===2
|
range(i); // $ range===2
|
||||||
range(total + i); // $ range===i+2 range=>=2 range=>=i+0
|
range(total + i); // $ range=<=i+2 MISSING: range===i+2 range=>=2 range=>=i+0
|
||||||
return total + i;
|
return total + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,13 +55,13 @@ int test5() {
|
|||||||
int total = 0;
|
int total = 0;
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
range(i); // $ range=<=1 range=>=0
|
range(i); // $ range=<=1 range=>=0
|
||||||
range(total); // $ range=>=0
|
range(total); // $ MISSING: range=>=0
|
||||||
total += i;
|
total += i;
|
||||||
range(total); // $ range=<=i+1 range=>=0 range=>=i+0
|
range(total); // $ range=<=i+1 MISSING: range=>=0 range=>=i+0
|
||||||
}
|
}
|
||||||
range(total); // $ range=>=0
|
range(total); // $ MISSING: range=>=0
|
||||||
range(i); // $ range===2
|
range(i); // $ range===2
|
||||||
range(total + i); // $ range===i+2 range=>=2 range=>=i+0
|
range(total + i); // $ range=<=i+2 MISSING: range===i+2 range=>=2 range=>=i+0
|
||||||
return total + i;
|
return total + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,9 +70,9 @@ int test6() {
|
|||||||
int total = 0;
|
int total = 0;
|
||||||
for (i = 0; i+2 < 4; i = i+1) {
|
for (i = 0; i+2 < 4; i = i+1) {
|
||||||
range(i); // $ range=<=1 range=>=0
|
range(i); // $ range=<=1 range=>=0
|
||||||
range(total); // $ range=>=0
|
range(total); // $ MISSING: range=>=0
|
||||||
total += i;
|
total += i;
|
||||||
range(total); // $ range=<=i+1 range=>=0 range=>=i+0
|
range(total); // $ range=<=i+1 MISSING: range=>=0 range=>=i+0
|
||||||
}
|
}
|
||||||
return total + i;
|
return total + i;
|
||||||
}
|
}
|
||||||
@@ -168,19 +168,19 @@ typedef unsigned long long size_type;
|
|||||||
|
|
||||||
size_type test12_helper() {
|
size_type test12_helper() {
|
||||||
static size_type n = 0;
|
static size_type n = 0;
|
||||||
return n++;
|
return n++; // $ overflow=+
|
||||||
}
|
}
|
||||||
|
|
||||||
int test12() {
|
int test12() {
|
||||||
size_type Start = 0;
|
size_type Start = 0;
|
||||||
while (Start <= test12_helper()-1)
|
while (Start <= test12_helper()-1)
|
||||||
{
|
{
|
||||||
range(Start);
|
range(Start); // $ MISSING:range=>=0
|
||||||
const size_type Length = test12_helper();
|
const size_type Length = test12_helper();
|
||||||
Start += Length + 1;
|
Start += Length + 1; // $ overflow=+
|
||||||
range(Start);
|
range(Start); // $ MISSING:range=>=1 MISSING:range=>=Start+1 MISSING:range=">=call to test12_helper+1"
|
||||||
}
|
}
|
||||||
range(Start);
|
range(Start); // $ MISSING:range=>=0
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -190,13 +190,13 @@ int test13(char c, int i) {
|
|||||||
unsigned char uc = c;
|
unsigned char uc = c;
|
||||||
range(uc);
|
range(uc);
|
||||||
unsigned int x = 0;
|
unsigned int x = 0;
|
||||||
unsigned int y = x-1;
|
unsigned int y = x-1; // $ overflow=-
|
||||||
range(y); // $ range===-1
|
range(y); // $ range===-1 overflow=-
|
||||||
int z = i+1;
|
int z = i+1; // $ overflow=+
|
||||||
range(z); // $ range===i+1
|
range(z); // $ range===i+1
|
||||||
range(c + i + uc + x + y + z);
|
range(c + i + uc + x + y + z); // $ overflow=+- overflow=+ overflow=- MISSING: range=>=1
|
||||||
range((double)(c + i + uc + x + y + z));
|
range((double)(c + i + uc + x + y + z)); // $ overflow=+ overflow=+- overflow=- MISSING: range=>=1
|
||||||
return (double)(c + i + uc + x + y + z);
|
return (double)(c + i + uc + x + y + z); // $ overflow=+- overflow=+ overflow=-
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regression test for ODASA-6013.
|
// Regression test for ODASA-6013.
|
||||||
@@ -213,8 +213,8 @@ int test14(int x) {
|
|||||||
range(c0);
|
range(c0);
|
||||||
unsigned short s0 = x;
|
unsigned short s0 = x;
|
||||||
range(s0);
|
range(s0);
|
||||||
range(x0 + x1 + x2 + x3 + c0 + s0);
|
range(x0 + x1 + x2 + x3 + c0 + s0); // $ overflow=+ overflow=+-
|
||||||
return x0 + x1 + x2 + x3 + c0 + s0;
|
return x0 + x1 + x2 + x3 + c0 + s0; // $ overflow=+ overflow=+-
|
||||||
}
|
}
|
||||||
|
|
||||||
long long test15(long long x) {
|
long long test15(long long x) {
|
||||||
@@ -243,7 +243,7 @@ int test_unary(int a) {
|
|||||||
range(b); // $ range=<=11 range=>=0
|
range(b); // $ range=<=11 range=>=0
|
||||||
int c = -a;
|
int c = -a;
|
||||||
range(c); // $ range=<=0 range=>=-11
|
range(c); // $ range=<=0 range=>=-11
|
||||||
range(b+c); // $ range=<=11 range=>=-11
|
range(b+c); // $ range=<=11 range=>=-11 MISSING:range=">=- ...+0"
|
||||||
total += b+c;
|
total += b+c;
|
||||||
range(total); // $ range=<=0+11 range=<=19 range=>=0-11 range=>=-19
|
range(total); // $ range=<=0+11 range=<=19 range=>=0-11 range=>=-19
|
||||||
}
|
}
|
||||||
@@ -273,7 +273,7 @@ int test_unary(int a) {
|
|||||||
range(b); // $ range=<=0 range=>=-7
|
range(b); // $ range=<=0 range=>=-7
|
||||||
int c = -a;
|
int c = -a;
|
||||||
range(c); // $ range=<=7 range=>=0
|
range(c); // $ range=<=7 range=>=0
|
||||||
range(b+c); // $ range=>=-7 range=<=7
|
range(b+c); // $ range=>=-7 range=<=7 MISSING:range="<=- ...+0"
|
||||||
total += b+c;
|
total += b+c;
|
||||||
range(total); // $ range="<=- ...+7" range="<=- ...+15" range="<=- ...+33" range=">=- ...-7" range=">=- ...-15" range=">=- ...-33" range=<=0+44 range=<=52 range=>=0-44 range=>=-52
|
range(total); // $ range="<=- ...+7" range="<=- ...+15" range="<=- ...+33" range=">=- ...-7" range=">=- ...-15" range=">=- ...-33" range=<=0+44 range=<=52 range=>=0-44 range=>=-52
|
||||||
}
|
}
|
||||||
@@ -315,9 +315,9 @@ int test_mult01(int a, int b) {
|
|||||||
if (3 <= a && a <= 11 && -13 <= b && b <= 23) {
|
if (3 <= a && a <= 11 && -13 <= b && b <= 23) {
|
||||||
range(a); // $ range=<=11 range=>=3
|
range(a); // $ range=<=11 range=>=3
|
||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // -143 .. 253
|
int r = a*b; // $ overflow=+- -143 .. 253
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r; // $ overflow=+
|
||||||
range(total); // $ MISSING: range=">=... * ...+0"
|
range(total); // $ MISSING: range=">=... * ...+0"
|
||||||
}
|
}
|
||||||
if (3 <= a && a <= 11 && -13 <= b && b <= 0) {
|
if (3 <= a && a <= 11 && -13 <= b && b <= 0) {
|
||||||
@@ -326,7 +326,7 @@ int test_mult01(int a, int b) {
|
|||||||
int r = a*b; // -143 .. 0
|
int r = a*b; // -143 .. 0
|
||||||
range(r); // $ range=<=0 range=>=-143
|
range(r); // $ range=<=0 range=>=-143
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=<=3+0 range=>=3-143
|
range(total); // $ range=>=3-143
|
||||||
}
|
}
|
||||||
if (3 <= a && a <= 11 && -13 <= b && b <= -7) {
|
if (3 <= a && a <= 11 && -13 <= b && b <= -7) {
|
||||||
range(a); // $ range=<=11 range=>=3
|
range(a); // $ range=<=11 range=>=3
|
||||||
@@ -334,9 +334,9 @@ int test_mult01(int a, int b) {
|
|||||||
int r = a*b; // -143 .. -21
|
int r = a*b; // -143 .. -21
|
||||||
range(r); // $ range=<=-21 range=>=-143
|
range(r); // $ range=<=-21 range=>=-143
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=<=3-21 range=>=3-143 range=>=3-286
|
range(total); // $ range=>=3-143 range=>=3-286
|
||||||
}
|
}
|
||||||
range(total); // $ range=<=3+0 range=>=3-143 range=>=3-286
|
range(total); // $ range=>=3-143 range=>=3-286
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,9 +363,9 @@ int test_mult02(int a, int b) {
|
|||||||
if (0 <= a && a <= 11 && -13 <= b && b <= 23) {
|
if (0 <= a && a <= 11 && -13 <= b && b <= 23) {
|
||||||
range(a); // $ range=<=11 range=>=0
|
range(a); // $ range=<=11 range=>=0
|
||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // -143 .. 253
|
int r = a*b; // $ overflow=+- -143 .. 253
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r; // $ overflow=+
|
||||||
range(total); // $ MISSING: range=">=... * ...+0"
|
range(total); // $ MISSING: range=">=... * ...+0"
|
||||||
}
|
}
|
||||||
if (0 <= a && a <= 11 && -13 <= b && b <= 0) {
|
if (0 <= a && a <= 11 && -13 <= b && b <= 0) {
|
||||||
@@ -374,7 +374,7 @@ int test_mult02(int a, int b) {
|
|||||||
int r = a*b; // -143 .. 0
|
int r = a*b; // -143 .. 0
|
||||||
range(r); // $ range=<=0 range=>=-143
|
range(r); // $ range=<=0 range=>=-143
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=<=0+0 range=>=0-143
|
range(total); // $ range=>=0-143
|
||||||
}
|
}
|
||||||
if (0 <= a && a <= 11 && -13 <= b && b <= -7) {
|
if (0 <= a && a <= 11 && -13 <= b && b <= -7) {
|
||||||
range(a); // $ range=<=11 range=>=0
|
range(a); // $ range=<=11 range=>=0
|
||||||
@@ -382,9 +382,9 @@ int test_mult02(int a, int b) {
|
|||||||
int r = a*b; // -143 .. 0
|
int r = a*b; // -143 .. 0
|
||||||
range(r); // $ range=<=0 range=>=-143
|
range(r); // $ range=<=0 range=>=-143
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=<=0+0 range=>=0-143 range=>=0-286
|
range(total); // $ range=>=0-143 range=>=0-286
|
||||||
}
|
}
|
||||||
range(total); // $ range=<=0+0 range=>=0-143 range=>=0-286
|
range(total); // $range=>=0-143 range=>=0-286
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,7 +395,7 @@ int test_mult03(int a, int b) {
|
|||||||
if (-17 <= a && a <= 11 && 5 <= b && b <= 23) {
|
if (-17 <= a && a <= 11 && 5 <= b && b <= 23) {
|
||||||
range(a); // $ range=<=11 range=>=-17
|
range(a); // $ range=<=11 range=>=-17
|
||||||
range(b); // $ range=<=23 range=>=5
|
range(b); // $ range=<=23 range=>=5
|
||||||
int r = a*b; // -391 .. 253
|
int r = a*b; // $ overflow=+- -391 .. 253
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r;
|
||||||
range(total);
|
range(total);
|
||||||
@@ -403,33 +403,33 @@ int test_mult03(int a, int b) {
|
|||||||
if (-17 <= a && a <= 11 && 0 <= b && b <= 23) {
|
if (-17 <= a && a <= 11 && 0 <= b && b <= 23) {
|
||||||
range(a); // $ range=<=11 range=>=-17
|
range(a); // $ range=<=11 range=>=-17
|
||||||
range(b); // $ range=<=23 range=>=0
|
range(b); // $ range=<=23 range=>=0
|
||||||
int r = a*b; // -391 .. 253
|
int r = a*b; // $ overflow=+- -391 .. 253
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r; // $ overflow=+-
|
||||||
range(total);
|
range(total);
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= 11 && -13 <= b && b <= 23) {
|
if (-17 <= a && a <= 11 && -13 <= b && b <= 23) {
|
||||||
range(a); // $ range=<=11 range=>=-17
|
range(a); // $ range=<=11 range=>=-17
|
||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // -391 .. 253
|
int r = a*b; // $ overflow=+- -391 .. 25
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r; // $ overflow=+-
|
||||||
range(total);
|
range(total);
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= 11 && -13 <= b && b <= 0) {
|
if (-17 <= a && a <= 11 && -13 <= b && b <= 0) {
|
||||||
range(a); // $ range=<=11 range=>=-17
|
range(a); // $ range=<=11 range=>=-17
|
||||||
range(b); // $ range=<=0 range=>=-13
|
range(b); // $ range=<=0 range=>=-13
|
||||||
int r = a*b; // -143 .. 221
|
int r = a*b; // $ overflow=+- -143 .. 221
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r; // $ overflow=+-
|
||||||
range(total);
|
range(total);
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= 11 && -13 <= b && b <= -7) {
|
if (-17 <= a && a <= 11 && -13 <= b && b <= -7) {
|
||||||
range(a); // $ range=<=11 range=>=-17
|
range(a); // $ range=<=11 range=>=-17
|
||||||
range(b); // $ range=<=-7 range=>=-13
|
range(b); // $ range=<=-7 range=>=-13
|
||||||
int r = a*b; // -143 .. 221
|
int r = a*b; // $ overflow=+- -143 .. 221
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r; // $ overflow=+-
|
||||||
range(total);
|
range(total);
|
||||||
}
|
}
|
||||||
range(total);
|
range(total);
|
||||||
@@ -458,9 +458,9 @@ int test_mult04(int a, int b) {
|
|||||||
if (-17 <= a && a <= 0 && -13 <= b && b <= 23) {
|
if (-17 <= a && a <= 0 && -13 <= b && b <= 23) {
|
||||||
range(a); // $ range=<=0 range=>=-17
|
range(a); // $ range=<=0 range=>=-17
|
||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // -391 .. 221
|
int r = a*b; // $ overflow=+- -391 .. 221
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r; // $ overflow=-
|
||||||
range(total); // $ MISSING: range="<=... * ...+0"
|
range(total); // $ MISSING: range="<=... * ...+0"
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= 0 && -13 <= b && b <= 0) {
|
if (-17 <= a && a <= 0 && -13 <= b && b <= 0) {
|
||||||
@@ -469,7 +469,7 @@ int test_mult04(int a, int b) {
|
|||||||
int r = a*b; // 0 .. 221
|
int r = a*b; // 0 .. 221
|
||||||
range(r); // $ range=<=221 range=>=0
|
range(r); // $ range=<=221 range=>=0
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range="<=- ...+221" range=">=- ...+0"
|
range(total); // $ range="<=- ...+221"
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= 0 && -13 <= b && b <= -7) {
|
if (-17 <= a && a <= 0 && -13 <= b && b <= -7) {
|
||||||
range(a); // $ range=<=0 range=>=-17
|
range(a); // $ range=<=0 range=>=-17
|
||||||
@@ -477,9 +477,9 @@ int test_mult04(int a, int b) {
|
|||||||
int r = a*b; // 0 .. 221
|
int r = a*b; // 0 .. 221
|
||||||
range(r); // $ range=<=221 range=>=0
|
range(r); // $ range=<=221 range=>=0
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442"
|
range(total); // $ range="<=- ...+221" range="<=- ...+442"
|
||||||
}
|
}
|
||||||
range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442"
|
range(total); // $ range="<=- ...+221" range="<=- ...+442"
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,9 +506,9 @@ int test_mult05(int a, int b) {
|
|||||||
if (-17 <= a && a <= -2 && -13 <= b && b <= 23) {
|
if (-17 <= a && a <= -2 && -13 <= b && b <= 23) {
|
||||||
range(a); // $ range=<=-2 range=>=-17
|
range(a); // $ range=<=-2 range=>=-17
|
||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // -391 .. 221
|
int r = a*b; // $ overflow=+- -391 .. 221
|
||||||
range(r);
|
range(r);
|
||||||
total += r;
|
total += r; // $ overflow=-
|
||||||
range(total); // $ MISSING: range="<=... * ...+0"
|
range(total); // $ MISSING: range="<=... * ...+0"
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= -2 && -13 <= b && b <= 0) {
|
if (-17 <= a && a <= -2 && -13 <= b && b <= 0) {
|
||||||
@@ -517,7 +517,7 @@ int test_mult05(int a, int b) {
|
|||||||
int r = a*b; // 0 .. 221
|
int r = a*b; // 0 .. 221
|
||||||
range(r); // $ range=<=221 range=>=0
|
range(r); // $ range=<=221 range=>=0
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range="<=- ...+221" range=">=- ...+0"
|
range(total); // $ range="<=- ...+221"
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= -2 && -13 <= b && b <= -7) {
|
if (-17 <= a && a <= -2 && -13 <= b && b <= -7) {
|
||||||
range(a); // $ range=<=-2 range=>=-17
|
range(a); // $ range=<=-2 range=>=-17
|
||||||
@@ -525,9 +525,9 @@ int test_mult05(int a, int b) {
|
|||||||
int r = a*b; // 14 .. 221
|
int r = a*b; // 14 .. 221
|
||||||
range(r); // $ range=<=221 range=>=14
|
range(r); // $ range=<=221 range=>=14
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range="<=- ...+221" range="<=- ...+442" range=">=- ...+14"
|
range(total); // $ range="<=- ...+221" range="<=- ...+442"
|
||||||
}
|
}
|
||||||
range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442"
|
range(total); // $ range="<=- ...+221" range="<=- ...+442"
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +541,7 @@ int test16(int x) {
|
|||||||
while (i < 3) {
|
while (i < 3) {
|
||||||
range(i); // $ range=<=2 range=>=0
|
range(i); // $ range=<=2 range=>=0
|
||||||
i++;
|
i++;
|
||||||
range(i); // $ range="==... = ...:i+1" range=<=3 range=>=1
|
range(i); // $ range=<=3 range=>=1 range="==... = ...:i+1" SPURIOUS:range="==... = ...:i+1"
|
||||||
}
|
}
|
||||||
range(d);
|
range(d);
|
||||||
d = i;
|
d = i;
|
||||||
@@ -586,7 +586,7 @@ unsigned int test_ternary01(unsigned int x) {
|
|||||||
(range(x), 500);
|
(range(x), 500);
|
||||||
range(y4); // $ range=<=500
|
range(y4); // $ range=<=500
|
||||||
y5 = (x+1) ?:
|
y5 = (x+1) ?:
|
||||||
(range(x), 500); // $ range===-1
|
(range(x), 500); // $ overflow=- range===-1
|
||||||
range(y5); // $ range=<=500
|
range(y5); // $ range=<=500
|
||||||
y6 = ((unsigned char)(x+1)) ?:
|
y6 = ((unsigned char)(x+1)) ?:
|
||||||
(range(x), 5); // $ range=<=299
|
(range(x), 5); // $ range=<=299
|
||||||
@@ -598,8 +598,8 @@ unsigned int test_ternary01(unsigned int x) {
|
|||||||
(range(x), 500); // $ range=<=299
|
(range(x), 500); // $ range=<=299
|
||||||
range(y8); // y8 <= 300
|
range(y8); // y8 <= 300
|
||||||
}
|
}
|
||||||
range(y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8); // $ MISSING: range=">=... = ...:... ? ... : ...+0" range=">=call to range+0"
|
range(y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8); // $ overflow=+ MISSING: range=">=... = ...:... ? ... : ...+0" range=">=call to range+0"
|
||||||
return y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8;
|
return y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8; // $ overflow=+
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test ternary expression lower bounds.
|
// Test ternary expression lower bounds.
|
||||||
@@ -628,8 +628,8 @@ unsigned int test_ternary02(unsigned int x) {
|
|||||||
(range(x), 5); // $ range=>=300
|
(range(x), 5); // $ range=>=300
|
||||||
range(y5); // y6 >= 0
|
range(y5); // y6 >= 0
|
||||||
}
|
}
|
||||||
range(y1 + y2 + y3 + y4 + y5); // $ range=">=call to range+207" MISSING: range=">=... = ...:... ? ... : ...+0" range=">=call to range+0"
|
range(y1 + y2 + y3 + y4 + y5); // $ overflow=+ MISSING: range=">=call to range+207" range=">=... = ...:... ? ... : ...+0" range=">=call to range+0"
|
||||||
return y1 + y2 + y3 + y4 + y5;
|
return y1 + y2 + y3 + y4 + y5; // $ overflow=+
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the comma expression.
|
// Test the comma expression.
|
||||||
@@ -691,9 +691,9 @@ int test_unsigned_mult01(unsigned int a, unsigned b) {
|
|||||||
range(a); // $ range=<=11 range=>=3
|
range(a); // $ range=<=11 range=>=3
|
||||||
range(b); // $ range=<=23 range=>=0
|
range(b); // $ range=<=23 range=>=0
|
||||||
int r = a*b; // 0 .. 253
|
int r = a*b; // 0 .. 253
|
||||||
range(r); // $ range=>=0 range=<=253
|
range(r);// $ range=>=0 range=<=253
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=>=0 range=<=506 range=">=(unsigned int)...+0" range="<=(unsigned int)...+253"
|
range(total); // $ range=">=(unsigned int)...+0" range=>=0 range=<=506 range="<=(unsigned int)...+253"
|
||||||
}
|
}
|
||||||
if (3 <= a && a <= 11 && 13 <= b && b <= 23) {
|
if (3 <= a && a <= 11 && 13 <= b && b <= 23) {
|
||||||
range(a); // $ range=<=11 range=>=3
|
range(a); // $ range=<=11 range=>=3
|
||||||
@@ -701,7 +701,7 @@ int test_unsigned_mult01(unsigned int a, unsigned b) {
|
|||||||
int r = a*b; // 39 .. 253
|
int r = a*b; // 39 .. 253
|
||||||
range(r); // $ range=>=39 range=<=253
|
range(r); // $ range=>=39 range=<=253
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=>=39 range=<=759 range=">=(unsigned int)...+39" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253"
|
range(total); // $ range=>=39 range=<=759 range="<=(unsigned int)...+253" range="<=(unsigned int)...+506" range=">=(unsigned int)...+39"
|
||||||
}
|
}
|
||||||
range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253"
|
range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253"
|
||||||
return total;
|
return total;
|
||||||
@@ -722,14 +722,14 @@ int test_unsigned_mult02(unsigned b) {
|
|||||||
int r = 11*b; // 0 .. 253
|
int r = 11*b; // 0 .. 253
|
||||||
range(r); // $ range=>=0 range=<=253
|
range(r); // $ range=>=0 range=<=253
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=>=0 range=<=506 range=">=(unsigned int)...+0" range="<=(unsigned int)...+253"
|
range(total); // $ range=">=(unsigned int)...+0" range=>=0 range="<=(unsigned int)...+253" range=<=506
|
||||||
}
|
}
|
||||||
if (13 <= b && b <= 23) {
|
if (13 <= b && b <= 23) {
|
||||||
range(b); // $ range=<=23 range=>=13
|
range(b); // $ range=<=23 range=>=13
|
||||||
int r = 11*b; // 143 .. 253
|
int r = 11*b; // 143 .. 253
|
||||||
range(r); // $ range=>=143 range=<=253
|
range(r); // $ range=>=143 range=<=253
|
||||||
total += r;
|
total += r;
|
||||||
range(total); // $ range=>=143 range=<=759 range=">=(unsigned int)...+143" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253"
|
range(total); // $ range="<=(unsigned int)...+253" range="<=(unsigned int)...+506" range=">=(unsigned int)...+143" range=>=143 range=<=759
|
||||||
}
|
}
|
||||||
range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253"
|
range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253"
|
||||||
return total;
|
return total;
|
||||||
@@ -751,7 +751,7 @@ unsigned long mult_overflow() {
|
|||||||
range(x); // $ range===274177
|
range(x); // $ range===274177
|
||||||
y = 67280421310721UL;
|
y = 67280421310721UL;
|
||||||
range(y);
|
range(y);
|
||||||
xy = x * y;
|
xy = x * y; // $ overflow=+-
|
||||||
range(xy);
|
range(xy);
|
||||||
return xy; // BUG: upper bound should be >= 18446744073709551617UL
|
return xy; // BUG: upper bound should be >= 18446744073709551617UL
|
||||||
}
|
}
|
||||||
@@ -760,14 +760,14 @@ unsigned long mult_lower_bound(unsigned int ui, unsigned long ul) {
|
|||||||
if (ui >= 10) {
|
if (ui >= 10) {
|
||||||
range(ui); // $ range=>=10
|
range(ui); // $ range=>=10
|
||||||
range((unsigned long)ui); // $ range=>=10
|
range((unsigned long)ui); // $ range=>=10
|
||||||
unsigned long result = (unsigned long)ui * ui;
|
unsigned long result = (unsigned long)ui * ui; // $ overflow=+
|
||||||
range(result); // $ range=>=100 range=>=100
|
range(result); // $ MISSING: range=>=100
|
||||||
return result; // BUG: upper bound should be >= 18446744065119617025
|
return result; // BUG: upper bound should be >= 18446744065119617025
|
||||||
}
|
}
|
||||||
if (ul >= 10) {
|
if (ul >= 10) {
|
||||||
range(ul); // $ range=>=10
|
range(ul); // $ range=>=10
|
||||||
unsigned long result = ul * ul;
|
unsigned long result = ul * ul; // $ overflow=+
|
||||||
range(result); // $ range=>=100
|
range(result); // $ MISSING: range=>=100
|
||||||
return result; // BUG: lower bound should be 0 (overflow is possible)
|
return result; // BUG: lower bound should be 0 (overflow is possible)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -800,13 +800,13 @@ int mul_by_constant(int i, int j) {
|
|||||||
i = 5 * i;
|
i = 5 * i;
|
||||||
range(i); // $ range=<=10 range=>=-5
|
range(i); // $ range=<=10 range=>=-5
|
||||||
|
|
||||||
i = i * -3;
|
i = i * -3; // $ overflow=+-
|
||||||
range(i); // -30 .. 15
|
range(i); // -30 .. 15
|
||||||
|
|
||||||
i *= 7;
|
i *= 7; // $ overflow=+-
|
||||||
range(i); // -210 .. 105
|
range(i); // -210 .. 105
|
||||||
|
|
||||||
i *= -11;
|
i *= -11; // $ overflow=+-
|
||||||
range(i); // -1155 .. 2310
|
range(i); // -1155 .. 2310
|
||||||
}
|
}
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
@@ -815,7 +815,7 @@ int mul_by_constant(int i, int j) {
|
|||||||
i = i * (int)0xffFFffFF; // fully converted literal is -1
|
i = i * (int)0xffFFffFF; // fully converted literal is -1
|
||||||
range(i); // $ range===1
|
range(i); // $ range===1
|
||||||
}
|
}
|
||||||
i = i * -1;
|
i = i * -1; // $ overflow=+-
|
||||||
range( i); // -2^31 .. 2^31-1
|
range( i); // -2^31 .. 2^31-1
|
||||||
|
|
||||||
signed char sc = 1;
|
signed char sc = 1;
|
||||||
@@ -873,11 +873,11 @@ void notequal_refinement(short n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (n != 0) {
|
while (n != 0) {
|
||||||
range(n); // $ range=<=n+0
|
range(n); // $ MISSING:range=<=n+0
|
||||||
n--; // 1 ..
|
n--; // 1 ..
|
||||||
}
|
}
|
||||||
|
|
||||||
range(n); // $ range=<=n+0 // 0 .. 0
|
range(n); // $ MISSING:range=<=n+0 // 0 .. 0
|
||||||
}
|
}
|
||||||
|
|
||||||
void notequal_variations(short n, float f) {
|
void notequal_variations(short n, float f) {
|
||||||
@@ -888,7 +888,7 @@ void notequal_variations(short n, float f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n >= 5) {
|
if (n >= 5) {
|
||||||
if (2 * n - 10 == 0) { // Same as `n == 10/2` (modulo overflow)
|
if (2 * n - 10 == 0) { // $ overflow=+
|
||||||
range(n); // $ range=>=5 MISSING: range===5
|
range(n); // $ range=>=5 MISSING: range===5
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -921,7 +921,7 @@ void two_bounds_from_one_test(short ss, unsigned short us) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ss < 0x8001) { // Lower bound removed in `getDefLowerBounds`
|
if (ss < 0x8001) { // Lower bound removed in `getDefLowerBounds`
|
||||||
range(ss); // $ range=<=32768 MISSING: range=>=-32768
|
range(ss); // $ overflow=+ range=<=32768 MISSING: range=>=-32768
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((short)us >= 0) {
|
if ((short)us >= 0) {
|
||||||
@@ -936,7 +936,7 @@ void two_bounds_from_one_test(short ss, unsigned short us) {
|
|||||||
range(ss); // -32768 .. 32767
|
range(ss); // -32768 .. 32767
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss + 1 < sizeof(int)) {
|
if (ss + 1 < sizeof(int)) { // $ overflow=+
|
||||||
range(ss); // -1 .. 2
|
range(ss); // -1 .. 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1020,7 +1020,7 @@ void test_overflow() {
|
|||||||
|
|
||||||
void test_negate_unsigned(unsigned u) {
|
void test_negate_unsigned(unsigned u) {
|
||||||
if(10 < u && u < 20) {
|
if(10 < u && u < 20) {
|
||||||
range<unsigned>(-u); // underflows
|
range<unsigned>(-u); // $ overflow=-
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,17 @@
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y - 2 == x && y > 300) {
|
if (y - 2 == x && y > 300) { // $ overflow=-
|
||||||
range(x + y); // $ range=<=802 range=>=600
|
range(x + y); // $ range=<=802 range=>=600
|
||||||
return x + y;
|
return x + y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x != y + 1) {
|
if (x != y + 1) { // $ overflow=+
|
||||||
range(x); // $ range=<=400
|
range(x); // $ range=<=400
|
||||||
int sum = x + y;
|
int sum = x + y; // $ overflow=+-
|
||||||
} else {
|
} else {
|
||||||
if (y > 300) {
|
if (y > 300) {
|
||||||
range(x); // $ range=>=302 range=<=400 range===y+1
|
range(x); // $ range=>=302 range=<=400 range=<=y+1 MISSING: range===y+1
|
||||||
range(y); // $ range=>=301 range=<=399 range===x-1
|
range(y); // $ range=>=301 range=<=399 range===x-1
|
||||||
int sum = x + y;
|
int sum = x + y;
|
||||||
}
|
}
|
||||||
@@ -38,10 +38,10 @@
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y == x - 1 && y > 300 && y + 2 == z && z == 350) {
|
if (y == x - 1 && y > 300 && y + 2 == z && z == 350) { // $ overflow=+ overflow=-
|
||||||
range(x); // $ range===349 range===y+1 range===z-1
|
range(x); // $ range===349 range===y+1 range===z-1
|
||||||
range(y); // $ range===348 range===x-1 range===z-2
|
range(y); // $ range===348 range=>=x-1 range===z-2 MISSING: range===x-1
|
||||||
range(z); // $ range===350 range===x+1 range===y+2
|
range(z); // $ range===350 range=<=y+2 MISSING: range===x+1 range===y+2
|
||||||
return x + y + z;
|
return x + y + z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.SignAnalysis
|
|||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisSpecific
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisRelativeSpecific
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
||||||
import semmle.code.cpp.ir.IR as IR
|
import semmle.code.cpp.ir.IR as IR
|
||||||
import TestUtilities.InlineExpectationsTest
|
import TestUtilities.InlineExpectationsTest
|
||||||
|
|
||||||
module SignAnalysisInstantiated = SignAnalysis<FloatDelta, RangeUtil<FloatDelta, CppLangImpl>>;
|
module SignAnalysisInstantiated =
|
||||||
|
SignAnalysis<FloatDelta, RangeUtil<FloatDelta, CppLangImplRelative>>;
|
||||||
|
|
||||||
class SignAnalysisTest extends InlineExpectationsTest {
|
class SignAnalysisTest extends InlineExpectationsTest {
|
||||||
SignAnalysisTest() { this = "SignAnalysisTest" }
|
SignAnalysisTest() { this = "SignAnalysisTest" }
|
||||||
|
|||||||
Reference in New Issue
Block a user