Python points-to: Handle list, dict and float literals as instances.

This commit is contained in:
Mark Shannon
2019-03-25 16:44:02 +00:00
parent 48297e299e
commit f5c32421f4
3 changed files with 32 additions and 8 deletions

View File

@@ -80,6 +80,8 @@ newtype TObject =
TSpecificInstance(ControlFlowNode instantiation, ClassObjectInternal cls, PointsToContext context) {
PointsTo2::points_to(instantiation.(CallNode).getFunction(), context, cls, _) and
cls.isSpecial() = false
or
literal_instantiation(instantiation, cls, context)
}
or
TSelfInstance(ParameterDefinition def, PointsToContext context, PythonClassObjectInternal cls) {
@@ -129,6 +131,19 @@ predicate class_method(CallNode instantiation, CallableObjectInternal function,
PointsTo2::points_to(instantiation.getArg(0), context, function, _)
}
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.getNode() instanceof FloatLiteral and cls = ObjectInternal::builtin("float")
or
n.getNode() instanceof ImaginaryLiteral and cls = ObjectInternal::builtin("complex")
)
}
predicate super_instantiation(CallNode instantiation, ObjectInternal self, ClassObjectInternal startclass, PointsToContext context) {
PointsTo2::points_to(instantiation.getFunction(), context, ObjectInternal::builtin("super"), _) and
(
@@ -267,12 +282,20 @@ library class ClassDecl extends @py_object {
predicate isSpecial() {
exists(string name |
this = Builtin::special(name) |
not name = "object" and
not name = "list" and
not name = "set" and
not name = "dict" and
not name.matches("%Exception") and
not name.matches("%Error")
name = "type" or
name = "bool" or
name = "NoneType" or
name = "int" or
name = "long" or
name = "str" or
name = "bytes" or
name = "unicode" or
name = "tuple" or
name = "property" or
name = "classmethod" or
name = "staticmethod" or
name = "MethodType" or
name = "ModuleType"
)
}

View File

@@ -166,7 +166,7 @@ cached module PointsTo2 {
/* Holds if the edge `pred` -> `succ` is reachable, given the context `context`.
*/
pragma [noopt]
private predicate controlledReachableEdge(BasicBlock pred, BasicBlock succ, PointsToContext context) {
cached predicate controlledReachableEdge(BasicBlock pred, BasicBlock succ, PointsToContext context) {
exists(ConditionBlock guard, ObjectInternal value, boolean sense, ControlFlowNode test |
test = guard.getLastNode() and
points_to(test, context, value, _) and

View File

@@ -6,7 +6,8 @@ private import semmle.python.types.Builtins
private cached predicate is_an_object(@py_object obj) {
/* CFG nodes for numeric literals, all of which have a @py_cobject for the value of that literal */
obj instanceof ControlFlowNode and
not obj.(ControlFlowNode).getNode() instanceof ImmutableLiteral
not obj.(ControlFlowNode).getNode() instanceof IntegerLiteral and
not obj.(ControlFlowNode).getNode() instanceof StrConst
or
obj instanceof Builtin
}