Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 89148a9

Browse files
author
Robert Marsh
committed
C++: respond to further PR comments
1 parent ae4ffd9 commit 89148a9

9 files changed

Lines changed: 146 additions & 104 deletions

File tree

cpp/ql/src/semmle/code/cpp/controlflow/IRGuards.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ class IRGuardCondition extends Instruction {
295295
* return x;
296296
* ```
297297
*/
298-
predicate controlsEdgeDirectly(ConditionalBranchInstruction branch, IRBlock succ, boolean testIsTrue) {
298+
predicate hasBranchEdge(ConditionalBranchInstruction branch, IRBlock succ, boolean testIsTrue) {
299299
branch.getCondition() = this and
300300
(
301301
testIsTrue = true and

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,9 @@ class BinaryInstruction extends Instruction {
751751
result = getAnOperand().(RightOperand).getDefinitionInstruction()
752752
}
753753

754+
/**
755+
* Holds if this instruction's operands are `op1` and `op2`, in either order.
756+
*/
754757
final predicate hasOperands(Operand op1, Operand op2) {
755758
op1 = getAnOperand().(LeftOperand) and op2 = getAnOperand().(RightOperand)
756759
or

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ class ValueNumber extends TValueNumber {
8383
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
8484
)
8585
}
86+
87+
final Operand getAUse() {
88+
this = valueNumber(result.getDefinitionInstruction())
89+
}
8690
}
8791

8892
/**
@@ -220,6 +224,13 @@ ValueNumber valueNumber(Instruction instr) {
220224
)
221225
}
222226

227+
/**
228+
* Gets the value number assigned to `instr`, if any. Returns at most one result.
229+
*/
230+
ValueNumber valueNumberOfOperand(Operand op) {
231+
result = valueNumber(op.getDefinitionInstruction())
232+
}
233+
223234
/**
224235
* Gets the value number assigned to `instr`, if any, unless that instruction is assigned a unique
225236
* value number.

cpp/ql/src/semmle/code/cpp/rangeanalysis/Bound.qll

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ private newtype TBound =
66
TBoundInstruction(Instruction i) {
77
i.getResultType() instanceof IntegralType or
88
i.getResultType() instanceof PointerType
9-
} or
10-
TBoundOperand(Operand o) {
11-
o.getDefinitionInstruction().getResultType() instanceof IntegralType or
12-
o.getDefinitionInstruction().getResultType() instanceof PointerType
139
}
1410

1511
/**
@@ -52,24 +48,4 @@ class InstructionBound extends Bound, TBoundInstruction {
5248
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
5349
getInstruction().getLocation().hasLocationInfo(path, sl, sc, el, ec)
5450
}
55-
}
56-
57-
/**
58-
* A bound corresponding to the value of an `Operand`.
59-
*/
60-
class OperandBound extends Bound, TBoundOperand {
61-
Operand getOperand() {
62-
this = TBoundOperand(result)
63-
}
64-
65-
override Instruction getInstruction(int delta) {
66-
this = TBoundOperand(result.getAUse()) and
67-
delta = 0
68-
}
69-
70-
override string toString() { result = getOperand().toString() }
71-
72-
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
73-
getOperand().getLocation().hasLocationInfo(path, sl, sc, el, ec)
74-
}
75-
}
51+
}

cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,10 @@ import RangeAnalysisPublic
124124
* - `isEq = true` : `i == bound + delta`
125125
* - `isEq = false` : `i != bound + delta`
126126
*/
127-
private IRGuardCondition eqFlowCond(Operand op, Operand bound, int delta,
127+
private IRGuardCondition eqFlowCond(ValueNumber vn, Operand bound, int delta,
128128
boolean isEq, boolean testIsTrue)
129129
{
130-
exists(Operand compared |
131-
result.ensuresEq(compared, bound, delta, op.getInstruction().getBlock(), isEq) and
132-
result.controls(bound.getInstruction().getBlock(), testIsTrue) and
133-
valueNumber(compared.getDefinitionInstruction()) = valueNumber (op.getDefinitionInstruction())
134-
)
130+
result.comparesEq(vn.getAUse(), bound, delta, isEq, testIsTrue)
135131
}
136132

137133
/**
@@ -147,8 +143,9 @@ private predicate boundFlowStepSsa(
147143
reason = TNoReason() and
148144
delta = 0
149145
or*/
150-
exists(IRGuardCondition guard |
151-
guard = boundFlowCond(op2, op1, delta, upper, _) and
146+
exists(IRGuardCondition guard, boolean testIsTrue |
147+
guard = boundFlowCond(valueNumberOfOperand(op2), op1, delta, upper, testIsTrue) and
148+
guard.controls(op2.getInstruction().getBlock(), testIsTrue) and
152149
reason = TCondReason(guard)
153150
)
154151
}
@@ -160,37 +157,19 @@ private predicate boundFlowStepSsa(
160157
* - `upper = true` : `op <= bound + delta`
161158
* - `upper = false` : `op >= bound + delta`
162159
*/
163-
private IRGuardCondition boundFlowCond(NonPhiOperand op, NonPhiOperand bound, int delta, boolean upper,
160+
private IRGuardCondition boundFlowCond(ValueNumber vn, NonPhiOperand bound, int delta, boolean upper,
164161
boolean testIsTrue)
165162
{
166-
exists(Operand compared |
167-
result.comparesLt(compared, bound, delta, upper, testIsTrue) and
168-
result.controls(op.getInstruction().getBlock(), testIsTrue) and
169-
valueNumber(compared.getDefinitionInstruction()) = valueNumber(op.getDefinitionInstruction())
170-
)
171-
// TODO: strengthening through modulus library
172-
}
173-
174-
/**
175-
* Gets a condition that tests whether `op` is bounded by `bound + delta`.
176-
*
177-
* - `upper = true` : `op <= bound + delta`
178-
* - `upper = false` : `op >= bound + delta`
179-
*/
180-
private IRGuardCondition boundFlowCondPhi(PhiOperand op, NonPhiOperand bound, int delta, boolean upper,
181-
boolean testIsTrue)
182-
{
183-
exists(Operand compared |
184-
result.comparesLt(compared, bound, delta, upper, testIsTrue) and
185-
result.controlsEdgeDirectly(op.getPredecessorBlock().getLastInstruction(), op.getInstruction().getBlock(), testIsTrue) and
186-
valueNumber(compared.getDefinitionInstruction()) = valueNumber (op.getDefinitionInstruction())
163+
exists(int d |
164+
result.comparesLt(vn.getAUse(), bound, d, upper, testIsTrue) and
165+
// strengthen from x < y to x <= y-1
166+
if upper = true
167+
then delta = d-1
168+
else delta = d
187169
)
188170
or
189-
exists(Operand compared |
190-
result.comparesLt(compared, bound, delta, upper, testIsTrue) and
191-
result.controls(op.getPredecessorBlock(), testIsTrue) and
192-
valueNumber(compared.getDefinitionInstruction()) = valueNumber (op.getDefinitionInstruction())
193-
)
171+
result = eqFlowCond(vn, bound, delta, true, testIsTrue) and
172+
(upper = true or upper = false)
194173
// TODO: strengthening through modulus library
195174
}
196175

@@ -239,6 +218,9 @@ private predicate safeCast(IntegralType fromtyp, IntegralType totyp) {
239218
private class SafeCastInstruction extends ConvertInstruction {
240219
SafeCastInstruction() {
241220
safeCast(getResultType(), getOperand().getResultType())
221+
or
222+
getResultType() instanceof PointerType and
223+
getOperand().getResultType() instanceof PointerType
242224
}
243225
}
244226

@@ -402,8 +384,13 @@ private predicate boundFlowStepPhi(
402384
reason = TNoReason() and
403385
delta = 0
404386
or
405-
exists(IRGuardCondition guard |
406-
guard = boundFlowCondPhi(op2, op1, delta, upper, _) and
387+
exists(IRGuardCondition guard, boolean testIsTrue |
388+
guard = boundFlowCond(valueNumberOfOperand(op2), op1, delta, upper, testIsTrue) and
389+
(
390+
guard.hasBranchEdge(op2.getPredecessorBlock().getLastInstruction(), op2.getInstruction().getBlock(), testIsTrue)
391+
or
392+
guard.controls(op2.getPredecessorBlock(), testIsTrue)
393+
) and
407394
reason = TCondReason(guard)
408395
)
409396
}
@@ -472,12 +459,10 @@ private int weakenDelta(boolean upper, int delta) {
472459

473460
private predicate boundedPhiInp(
474461
PhiInstruction phi, PhiOperand op, Bound b, int delta, boolean upper, boolean fromBackEdge,
475-
int origdelta, Reason reason
462+
int origdelta, Reason reason
476463
) {
477464
phi.getAnOperand() = op and
478465
exists(int d, boolean fromBackEdge0 |
479-
boundedInstruction(op.getDefinitionInstruction(), b, d, upper, fromBackEdge0, origdelta, reason)
480-
or
481466
boundedPhiOperand(op, b, d, upper, fromBackEdge0, origdelta, reason)
482467
or
483468
b.(InstructionBound).getInstruction() = op.getDefinitionInstruction() and
@@ -564,6 +549,7 @@ private predicate boundedInstruction(
564549
boundedPhiCandValidForEdge(i, b, delta, upper, fromBackEdge, origdelta, reason, op)
565550
)
566551
or
552+
not i instanceof PhiInstruction and
567553
i = b.getInstruction(delta) and
568554
(upper = true or upper = false) and
569555
fromBackEdge = false and

cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeUtils.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,21 @@ predicate valueFlowStep(Instruction i, Operand op, int delta) {
4444
|
4545
delta = -getValue(getConstantValue(x.getDefinitionInstruction()))
4646
)
47+
or
48+
exists(Operand x |
49+
i.(PointerAddInstruction).getAnOperand() = op and
50+
i.(PointerAddInstruction).getAnOperand() = x and
51+
op != x
52+
|
53+
delta = i.(PointerAddInstruction).getElementSize() *
54+
getValue(getConstantValue(x.getDefinitionInstruction()))
55+
)
56+
or
57+
exists(Operand x |
58+
i.(PointerSubInstruction).getAnOperand().(LeftOperand) = op and
59+
i.(PointerSubInstruction).getAnOperand().(RightOperand) = x
60+
|
61+
delta = i.(PointerSubInstruction).getElementSize() *
62+
-getValue(getConstantValue(x.getDefinitionInstruction()))
63+
)
4764
}
Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,39 @@
1-
| test.cpp:8:9:8:9 | Load: y | test.cpp:6:15:6:15 | InitializeParameter: x | 1 | false | CompareLT: ... < ... |
2-
| test.cpp:10:10:10:10 | Load: x | test.cpp:6:15:6:15 | InitializeParameter: x | 0 | false | NoReason |
3-
| test.cpp:10:10:10:10 | Load: x | test.cpp:6:22:6:22 | InitializeParameter: y | 0 | false | CompareLT: ... < ... |
4-
| test.cpp:10:10:10:10 | Load: x | test.cpp:6:22:6:22 | InitializeParameter: y | 0 | false | NoReason |
5-
| test.cpp:16:9:16:9 | Load: y | test.cpp:14:15:14:15 | InitializeParameter: x | 1 | false | CompareLT: ... < ... |
6-
| test.cpp:18:9:18:9 | Load: x | test.cpp:14:22:14:22 | InitializeParameter: y | 0 | false | CompareLT: ... < ... |
7-
| test.cpp:20:10:20:10 | Load: x | test.cpp:14:15:14:15 | InitializeParameter: x | -2 | false | NoReason |
8-
| test.cpp:20:10:20:10 | Load: x | test.cpp:14:22:14:22 | InitializeParameter: y | -2 | false | CompareLT: ... < ... |
9-
| test.cpp:26:14:26:14 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason |
10-
| test.cpp:26:21:26:23 | Load: ... ++ | file://:0:0:0:0 | 0 | 0 | false | NoReason |
11-
| test.cpp:26:21:26:23 | Load: ... ++ | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | CompareLT: ... < ... |
12-
| test.cpp:27:7:27:7 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason |
13-
| test.cpp:27:7:27:7 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | CompareLT: ... < ... |
14-
| test.cpp:29:14:29:14 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | NoReason |
15-
| test.cpp:29:21:29:23 | Load: ... -- | file://:0:0:0:0 | 0 | 1 | false | CompareGT: ... > ... |
16-
| test.cpp:29:21:29:23 | Load: ... -- | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | NoReason |
17-
| test.cpp:30:7:30:7 | Load: i | file://:0:0:0:0 | 0 | 1 | false | CompareGT: ... > ... |
18-
| test.cpp:30:7:30:7 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | NoReason |
19-
| test.cpp:37:6:37:10 | Load: begin | test.cpp:35:28:35:30 | InitializeParameter: end | 0 | true | CompareLT: ... < ... |
20-
| test.cpp:37:16:37:20 | Load: begin | test.cpp:35:28:35:30 | InitializeParameter: end | 0 | true | CompareLT: ... < ... |
21-
| test.cpp:38:5:38:11 | Load: ... ++ | test.cpp:35:28:35:30 | InitializeParameter: end | 0 | true | CompareLT: ... < ... |
22-
| test.cpp:44:13:44:13 | Load: y | test.cpp:42:29:42:29 | InitializeParameter: z | 0 | true | CompareLT: ... < ... |
23-
| test.cpp:45:12:45:12 | Load: x | test.cpp:42:22:42:22 | InitializeParameter: y | 0 | true | CompareLT: ... < ... |
24-
| test.cpp:45:12:45:12 | Load: x | test.cpp:42:29:42:29 | InitializeParameter: z | 0 | true | CompareLT: ... < ... |
25-
| test.cpp:49:9:49:9 | Load: y | test.cpp:42:15:42:15 | InitializeParameter: x | 1 | false | CompareLT: ... < ... |
26-
| test.cpp:50:12:50:12 | Load: x | test.cpp:42:22:42:22 | InitializeParameter: y | 0 | true | CompareLT: ... < ... |
1+
| 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 |
2+
| 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 |
3+
| 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 |
4+
| 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 |
5+
| 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 |
6+
| 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 |
7+
| 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 |
8+
| 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 |
9+
| 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 |
10+
| 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 |
11+
| 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 |
12+
| 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 |
13+
| 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 |
14+
| 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 |
15+
| 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 |
16+
| 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 |
17+
| 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 |
18+
| 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 |
19+
| 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 |
20+
| 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 |
21+
| 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 |
22+
| 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 |
23+
| 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 |
24+
| 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 |
25+
| 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 |
26+
| 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 |
27+
| 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 |
28+
| 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 |
29+
| 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 |
30+
| 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 |
31+
| 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 |
32+
| 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 |
33+
| 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 |
34+
| 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 |
35+
| 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 |
36+
| 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 |
37+
| 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 |
38+
| 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 |
39+
| 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 |

cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.ql

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,23 @@ import semmle.code.cpp.ir.IR
33
import semmle.code.cpp.controlflow.IRGuards
44
import semmle.code.cpp.ir.ValueNumbering
55

6-
query predicate instructionBounds(Instruction i, Bound b, int delta, boolean upper, Reason reason)
6+
query predicate instructionBounds(Instruction i, Bound b, int delta, boolean upper, Reason reason,
7+
Location reasonLoc)
78
{
8-
i instanceof LoadInstruction and
9-
boundedInstruction(i, b, delta, upper, reason) and
109
(
11-
b.(InstructionBound).getInstruction() instanceof InitializeParameterInstruction or
12-
b.(InstructionBound).getInstruction() instanceof CallInstruction or
13-
b instanceof ZeroBound
10+
i.getAUse() instanceof ArgumentOperand
11+
or
12+
i.getAUse() instanceof ReturnValueOperand
1413
) and
15-
not valueNumber(b.(InstructionBound).getInstruction()) = valueNumber(i)
16-
}
14+
(
15+
upper = true and
16+
delta = min(int d | boundedInstruction(i, b, d, upper, reason))
17+
or
18+
upper = false and
19+
delta = max(int d | boundedInstruction(i, b, d, upper, reason))
20+
) and
21+
not valueNumber(b.getInstruction()) = valueNumber(i)
22+
and if reason instanceof CondReason
23+
then reasonLoc = reason.(CondReason).getCond().getLocation()
24+
else reasonLoc instanceof UnknownDefaultLocation
25+
}

cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/test.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,28 @@ int test2(int x, int y) {
2121
}
2222

2323
// for loops
24-
int test3(int x, int *p) {
24+
int test3(int x) {
2525
int i;
2626
for(i = 0; i < x; i++) {
27-
p[i];
27+
sink(i);
2828
}
2929
for(i = x; i > 0; i--) {
30-
p[i];
30+
sink(i);
31+
}
32+
for(i = 0; i < x + 2; i++) {
33+
sink(i);
3134
}
3235
}
3336

3437
// pointer bounds
3538
int test4(int *begin, int *end) {
3639
while (begin < end) {
37-
*begin = (*begin) + 1;
40+
sink(begin);
3841
begin++;
3942
}
4043
}
4144

45+
// bound propagation through conditionals
4246
int test5(int x, int y, int z) {
4347
if (y < z) {
4448
if (x < y) {
@@ -51,3 +55,26 @@ int test5(int x, int y, int z) {
5155
}
5256
}
5357
}
58+
59+
// pointer arithmetic and sizes
60+
void test6(int *p) {
61+
for (char *iter = (char *)p; iter < (char *)(p+1); iter++) {
62+
sink(iter);
63+
}
64+
65+
char *end = (char *)(p+1);
66+
for (char *iter = (char *)p; iter < end; iter++) {
67+
sink(iter);
68+
}
69+
}
70+
71+
// inference from equality
72+
int test8(int x, int y) {
73+
int *p = new int[x];
74+
75+
if (x == y) {
76+
for(int i = 0; i < y; ++i) {
77+
sink(i);
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)