Skip to content

Commit 2436b06

Browse files
authored
Python: Fix another bad "value transfer" join
The culprit: ``` Tuple counts for PointsTo::InterProceduralPointsTo::scope_entry_value_transfer_from_earlier#741b54e2#ffff#join_rhs/5@eb1340iv after 12.6s: 72973 ~3% {2} r1 = JOIN PointsToContext::TImportContext#cf3039a0#f WITH Definitions::NonEscapingGlobalVariable#class#486534ab#f CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.0 'arg1' 537932 ~0% {3} r2 = JOIN r1 WITH Essa::EssaDefinition::getSourceVariable#dispred#f0820431#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1 'arg2', Lhs.1 'arg1', Lhs.0 982333 ~0% {4} r3 = JOIN r2 WITH Essa::EssaVariable::getAUse#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.2, Lhs.1 'arg1', Lhs.0 'arg2', Rhs.1 'arg0' 37029774 ~0% {4} r4 = JOIN r3 WITH Essa::TEssaNodeDefinition#24e22a14#ffff ON FIRST 1 OUTPUT Rhs.3 'arg3', Lhs.1 'arg1', Lhs.2 'arg2', Lhs.3 'arg0' 35956211 ~0% {5} r5 = JOIN r4 WITH Essa::ScopeEntryDefinition::getScope#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.3 'arg0', Lhs.1 'arg1', Lhs.2 'arg2', Lhs.0 'arg3', Rhs.1 'arg4' return r5 ``` You may notice that this is a predicate that's _materialised_, but it's never actually used anywhere. It's the old "standard order" bringing much sadness. The problem here is that in the standard order (which we never actually use here), we end up with a join between the bits above, `getRootCall`, and `appliesToScope`. The `join_rhs` bit is joined twice, once with `getRootCall#prev` and `appliesToScope#prev_delta` (in that order), and once with `prev` and `prev_delta` swapped. So to fix this, I used the unbinding pragma to force `appliesToScope` to appear first in the join order. This was enough to make the compiler _not_ push the common context into its own `join_rhs` predicate (and the join-order is still decent.)
1 parent 4101676 commit 2436b06

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1271,12 +1271,21 @@ module InterProceduralPointsTo {
12711271
)
12721272
)
12731273
or
1274+
non_escaping_global_transfer(pred_var, pred_context, succ_def, succ_context)
1275+
}
1276+
1277+
pragma[nomagic]
1278+
private predicate non_escaping_global_transfer(
1279+
EssaVariable pred_var, PointsToContext pred_context, ScopeEntryDefinition succ_def,
1280+
PointsToContext succ_context
1281+
) {
12741282
exists(NonEscapingGlobalVariable var |
12751283
var = pred_var.getSourceVariable() and
12761284
var = succ_def.getSourceVariable() and
12771285
pred_var.getAUse() = succ_context.getRootCall() and
12781286
pred_context.isImport() and
1279-
succ_context.appliesToScope(succ_def.getScope())
1287+
pragma[only_bind_into](succ_context)
1288+
.appliesToScope(pragma[only_bind_into](succ_def).getScope())
12801289
)
12811290
}
12821291

0 commit comments

Comments
 (0)