Skip to content

Commit 7ed8a85

Browse files
authored
Merge pull request #19246 from hvitved/rust/cache-tweaks
2 parents c2baf9a + 7459548 commit 7ed8a85

File tree

5 files changed

+69
-33
lines changed

5 files changed

+69
-33
lines changed

Diff for: rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll

+2
Original file line numberDiff line numberDiff line change
@@ -846,9 +846,11 @@ module RustDataFlow implements InputSig<Location> {
846846

847847
/** Provides logic related to captured variables. */
848848
module VariableCapture {
849+
private import codeql.rust.internal.CachedStages
849850
private import codeql.dataflow.VariableCapture as SharedVariableCapture
850851

851852
private predicate closureFlowStep(ExprCfgNode e1, ExprCfgNode e2) {
853+
Stages::DataFlowStage::ref() and
852854
e1 = getALastEvalNode(e2)
853855
or
854856
exists(Ssa::Definition def |

Diff for: rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ module Impl {
3333
* Gets the nearest enclosing parent of this node, which is also an `AstNode`,
3434
* if any.
3535
*/
36+
cached
3637
AstNode getParentNode() { result = getParentOfAstStep*(getImmediateParent(this)) }
3738

3839
/** Gets the immediately enclosing callable of this node, if any. */

Diff for: rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll

+57-31
Original file line numberDiff line numberDiff line change
@@ -68,36 +68,36 @@ module Impl {
6868
* where `definingNode` is the entire `Either::Left(x) | Either::Right(x)`
6969
* pattern.
7070
*/
71+
cached
7172
private predicate variableDecl(AstNode definingNode, Name name, string text) {
72-
(
73-
exists(SelfParam sp |
74-
name = sp.getName() and
75-
definingNode = name and
76-
text = name.getText() and
77-
// exclude self parameters from functions without a body as these are
78-
// trait method declarations without implementations
79-
not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp)
80-
)
81-
or
82-
exists(IdentPat pat |
83-
name = pat.getName() and
84-
(
85-
definingNode = getOutermostEnclosingOrPat(pat)
86-
or
87-
not exists(getOutermostEnclosingOrPat(pat)) and definingNode = name
88-
) and
89-
text = name.getText() and
90-
// exclude for now anything starting with an uppercase character, which may be a reference to
91-
// an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE),
92-
// which we don't appear to recognize yet anyway. This also assumes programmers follow the
93-
// naming guidelines, which they generally do, but they're not enforced.
94-
not text.charAt(0).isUppercase() and
95-
// exclude parameters from functions without a body as these are trait method declarations
96-
// without implementations
97-
not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = pat) and
98-
// exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`)
99-
not exists(FnPtrTypeRepr fp | fp.getParamList().getParam(_).getPat() = pat)
100-
)
73+
Cached::ref() and
74+
exists(SelfParam sp |
75+
name = sp.getName() and
76+
definingNode = name and
77+
text = name.getText() and
78+
// exclude self parameters from functions without a body as these are
79+
// trait method declarations without implementations
80+
not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp)
81+
)
82+
or
83+
exists(IdentPat pat |
84+
name = pat.getName() and
85+
(
86+
definingNode = getOutermostEnclosingOrPat(pat)
87+
or
88+
not exists(getOutermostEnclosingOrPat(pat)) and definingNode = name
89+
) and
90+
text = name.getText() and
91+
// exclude for now anything starting with an uppercase character, which may be a reference to
92+
// an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE),
93+
// which we don't appear to recognize yet anyway. This also assumes programmers follow the
94+
// naming guidelines, which they generally do, but they're not enforced.
95+
not text.charAt(0).isUppercase() and
96+
// exclude parameters from functions without a body as these are trait method declarations
97+
// without implementations
98+
not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = pat) and
99+
// exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`)
100+
not exists(FnPtrTypeRepr fp | fp.getParamList().getParam(_).getPat() = pat)
101101
)
102102
}
103103

@@ -156,8 +156,12 @@ module Impl {
156156
predicate isCaptured() { this.getAnAccess().isCapture() }
157157

158158
/** Gets the parameter that introduces this variable, if any. */
159+
cached
159160
ParamBase getParameter() {
160-
result = this.getSelfParam() or result.(Param).getPat() = getAVariablePatAncestor(this)
161+
Cached::ref() and
162+
result = this.getSelfParam()
163+
or
164+
result.(Param).getPat() = getAVariablePatAncestor(this)
161165
}
162166

163167
/** Hold is this variable is mutable. */
@@ -614,12 +618,18 @@ module Impl {
614618

615619
/** A variable write. */
616620
class VariableWriteAccess extends VariableAccess {
617-
VariableWriteAccess() { assignmentExprDescendant(this) }
621+
cached
622+
VariableWriteAccess() {
623+
Cached::ref() and
624+
assignmentExprDescendant(this)
625+
}
618626
}
619627

620628
/** A variable read. */
621629
class VariableReadAccess extends VariableAccess {
630+
cached
622631
VariableReadAccess() {
632+
Cached::ref() and
623633
not this instanceof VariableWriteAccess and
624634
not this = any(RefExpr re).getExpr() and
625635
not this = any(CompoundAssignmentExpr cae).getLhs()
@@ -638,6 +648,22 @@ module Impl {
638648

639649
cached
640650
private module Cached {
651+
cached
652+
predicate ref() { 1 = 1 }
653+
654+
cached
655+
predicate backref() {
656+
1 = 1
657+
or
658+
variableDecl(_, _, _)
659+
or
660+
exists(VariableReadAccess a)
661+
or
662+
exists(VariableWriteAccess a)
663+
or
664+
exists(any(Variable v).getParameter())
665+
}
666+
641667
cached
642668
newtype TVariable =
643669
MkVariable(AstNode definingNode, string name) { variableDecl(definingNode, _, name) }

Diff for: rust/ql/lib/codeql/rust/internal/CachedStages.qll

+4
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ module Stages {
123123
exists(any(ItemNode i).getASuccessor(_))
124124
or
125125
exists(any(ItemNode i).getASuccessorRec(_))
126+
or
127+
exists(any(ImplOrTraitItemNode i).getASelfPath())
128+
or
129+
any(TypeParamItemNode i).hasTraitBound()
126130
}
127131
}
128132

Diff for: rust/ql/lib/codeql/rust/internal/PathResolution.qll

+5-2
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,9 @@ abstract class ImplOrTraitItemNode extends ItemNode {
384384
}
385385

386386
/** Gets a `Self` path that refers to this item. */
387+
cached
387388
Path getASelfPath() {
389+
Stages::PathResolutionStage::ref() and
388390
isUnqualifiedSelfPath(result) and
389391
this = unqualifiedPathLookup(result, _)
390392
}
@@ -578,7 +580,7 @@ private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
578580
override TypeParam getTypeParam(int i) { none() }
579581
}
580582

581-
private class TypeParamItemNode extends ItemNode instanceof TypeParam {
583+
class TypeParamItemNode extends ItemNode instanceof TypeParam {
582584
pragma[nomagic]
583585
Path getABoundPath() {
584586
result = super.getTypeBoundList().getABound().getTypeRepr().(PathTypeRepr).getPath()
@@ -598,8 +600,9 @@ private class TypeParamItemNode extends ItemNode instanceof TypeParam {
598600
* impl<T> Foo<T> where T: Trait { ... } // has trait bound
599601
* ```
600602
*/
601-
pragma[nomagic]
603+
cached
602604
predicate hasTraitBound() {
605+
Stages::PathResolutionStage::ref() and
603606
exists(this.getABoundPath())
604607
or
605608
exists(ItemNode declaringItem, WherePred wp |

0 commit comments

Comments
 (0)