Skip to content

Commit 1deb1e6

Browse files
committed
C++: Add SimpleRangeAnalysisExpr.dependsOnChild
1 parent 1b5b374 commit 1deb1e6

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisExpr.qll

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,27 @@ abstract class SimpleRangeAnalysisExpr extends Expr {
3232
*/
3333
abstract float getUpperBounds();
3434

35-
/** Holds if this expression depends on the definition `srcDef` for StackVariable `srcVar`. */
35+
/**
36+
* Holds if the range this expression depends on the definition `srcDef` for
37+
* StackVariable `srcVar`.
38+
*
39+
* Because this predicate cannot be recursive, most implementations should
40+
* override `dependsOnChild` instead.
41+
*/
3642
predicate dependsOnDef(RangeSsaDefinition srcDef, StackVariable srcVar) { none() }
43+
44+
/**
45+
* Holds if this expression depends on the range of its unconverted
46+
* subexpression `child`. This information is used to inform the range
47+
* analysis about cyclic dependencies. Without this information, range
48+
* analysis might work for simple cases but will go into infinite loops on
49+
* complex code.
50+
*
51+
* For example, when modeling a function call whose return value depends on
52+
* all of its arguments, implement this predicate as
53+
* `child = this.getAnArgument()`.
54+
*/
55+
abstract predicate dependsOnChild(Expr child);
3756
}
3857

3958
import SimpleRangeAnalysisInternal

cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,14 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
334334
e = srcDef.getAUse(srcVar)
335335
or
336336
// A modeled expression for range analysis
337-
exists(SimpleRangeAnalysisExpr rae | rae = e | rae.dependsOnDef(srcDef, srcVar))
337+
exists(SimpleRangeAnalysisExpr rae | rae = e |
338+
rae.dependsOnDef(srcDef, srcVar)
339+
or
340+
exists(Expr child |
341+
rae.dependsOnChild(child) and
342+
exprDependsOnDef(child, srcDef, srcVar)
343+
)
344+
)
338345
}
339346

340347
/**

0 commit comments

Comments
 (0)