Skip to content

Commit

Permalink
Merge pull request #18290 from hvitved/rust/perf-fixes
Browse files Browse the repository at this point in the history
Rust: Fix two bad joins
  • Loading branch information
hvitved authored Dec 17, 2024
2 parents 132dbd7 + aabcc10 commit d8c05b5
Showing 1 changed file with 49 additions and 47 deletions.
96 changes: 49 additions & 47 deletions rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -957,8 +957,8 @@ module RustDataFlow implements InputSig<Location> {
/** Holds if path `p` resolves to variant `v`. */
private predicate pathResolveToVariantCanonicalPath(PathAstNode p, VariantCanonicalPath v) {
exists(CrateOriginOption crate, string path, string name |
resolveExtendedCanonicalPath(p, crate, path + "::" + name) and
v = MkVariantCanonicalPath(crate, path, name)
resolveExtendedCanonicalPath(p, pragma[only_bind_into](crate), path + "::" + name) and
v = MkVariantCanonicalPath(pragma[only_bind_into](crate), path, name)
)
}

Expand Down Expand Up @@ -1074,57 +1074,59 @@ module RustDataFlow implements InputSig<Location> {
)
}

pragma[nomagic]
private predicate storeContentStep(Node node1, Content c, Node node2) {
exists(CallExprCfgNode call, int pos |
tupleVariantConstruction(call.getCallExpr(),
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
node1.asExpr() = call.getArgument(pos) and
node2.asExpr() = call
)
or
exists(RecordExprCfgNode re, string field |
(
// Expression is for a struct-like enum variant.
recordVariantConstruction(re.getRecordExpr(),
c.(VariantFieldContent).getVariantCanonicalPath(field))
or
// Expression is for a struct.
structConstruction(re.getRecordExpr(), c.(StructFieldContent).getStructCanonicalPath(field))
) and
node1.asExpr() = re.getFieldExpr(field) and
node2.asExpr() = re
)
or
exists(TupleExprCfgNode tuple |
node1.asExpr() = tuple.getField(c.(TuplePositionContent).getPosition()) and
node2.asExpr() = tuple
)
or
c instanceof ArrayElementContent and
node1.asExpr() =
[
node2.asExpr().(ArrayRepeatExprCfgNode).getRepeatOperand(),
node2.asExpr().(ArrayListExprCfgNode).getAnExpr()
]
or
tupleAssignment(node1, node2.(PostUpdateNode).getPreUpdateNode(), c)
or
exists(AssignmentExprCfgNode assignment, IndexExprCfgNode index |
c instanceof ArrayElementContent and
assignment.getLhs() = index and
node1.asExpr() = assignment.getRhs() and
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = index.getBase()
)
or
VariableCapture::storeStep(node1, c, node2)
}

/**
* Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
* `node2` references an object with a content `c.getAStoreContent()` that
* contains the value of `node1`.
*/
predicate storeStep(Node node1, ContentSet cs, Node node2) {
exists(Content c | c = cs.(SingletonContentSet).getContent() |
exists(CallExprCfgNode call, int pos |
tupleVariantConstruction(call.getCallExpr(),
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
node1.asExpr() = call.getArgument(pos) and
node2.asExpr() = call
)
or
exists(RecordExprCfgNode re, string field |
(
// Expression is for a struct-like enum variant.
recordVariantConstruction(re.getRecordExpr(),
c.(VariantFieldContent).getVariantCanonicalPath(field))
or
// Expression is for a struct.
structConstruction(re.getRecordExpr(),
c.(StructFieldContent).getStructCanonicalPath(field))
) and
node1.asExpr() = re.getFieldExpr(field) and
node2.asExpr() = re
)
or
exists(TupleExprCfgNode tuple |
node1.asExpr() = tuple.getField(c.(TuplePositionContent).getPosition()) and
node2.asExpr() = tuple
)
or
c instanceof ArrayElementContent and
node1.asExpr() =
[
node2.asExpr().(ArrayRepeatExprCfgNode).getRepeatOperand(),
node2.asExpr().(ArrayListExprCfgNode).getAnExpr()
]
or
tupleAssignment(node1, node2.(PostUpdateNode).getPreUpdateNode(), c)
or
exists(AssignmentExprCfgNode assignment, IndexExprCfgNode index |
c instanceof ArrayElementContent and
assignment.getLhs() = index and
node1.asExpr() = assignment.getRhs() and
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = index.getBase()
)
or
VariableCapture::storeStep(node1, c, node2)
)
storeContentStep(node1, cs.(SingletonContentSet).getContent(), node2)
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(Node::FlowSummaryNode).getSummaryNode(),
cs, node2.(Node::FlowSummaryNode).getSummaryNode())
Expand Down

0 comments on commit d8c05b5

Please sign in to comment.