Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b95163c

Browse files
authored
Merge pull request #11112 from MathiasVP/local-expr-flow
C++: Improve `Buffer.qll` performance
2 parents ae01201 + 2617e6d commit b95163c

2 files changed

Lines changed: 49 additions & 34 deletions

File tree

cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -73,47 +73,33 @@ private int isSource(Expr bufferExpr, Element why) {
7373
)
7474
}
7575

76-
private predicate localFlowToExprStep(DataFlow::Node n1, DataFlow::Node n2) {
77-
not exists(n2.asExpr()) and
78-
DataFlow::localFlowStep(n1, n2)
79-
}
80-
81-
/** Holds if `n2 + delta` may be equal to `n1`. */
82-
private predicate localFlowStepToExpr(Expr e1, Expr e2) {
83-
getBufferSizeCand0(e1) and
84-
exists(DataFlow::Node n1, DataFlow::Node mid, DataFlow::Node n2 |
85-
n1.asExpr() = e1 and
86-
localFlowToExprStep*(n1, mid) and
87-
DataFlow::localFlowStep(mid, n2) and
88-
n2.asExpr() = e2
89-
)
90-
}
91-
9276
/**
9377
* Holds if `e2` is an expression that is derived from `e1` such that if `e1[n]` is a
9478
* well-defined expression for some number `n`, then `e2[n + delta]` is also a well-defined
9579
* expression.
9680
*/
9781
private predicate step(Expr e1, Expr e2, int delta) {
9882
getBufferSizeCand0(e1) and
99-
exists(Variable bufferVar, Class parentClass, VariableAccess parentPtr, int bufferSize |
100-
e1 = parentPtr
101-
|
102-
bufferVar = e2.(VariableAccess).getTarget() and
103-
// buffer is the parentPtr->bufferVar of a 'variable size struct'
104-
memberMayBeVarSize(parentClass, bufferVar) and
105-
parentPtr = e2.(VariableAccess).getQualifier() and
106-
parentPtr.getTarget().getUnspecifiedType().(PointerType).getBaseType() = parentClass and
107-
(
108-
if exists(bufferVar.getType().getSize())
109-
then bufferSize = bufferVar.getType().getSize()
110-
else bufferSize = 0
111-
) and
112-
delta = bufferSize - parentClass.getSize()
83+
(
84+
exists(Variable bufferVar, Class parentClass, VariableAccess parentPtr, int bufferSize |
85+
e1 = parentPtr
86+
|
87+
bufferVar = e2.(VariableAccess).getTarget() and
88+
// buffer is the parentPtr->bufferVar of a 'variable size struct'
89+
memberMayBeVarSize(parentClass, bufferVar) and
90+
parentPtr = e2.(VariableAccess).getQualifier() and
91+
parentPtr.getTarget().getUnspecifiedType().(PointerType).getBaseType() = parentClass and
92+
(
93+
if exists(bufferVar.getType().getSize())
94+
then bufferSize = bufferVar.getType().getSize()
95+
else bufferSize = 0
96+
) and
97+
delta = bufferSize - parentClass.getSize()
98+
)
99+
or
100+
DataFlow::localExprFlowStep(e1, e2) and
101+
delta = 0
113102
)
114-
or
115-
localFlowStepToExpr(e1, e2) and
116-
delta = 0
117103
}
118104

119105
pragma[nomagic]

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,36 @@ predicate localInstructionFlow(Instruction e1, Instruction e2) {
13221322
* local (intra-procedural) steps.
13231323
*/
13241324
pragma[inline]
1325-
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
1325+
predicate localExprFlow(Expr e1, Expr e2) { localExprFlowStep*(e1, e2) }
1326+
1327+
/**
1328+
* Holds if `n1.asExpr()` doesn't have a result and `n1` flows to `n2` in a single
1329+
* dataflow step.
1330+
*/
1331+
private predicate localStepFromNonExpr(Node n1, Node n2) {
1332+
not exists(n1.asExpr()) and
1333+
localFlowStep(n1, n2)
1334+
}
1335+
1336+
/**
1337+
* Holds if `n1.asExpr()` doesn't have a result, `n2.asExpr() = e2` and
1338+
* `n2` is the first node reachable from `n1` such that `n2.asExpr()` exists.
1339+
*/
1340+
pragma[nomagic]
1341+
private predicate localStepsToExpr(Node n1, Node n2, Expr e2) {
1342+
localStepFromNonExpr*(n1, n2) and
1343+
e2 = n2.asExpr()
1344+
}
1345+
1346+
/** Holds if data can flow from `e1` to `e2` in one local (intra-procedural) step. */
1347+
cached
1348+
predicate localExprFlowStep(Expr e1, Expr e2) {
1349+
exists(Node mid, Node n1, Node n2 |
1350+
localFlowStep(n1, mid) and
1351+
localStepsToExpr(mid, n2, e2) and
1352+
e1 = n1.asExpr()
1353+
)
1354+
}
13261355

13271356
cached
13281357
private newtype TContent =

0 commit comments

Comments
 (0)