Skip to content

Commit b502ca1

Browse files
authored
Python: Fix bad callsite_points_to join
From `pritomrajkhowa/LoopBound`: ``` Definitions.ql-7:PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#join_rhs#3 ........... 5m53s ``` specifically ``` (767s) Tuple counts for PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#join_rhs#3/3@f8f86764 after 5m53s: 832806293 ~0% {4} r1 = JOIN PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#shared#1 WITH PointsTo::InterProceduralPointsTo::var_at_exit#fff ON FIRST 1 OUTPUT Lhs.0, Lhs.1 'arg1', Rhs.1 'arg2', Rhs.2 'arg0' 832806293 ~0% {3} r2 = JOIN r1 WITH Essa::TEssaNodeRefinement#ffff_03#join_rhs ON FIRST 2 OUTPUT Lhs.3 'arg0', Lhs.1 'arg1', Lhs.2 'arg2' return r2 ``` This one is a bit tricky to unpack. Where is this `shared#1` defined? ``` EVALUATE NONRECURSIVE RELATION: SYNTHETIC PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#shared#1(int arg0, numbered_tuple arg1) :- SENTINEL PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#shared SENTINEL Definitions::EscapingAssignmentGlobalVariable#class#f SENTINEL Essa::TEssaNodeRefinement#ffff_03#join_rhs {2} r1 = JOIN PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#shared WITH Definitions::EscapingAssignmentGlobalVariable#class#f ON FIRST 1 OUTPUT Lhs.0 'arg0', Lhs.1 'arg1' {2} r2 = STREAM DEDUP r1 {2} r3 = JOIN r2 WITH Essa::TEssaNodeRefinement#ffff_03#join_rhs ON FIRST 2 OUTPUT Lhs.0 'arg0', Lhs.1 'arg1' {2} r4 = STREAM DEDUP r3 return r4 ``` Looking at `callsite_points_to`, we see a likely candidate in `srcvar`. It is guarded with an `instanceof` check for `EscapingAssignmentGlobalVariable` (which lines up nicely with the sentinel on its charpred) and `getSourceVariable` is just a projection of `TEssaNodeRefinement`. So let's try unbinding `srcvar` to prevent an early join. The timing is now: ``` Definitions.ql-7:PointsTo::InterProceduralPointsTo::callsite_points_to#ffff ...................... 31.3s (2554 evaluations with max 101ms in PointsTo::InterProceduralPointsTo::callsite_points_to#ffff/4@i516#581fap5w) ``` (Showing the tuple counts doesn't make sense here, since all of the `shared` and `join_rhs` predicates have been smooshed around.)
1 parent bf0ecde commit b502ca1

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

python/ql/lib/semmle/python/pointsto/PointsTo.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,13 +1332,13 @@ module InterProceduralPointsTo {
13321332
predicate callsite_points_to(
13331333
CallsiteRefinement def, PointsToContext context, ObjectInternal value, CfgOrigin origin
13341334
) {
1335-
exists(SsaSourceVariable srcvar | srcvar = def.getSourceVariable() |
1335+
exists(SsaSourceVariable srcvar | pragma[only_bind_into](srcvar) = def.getSourceVariable() |
13361336
if srcvar instanceof EscapingAssignmentGlobalVariable
13371337
then
13381338
/* If global variable can be reassigned, we need to track it through calls */
13391339
exists(EssaVariable var, Function func, PointsToContext callee |
13401340
callsite_calls_function(def.getCall(), context, func, callee, _) and
1341-
var_at_exit(srcvar, func, var) and
1341+
var_at_exit(pragma[only_bind_into](srcvar), func, var) and
13421342
PointsToInternal::variablePointsTo(var, callee, value, origin)
13431343
)
13441344
or

0 commit comments

Comments
 (0)