Skip to content

Commit fc05455

Browse files
committed
Python: Introduce points-to cached stage
With points-to not being used for the call-graph any longer, it's time to split them.
1 parent bd46b7d commit fc05455

File tree

6 files changed

+47
-23
lines changed

6 files changed

+47
-23
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class ControlFlowNode extends @py_flow_node {
125125
/** Gets a textual representation of this element. */
126126
cached
127127
string toString() {
128-
Stages::DataFlow::ref() and
128+
Stages::PointsTo::ref() and
129129
exists(Scope s | s.getEntryNode() = this | result = "Entry node for " + s.toString())
130130
or
131131
exists(Scope s | s.getANormalExit() = this | result = "Exit node for " + s.toString())

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

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -126,26 +126,24 @@ module Stages {
126126
}
127127

128128
/**
129-
* The `dataflow` stage.
129+
* The points-to stage.
130130
*/
131131
cached
132-
module DataFlow {
132+
module PointsTo {
133133
/**
134134
* Always holds.
135-
* Ensures that a predicate is evaluated as part of the DataFlow stage.
135+
* Ensures that a predicate is evaluated as part of the points-to stage.
136136
*/
137137
cached
138138
predicate ref() { 1 = 1 }
139139

140-
private import semmle.python.dataflow.new.internal.DataFlowPublic as DataFlowPublic
141-
private import semmle.python.dataflow.new.internal.LocalSources as LocalSources
142-
private import semmle.python.internal.Awaited as Awaited
143140
private import semmle.python.pointsto.Base as PointsToBase
144141
private import semmle.python.types.Object as TypeObject
145142
private import semmle.python.objects.TObject as TObject
146143
private import semmle.python.Flow as Flow
147144
private import semmle.python.objects.ObjectInternal as ObjectInternal
148-
private import semmle.python.pointsto.PointsTo as PointsTo
145+
// have to alias since this module is also called PointsTo
146+
private import semmle.python.pointsto.PointsTo as RealPointsTo
149147

150148
/**
151149
* DONT USE!
@@ -155,14 +153,6 @@ module Stages {
155153
predicate backref() {
156154
1 = 1
157155
or
158-
exists(any(DataFlowPublic::Node node).toString())
159-
or
160-
any(DataFlowPublic::Node node).hasLocationInfo(_, _, _, _, _)
161-
or
162-
any(LocalSources::LocalSourceNode n).flowsTo(_)
163-
or
164-
exists(Awaited::awaited(_))
165-
or
166156
PointsToBase::BaseFlow::scope_entry_value_transfer_from_earlier(_, _, _, _)
167157
or
168158
exists(TypeObject::Object a)
@@ -173,7 +163,41 @@ module Stages {
173163
or
174164
exists(any(ObjectInternal::ObjectInternal o).toString())
175165
or
176-
PointsTo::AttributePointsTo::variableAttributePointsTo(_, _, _, _, _)
166+
RealPointsTo::AttributePointsTo::variableAttributePointsTo(_, _, _, _, _)
167+
}
168+
}
169+
170+
/**
171+
* The `dataflow` stage.
172+
*/
173+
cached
174+
module DataFlow {
175+
/**
176+
* Always holds.
177+
* Ensures that a predicate is evaluated as part of the DataFlow stage.
178+
*/
179+
cached
180+
predicate ref() { 1 = 1 }
181+
182+
private import semmle.python.dataflow.new.internal.DataFlowPublic as DataFlowPublic
183+
private import semmle.python.dataflow.new.internal.LocalSources as LocalSources
184+
private import semmle.python.internal.Awaited as Awaited
185+
186+
/**
187+
* DONT USE!
188+
* Contains references to each predicate that use the above `ref` predicate.
189+
*/
190+
cached
191+
predicate backref() {
192+
1 = 1
193+
or
194+
exists(any(DataFlowPublic::Node node).toString())
195+
or
196+
any(DataFlowPublic::Node node).hasLocationInfo(_, _, _, _, _)
197+
or
198+
any(LocalSources::LocalSourceNode n).flowsTo(_)
199+
or
200+
exists(Awaited::awaited(_))
177201
}
178202
}
179203
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ class BuiltinOpaqueObjectInternal extends ObjectInternal, TBuiltinOpaqueObject {
216216
override Builtin getBuiltin() { this = TBuiltinOpaqueObject(result) }
217217

218218
override string toString() {
219-
Stages::DataFlow::ref() and
219+
Stages::PointsTo::ref() and
220220
result = this.getBuiltin().getClass().getName() + " object"
221221
}
222222

python/ql/lib/semmle/python/pointsto/Base.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ module BaseFlow {
318318
predicate scope_entry_value_transfer_from_earlier(
319319
EssaVariable pred_var, Scope pred_scope, ScopeEntryDefinition succ_def, Scope succ_scope
320320
) {
321-
Stages::DataFlow::ref() and
321+
Stages::PointsTo::ref() and
322322
exists(SsaSourceVariable var |
323323
essa_var_scope(var, pred_scope, pred_var) and
324324
scope_entry_def_scope(var, succ_scope, succ_def)

python/ql/lib/semmle/python/pointsto/PointsTo.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2569,7 +2569,7 @@ module AttributePointsTo {
25692569
predicate variableAttributePointsTo(
25702570
EssaVariable var, Context context, string name, ObjectInternal value, CfgOrigin origin
25712571
) {
2572-
Stages::DataFlow::ref() and
2572+
Stages::PointsTo::ref() and
25732573
definitionAttributePointsTo(var.getDefinition(), context, name, value, origin)
25742574
or
25752575
exists(EssaVariable prev |

python/ql/lib/semmle/python/types/Object.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ private import semmle.python.internal.CachedStages
55

66
cached
77
private predicate is_an_object(@py_object obj) {
8-
Stages::DataFlow::ref() and
8+
Stages::PointsTo::ref() and
99
/* CFG nodes for numeric literals, all of which have a @py_cobject for the value of that literal */
1010
obj instanceof ControlFlowNode and
1111
not obj.(ControlFlowNode).getNode() instanceof IntegerLiteral and
@@ -78,7 +78,7 @@ class Object extends @py_object {
7878
predicate hasLocationInfo(
7979
string filepath, int startline, int startcolumn, int endline, int endcolumn
8080
) {
81-
Stages::DataFlow::ref() and
81+
Stages::PointsTo::ref() and
8282
this.hasOrigin() and
8383
this.getOrigin()
8484
.getLocation()
@@ -98,7 +98,7 @@ class Object extends @py_object {
9898
/** Gets a textual representation of this element. */
9999
cached
100100
string toString() {
101-
Stages::DataFlow::ref() and
101+
Stages::PointsTo::ref() and
102102
not this = undefinedVariable() and
103103
not this = unknownValue() and
104104
exists(ClassObject type | type.asBuiltin() = this.asBuiltin().getClass() |

0 commit comments

Comments
 (0)