Python points-to: Track implicit module attributes through phi-nodes.

This commit is contained in:
Mark Shannon
2019-07-16 15:39:58 +01:00
parent 59a402fcce
commit b4d413cfa8
9 changed files with 143 additions and 8 deletions

View File

@@ -555,8 +555,8 @@ cached module PointsToInternal {
}
/* Helper for ssa_phi_points_to */
pragma [noinline]
private predicate ssa_phi_reachable_from_input(PhiFunction phi, PointsToContext context, EssaVariable input) {
cached
predicate ssa_phi_reachable_from_input(PhiFunction phi, PointsToContext context, EssaVariable input) {
exists(BasicBlock pred |
input = phi.getInput(pred) and
reachableEdge(pred, phi.getBasicBlock(), context)
@@ -2233,6 +2233,17 @@ cached module ModuleAttributes {
callsitePointsTo(var.getDefinition(), name, value, origin)
or
scopeEntryPointsTo(var.getDefinition(), name, value, origin)
or
phiPointsTo(var.getDefinition(), name, value, origin)
}
/** Holds if the phi-function `phi` refers to `(value, origin)` given the context `context`. */
pragma [nomagic]
private predicate phiPointsTo(PhiFunction phi, string name, ObjectInternal value, CfgOrigin origin) {
exists(EssaVariable input |
PointsToInternal::ssa_phi_reachable_from_input(phi, any(Context c | c.isImport()), input) and
attributePointsTo(input, name, value, origin)
)
}
pragma [nomagic]

View File

@@ -559,6 +559,11 @@
| i_imports.py:37 | code_2 = ImportExpr |
| j_convoluted_imports.py:0 | __name___0 = ScopeEntryDefinition |
| j_convoluted_imports.py:0 | __package___0 = ScopeEntryDefinition |
| j_convoluted_imports.py:0 | object_0 = ScopeEntryDefinition |
| j_convoluted_imports.py:0 | p_0 = ScopeEntryDefinition |
| j_convoluted_imports.py:0 | q_0 = ScopeEntryDefinition |
| j_convoluted_imports.py:0 | r_0 = ScopeEntryDefinition |
| j_convoluted_imports.py:0 | unknown_0 = ScopeEntryDefinition |
| j_convoluted_imports.py:3 | module_0 = ImportMember |
| j_convoluted_imports.py:6 | x_0 = ImportMember |
| j_convoluted_imports.py:9 | C_0 = ClassExpr |
@@ -567,6 +572,39 @@
| j_convoluted_imports.py:13 | self_0 = ParameterDefinition |
| j_convoluted_imports.py:14 | x_0 = ImportMember |
| j_convoluted_imports.py:16 | moduleX_0 = ImportMember |
| j_convoluted_imports.py:20 | C_1 = ImportStarRefinement(C_0) |
| j_convoluted_imports.py:20 | __name___1 = ImportStarRefinement(__name___0) |
| j_convoluted_imports.py:20 | __package___1 = ImportStarRefinement(__package___0) |
| j_convoluted_imports.py:20 | moduleX_1 = ImportStarRefinement(moduleX_0) |
| j_convoluted_imports.py:20 | module_1 = ImportStarRefinement(module_0) |
| j_convoluted_imports.py:20 | object_1 = ImportStarRefinement(object_0) |
| j_convoluted_imports.py:20 | p_1 = ImportStarRefinement(p_0) |
| j_convoluted_imports.py:20 | q_1 = ImportStarRefinement(q_0) |
| j_convoluted_imports.py:20 | r_1 = ImportStarRefinement(r_0) |
| j_convoluted_imports.py:20 | unknown_1 = ImportStarRefinement(unknown_0) |
| j_convoluted_imports.py:20 | x_1 = ImportStarRefinement(x_0) |
| j_convoluted_imports.py:22 | C_2 = ImportStarRefinement(C_0) |
| j_convoluted_imports.py:22 | __name___2 = ImportStarRefinement(__name___0) |
| j_convoluted_imports.py:22 | __package___2 = ImportStarRefinement(__package___0) |
| j_convoluted_imports.py:22 | moduleX_2 = ImportStarRefinement(moduleX_0) |
| j_convoluted_imports.py:22 | module_2 = ImportStarRefinement(module_0) |
| j_convoluted_imports.py:22 | object_2 = ImportStarRefinement(object_0) |
| j_convoluted_imports.py:22 | p_2 = ImportStarRefinement(p_0) |
| j_convoluted_imports.py:22 | q_2 = ImportStarRefinement(q_0) |
| j_convoluted_imports.py:22 | r_2 = ImportStarRefinement(r_0) |
| j_convoluted_imports.py:22 | unknown_2 = ImportStarRefinement(unknown_0) |
| j_convoluted_imports.py:22 | x_2 = ImportStarRefinement(x_0) |
| j_convoluted_imports.py:23 | C_3 = phi(C_1, C_2) |
| j_convoluted_imports.py:23 | __name___3 = phi(__name___1, __name___2) |
| j_convoluted_imports.py:23 | __package___3 = phi(__package___1, __package___2) |
| j_convoluted_imports.py:23 | moduleX_3 = phi(moduleX_1, moduleX_2) |
| j_convoluted_imports.py:23 | module_3 = phi(module_1, module_2) |
| j_convoluted_imports.py:23 | object_3 = phi(object_1, object_2) |
| j_convoluted_imports.py:23 | p_3 = phi(p_1, p_2) |
| j_convoluted_imports.py:23 | q_3 = phi(q_1, q_2) |
| j_convoluted_imports.py:23 | r_3 = phi(r_1, r_2) |
| j_convoluted_imports.py:23 | unknown_3 = phi(unknown_1, unknown_2) |
| j_convoluted_imports.py:23 | x_3 = phi(x_1, x_2) |
| k_getsetattr.py:0 | __name___0 = ScopeEntryDefinition |
| k_getsetattr.py:0 | __package___0 = ScopeEntryDefinition |
| k_getsetattr.py:4 | C_0 = ClassExpr |

View File

@@ -107,6 +107,11 @@
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | C | class C |
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | module | Function module |
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | moduleX | Module code.package.moduleX |
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | p | int 1 |
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | q | int 2 |
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | r | Dict |
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | r | int 3 |
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | s | NoneType None |
| j_convoluted_imports.py:0 | Module code.j_convoluted_imports | x | Module code.package.x |
| j_convoluted_imports.py:9 | Class C | f | Function f |
| j_convoluted_imports.py:9 | Class C | module2 | int 7 |

View File

@@ -488,6 +488,12 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
| j_convoluted_imports.py:16 | ControlFlowNode for moduleX | Module code.package.moduleX | builtin-class module | 0 | import |
| j_convoluted_imports.py:17 | ControlFlowNode for Attribute | class Y | builtin-class type | 1 | import |
| j_convoluted_imports.py:17 | ControlFlowNode for moduleX | Module code.package.moduleX | builtin-class module | 0 | import |
| j_convoluted_imports.py:20 | ControlFlowNode for ImportExpr | Module code.test_package.module1 | builtin-class module | 20 | import |
| j_convoluted_imports.py:22 | ControlFlowNode for ImportExpr | Module code.test_package.module2 | builtin-class module | 22 | import |
| j_convoluted_imports.py:23 | ControlFlowNode for p | int 1 | builtin-class int | 3 | import |
| j_convoluted_imports.py:24 | ControlFlowNode for q | int 2 | builtin-class int | 4 | import |
| j_convoluted_imports.py:25 | ControlFlowNode for r | Dict | builtin-class dict | 5 | import |
| j_convoluted_imports.py:25 | ControlFlowNode for r | int 3 | builtin-class int | 5 | import |
| k_getsetattr.py:4 | ControlFlowNode for C | class C | builtin-class type | 4 | import |
| k_getsetattr.py:4 | ControlFlowNode for ClassExpr | class C | builtin-class type | 4 | import |
| k_getsetattr.py:4 | ControlFlowNode for object | builtin-class object | builtin-class type | 4 | import |

View File

@@ -585,6 +585,12 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
| j_convoluted_imports.py:16 | ControlFlowNode for moduleX | Module code.package.moduleX | builtin-class module | 0 |
| j_convoluted_imports.py:17 | ControlFlowNode for Attribute | class Y | builtin-class type | 1 |
| j_convoluted_imports.py:17 | ControlFlowNode for moduleX | Module code.package.moduleX | builtin-class module | 0 |
| j_convoluted_imports.py:20 | ControlFlowNode for ImportExpr | Module code.test_package.module1 | builtin-class module | 20 |
| j_convoluted_imports.py:22 | ControlFlowNode for ImportExpr | Module code.test_package.module2 | builtin-class module | 22 |
| j_convoluted_imports.py:23 | ControlFlowNode for p | int 1 | builtin-class int | 3 |
| j_convoluted_imports.py:24 | ControlFlowNode for q | int 2 | builtin-class int | 4 |
| j_convoluted_imports.py:25 | ControlFlowNode for r | Dict | builtin-class dict | 5 |
| j_convoluted_imports.py:25 | ControlFlowNode for r | int 3 | builtin-class int | 5 |
| k_getsetattr.py:4 | ControlFlowNode for C | class C | builtin-class type | 4 |
| k_getsetattr.py:4 | ControlFlowNode for ClassExpr | class C | builtin-class type | 4 |
| k_getsetattr.py:4 | ControlFlowNode for object | builtin-class object | builtin-class type | 4 |

View File

@@ -357,6 +357,29 @@ WARNING: Predicate ssa_variable_points_to has been deprecated and may be removed
| j_convoluted_imports.py:13 | self_0 = ParameterDefinition | self | class C |
| j_convoluted_imports.py:14 | x_0 = ImportMember | Module code.package.x | builtin-class module |
| j_convoluted_imports.py:16 | moduleX_0 = ImportMember | Module code.package.moduleX | builtin-class module |
| j_convoluted_imports.py:20 | C_1 = ImportStarRefinement(C_0) | class C | builtin-class type |
| j_convoluted_imports.py:20 | __name___1 = ImportStarRefinement(__name___0) | 'code.j_convoluted_imports' | builtin-class str |
| j_convoluted_imports.py:20 | moduleX_1 = ImportStarRefinement(moduleX_0) | Module code.package.moduleX | builtin-class module |
| j_convoluted_imports.py:20 | module_1 = ImportStarRefinement(module_0) | Function module | builtin-class function |
| j_convoluted_imports.py:20 | p_1 = ImportStarRefinement(p_0) | int 1 | builtin-class int |
| j_convoluted_imports.py:20 | q_1 = ImportStarRefinement(q_0) | int 2 | builtin-class int |
| j_convoluted_imports.py:20 | r_1 = ImportStarRefinement(r_0) | int 3 | builtin-class int |
| j_convoluted_imports.py:20 | x_1 = ImportStarRefinement(x_0) | Module code.package.x | builtin-class module |
| j_convoluted_imports.py:22 | C_2 = ImportStarRefinement(C_0) | class C | builtin-class type |
| j_convoluted_imports.py:22 | __name___2 = ImportStarRefinement(__name___0) | 'code.j_convoluted_imports' | builtin-class str |
| j_convoluted_imports.py:22 | moduleX_2 = ImportStarRefinement(moduleX_0) | Module code.package.moduleX | builtin-class module |
| j_convoluted_imports.py:22 | module_2 = ImportStarRefinement(module_0) | Function module | builtin-class function |
| j_convoluted_imports.py:22 | r_2 = ImportStarRefinement(r_0) | Dict | builtin-class dict |
| j_convoluted_imports.py:22 | x_2 = ImportStarRefinement(x_0) | Module code.package.x | builtin-class module |
| j_convoluted_imports.py:23 | C_3 = phi(C_1, C_2) | class C | builtin-class type |
| j_convoluted_imports.py:23 | __name___3 = phi(__name___1, __name___2) | 'code.j_convoluted_imports' | builtin-class str |
| j_convoluted_imports.py:23 | moduleX_3 = phi(moduleX_1, moduleX_2) | Module code.package.moduleX | builtin-class module |
| j_convoluted_imports.py:23 | module_3 = phi(module_1, module_2) | Function module | builtin-class function |
| j_convoluted_imports.py:23 | p_3 = phi(p_1, p_2) | int 1 | builtin-class int |
| j_convoluted_imports.py:23 | q_3 = phi(q_1, q_2) | int 2 | builtin-class int |
| j_convoluted_imports.py:23 | r_3 = phi(r_1, r_2) | Dict | builtin-class dict |
| j_convoluted_imports.py:23 | r_3 = phi(r_1, r_2) | int 3 | builtin-class int |
| j_convoluted_imports.py:23 | x_3 = phi(x_1, x_2) | Module code.package.x | builtin-class module |
| m_attributes.py:0 | __name___0 = ScopeEntryDefinition | 'code.m_attributes' | builtin-class str |
| m_attributes.py:3 | C_0 = ClassExpr | class C | builtin-class type |
| m_attributes.py:5 | __init___0 = FunctionExpr | Function __init__ | builtin-class function |

View File

@@ -618,17 +618,49 @@
| h_classes.py:50 | f_2 | ControlFlowNode for f |
| h_classes.py:52 | arg1_0 | Exit node for Function n |
| h_classes.py:52 | self_0 | Exit node for Function n |
| j_convoluted_imports.py:0 | C_0 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | __name___0 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | __package___0 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | moduleX_0 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | module_0 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | x_0 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | C_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | __name___3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | __package___3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | moduleX_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | module_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | object_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | p_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | q_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | r_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | unknown_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:0 | x_3 | Exit node for Module code.j_convoluted_imports |
| j_convoluted_imports.py:9 | f_0 | Exit node for Class C |
| j_convoluted_imports.py:9 | module2_0 | Exit node for Class C |
| j_convoluted_imports.py:9 | object_0 | ControlFlowNode for object |
| j_convoluted_imports.py:13 | self_0 | Exit node for Function f |
| j_convoluted_imports.py:13 | x_0 | Exit node for Function f |
| j_convoluted_imports.py:17 | moduleX_0 | ControlFlowNode for moduleX |
| j_convoluted_imports.py:19 | unknown_0 | ControlFlowNode for unknown |
| j_convoluted_imports.py:20 | C_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | __name___0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | __package___0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | moduleX_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | module_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | object_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | p_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | q_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | r_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | unknown_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:20 | x_0 | ControlFlowNode for from code.test_package.module1 import * |
| j_convoluted_imports.py:22 | C_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | __name___0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | __package___0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | moduleX_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | module_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | object_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | p_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | q_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | r_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | unknown_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:22 | x_0 | ControlFlowNode for from code.test_package.module2 import * |
| j_convoluted_imports.py:23 | p_3 | ControlFlowNode for p |
| j_convoluted_imports.py:24 | q_3 | ControlFlowNode for q |
| j_convoluted_imports.py:25 | r_3 | ControlFlowNode for r |
| k_getsetattr.py:0 | C_0 | Exit node for Module code.k_getsetattr |
| k_getsetattr.py:0 | __name___0 | Exit node for Module code.k_getsetattr |
| k_getsetattr.py:0 | __package___0 | Exit node for Module code.k_getsetattr |

View File

@@ -372,6 +372,12 @@
| j_convoluted_imports.py:16 | ControlFlowNode for ImportMember | import | Module code.package.moduleX | builtin-class module |
| j_convoluted_imports.py:17 | ControlFlowNode for Attribute | import | class Y | builtin-class type |
| j_convoluted_imports.py:17 | ControlFlowNode for moduleX | import | Module code.package.moduleX | builtin-class module |
| j_convoluted_imports.py:20 | ControlFlowNode for ImportExpr | import | Module code.test_package.module1 | builtin-class module |
| j_convoluted_imports.py:22 | ControlFlowNode for ImportExpr | import | Module code.test_package.module2 | builtin-class module |
| j_convoluted_imports.py:23 | ControlFlowNode for p | import | int 1 | builtin-class int |
| j_convoluted_imports.py:24 | ControlFlowNode for q | import | int 2 | builtin-class int |
| j_convoluted_imports.py:25 | ControlFlowNode for r | import | Dict | builtin-class dict |
| j_convoluted_imports.py:25 | ControlFlowNode for r | import | int 3 | builtin-class int |
| k_getsetattr.py:4 | ControlFlowNode for ClassExpr | import | class C | builtin-class type |
| k_getsetattr.py:4 | ControlFlowNode for object | import | builtin-class object | builtin-class type |
| k_getsetattr.py:6 | ControlFlowNode for FunctionExpr | import | Function C.meth1 | builtin-class function |

View File

@@ -15,3 +15,11 @@ class C(object):
from code.package import moduleX
moduleX.Y
if unknown:
from code.test_package.module1 import *
else:
from code.test_package.module2 import *
p
q
r