@@ -114,19 +114,23 @@ module PointsTo {
114114 /** INTERNAL -- Do not use.
115115 *
116116 * Holds if `package.name` points to `(value, cls, origin)`, where `package` is a package object. */
117- cached predicate package_attribute_points_to ( PackageObject package , string name , Object value , ClassObject cls , ControlFlowNode origin ) {
117+ cached predicate package_attribute_points_to ( PackageObject package , string name , Object value , ClassObject cls , ObjectOrCfg origin ) {
118118 py_module_attributes ( package .getInitModule ( ) .getModule ( ) , name , value , cls , origin )
119119 or
120120 exists ( Module init |
121- init = package .getInitModule ( ) .getModule ( ) |
122- not exists ( PythonSsaSourceVariable v | v .getScope ( ) = init | v .getName ( ) = name or v .getName ( ) = "*" )
123- or
124- exists ( EssaVariable v , PointsToContext imp |
125- v .getScope ( ) = init and v .getName ( ) = "*" and v .getAUse ( ) = init .getANormalExit ( ) |
126- SSA:: ssa_variable_named_attribute_points_to ( v , imp , name , undefinedVariable ( ) , _, _) and
127- imp .isImport ( )
121+ init = package .getInitModule ( ) .getModule ( ) and
122+ not exists ( EssaVariable var | var .getAUse ( ) = init .getANormalExit ( ) and var .getSourceVariable ( ) .getName ( ) = name ) and
123+ exists ( EssaVariable var , Context context |
124+ isModuleStateVariable ( var ) and var .getAUse ( ) = init .getANormalExit ( ) and
125+ context .isImport ( ) and
126+ SSA:: ssa_variable_named_attribute_points_to ( var , context , name , undefinedVariable ( ) , _, _) and
127+ origin = value and
128+ value = package .submodule ( name ) and
129+ cls = theModuleType ( )
128130 )
129- ) and explicitly_imported ( value ) and
131+ )
132+ or
133+ package .hasNoInitModule ( ) and
130134 value = package .submodule ( name ) and cls = theModuleType ( ) and origin = value
131135 }
132136
@@ -145,7 +149,7 @@ module PointsTo {
145149 or
146150 not exists ( EssaVariable var | var .getAUse ( ) = m .getANormalExit ( ) and var .getSourceVariable ( ) .getName ( ) = name ) and
147151 exists ( EssaVariable var , PointsToContext imp |
148- var .getAUse ( ) = m .getANormalExit ( ) and var . getName ( ) = "*" |
152+ var .getAUse ( ) = m .getANormalExit ( ) and isModuleStateVariable ( var ) |
149153 SSA:: ssa_variable_named_attribute_points_to ( var , imp , name , obj , cls , origin ) and
150154 imp .isImport ( ) and obj != undefinedVariable ( )
151155 )
@@ -661,19 +665,25 @@ module PointsTo {
661665 /** Holds if `f` is a "from import" expression, `from mod import x` and points to `(value, cls, origin)`. */
662666 pragma [ nomagic]
663667 private predicate from_import_points_to ( ImportMemberNode f , PointsToContext context , Object value , ClassObject cls , ControlFlowNode origin ) {
664- exists ( EssaVariable var , ObjectOrCfg orig |
665- live_import_from_dot_in_init ( f , var ) and
666- ssa_variable_points_to ( var , context , value , cls , orig ) and
668+ exists ( string name , ModuleObject mod , ObjectOrCfg orig |
669+ points_to ( f .getModule ( name ) , context , mod , _, _) and
667670 origin = origin_from_object_or_here ( orig , f )
668- )
669- or
670- not live_import_from_dot_in_init ( f , _) and
671- exists ( string name , ModuleObject mod |
672- points_to ( f .getModule ( name ) , context , mod , _, _) |
673- exists ( ObjectOrCfg orig |
674- Layer:: module_attribute_points_to ( mod , name , value , cls , orig ) and
675- origin = origin_from_object_or_here ( orig , f )
671+ |
672+ mod .getSourceModule ( ) = f .getEnclosingModule ( ) and
673+ exists ( EssaVariable var |
674+ var .getSourceVariable ( ) .getName ( ) = name and var .getAUse ( ) = f and
675+ ssa_variable_points_to ( var , context , value , cls , orig )
676676 )
677+ or
678+ mod .getSourceModule ( ) = f .getEnclosingModule ( ) and
679+ not exists ( EssaVariable var | var .getSourceVariable ( ) .getName ( ) = name and var .getAUse ( ) = f ) and
680+ exists ( EssaVariable dollar |
681+ isModuleStateVariable ( dollar ) and dollar .getAUse ( ) = f and
682+ SSA:: ssa_variable_named_attribute_points_to ( dollar , context , name , value , cls , orig )
683+ )
684+ or
685+ not mod .getSourceModule ( ) = f .getEnclosingModule ( ) and
686+ Layer:: module_attribute_points_to ( mod , name , value , cls , orig )
677687 )
678688 }
679689
@@ -1679,7 +1689,7 @@ module PointsTo {
16791689 /* Undefined variable */
16801690 exists ( Scope scope |
16811691 not def .getVariable ( ) .getName ( ) = "__name__" and
1682- not def .getVariable ( ) .getName ( ) = "* " and
1692+ not def .getVariable ( ) .getName ( ) = "$ " and
16831693 def .getScope ( ) = scope and context .appliesToScope ( scope ) |
16841694 def .getSourceVariable ( ) instanceof GlobalVariable and scope instanceof Module
16851695 or
@@ -1852,7 +1862,7 @@ module PointsTo {
18521862 )
18531863 or
18541864 origin = def .getDefiningNode ( ) and
1855- def .getSourceVariable ( ) . getName ( ) = "*" and
1865+ isModuleStateVariable ( def .getVariable ( ) ) and
18561866 context .isImport ( ) and
18571867 exists ( PackageObject package |
18581868 package .getInitModule ( ) .getModule ( ) = def .getScope ( ) |
@@ -1963,7 +1973,7 @@ module PointsTo {
19631973 /* Helper for import_star_named_attribute_points_to */
19641974 pragma [ noinline]
19651975 private predicate star_variable_import_star_module ( ImportStarRefinement def , ImportStarNode imp , PointsToContext context , ModuleObject mod ) {
1966- def .getSourceVariable ( ) . getName ( ) = "*" and
1976+ isModuleStateVariable ( def .getVariable ( ) ) and
19671977 exists ( ControlFlowNode fmod |
19681978 fmod = imp .getModule ( ) and
19691979 imp = def .getDefiningNode ( ) and
@@ -1983,7 +1993,7 @@ module PointsTo {
19831993 /* Helper for ssa_star_variable_input_points_to */
19841994 pragma [ noinline]
19851995 private predicate ssa_star_import_star_input ( ImportStarRefinement def , EssaVariable var ) {
1986- def .getSourceVariable ( ) . getName ( ) = "*" and var = def .getInput ( )
1996+ isModuleStateVariable ( def .getVariable ( ) ) and var = def .getInput ( )
19871997 }
19881998
19891999 pragma [ noinline]
@@ -2777,6 +2787,15 @@ module PointsTo {
27772787
27782788 }
27792789
2790+ /** Get the ESSA pseudo-variable used to retain module state
2791+ * during module initialization. Module attributes are handled
2792+ * as attributes of this variable, allowing the SSA form to track
2793+ * mutations of the module during its creation.
2794+ */
2795+ private predicate isModuleStateVariable ( EssaVariable var ) {
2796+ var .getName ( ) = "$" and var .getScope ( ) instanceof Module
2797+ }
2798+
27802799 /** INTERNAL -- Public for testing only */
27812800 module Test {
27822801
0 commit comments