@@ -126,7 +126,7 @@ module PointsTo {
126126 deprecated predicate
127127 points_to ( ControlFlowNode f , PointsToContext context , Object obj , ClassObject cls , ControlFlowNode origin ) {
128128 exists ( Value value |
129- pointsToValue ( f , context , value , origin ) and
129+ PointsToInternal :: pointsTo ( f , context , value , origin ) and
130130 cls = value .getClass ( ) .getSource ( ) |
131131 obj = value .getSource ( ) or
132132 not exists ( value .getSource ( ) ) and obj = origin
@@ -148,14 +148,6 @@ module PointsTo {
148148 )
149149 }
150150
151- private predicate pointsToValue ( ControlFlowNode f , PointsToContext context , Value value , ControlFlowNode origin ) {
152- PointsToInternal:: pointsTo ( f , context , value , origin )
153- or
154- exists ( string name |
155- AttributePointsTo:: attributePointsTo ( f .( AttrNode ) .getObject ( name ) , context , name , value , origin )
156- )
157- }
158-
159151 deprecated predicate
160152 ssa_variable_points_to ( EssaVariable var , PointsToContext context , Object obj , ClassObject cls , CfgOrigin origin ) {
161153 exists ( Value value |
@@ -199,6 +191,8 @@ cached module PointsToInternal {
199191 InterModulePointsTo:: from_import_points_to ( f , context , value , origin )
200192 or
201193 InterProceduralPointsTo:: call_points_to ( f , context , value , origin )
194+ or
195+ AttributePointsTo:: pointsTo ( f , context , value , origin )
202196 // To do... More stuff here :)
203197 // or
204198 // f.(CustomPointsToFact).pointsTo(context, value, origin)
@@ -1135,8 +1129,10 @@ module Expressions {
11351129
11361130 private boolean otherComparisonEvaluatesTo ( CompareNode comp , PointsToContext context , ControlFlowNode operand , ObjectInternal opvalue ) {
11371131 exists ( Cmpop op |
1138- comp .operands ( operand , op , _) and
1139- ( op instanceof In or op instanceof NotIn ) |
1132+ comp .operands ( operand , op , _) or
1133+ comp .operands ( _, op , operand )
1134+ |
1135+ ( op instanceof In or op instanceof NotIn ) and
11401136 PointsToInternal:: pointsTo ( operand , context , opvalue , _)
11411137 ) and result = maybe ( )
11421138 }
@@ -1694,19 +1690,100 @@ cached module Types {
16941690
16951691module AttributePointsTo {
16961692
1697- predicate attributePointsTo ( ControlFlowNode f , Context context , string name , ObjectInternal value , ControlFlowNode origin ) {
1698- exists ( ObjectInternal defobj , Context prev , AttributeAssignment def , ObjectInternal useobj |
1699- PointsToInternal:: pointsTo ( f , context , useobj , _) and
1700- PointsToInternal:: variablePointsTo ( def .getInput ( ) , prev , defobj , _) and
1701- PointsToInternal:: pointsTo ( def .getValue ( ) , prev , value , origin ) and name = def .getName ( )
1702- |
1703- prev .getOuter * ( ) .getCall ( ) .getBasicBlock ( ) .reaches ( context .getOuter * ( ) .getCall ( ) .getBasicBlock ( ) ) and
1704- useobj .( SelfInstanceInternal ) .getClass ( ) = defobj .( SelfInstanceInternal ) .getClass ( )
1705- or
1706- def .getScope ( ) .getScope * ( ) .precedes ( f .getScope ( ) .getScope * ( ) ) and
1707- useobj .( SelfInstanceInternal ) .getClass ( ) = defobj .( SelfInstanceInternal ) .getClass ( )
1708- or
1709- def .getDefiningNode ( ) .getBasicBlock ( ) .dominates ( f .getBasicBlock ( ) ) and defobj = useobj
1693+ predicate pointsTo ( AttrNode f , Context context , ObjectInternal value , ControlFlowNode origin ) {
1694+ exists ( EssaVariable var , string name , CfgOrigin orig |
1695+ var .getASourceUse ( ) = f .getObject ( name ) and
1696+ variableAttributePointsTo ( var , context , name , value , orig ) and
1697+ origin = orig .asCfgNodeOrHere ( f )
1698+ )
1699+ }
1700+
1701+ predicate variableAttributePointsTo ( EssaVariable var , Context context , string name , ObjectInternal value , CfgOrigin origin ) {
1702+ definitionAttributePointsTo ( var .getDefinition ( ) , context , name , value , origin )
1703+ or
1704+ exists ( EssaVariable prev |
1705+ var .getDefinition ( ) .( PhiFunction ) .getShortCircuitInput ( ) = prev and
1706+ variableAttributePointsTo ( prev , context , name , value , origin )
1707+ )
1708+ }
1709+
1710+ predicate definitionAttributePointsTo ( EssaDefinition def , Context context , string name , ObjectInternal value , CfgOrigin origin ) {
1711+ variableAttributePointsTo ( def .( PhiFunction ) .getAnInput ( ) , context , name , value , origin )
1712+ or
1713+ piNodeAttributePointsTo ( def , context , name , value , origin )
1714+ or
1715+ refinementAttributePointsTo ( def , context , name , value , origin )
1716+ or
1717+ selfParameterAttributePointsTo ( def , context , name , value , origin )
1718+ or
1719+ selfMethodCallsitePointsTo ( def , context , name , value , origin )
1720+ }
1721+
1722+ pragma [ noinline]
1723+ private predicate refinementAttributePointsTo ( EssaNodeRefinement def , PointsToContext context , string name , ObjectInternal value , CfgOrigin origin ) {
1724+ attributeAssignmentAttributePointsTo ( def , context , name , value , origin )
1725+ or
1726+ attributeDeleteAttributePointsTo ( def , context , name , value , origin )
1727+ or
1728+ uniEdgedPhiAttributePointsTo ( def , context , name , value , origin )
1729+ }
1730+
1731+
1732+ /** Attribute deletions have no effect as far as value tracking is concerned. */
1733+ pragma [ noinline]
1734+ private predicate attributeAssignmentAttributePointsTo ( AttributeAssignment def , PointsToContext context , string name , ObjectInternal value , CfgOrigin origin ) {
1735+ def .getName ( ) != name and
1736+ variableAttributePointsTo ( def .getInput ( ) , context , name , value , origin )
1737+ or
1738+ def .getName ( ) = name and
1739+ exists ( ControlFlowNode cfgnode |
1740+ PointsToInternal:: pointsTo ( def .getValue ( ) , context , value , cfgnode ) and
1741+ origin = CfgOrigin:: fromCfgNode ( cfgnode )
1742+ )
1743+ }
1744+
1745+ /** Attribute deletions have no effect as far as value tracking is concerned. */
1746+ pragma [ noinline]
1747+ private predicate attributeDeleteAttributePointsTo ( EssaAttributeDeletion def , PointsToContext context , string name , ObjectInternal value , CfgOrigin origin ) {
1748+ def .getName ( ) != name and
1749+ variableAttributePointsTo ( def .getInput ( ) , context , name , value , origin )
1750+ }
1751+
1752+ private predicate uniEdgedPhiAttributePointsTo ( SingleSuccessorGuard uniphi , PointsToContext context , string name , ObjectInternal value , CfgOrigin origin ) {
1753+ variableAttributePointsTo ( uniphi .getInput ( ) , context , name , value , origin )
1754+ }
1755+
1756+ private predicate piNodeAttributePointsTo ( PyEdgeRefinement pi , PointsToContext context , string name , ObjectInternal value , CfgOrigin origin ) {
1757+ variableAttributePointsTo ( pi .getInput ( ) , context , name , value , origin )
1758+ }
1759+
1760+ private predicate selfParameterAttributePointsTo ( ParameterDefinition def , PointsToContext context , string name , ObjectInternal value , CfgOrigin origin ) {
1761+ exists ( MethodCallsiteRefinement call , Function func , PointsToContext caller |
1762+ selfMethodCall ( call , caller , func , context ) and
1763+ def .isSelf ( ) and def .getScope ( ) = func and
1764+ variableAttributePointsTo ( call .getInput ( ) , caller , name , value , origin )
1765+ )
1766+ }
1767+
1768+ /** Pass through for `self` for the implicit re-definition of `self` in `self.foo()`. */
1769+ private predicate selfMethodCallsitePointsTo ( MethodCallsiteRefinement def , PointsToContext context , string name , ObjectInternal value , CfgOrigin origin ) {
1770+ /* The value of self remains the same, only the attributes may change */
1771+ exists ( Function func , PointsToContext callee , EssaVariable exit_self |
1772+ selfMethodCall ( def , context , func , callee ) and
1773+ exit_self .getSourceVariable ( ) .( Variable ) .isSelf ( ) and
1774+ exit_self .getScope ( ) = func and
1775+ BaseFlow:: reaches_exit ( exit_self ) and
1776+ variableAttributePointsTo ( exit_self , context , name , value , origin )
1777+ )
1778+ }
1779+
1780+ private predicate selfMethodCall ( MethodCallsiteRefinement def , PointsToContext caller , Function func , PointsToContext callee ) {
1781+ def .getInput ( ) .getSourceVariable ( ) .( Variable ) .isSelf ( ) and
1782+ exists ( PythonFunctionObjectInternal method , CallNode call |
1783+ method .getScope ( ) = func and
1784+ call = method .getACall ( ) and
1785+ call = def .getDefiningNode ( ) and
1786+ callee .fromCall ( call , caller )
17101787 )
17111788 }
17121789
0 commit comments