Python points-to: track instances of int, float or str without a specific value, and calls to bool().

This commit is contained in:
Mark Shannon
2019-07-25 10:24:54 +01:00
parent fc4bb028b7
commit cb719a8998
11 changed files with 160 additions and 11 deletions

View File

@@ -78,6 +78,14 @@ abstract class ConstantObjectInternal extends ObjectInternal {
}
private boolean callToBool(CallNode call, PointsToContext context) {
PointsToInternal::pointsTo(call.getFunction(), context, ClassValue::bool(), _) and
exists(ObjectInternal arg |
PointsToInternal::pointsTo(call.getArg(0),context, arg, _) and
arg.booleanValue() = result
)
}
private abstract class BooleanObjectInternal extends ConstantObjectInternal {
override ObjectInternal getClass() {
@@ -111,6 +119,8 @@ private class TrueObjectInternal extends BooleanObjectInternal, TTrue {
override predicate introducedAt(ControlFlowNode node, PointsToContext context) {
node.(NameNode).getId() = "True" and context.appliesTo(node)
or
callToBool(node, context) = true
}
override int intValue() {
@@ -135,6 +145,8 @@ private class FalseObjectInternal extends BooleanObjectInternal, TFalse {
override predicate introducedAt(ControlFlowNode node, PointsToContext context) {
node.(NameNode).getId() = "False" and context.appliesTo(node)
or
callToBool(node, context) = false
}
override int intValue() {

View File

@@ -469,7 +469,7 @@ library class ClassDecl extends @py_object {
result = this.getClass().getName()
}
/** Whether this is a class whose instances we treat specially, rather than as a generic instance.
/** Whether this is a class whose instances must be treated specially, rather than as generic instances.
*/
predicate isSpecial() {
exists(string name |
@@ -478,11 +478,6 @@ library class ClassDecl extends @py_object {
name = "super" 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
@@ -490,8 +485,6 @@ library class ClassDecl extends @py_object {
name = "MethodType" or
name = "ModuleType"
)
or
this = Builtin::builtin("float")
}
/** Holds if for class `C`, `C()` returns an instance of `C` */

View File

@@ -1249,7 +1249,13 @@ module Expressions {
not op instanceof BitOr and
(operand = left or operand = right) and
PointsToInternal::pointsTo(operand, context, opvalue, _) and
value = ObjectInternal::unknown()
(
op instanceof Add and
value = TUnknownInstance(opvalue.getClass())
or
not op instanceof Add and
value = ObjectInternal::unknown()
)
or
op instanceof BitOr and
exists(ObjectInternal lobj, ObjectInternal robj |