mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
C++: switch to using ValueNumbers as bounds
This reduces the number of bounds computed, and will simplify use of the library. The resulting locations in the tests may be slightly strange, because the example `Instruction` for a `ValueNumber` is the first appearing in the IR, regardless of source order, and may not be the most closely related `Instruction` to the bounded value. I think that's worth doing for the performance and usability benefits.
This commit is contained in:
@@ -1,11 +1,33 @@
|
||||
import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
|
||||
private newtype TBound =
|
||||
TBoundZero() or
|
||||
TBoundInstruction(Instruction i) {
|
||||
i.getResultType() instanceof IntegralType or
|
||||
i.getResultType() instanceof PointerType
|
||||
TBoundValueNumber(ValueNumber vn) {
|
||||
exists(Instruction i |
|
||||
vn.getAnInstruction() = i and
|
||||
(
|
||||
i.getResultType() instanceof IntegralType or
|
||||
i.getResultType() instanceof PointerType
|
||||
)
|
||||
|
|
||||
i instanceof PhiInstruction
|
||||
or
|
||||
i instanceof InitializeParameterInstruction
|
||||
or
|
||||
i instanceof CallInstruction
|
||||
or
|
||||
i instanceof VariableAddressInstruction
|
||||
or
|
||||
i instanceof FieldAddressInstruction
|
||||
or
|
||||
i.(LoadInstruction).getSourceAddress() instanceof VariableAddressInstruction
|
||||
or
|
||||
i.(LoadInstruction).getSourceAddress() instanceof FieldAddressInstruction
|
||||
or
|
||||
i.getAUse() instanceof ArgumentOperand
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20,12 +42,9 @@ abstract class Bound extends TBound {
|
||||
/** Gets an expression that equals this bound. */
|
||||
Instruction getInstruction() { result = getInstruction(0) }
|
||||
|
||||
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
|
||||
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
|
||||
}
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The bound that corresponds to the integer 0. This is used to represent all
|
||||
* integer bounds as bounds are always accompanied by an added integer delta.
|
||||
@@ -34,18 +53,27 @@ class ZeroBound extends Bound, TBoundZero {
|
||||
override string toString() { result = "0" }
|
||||
|
||||
override Instruction getInstruction(int delta) { result.(ConstantValueInstruction).getValue().toInt() = delta }
|
||||
|
||||
override Location getLocation() {
|
||||
result instanceof UnknownDefaultLocation
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A bound corresponding to the value of an `Instruction`.
|
||||
*/
|
||||
class InstructionBound extends Bound, TBoundInstruction {
|
||||
/** Gets the SSA variable that equals this bound. */
|
||||
override Instruction getInstruction(int delta) { this = TBoundInstruction(result) and delta = 0}
|
||||
|
||||
override string toString() { result = getInstruction().toString() }
|
||||
|
||||
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
|
||||
getInstruction().getLocation().hasLocationInfo(path, sl, sc, el, ec)
|
||||
class ValueNumberBound extends Bound, TBoundValueNumber {
|
||||
ValueNumber vn;
|
||||
|
||||
ValueNumberBound() {
|
||||
this = TBoundValueNumber(vn)
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the SSA variable that equals this bound. */
|
||||
override Instruction getInstruction(int delta) { this = TBoundValueNumber(valueNumber(result)) and delta = 0}
|
||||
|
||||
override string toString() { result = vn.getExampleInstruction().toString() }
|
||||
|
||||
override Location getLocation() {
|
||||
result = vn.getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ private predicate boundedPhiInp(
|
||||
exists(int d, boolean fromBackEdge0 |
|
||||
boundedPhiOperand(op, b, d, upper, fromBackEdge0, origdelta, reason)
|
||||
or
|
||||
b.(InstructionBound).getInstruction() = op.getDefinitionInstruction() and
|
||||
b.(ValueNumberBound).getInstruction() = op.getDefinitionInstruction() and
|
||||
d = 0 and
|
||||
(upper = true or upper = false) and
|
||||
fromBackEdge0 = false and
|
||||
@@ -494,7 +494,7 @@ private predicate boundedPhiInp1(
|
||||
}
|
||||
|
||||
private predicate selfBoundedPhiInp(PhiInstruction phi, PhiOperand op, boolean upper) {
|
||||
exists(int d, InstructionBound phibound |
|
||||
exists(int d, ValueNumberBound phibound |
|
||||
phibound.getInstruction() = phi and
|
||||
boundedPhiInp(phi, op, phibound, d, upper, _, _, _) and
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user