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

Skip to content

Commit 3119639

Browse files
committed
C++: Only give the best delta in range analysis
This mirrors Java's 6b85fe0.
1 parent 2cddb82 commit 3119639

2 files changed

Lines changed: 43 additions & 7 deletions

File tree

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

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ private module RangeAnalysisCache {
8080
cached
8181
module RangeAnalysisPublic {
8282
/**
83-
* Holds if `b + delta` is a valid bound for `i`.
83+
* Holds if `b + delta` is a valid bound for `i` and this is the best such delta.
8484
* - `upper = true` : `i <= b + delta`
8585
* - `upper = false` : `i >= b + delta`
8686
*
@@ -90,11 +90,12 @@ private module RangeAnalysisCache {
9090
*/
9191
cached
9292
predicate boundedInstruction(Instruction i, Bound b, int delta, boolean upper, Reason reason) {
93-
boundedInstruction(i, b, delta, upper, _, _, reason)
93+
boundedInstruction(i, b, delta, upper, _, _, reason) and
94+
bestInstructionBound(i, b, delta, upper)
9495
}
9596

9697
/**
97-
* Holds if `b + delta` is a valid bound for `op`.
98+
* Holds if `b + delta` is a valid bound for `op` and this is the best such delta.
9899
* - `upper = true` : `op <= b + delta`
99100
* - `upper = false` : `op >= b + delta`
100101
*
@@ -104,9 +105,8 @@ private module RangeAnalysisCache {
104105
*/
105106
cached
106107
predicate boundedOperand(Operand op, Bound b, int delta, boolean upper, Reason reason) {
107-
boundedNonPhiOperand(op, b, delta, upper, _, _, reason)
108-
or
109-
boundedPhiOperand(op, b, delta, upper, _, _, reason)
108+
boundedOperandCand(op, b, delta, upper, reason) and
109+
bestOperandBound(op, b, delta, upper)
110110
}
111111
}
112112

@@ -124,6 +124,43 @@ private module RangeAnalysisCache {
124124
private import RangeAnalysisCache
125125
import RangeAnalysisPublic
126126

127+
/**
128+
* Holds if `b + delta` is a valid bound for `e` and this is the best such delta.
129+
* - `upper = true` : `e <= b + delta`
130+
* - `upper = false` : `e >= b + delta`
131+
*/
132+
private predicate bestInstructionBound(Instruction i, Bound b, int delta, boolean upper) {
133+
delta = min(int d | boundedInstruction(i, b, d, upper, _, _, _)) and upper = true
134+
or
135+
delta = max(int d | boundedInstruction(i, b, d, upper, _, _, _)) and upper = false
136+
}
137+
138+
/**
139+
* Holds if `b + delta` is a valid bound for `op`.
140+
* - `upper = true` : `op <= b + delta`
141+
* - `upper = false` : `op >= b + delta`
142+
*
143+
* The reason for the bound is given by `reason` and may be either a condition
144+
* or `NoReason` if the bound was proven directly without the use of a bounding
145+
* condition.
146+
*/
147+
private predicate boundedOperandCand(Operand op, Bound b, int delta, boolean upper, Reason reason) {
148+
boundedNonPhiOperand(op, b, delta, upper, _, _, reason)
149+
or
150+
boundedPhiOperand(op, b, delta, upper, _, _, reason)
151+
}
152+
153+
/**
154+
* Holds if `b + delta` is a valid bound for `op` and this is the best such delta.
155+
* - `upper = true` : `op <= b + delta`
156+
* - `upper = false` : `op >= b + delta`
157+
*/
158+
private predicate bestOperandBound(Operand op, Bound b, int delta, boolean upper) {
159+
delta = min(int d | boundedOperandCand(op, b, d, upper, _)) and upper = true
160+
or
161+
delta = max(int d | boundedOperandCand(op, b, d, upper, _)) and upper = false
162+
}
163+
127164
/**
128165
* Gets a condition that tests whether `vn` equals `bound + delta`.
129166
*

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | false | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 |
5252
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
5353
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 |
54-
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
5554
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 1 | false | CompareEQ: ... == ... | test.cpp:166:9:166:16 | test.cpp:166:9:166:16 |
5655
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 1 | true | CompareEQ: ... == ... | test.cpp:166:9:166:16 | test.cpp:166:9:166:16 |
5756
| test.cpp:169:12:169:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |

0 commit comments

Comments
 (0)