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

Skip to content

Commit 1b50168

Browse files
committed
C++: Add an initial pruning stage to prevent this
large TC in 'localFlowToExpr': ``` Evaluated relational algebra for predicate Buffer#61e3d199::localFlowStepToExpr#2#ff@0a49913i with tuple counts: 4713946 ~0% {2} r1 = SCAN DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff OUTPUT In.1, In.0 40897385 ~46% {2} r2 = JOIN boundedFastTC:Buffer#61e3d199::localFlowToExprStep#2#ff_10#higher_order_body:DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff_0#higher_order_body WITH DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1 45611331 ~43% {2} r3 = r1 UNION r2 3376553 ~14% {2} r4 = JOIN r3 WITH DataFlowUtil#47741e1f::ExprNode::getExpr#0#dispred#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1 return r4 ``` After this commit the tuple counts looks like: ``` Evaluated relational algebra for predicate Buffer#61e3d199::localFlowStepToExpr#2#ff@8cc38x5k on iteration 2 running pipeline standard with tuple counts: 51367 ~3% {2} r1 = JOIN Buffer#61e3d199::getBufferSize0#1#f#prev_delta WITH DataFlowUtil#47741e1f::ExprNode::getExpr#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.0 124933 ~18% {2} r2 = JOIN r1 WITH #Buffer#61e3d199::localFlowToExprStep#2Plus#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1 176300 ~17% {2} r3 = r1 UNION r2 184685 ~22% {2} r4 = JOIN r3 WITH DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1 56646 ~47% {2} r5 = JOIN r4 WITH DataFlowUtil#47741e1f::ExprNode::getExpr#0#dispred#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1 44635 ~16% {2} r6 = r5 AND NOT Buffer#61e3d199::localFlowStepToExpr#2#ff#prev(Lhs.0, Lhs.1) return r6 ```
1 parent aa8214a commit 1b50168

1 file changed

Lines changed: 25 additions & 9 deletions

File tree

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

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,10 @@ private predicate localFlowToExprStep(DataFlow::Node n1, DataFlow::Node n2) {
7979
}
8080

8181
/** Holds if `n2 + delta` may be equal to `n1`. */
82-
private predicate localFlowStepToExpr(DataFlow::Node n1, Expr e2) {
83-
exists(DataFlow::Node mid, DataFlow::Node n2 |
82+
private predicate localFlowStepToExpr(Expr e1, Expr e2) {
83+
getBufferSize0(e1) and
84+
exists(DataFlow::Node n1, DataFlow::Node mid, DataFlow::Node n2 |
85+
n1.asExpr() = e1 and
8486
localFlowToExprStep*(n1, mid) and
8587
DataFlow::localFlowStep(mid, n2) and
8688
n2.asExpr() = e2
@@ -93,6 +95,7 @@ private predicate localFlowStepToExpr(DataFlow::Node n1, Expr e2) {
9395
* expression.
9496
*/
9597
private predicate step(Expr e1, Expr e2, int delta) {
98+
getBufferSize0(e1) and
9699
exists(Variable bufferVar, Class parentClass, VariableAccess parentPtr, int bufferSize |
97100
e1 = parentPtr
98101
|
@@ -109,19 +112,32 @@ private predicate step(Expr e1, Expr e2, int delta) {
109112
delta = bufferSize - parentClass.getSize()
110113
)
111114
or
112-
localFlowStepToExpr(DataFlow::exprNode(e1), e2) and
115+
localFlowStepToExpr(e1, e2) and
113116
delta = 0
114117
}
115118

119+
pragma[nomagic]
120+
private predicate getBufferSize0(Expr e) {
121+
exists(isSource(e, _))
122+
or
123+
exists(Expr e0 |
124+
getBufferSize0(e0) and
125+
step(e0, e, _)
126+
)
127+
}
128+
116129
/**
117130
* Get the size in bytes of the buffer pointed to by an expression (if this can be determined).
118131
*/
119132
int getBufferSize(Expr bufferExpr, Element why) {
120-
result = isSource(bufferExpr, why)
121-
or
122-
exists(Expr e0, int delta, int size |
123-
size = getBufferSize(e0, why) and
124-
delta = unique(int cand | step(e0, bufferExpr, cand) | cand) and
125-
result = size + delta
133+
getBufferSize0(bufferExpr) and
134+
(
135+
result = isSource(bufferExpr, why)
136+
or
137+
exists(Expr e0, int delta, int size |
138+
size = getBufferSize(e0, why) and
139+
delta = unique(int cand | step(e0, bufferExpr, cand) | cand) and
140+
result = size + delta
141+
)
126142
)
127143
}

0 commit comments

Comments
 (0)