Adds modernized files.

This commit is contained in:
Rebecca Valentine
2020-02-11 21:35:30 -08:00
parent 2df3fe8f36
commit 96b8d78650
3 changed files with 75 additions and 6 deletions

View File

@@ -18,18 +18,20 @@ where
// Only relevant for Python 2, as all later versions implement true division
major_version() = 2
and
exists(BinaryExprNode bin, Object lobj, Object robj |
exists(BinaryExprNode bin, Value lobj, Value robj |
bin = div.getAFlowNode()
and bin.getNode().getOp() instanceof Div
and bin.getLeft().refersTo(lobj, theIntType(), left)
and bin.getRight().refersTo(robj, theIntType(), right)
and bin.getLeft().pointsTo(lobj, left)
and lobj.getClass() = ClassValue::int_()
and bin.getRight().pointsTo(robj, right)
and robj.getClass() = ClassValue::int_()
// Ignore instances where integer division leaves no remainder
and not lobj.(NumericObject).intValue() % robj.(NumericObject).intValue() = 0
and not lobj.(NumericValue).intValue() % robj.(NumericValue).intValue() = 0
and not bin.getNode().getEnclosingModule().hasFromFuture("division")
// Filter out results wrapped in `int(...)`
and not exists(CallNode c, ClassObject cls |
and not exists(CallNode c, ClassValue cls |
c.getAnArg() = bin
and c.getFunction().refersTo(cls)
and c.getFunction().pointsTo(cls)
and cls.getName() = "int"
)
)

View File

@@ -78,6 +78,16 @@ class Value extends TObject {
predicate isBuiltin() {
this.(ObjectInternal).isBuiltin()
}
/** INTERNAL -- Do not use */
Builtin asBuiltin() {
this = TBuiltinClassObject(result) or
this = TBuiltinFunctionObject(result) or
this = TBuiltinMethodObject(result) or
this = TBuiltinModuleObject(result) or
this = TBuiltinOpaqueObject(result) or
this = TBuiltinTuple(result)
}
predicate hasLocationInfo(string filepath, int bl, int bc, int el, int ec) {
this.(ObjectInternal).getOrigin().getLocation().hasLocationInfo(filepath, bl, bc, el, ec)
@@ -134,6 +144,62 @@ class Value extends TObject {
}
}
/** Numeric values (ints and floats).
* Includes those occurring in the source as a literal
* or in a builtin module as a value.
*/
class NumericValue extends Value {
NumericValue() {
this.asBuiltin().getClass() = theIntType().asBuiltin() or
this.asBuiltin().getClass() = theLongType().asBuiltin() or
this.asBuiltin().getClass() = theFloatType().asBuiltin()
}
/** Gets the Boolean value that this object
* would evaluate to in a Boolean context,
* such as `bool(x)` or `if x: ...`
*/
override boolean booleanValue() {
this.intValue() != 0 and result = true
or
this.intValue() = 0 and result = false
or
this.floatValue() != 0 and result = true
or
this.floatValue() = 0 and result = false
}
/** Gets the value of this object if it is a constant integer and it fits in a QL int */
int intValue() {
(
this.asBuiltin().getClass() = theIntType().asBuiltin() or
this.asBuiltin().getClass() = theLongType().asBuiltin()
)
and
result = this.asBuiltin().getName().toInt()
}
/** Gets the value of this object if it is a constant float */
float floatValue() {
this.asBuiltin().getClass() = theFloatType().asBuiltin()
and
result = this.asBuiltin().getName().toFloat()
}
/** Gets the string representation of this object, equivalent to calling repr() in Python */
string repr() {
exists(string s |
s = this.asBuiltin().getName() |
if this.asBuiltin().getClass() = theLongType().asBuiltin() then
result = s + "L"
else
result = s
)
}
}
/** Class representing modules in the Python program
* Each `ModuleValue` represents a module object in the Python program.
*/

View File

@@ -0,0 +1 @@
Expressions/TruncatedDivision.ql