зеркало из https://github.com/github/codeql.git
C++: respond to further PR comments
This commit is contained in:
Родитель
ae4ffd9166
Коммит
89148a9ec7
|
@ -295,7 +295,7 @@ class IRGuardCondition extends Instruction {
|
|||
* return x;
|
||||
* ```
|
||||
*/
|
||||
predicate controlsEdgeDirectly(ConditionalBranchInstruction branch, IRBlock succ, boolean testIsTrue) {
|
||||
predicate hasBranchEdge(ConditionalBranchInstruction branch, IRBlock succ, boolean testIsTrue) {
|
||||
branch.getCondition() = this and
|
||||
(
|
||||
testIsTrue = true and
|
||||
|
|
|
@ -751,6 +751,9 @@ class BinaryInstruction extends Instruction {
|
|||
result = getAnOperand().(RightOperand).getDefinitionInstruction()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this instruction's operands are `op1` and `op2`, in either order.
|
||||
*/
|
||||
final predicate hasOperands(Operand op1, Operand op2) {
|
||||
op1 = getAnOperand().(LeftOperand) and op2 = getAnOperand().(RightOperand)
|
||||
or
|
||||
|
|
|
@ -83,6 +83,10 @@ class ValueNumber extends TValueNumber {
|
|||
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
|
||||
)
|
||||
}
|
||||
|
||||
final Operand getAUse() {
|
||||
this = valueNumber(result.getDefinitionInstruction())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,6 +224,13 @@ ValueNumber valueNumber(Instruction instr) {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value number assigned to `instr`, if any. Returns at most one result.
|
||||
*/
|
||||
ValueNumber valueNumberOfOperand(Operand op) {
|
||||
result = valueNumber(op.getDefinitionInstruction())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value number assigned to `instr`, if any, unless that instruction is assigned a unique
|
||||
* value number.
|
||||
|
|
|
@ -6,10 +6,6 @@ private newtype TBound =
|
|||
TBoundInstruction(Instruction i) {
|
||||
i.getResultType() instanceof IntegralType or
|
||||
i.getResultType() instanceof PointerType
|
||||
} or
|
||||
TBoundOperand(Operand o) {
|
||||
o.getDefinitionInstruction().getResultType() instanceof IntegralType or
|
||||
o.getDefinitionInstruction().getResultType() instanceof PointerType
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,24 +48,4 @@ class InstructionBound extends Bound, TBoundInstruction {
|
|||
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
|
||||
getInstruction().getLocation().hasLocationInfo(path, sl, sc, el, ec)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A bound corresponding to the value of an `Operand`.
|
||||
*/
|
||||
class OperandBound extends Bound, TBoundOperand {
|
||||
Operand getOperand() {
|
||||
this = TBoundOperand(result)
|
||||
}
|
||||
|
||||
override Instruction getInstruction(int delta) {
|
||||
this = TBoundOperand(result.getAUse()) and
|
||||
delta = 0
|
||||
}
|
||||
|
||||
override string toString() { result = getOperand().toString() }
|
||||
|
||||
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
|
||||
getOperand().getLocation().hasLocationInfo(path, sl, sc, el, ec)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -124,14 +124,10 @@ import RangeAnalysisPublic
|
|||
* - `isEq = true` : `i == bound + delta`
|
||||
* - `isEq = false` : `i != bound + delta`
|
||||
*/
|
||||
private IRGuardCondition eqFlowCond(Operand op, Operand bound, int delta,
|
||||
private IRGuardCondition eqFlowCond(ValueNumber vn, Operand bound, int delta,
|
||||
boolean isEq, boolean testIsTrue)
|
||||
{
|
||||
exists(Operand compared |
|
||||
result.ensuresEq(compared, bound, delta, op.getInstruction().getBlock(), isEq) and
|
||||
result.controls(bound.getInstruction().getBlock(), testIsTrue) and
|
||||
valueNumber(compared.getDefinitionInstruction()) = valueNumber (op.getDefinitionInstruction())
|
||||
)
|
||||
result.comparesEq(vn.getAUse(), bound, delta, isEq, testIsTrue)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,8 +143,9 @@ private predicate boundFlowStepSsa(
|
|||
reason = TNoReason() and
|
||||
delta = 0
|
||||
or*/
|
||||
exists(IRGuardCondition guard |
|
||||
guard = boundFlowCond(op2, op1, delta, upper, _) and
|
||||
exists(IRGuardCondition guard, boolean testIsTrue |
|
||||
guard = boundFlowCond(valueNumberOfOperand(op2), op1, delta, upper, testIsTrue) and
|
||||
guard.controls(op2.getInstruction().getBlock(), testIsTrue) and
|
||||
reason = TCondReason(guard)
|
||||
)
|
||||
}
|
||||
|
@ -160,37 +157,19 @@ private predicate boundFlowStepSsa(
|
|||
* - `upper = true` : `op <= bound + delta`
|
||||
* - `upper = false` : `op >= bound + delta`
|
||||
*/
|
||||
private IRGuardCondition boundFlowCond(NonPhiOperand op, NonPhiOperand bound, int delta, boolean upper,
|
||||
private IRGuardCondition boundFlowCond(ValueNumber vn, NonPhiOperand bound, int delta, boolean upper,
|
||||
boolean testIsTrue)
|
||||
{
|
||||
exists(Operand compared |
|
||||
result.comparesLt(compared, bound, delta, upper, testIsTrue) and
|
||||
result.controls(op.getInstruction().getBlock(), testIsTrue) and
|
||||
valueNumber(compared.getDefinitionInstruction()) = valueNumber(op.getDefinitionInstruction())
|
||||
)
|
||||
// TODO: strengthening through modulus library
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a condition that tests whether `op` is bounded by `bound + delta`.
|
||||
*
|
||||
* - `upper = true` : `op <= bound + delta`
|
||||
* - `upper = false` : `op >= bound + delta`
|
||||
*/
|
||||
private IRGuardCondition boundFlowCondPhi(PhiOperand op, NonPhiOperand bound, int delta, boolean upper,
|
||||
boolean testIsTrue)
|
||||
{
|
||||
exists(Operand compared |
|
||||
result.comparesLt(compared, bound, delta, upper, testIsTrue) and
|
||||
result.controlsEdgeDirectly(op.getPredecessorBlock().getLastInstruction(), op.getInstruction().getBlock(), testIsTrue) and
|
||||
valueNumber(compared.getDefinitionInstruction()) = valueNumber (op.getDefinitionInstruction())
|
||||
exists(int d |
|
||||
result.comparesLt(vn.getAUse(), bound, d, upper, testIsTrue) and
|
||||
// strengthen from x < y to x <= y-1
|
||||
if upper = true
|
||||
then delta = d-1
|
||||
else delta = d
|
||||
)
|
||||
or
|
||||
exists(Operand compared |
|
||||
result.comparesLt(compared, bound, delta, upper, testIsTrue) and
|
||||
result.controls(op.getPredecessorBlock(), testIsTrue) and
|
||||
valueNumber(compared.getDefinitionInstruction()) = valueNumber (op.getDefinitionInstruction())
|
||||
)
|
||||
result = eqFlowCond(vn, bound, delta, true, testIsTrue) and
|
||||
(upper = true or upper = false)
|
||||
// TODO: strengthening through modulus library
|
||||
}
|
||||
|
||||
|
@ -239,6 +218,9 @@ private predicate safeCast(IntegralType fromtyp, IntegralType totyp) {
|
|||
private class SafeCastInstruction extends ConvertInstruction {
|
||||
SafeCastInstruction() {
|
||||
safeCast(getResultType(), getOperand().getResultType())
|
||||
or
|
||||
getResultType() instanceof PointerType and
|
||||
getOperand().getResultType() instanceof PointerType
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,8 +384,13 @@ private predicate boundFlowStepPhi(
|
|||
reason = TNoReason() and
|
||||
delta = 0
|
||||
or
|
||||
exists(IRGuardCondition guard |
|
||||
guard = boundFlowCondPhi(op2, op1, delta, upper, _) and
|
||||
exists(IRGuardCondition guard, boolean testIsTrue |
|
||||
guard = boundFlowCond(valueNumberOfOperand(op2), op1, delta, upper, testIsTrue) and
|
||||
(
|
||||
guard.hasBranchEdge(op2.getPredecessorBlock().getLastInstruction(), op2.getInstruction().getBlock(), testIsTrue)
|
||||
or
|
||||
guard.controls(op2.getPredecessorBlock(), testIsTrue)
|
||||
) and
|
||||
reason = TCondReason(guard)
|
||||
)
|
||||
}
|
||||
|
@ -472,12 +459,10 @@ private int weakenDelta(boolean upper, int delta) {
|
|||
|
||||
private predicate boundedPhiInp(
|
||||
PhiInstruction phi, PhiOperand op, Bound b, int delta, boolean upper, boolean fromBackEdge,
|
||||
int origdelta, Reason reason
|
||||
int origdelta, Reason reason
|
||||
) {
|
||||
phi.getAnOperand() = op and
|
||||
exists(int d, boolean fromBackEdge0 |
|
||||
boundedInstruction(op.getDefinitionInstruction(), b, d, upper, fromBackEdge0, origdelta, reason)
|
||||
or
|
||||
boundedPhiOperand(op, b, d, upper, fromBackEdge0, origdelta, reason)
|
||||
or
|
||||
b.(InstructionBound).getInstruction() = op.getDefinitionInstruction() and
|
||||
|
@ -564,6 +549,7 @@ private predicate boundedInstruction(
|
|||
boundedPhiCandValidForEdge(i, b, delta, upper, fromBackEdge, origdelta, reason, op)
|
||||
)
|
||||
or
|
||||
not i instanceof PhiInstruction and
|
||||
i = b.getInstruction(delta) and
|
||||
(upper = true or upper = false) and
|
||||
fromBackEdge = false and
|
||||
|
|
|
@ -44,4 +44,21 @@ predicate valueFlowStep(Instruction i, Operand op, int delta) {
|
|||
|
|
||||
delta = -getValue(getConstantValue(x.getDefinitionInstruction()))
|
||||
)
|
||||
or
|
||||
exists(Operand x |
|
||||
i.(PointerAddInstruction).getAnOperand() = op and
|
||||
i.(PointerAddInstruction).getAnOperand() = x and
|
||||
op != x
|
||||
|
|
||||
delta = i.(PointerAddInstruction).getElementSize() *
|
||||
getValue(getConstantValue(x.getDefinitionInstruction()))
|
||||
)
|
||||
or
|
||||
exists(Operand x |
|
||||
i.(PointerSubInstruction).getAnOperand().(LeftOperand) = op and
|
||||
i.(PointerSubInstruction).getAnOperand().(RightOperand) = x
|
||||
|
|
||||
delta = i.(PointerSubInstruction).getElementSize() *
|
||||
-getValue(getConstantValue(x.getDefinitionInstruction()))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,26 +1,39 @@
|
|||
| test.cpp:8:9:8:9 | Load: y | test.cpp:6:15:6:15 | InitializeParameter: x | 1 | false | CompareLT: ... < ... |
|
||||
| test.cpp:10:10:10:10 | Load: x | test.cpp:6:15:6:15 | InitializeParameter: x | 0 | false | NoReason |
|
||||
| test.cpp:10:10:10:10 | Load: x | test.cpp:6:22:6:22 | InitializeParameter: y | 0 | false | CompareLT: ... < ... |
|
||||
| test.cpp:10:10:10:10 | Load: x | test.cpp:6:22:6:22 | InitializeParameter: y | 0 | false | NoReason |
|
||||
| test.cpp:16:9:16:9 | Load: y | test.cpp:14:15:14:15 | InitializeParameter: x | 1 | false | CompareLT: ... < ... |
|
||||
| test.cpp:18:9:18:9 | Load: x | test.cpp:14:22:14:22 | InitializeParameter: y | 0 | false | CompareLT: ... < ... |
|
||||
| test.cpp:20:10:20:10 | Load: x | test.cpp:14:15:14:15 | InitializeParameter: x | -2 | false | NoReason |
|
||||
| test.cpp:20:10:20:10 | Load: x | test.cpp:14:22:14:22 | InitializeParameter: y | -2 | false | CompareLT: ... < ... |
|
||||
| test.cpp:26:14:26:14 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason |
|
||||
| test.cpp:26:21:26:23 | Load: ... ++ | file://:0:0:0:0 | 0 | 0 | false | NoReason |
|
||||
| test.cpp:26:21:26:23 | Load: ... ++ | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:27:7:27:7 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason |
|
||||
| test.cpp:27:7:27:7 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:29:14:29:14 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | NoReason |
|
||||
| test.cpp:29:21:29:23 | Load: ... -- | file://:0:0:0:0 | 0 | 1 | false | CompareGT: ... > ... |
|
||||
| test.cpp:29:21:29:23 | Load: ... -- | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | NoReason |
|
||||
| test.cpp:30:7:30:7 | Load: i | file://:0:0:0:0 | 0 | 1 | false | CompareGT: ... > ... |
|
||||
| test.cpp:30:7:30:7 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | NoReason |
|
||||
| test.cpp:37:6:37:10 | Load: begin | test.cpp:35:28:35:30 | InitializeParameter: end | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:37:16:37:20 | Load: begin | test.cpp:35:28:35:30 | InitializeParameter: end | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:38:5:38:11 | Load: ... ++ | test.cpp:35:28:35:30 | InitializeParameter: end | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:44:13:44:13 | Load: y | test.cpp:42:29:42:29 | InitializeParameter: z | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:45:12:45:12 | Load: x | test.cpp:42:22:42:22 | InitializeParameter: y | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:45:12:45:12 | Load: x | test.cpp:42:29:42:29 | InitializeParameter: z | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:49:9:49:9 | Load: y | test.cpp:42:15:42:15 | InitializeParameter: x | 1 | false | CompareLT: ... < ... |
|
||||
| test.cpp:50:12:50:12 | Load: x | test.cpp:42:22:42:22 | InitializeParameter: y | 0 | true | CompareLT: ... < ... |
|
||||
| test.cpp:10:10:10:10 | Store: x | test.cpp:6:15:6:15 | InitializeParameter: x | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
|
||||
| test.cpp:10:10:10:10 | Store: x | test.cpp:6:22:6:22 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:7:7:7:11 | test.cpp:7:7:7:11 |
|
||||
| test.cpp:10:10:10:10 | Store: x | test.cpp:6:22:6:22 | InitializeParameter: y | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
|
||||
| test.cpp:20:10:20:10 | Store: x | test.cpp:14:15:14:15 | InitializeParameter: x | -2 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
|
||||
| test.cpp:20:10:20:10 | Store: x | test.cpp:14:22:14:22 | InitializeParameter: y | -2 | false | CompareLT: ... < ... | test.cpp:15:7:15:11 | test.cpp:15:7:15:11 |
|
||||
| test.cpp:27:10:27:10 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
|
||||
| test.cpp:27:10:27:10 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | -1 | true | CompareLT: ... < ... | test.cpp:26:14:26:18 | test.cpp:26:14:26:18 |
|
||||
| test.cpp:27:10:27:10 | Load: i | test.cpp:26:18:26:18 | Load: x | -1 | true | CompareLT: ... < ... | test.cpp:26:14:26:18 | test.cpp:26:14:26:18 |
|
||||
| test.cpp:30:10:30:10 | Load: i | file://:0:0:0:0 | 0 | 1 | false | CompareGT: ... > ... | test.cpp:29:14:29:18 | test.cpp:29:14:29:18 |
|
||||
| test.cpp:30:10:30:10 | Load: i | test.cpp:29:18:29:18 | Constant: 0 | 1 | false | CompareGT: ... > ... | test.cpp:29:14:29:18 | test.cpp:29:14:29:18 |
|
||||
| test.cpp:33:10:33:10 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
|
||||
| test.cpp:33:10:33:10 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 1 | true | CompareLT: ... < ... | test.cpp:32:14:32:22 | test.cpp:32:14:32:22 |
|
||||
| test.cpp:33:10:33:10 | Load: i | test.cpp:26:14:26:14 | Load: i | 1 | true | CompareLT: ... < ... | test.cpp:32:14:32:22 | test.cpp:32:14:32:22 |
|
||||
| test.cpp:33:10:33:10 | Load: i | test.cpp:32:18:32:18 | Load: x | 1 | true | CompareLT: ... < ... | test.cpp:32:14:32:22 | test.cpp:32:14:32:22 |
|
||||
| test.cpp:33:10:33:10 | Load: i | test.cpp:32:18:32:22 | Add: ... + ... | -1 | true | CompareLT: ... < ... | test.cpp:32:14:32:22 | test.cpp:32:14:32:22 |
|
||||
| test.cpp:40:10:40:14 | Load: begin | test.cpp:38:28:38:30 | InitializeParameter: end | -1 | true | CompareLT: ... < ... | test.cpp:39:10:39:20 | test.cpp:39:10:39:20 |
|
||||
| test.cpp:40:10:40:14 | Load: begin | test.cpp:39:18:39:20 | Load: end | -1 | true | CompareLT: ... < ... | test.cpp:39:10:39:20 | test.cpp:39:10:39:20 |
|
||||
| test.cpp:49:12:49:12 | Load: x | test.cpp:46:22:46:22 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:48:9:48:13 | test.cpp:48:9:48:13 |
|
||||
| test.cpp:49:12:49:12 | Load: x | test.cpp:46:29:46:29 | InitializeParameter: z | -2 | true | CompareLT: ... < ... | test.cpp:48:9:48:13 | test.cpp:48:9:48:13 |
|
||||
| test.cpp:49:12:49:12 | Load: x | test.cpp:47:11:47:11 | Load: z | -2 | true | CompareLT: ... < ... | test.cpp:48:9:48:13 | test.cpp:48:9:48:13 |
|
||||
| test.cpp:49:12:49:12 | Load: x | test.cpp:48:13:48:13 | Load: y | -1 | true | CompareLT: ... < ... | test.cpp:48:9:48:13 | test.cpp:48:9:48:13 |
|
||||
| test.cpp:54:12:54:12 | Load: x | test.cpp:46:22:46:22 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:52:7:52:11 | test.cpp:52:7:52:11 |
|
||||
| test.cpp:54:12:54:12 | Load: x | test.cpp:52:11:52:11 | Load: y | -1 | true | CompareLT: ... < ... | test.cpp:52:7:52:11 | test.cpp:52:7:52:11 |
|
||||
| test.cpp:62:10:62:13 | Load: iter | test.cpp:60:17:60:17 | InitializeParameter: p | 3 | true | CompareLT: ... < ... | test.cpp:61:32:61:51 | test.cpp:61:32:61:51 |
|
||||
| test.cpp:62:10:62:13 | Load: iter | test.cpp:61:39:61:51 | Convert: (char *)... | -1 | true | CompareLT: ... < ... | test.cpp:61:32:61:51 | test.cpp:61:32:61:51 |
|
||||
| test.cpp:62:10:62:13 | Load: iter | test.cpp:61:48:61:48 | Load: p | 3 | true | CompareLT: ... < ... | test.cpp:61:32:61:51 | test.cpp:61:32:61:51 |
|
||||
| test.cpp:62:10:62:13 | Load: iter | test.cpp:61:48:61:50 | PointerAdd: ... + ... | -1 | true | CompareLT: ... < ... | test.cpp:61:32:61:51 | test.cpp:61:32:61:51 |
|
||||
| test.cpp:67:10:67:13 | Load: iter | test.cpp:60:17:60:17 | InitializeParameter: p | 3 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
|
||||
| test.cpp:67:10:67:13 | Load: iter | test.cpp:61:32:61:35 | Load: iter | -1 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
|
||||
| test.cpp:67:10:67:13 | Load: iter | test.cpp:65:15:65:27 | Convert: (char *)... | -1 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
|
||||
| test.cpp:67:10:67:13 | Load: iter | test.cpp:65:15:65:27 | Store: (char *)... | -1 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
|
||||
| test.cpp:67:10:67:13 | Load: iter | test.cpp:65:24:65:24 | Load: p | 3 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
|
||||
| test.cpp:67:10:67:13 | Load: iter | test.cpp:65:24:65:26 | PointerAdd: ... + ... | -1 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
|
||||
| test.cpp:67:10:67:13 | Load: iter | test.cpp:66:39:66:41 | Load: end | -1 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
|
||||
| test.cpp:77:12:77:12 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
|
||||
| test.cpp:77:12:77:12 | Load: i | test.cpp:72:15:72:15 | InitializeParameter: x | -1 | true | CompareLT: ... < ... | test.cpp:76:20:76:24 | test.cpp:76:20:76:24 |
|
||||
| test.cpp:77:12:77:12 | Load: i | test.cpp:72:22:72:22 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:76:20:76:24 | test.cpp:76:20:76:24 |
|
||||
| test.cpp:77:12:77:12 | Load: i | test.cpp:75:7:75:7 | Load: x | -1 | true | CompareLT: ... < ... | test.cpp:76:20:76:24 | test.cpp:76:20:76:24 |
|
||||
| test.cpp:77:12:77:12 | Load: i | test.cpp:76:24:76:24 | Load: y | -1 | true | CompareLT: ... < ... | test.cpp:76:20:76:24 | test.cpp:76:20:76:24 |
|
||||
|
|
|
@ -3,14 +3,23 @@ import semmle.code.cpp.ir.IR
|
|||
import semmle.code.cpp.controlflow.IRGuards
|
||||
import semmle.code.cpp.ir.ValueNumbering
|
||||
|
||||
query predicate instructionBounds(Instruction i, Bound b, int delta, boolean upper, Reason reason)
|
||||
query predicate instructionBounds(Instruction i, Bound b, int delta, boolean upper, Reason reason,
|
||||
Location reasonLoc)
|
||||
{
|
||||
i instanceof LoadInstruction and
|
||||
boundedInstruction(i, b, delta, upper, reason) and
|
||||
(
|
||||
b.(InstructionBound).getInstruction() instanceof InitializeParameterInstruction or
|
||||
b.(InstructionBound).getInstruction() instanceof CallInstruction or
|
||||
b instanceof ZeroBound
|
||||
i.getAUse() instanceof ArgumentOperand
|
||||
or
|
||||
i.getAUse() instanceof ReturnValueOperand
|
||||
) and
|
||||
not valueNumber(b.(InstructionBound).getInstruction()) = valueNumber(i)
|
||||
}
|
||||
(
|
||||
upper = true and
|
||||
delta = min(int d | boundedInstruction(i, b, d, upper, reason))
|
||||
or
|
||||
upper = false and
|
||||
delta = max(int d | boundedInstruction(i, b, d, upper, reason))
|
||||
) and
|
||||
not valueNumber(b.getInstruction()) = valueNumber(i)
|
||||
and if reason instanceof CondReason
|
||||
then reasonLoc = reason.(CondReason).getCond().getLocation()
|
||||
else reasonLoc instanceof UnknownDefaultLocation
|
||||
}
|
|
@ -21,24 +21,28 @@ int test2(int x, int y) {
|
|||
}
|
||||
|
||||
// for loops
|
||||
int test3(int x, int *p) {
|
||||
int test3(int x) {
|
||||
int i;
|
||||
for(i = 0; i < x; i++) {
|
||||
p[i];
|
||||
sink(i);
|
||||
}
|
||||
for(i = x; i > 0; i--) {
|
||||
p[i];
|
||||
sink(i);
|
||||
}
|
||||
for(i = 0; i < x + 2; i++) {
|
||||
sink(i);
|
||||
}
|
||||
}
|
||||
|
||||
// pointer bounds
|
||||
int test4(int *begin, int *end) {
|
||||
while (begin < end) {
|
||||
*begin = (*begin) + 1;
|
||||
sink(begin);
|
||||
begin++;
|
||||
}
|
||||
}
|
||||
|
||||
// bound propagation through conditionals
|
||||
int test5(int x, int y, int z) {
|
||||
if (y < z) {
|
||||
if (x < y) {
|
||||
|
@ -51,3 +55,26 @@ int test5(int x, int y, int z) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pointer arithmetic and sizes
|
||||
void test6(int *p) {
|
||||
for (char *iter = (char *)p; iter < (char *)(p+1); iter++) {
|
||||
sink(iter);
|
||||
}
|
||||
|
||||
char *end = (char *)(p+1);
|
||||
for (char *iter = (char *)p; iter < end; iter++) {
|
||||
sink(iter);
|
||||
}
|
||||
}
|
||||
|
||||
// inference from equality
|
||||
int test8(int x, int y) {
|
||||
int *p = new int[x];
|
||||
|
||||
if (x == y) {
|
||||
for(int i = 0; i < y; ++i) {
|
||||
sink(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче