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

Skip to content

Commit 60b5af2

Browse files
committed
cached stages iteration 2
1 parent 71eacea commit 60b5af2

8 files changed

Lines changed: 81 additions & 6 deletions

File tree

python/ql/lib/semmle/python/ApiGraphs.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// Importing python under the `py` namespace to avoid importing `CallNode` from `Flow.qll` and thereby having a naming conflict with `API::CallNode`.
1010
private import python as py
1111
import semmle.python.dataflow.new.DataFlow
12+
private import semmle.python.internal.CachedStages
1213

1314
/**
1415
* Provides classes and predicates for working with APIs used in a database.
@@ -683,6 +684,7 @@ module API {
683684
*/
684685
cached
685686
DataFlow::LocalSourceNode trackUseNode(DataFlow::LocalSourceNode src) {
687+
Stages::TypeTracking::ref() and
686688
result = trackUseNode(src, DataFlow::TypeTracker::end()) and
687689
not result instanceof DataFlow::ModuleVariableNode
688690
}

python/ql/lib/semmle/python/AstExtended.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import python
2+
private import semmle.python.internal.CachedStages
23

34
/** A syntactic node (Class, Function, Module, Expr, Stmt or Comprehension) corresponding to a flow node */
45
abstract class AstNode extends AstNode_ {
@@ -20,6 +21,7 @@ abstract class AstNode extends AstNode_ {
2021
ControlFlowNode getAFlowNode() { py_flow_bb_node(result, this, _, _) }
2122

2223
/** Gets the location for this AST node */
24+
cached
2325
Location getLocation() { none() }
2426

2527
/**
@@ -106,7 +108,10 @@ class Comprehension extends Comprehension_, AstNode {
106108

107109
override string toString() { result = "Comprehension" }
108110

109-
override Location getLocation() { result = Comprehension_.super.getLocation() }
111+
override Location getLocation() {
112+
Stages::SSA::ref() and
113+
result = Comprehension_.super.getLocation()
114+
}
110115

111116
override AstNode getAChildNode() { result = this.getASubExpression() }
112117

python/ql/lib/semmle/python/Exprs.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import python
22
private import semmle.python.pointsto.PointsTo
33
private import semmle.python.objects.ObjectInternal
4+
private import semmle.python.internal.CachedStages
45

56
/** An expression */
67
class Expr extends Expr_, AstNode {
78
/** Gets the scope of this expression */
89
override Scope getScope() { py_scopes(this, result) }
910

1011
/** Gets a textual representation of this element. */
11-
override string toString() { result = "Expression" }
12+
cached
13+
override string toString() {
14+
Stages::SSA::ref() and
15+
result = "Expression"
16+
}
1217

1318
/** Gets the module in which this expression occurs */
1419
Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }

python/ql/lib/semmle/python/Flow.qll

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,12 +1001,16 @@ class BasicBlock extends @py_flow_node {
10011001
string toString() { result = "BasicBlock" }
10021002

10031003
/** Whether this basic block strictly dominates the other */
1004-
pragma[nomagic]
1005-
predicate strictlyDominates(BasicBlock other) { other.getImmediateDominator+() = this }
1004+
cached
1005+
predicate strictlyDominates(BasicBlock other) {
1006+
Stages::SSA::ref() and
1007+
other.getImmediateDominator+() = this
1008+
}
10061009

10071010
/** Whether this basic block dominates the other */
1008-
pragma[nomagic]
1011+
cached
10091012
predicate dominates(BasicBlock other) {
1013+
Stages::SSA::ref() and
10101014
this = other
10111015
or
10121016
this.strictlyDominates(other)

python/ql/lib/semmle/python/Module.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import python
22
private import semmle.python.objects.ObjectAPI
33
private import semmle.python.objects.Modules
4+
private import semmle.python.internal.CachedStages
45

56
/**
67
* A module. This is the top level element in an AST, corresponding to a source file.
@@ -221,7 +222,9 @@ private predicate transitively_imported_from_entry_point(File file) {
221222
)
222223
}
223224

225+
cached
224226
string moduleNameFromFile(Container file) {
227+
Stages::SSA::ref() and
225228
exists(string basename |
226229
basename = moduleNameFromBase(file) and
227230
legalShortName(basename)

python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** Step Summaries and Type Tracking */
22

33
private import TypeTrackerSpecific
4+
private import semmle.python.internal.CachedStages
45

56
/**
67
* A string that may appear as the name of a piece of content. This will usually include things like:
@@ -40,6 +41,7 @@ private module Cached {
4041
/** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */
4142
cached
4243
TypeTracker append(TypeTracker tt, StepSummary step) {
44+
Stages::TypeTracking::ref() and
4345
exists(Boolean hasCall, OptionalContentName content | tt = MkTypeTracker(hasCall, content) |
4446
step = LevelStep() and result = tt
4547
or

python/ql/lib/semmle/python/internal/CachedStages.qll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ module Stages {
3737
*/
3838
cached
3939
module SSA {
40+
// TODO: This is more a "basic AST", not a "SSA" stage.
4041
/**
4142
* Always holds.
4243
* Ensures that a predicate is evaluated as part of the Ast stage.
@@ -47,6 +48,10 @@ module Stages {
4748
private import semmle.python.essa.SsaDefinitions as SsaDefinitions
4849
private import semmle.python.essa.SsaCompute as SsaCompute
4950
private import semmle.python.essa.Essa as Essa
51+
private import semmle.python.Module as PyModule
52+
private import semmle.python.Exprs as Exprs
53+
private import semmle.python.AstExtended as AstExtended
54+
private import semmle.python.Flow as PyFlow
5055

5156
/**
5257
* DONT USE!
@@ -61,6 +66,47 @@ module Stages {
6166
SsaCompute::SsaDefinitions::reachesEndOfBlock(_, _, _, _)
6267
or
6368
exists(any(Essa::PhiFunction p).getInput(_))
69+
or
70+
exists(PyModule::moduleNameFromFile(_))
71+
or
72+
exists(any(Exprs::Expr e).toString())
73+
or
74+
exists(any(AstExtended::AstNode n).getLocation())
75+
or
76+
exists(any(PyFlow::BasicBlock b).getImmediateDominator())
77+
or
78+
any(PyFlow::BasicBlock b).strictlyDominates(_)
79+
or
80+
any(PyFlow::BasicBlock b).dominates(_)
81+
}
82+
}
83+
84+
/**
85+
* The `TypeTracking` stage.
86+
*/
87+
cached
88+
module TypeTracking {
89+
/**
90+
* Always holds.
91+
* Ensures that a predicate is evaluated as part of the Ast stage.
92+
*/
93+
cached
94+
predicate ref() { 1 = 1 }
95+
96+
private import semmle.python.dataflow.new.DataFlow::DataFlow as NewDataFlow
97+
private import semmle.python.ApiGraphs::API as API
98+
99+
/**
100+
* DONT USE!
101+
* Contains references to each predicate that use the above `ref` predicate.
102+
*/
103+
cached
104+
predicate backref() {
105+
1 = 1
106+
or
107+
exists(any(NewDataFlow::TypeTracker t).append(_))
108+
or
109+
exists(any(API::Node n).getAMember().getAUse())
64110
}
65111
}
66112

@@ -83,6 +129,7 @@ module Stages {
83129
private import semmle.python.types.Object as TypeObject
84130
private import semmle.python.objects.TObject as TObject
85131
private import semmle.python.Flow as Flow
132+
private import semmle.python.objects.ObjectInternal as ObjectInternal
86133

87134
/**
88135
* DONT USE!
@@ -107,6 +154,8 @@ module Stages {
107154
exists(TObject::TObject f)
108155
or
109156
exists(any(Flow::ControlFlowNode c).toString())
157+
or
158+
exists(any(ObjectInternal::ObjectInternal o).toString())
110159
}
111160
}
112161

python/ql/lib/semmle/python/objects/ObjectInternal.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ import semmle.python.objects.Callables
1515
import semmle.python.objects.Constants
1616
import semmle.python.objects.Sequences
1717
import semmle.python.objects.Descriptors
18+
private import semmle.python.internal.CachedStages
1819

1920
class ObjectInternal extends TObject {
2021
/** Gets a textual representation of this element. */
22+
cached
2123
abstract string toString();
2224

2325
/**
@@ -213,7 +215,10 @@ class ObjectInternal extends TObject {
213215
class BuiltinOpaqueObjectInternal extends ObjectInternal, TBuiltinOpaqueObject {
214216
override Builtin getBuiltin() { this = TBuiltinOpaqueObject(result) }
215217

216-
override string toString() { result = this.getBuiltin().getClass().getName() + " object" }
218+
override string toString() {
219+
Stages::DataFlow::ref() and
220+
result = this.getBuiltin().getClass().getName() + " object"
221+
}
217222

218223
override boolean booleanValue() {
219224
// TO DO ... Depends on class. `result = this.getClass().instancesBooleanValue()`

0 commit comments

Comments
 (0)