Python: Fix bad join in TObject::literal_instantiation

Here, `context.appliesTo(n)` was being distributed across all of the
disjuncts, which caused poor performance.

The new helper predicate, `literal_node_class` should be fairly small,
since it only applies to a subset of `ControlFlowNode`s, and only
assigns a limited set of `ClassObjectInternal`s to these nodes.
This commit is contained in:
Taus Brock-Nannestad
2020-11-05 16:40:29 +01:00
parent 35a63e2411
commit 1251bc57f5

View File

@@ -229,23 +229,32 @@ predicate class_method(
PointsToInternal::pointsTo(instantiation.getArg(0), context, function, _)
}
/**
* Holds if the literal corresponding to the control flow node `n` has class `cls`.
*
* Helper predicate for `literal_instantiation`. Prevents a bad join with
* `PointsToContext::appliesTo` from occuring.
*/
pragma[nomagic]
private predicate literal_node_class(ControlFlowNode n, ClassObjectInternal cls) {
n instanceof ListNode and cls = ObjectInternal::builtin("list")
or
n instanceof DictNode and cls = ObjectInternal::builtin("dict")
or
n instanceof SetNode and cls = ObjectInternal::builtin("set")
or
n.getNode() instanceof ImaginaryLiteral and cls = ObjectInternal::builtin("complex")
or
n.getNode() instanceof ListComp and cls = ObjectInternal::builtin("list")
or
n.getNode() instanceof SetComp and cls = ObjectInternal::builtin("set")
or
n.getNode() instanceof DictComp and cls = ObjectInternal::builtin("dict")
}
predicate literal_instantiation(ControlFlowNode n, ClassObjectInternal cls, PointsToContext context) {
context.appliesTo(n) and
(
n instanceof ListNode and cls = ObjectInternal::builtin("list")
or
n instanceof DictNode and cls = ObjectInternal::builtin("dict")
or
n instanceof SetNode and cls = ObjectInternal::builtin("set")
or
n.getNode() instanceof ImaginaryLiteral and cls = ObjectInternal::builtin("complex")
or
n.getNode() instanceof ListComp and cls = ObjectInternal::builtin("list")
or
n.getNode() instanceof SetComp and cls = ObjectInternal::builtin("set")
or
n.getNode() instanceof DictComp and cls = ObjectInternal::builtin("dict")
)
literal_node_class(n, cls)
}
predicate super_instantiation(