mirror of
https://github.com/github/codeql.git
synced 2026-04-24 16:25:15 +02:00
Merge pull request #18290 from hvitved/rust/perf-fixes
Rust: Fix two bad joins
This commit is contained in:
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user