@@ -214,43 +214,28 @@ cached module PointsToInternal {
214214
215215 /* Holds if BasicBlock `b` is reachable, given the context `context`. */
216216 cached predicate reachableBlock ( BasicBlock b , PointsToContext context ) {
217- context .appliesToScope ( b .getScope ( ) ) and not exists ( ConditionBlock guard | guard .controls ( b , _) )
218- or
219- exists ( ConditionBlock guard |
220- guard = b .getImmediatelyControllingBlock ( ) and
221- reachableBlock ( guard , context )
222- |
223- allowsFlow ( guard , b , context )
224- or
225- /* Assume the true edge of an assert is reachable (except for assert 0/False) */
226- guard .controls ( b , true ) and
227- exists ( Assert a , Expr test |
228- a .getTest ( ) = test and
229- guard .getLastNode ( ) .getNode ( ) = test and
230- not test instanceof ImmutableLiteral
231- )
232- )
233- }
234-
235- pragma [ noopt]
236- private predicate allowsFlow ( ConditionBlock guard , BasicBlock b , PointsToContext context ) {
237- exists ( ObjectInternal value , boolean sense , ControlFlowNode test |
238- test = guard .getLastNode ( ) and
239- pointsTo ( test , context , value , _) and
240- sense = value .booleanValue ( ) and
241- guard .controls ( b , sense )
217+ exists ( Scope scope |
218+ context .appliesToScope ( scope ) and
219+ scope .getEntryNode ( ) .getBasicBlock ( ) = b
242220 )
221+ or
222+ reachableEdge ( _, b , context )
243223 }
244224
245- /* Holds if the edge `pred` -> `succ` is reachable, given the context `context`.
246- */
247- pragma [ noopt]
248- cached predicate controlledReachableEdge ( BasicBlock pred , BasicBlock succ , PointsToContext context ) {
249- exists ( ConditionBlock guard , ObjectInternal value , boolean sense , ControlFlowNode test |
250- test = guard .getLastNode ( ) and
251- pointsTo ( test , context , value , _) and
252- sense = value .booleanValue ( ) and
253- guard .controlsEdge ( pred , succ , sense )
225+ private predicate reachableEdge ( BasicBlock pred , BasicBlock succ , PointsToContext context ) {
226+ reachableBlock ( pred , context ) and
227+ (
228+ pred .getAnUnconditionalSuccessor ( ) = succ
229+ or
230+ exists ( ObjectInternal value , boolean sense , ControlFlowNode test |
231+ test = pred .getLastNode ( ) and
232+ pointsTo ( test , context , value , _) and
233+ sense = value .booleanValue ( )
234+ |
235+ sense = true and succ = pred .getATrueSuccessor ( )
236+ or
237+ sense = false and succ = pred .getAFalseSuccessor ( )
238+ )
254239 )
255240 }
256241
@@ -519,13 +504,18 @@ cached module PointsToInternal {
519504 /** Holds if the phi-function `phi` refers to `(value, origin)` given the context `context`. */
520505 pragma [ nomagic]
521506 private predicate ssa_phi_points_to ( PhiFunction phi , PointsToContext context , ObjectInternal value , CfgOrigin origin ) {
522- exists ( EssaVariable input , BasicBlock pred |
523- input = phi . getInput ( pred ) and
507+ exists ( EssaVariable input |
508+ ssa_phi_reachable_from_input ( phi , context , input ) and
524509 variablePointsTo ( input , context , value , origin )
525- |
526- controlledReachableEdge ( pred , phi .getBasicBlock ( ) , context )
527- or
528- not exists ( ConditionBlock guard | guard .controlsEdge ( pred , phi .getBasicBlock ( ) , _) )
510+ )
511+ }
512+
513+ /* Helper for ssa_phi_points_to */
514+ pragma [ noinline]
515+ private predicate ssa_phi_reachable_from_input ( PhiFunction phi , PointsToContext context , EssaVariable input ) {
516+ exists ( BasicBlock pred |
517+ input = phi .getInput ( pred ) and
518+ reachableEdge ( pred , phi .getBasicBlock ( ) , context )
529519 )
530520 }
531521
@@ -839,9 +829,7 @@ module InterProceduralPointsTo {
839829 predicate parameter_points_to ( ParameterDefinition def , PointsToContext context , ObjectInternal value , ControlFlowNode origin ) {
840830 self_parameter_points_to ( def , context , value , origin )
841831 or
842- positional_parameter_points_to ( def , context , value , origin )
843- or
844- named_parameter_points_to ( def , context , value , origin )
832+ normal_parameter_points_to ( def , context , value , origin )
845833 or
846834 default_parameter_points_to ( def , context , value , origin )
847835 or
@@ -850,7 +838,7 @@ module InterProceduralPointsTo {
850838
851839 /** Helper for `parameter_points_to` */
852840 pragma [ noinline]
853- private predicate positional_parameter_points_to ( ParameterDefinition def , PointsToContext context , ObjectInternal value , ControlFlowNode origin ) {
841+ private predicate normal_parameter_points_to ( ParameterDefinition def , PointsToContext context , ObjectInternal value , ControlFlowNode origin ) {
854842 exists ( PointsToContext caller , ControlFlowNode arg |
855843 PointsToInternal:: pointsTo ( arg , caller , value , origin ) and
856844 callsite_argument_transfer ( arg , caller , def , context )
@@ -882,16 +870,6 @@ module InterProceduralPointsTo {
882870 )
883871 }
884872
885- /** Helper for `parameter_points_to` */
886- pragma [ noinline]
887- private predicate named_parameter_points_to ( ParameterDefinition def , PointsToContext context , ObjectInternal value , ControlFlowNode origin ) {
888- exists ( CallNode call , PointsToContext caller , PythonFunctionObjectInternal func , string name |
889- context .fromCall ( call , func , caller ) and
890- def .getParameter ( ) = func .getScope ( ) .getArgByName ( name ) and
891- PointsToInternal:: pointsTo ( call .getArgByName ( name ) , caller , value , origin )
892- )
893- }
894-
895873 /** Helper for parameter_points_to */
896874 pragma [ noinline]
897875 private predicate default_parameter_points_to ( ParameterDefinition def , PointsToContext context , ObjectInternal value , ControlFlowNode origin ) {
@@ -939,10 +917,18 @@ module InterProceduralPointsTo {
939917
940918 /** Holds if the `(argument, caller)` pair matches up with `(param, callee)` pair across call. */
941919 cached predicate callsite_argument_transfer ( ControlFlowNode argument , PointsToContext caller , ParameterDefinition param , PointsToContext callee ) {
942- exists ( CallNode call , Function func , int n , int offset |
943- callsite_calls_function ( call , caller , func , callee , offset ) and
944- argument = call .getArg ( n ) and
945- param .getParameter ( ) = func .getArg ( n + offset )
920+ exists ( CallNode call , Function func , int offset |
921+ callsite_calls_function ( call , caller , func , callee , offset )
922+ |
923+ exists ( int n |
924+ argument = call .getArg ( n ) and
925+ param .getParameter ( ) = func .getArg ( n + offset )
926+ )
927+ or
928+ exists ( string name |
929+ argument = call .getArgByName ( name ) and
930+ param .getParameter ( ) = func .getArgByName ( name )
931+ )
946932 )
947933 }
948934
@@ -1334,6 +1320,7 @@ module Expressions {
13341320 val .strValue ( ) = other .strValue ( ) and result = 1
13351321 }
13361322
1323+ pragma [ nomagic]
13371324 private int compare_sequence ( SequenceObjectInternal val , SequenceObjectInternal other , int n ) {
13381325 inequalityTest ( _, _, _, val , other , _, _) and
13391326 (
@@ -1342,11 +1329,17 @@ module Expressions {
13421329 n = other .length ( ) and val .length ( ) > n and result = 1
13431330 or
13441331 n = other .length ( ) and n = val .length ( ) and result = 0
1345- or
1346- result != 0 and result = compare_unbound ( val .getItem ( n ) , other .getItem ( n ) )
1347- or
1348- compare_unbound ( val .getItem ( n ) , other .getItem ( n ) ) = 0 and result = compare_sequence ( val , other , n + 1 )
13491332 )
1333+ or
1334+ result != 0 and result = compare_item ( val , other , n )
1335+ or
1336+ compare_item ( val , other , n ) = 0 and result = compare_sequence ( val , other , n + 1 )
1337+ }
1338+
1339+ pragma [ noinline]
1340+ private int compare_item ( SequenceObjectInternal val , SequenceObjectInternal other , int n ) {
1341+ inequalityTest ( _, _, _, val , other , _, _) and
1342+ result = compare_unbound ( val .getItem ( n ) , other .getItem ( n ) )
13501343 }
13511344
13521345 pragma [ noinline]
0 commit comments