11/** SSA library */
22
33import python
4- private import LegacyPointsTo
54
65/**
76 * A single static assignment variable.
@@ -62,14 +61,6 @@ class SsaVariable extends @py_ssa_var {
6261 )
6362 }
6463
65- /** Gets an argument of the phi function defining this variable, pruned of unlikely edges. */
66- SsaVariable getAPrunedPhiInput ( ) {
67- result = this .getAPhiInput ( ) and
68- exists ( BasicBlock incoming | incoming = this .getPredecessorBlockForPhiArgument ( result ) |
69- not incoming .getLastNode ( ) .( RaisingNode ) .unlikelySuccessor ( this .getDefinition ( ) )
70- )
71- }
72-
7364 /** Gets a variable that ultimately defines this variable and is not itself defined by another variable */
7465 SsaVariable getAnUltimateDefinition ( ) {
7566 result = this and not exists ( this .getAPhiInput ( ) )
@@ -86,17 +77,11 @@ class SsaVariable extends @py_ssa_var {
8677 string getId ( ) { result = this .getVariable ( ) .getId ( ) }
8778
8879 /** Gets the incoming edges for a Phi node. */
89- private BasicBlock getAPredecessorBlockForPhi ( ) {
80+ BasicBlock getAPredecessorBlockForPhi ( ) {
9081 exists ( this .getAPhiInput ( ) ) and
9182 result .getASuccessor ( ) = this .getDefinition ( ) .getBasicBlock ( )
9283 }
9384
94- /** Gets the incoming edges for a Phi node, pruned of unlikely edges. */
95- private BasicBlockWithPointsTo getAPrunedPredecessorBlockForPhi ( ) {
96- result = this .getAPredecessorBlockForPhi ( ) and
97- not result .unlikelySuccessor ( this .getDefinition ( ) .getBasicBlock ( ) )
98- }
99-
10085 /** Whether it is possible to reach a use of this variable without passing a definition */
10186 predicate reachableWithoutDefinition ( ) {
10287 not exists ( this .getDefinition ( ) ) and not py_ssa_phi ( this , _)
@@ -116,38 +101,6 @@ class SsaVariable extends @py_ssa_var {
116101 )
117102 }
118103
119- /** Whether this variable may be undefined */
120- predicate maybeUndefined ( ) {
121- not exists ( this .getDefinition ( ) ) and not py_ssa_phi ( this , _) and not this .implicitlyDefined ( )
122- or
123- this .getDefinition ( ) .isDelete ( )
124- or
125- exists ( SsaVariable var | var = this .getAPrunedPhiInput ( ) | var .maybeUndefined ( ) )
126- or
127- /*
128- * For phi-nodes, there must be a corresponding phi-input for each control-flow
129- * predecessor. Otherwise, the variable will be undefined on that incoming edge.
130- * WARNING: the same phi-input may cover multiple predecessors, so this check
131- * cannot be done by counting.
132- */
133-
134- exists ( BasicBlock incoming |
135- reaches_end ( incoming ) and
136- incoming = this .getAPrunedPredecessorBlockForPhi ( ) and
137- not this .getAPhiInput ( ) .getDefinition ( ) .getBasicBlock ( ) .dominates ( incoming )
138- )
139- }
140-
141- private predicate implicitlyDefined ( ) {
142- not exists ( this .getDefinition ( ) ) and
143- not py_ssa_phi ( this , _) and
144- exists ( GlobalVariable var | this .getVariable ( ) = var |
145- globallyDefinedName ( var .getId ( ) )
146- or
147- var .getId ( ) = "__path__" and var .getScope ( ) .( Module ) .isPackageInit ( )
148- )
149- }
150-
151104 /**
152105 * Gets the global variable that is accessed if this local is undefined.
153106 * Only applies to local variables in class scopes.
@@ -174,43 +127,6 @@ class SsaVariable extends @py_ssa_var {
174127 }
175128}
176129
177- private predicate reaches_end ( BasicBlock b ) {
178- not exits_early ( b ) and
179- (
180- /* Entry point */
181- not exists ( BasicBlock prev | prev .getASuccessor ( ) = b )
182- or
183- exists ( BasicBlock prev | prev .getASuccessor ( ) = b | reaches_end ( prev ) )
184- )
185- }
186-
187- private predicate exits_early ( BasicBlock b ) {
188- exists ( FunctionObject f |
189- f .neverReturns ( ) and
190- f .getACall ( ) .getBasicBlock ( ) = b
191- )
192- }
193-
194- private predicate gettext_installed ( ) {
195- // Good enough (and fast) approximation
196- exists ( Module m | m .getName ( ) = "gettext" )
197- }
198-
199- private predicate builtin_constant ( string name ) {
200- exists ( Object:: builtin ( name ) )
201- or
202- name = "WindowsError"
203- or
204- name = "_" and gettext_installed ( )
205- }
206-
207- private predicate auto_name ( string name ) {
208- name = "__file__" or name = "__builtins__" or name = "__name__"
209- }
210-
211- /** Whether this name is (almost) always defined, ie. it is a builtin or VM defined name */
212- predicate globallyDefinedName ( string name ) { builtin_constant ( name ) or auto_name ( name ) }
213-
214130/** An SSA variable that is backed by a global variable */
215131class GlobalSsaVariable extends EssaVariable {
216132 GlobalSsaVariable ( ) { this .getSourceVariable ( ) instanceof GlobalVariable }
0 commit comments