Python points-to: Distinguish between class attribute access and lookup. Fixes handling of classmethods.

This commit is contained in:
Mark Shannon
2019-04-09 16:20:01 +01:00
parent 55eac7d555
commit b8fb3e3e61
2 changed files with 21 additions and 7 deletions

View File

@@ -40,10 +40,24 @@ abstract class ClassObjectInternal extends ObjectInternal {
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) {
instance = this and
PointsToInternal::attributeRequired(this, name) and
this.attribute(name, descriptor, _) and
this.lookup(name, descriptor, _) and
descriptor.isDescriptor() = true
}
abstract predicate lookup(string name, ObjectInternal value, CfgOrigin origin);
/** Approximation to descriptor protocol, skipping meta-descriptor protocol */
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
exists(ObjectInternal descriptor, CfgOrigin desc_origin |
this.lookup(name, descriptor, desc_origin) |
descriptor.isDescriptor() = false and
value = descriptor and origin = desc_origin
or
descriptor.isDescriptor() = true and
descriptor.descriptorGet(this, value, origin)
)
}
}
class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject {
@@ -87,7 +101,7 @@ class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject
)
}
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
exists(ClassObjectInternal decl |
decl = Types::getMro(this).findDeclaringClass(name) |
Types::declaredAttribute(decl, name, value, origin)
@@ -142,7 +156,7 @@ class BuiltinClassObjectInternal extends ClassObjectInternal, TBuiltinClassObjec
none()
}
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
value = ObjectInternal::fromBuiltin(this.getBuiltin().getMember(name)) and
origin = CfgOrigin::unknown()
}
@@ -203,7 +217,7 @@ class UnknownClassInternal extends ClassObjectInternal, TUnknownClass {
none()
}
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
none()
}
@@ -251,7 +265,7 @@ class TypeInternal extends ClassObjectInternal, TType {
none()
}
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
none()
}

View File

@@ -91,7 +91,7 @@ class SpecificInstanceInternal extends TSpecificInstance, ObjectInternal {
this = instance and descriptor.isDescriptor() = true and
exists(AttrNode attr |
PointsToInternal::pointsTo(attr.getObject(name), _, instance, _) and
this.getClass().attribute(name, descriptor, _)
this.getClass().(ClassObjectInternal).lookup(name, descriptor, _)
)
}
@@ -302,7 +302,7 @@ private predicate receiver_type(AttrNode attr, string name, ObjectInternal value
}
private predicate cls_descriptor(ClassObjectInternal cls, string name, ObjectInternal descriptor) {
cls.attribute(name, descriptor, _) and
cls.lookup(name, descriptor, _) and
descriptor.isDescriptor() = true
}