Skip to content

Commit e945999

Browse files
author
Robert Marsh
authored
Merge pull request #3061 from MathiasVP/fix-constant-comparison
C++: Fix getValue in SimpleRangeAnalysis
2 parents 9fc75f1 + 09984a4 commit e945999

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,27 @@ private float wideningUpperBounds(ArithmeticType t) {
9393

9494
/**
9595
* Gets the value of the expression `e`, if it is a constant.
96-
* This predicate also handles the case of constant variables initialized in compilation units,
97-
* which doesn't necessarily have a getValue() result from the extractor.
96+
* This predicate also handles the case of constant variables initialized in different
97+
* compilation units, which doesn't necessarily have a getValue() result from the extractor.
9898
*/
9999
private string getValue(Expr e) {
100100
if exists(e.getValue())
101101
then result = e.getValue()
102102
else
103-
exists(VariableAccess access, Variable v |
103+
/*
104+
* It should be safe to propagate the initialization value to a variable if:
105+
* The type of v is const, and
106+
* The type of v is not volatile, and
107+
* Either:
108+
* v is a local/global variable, or
109+
* v is a static member variable
110+
*/
111+
112+
exists(VariableAccess access, StaticStorageDurationVariable v |
113+
not v.getUnderlyingType().isVolatile() and
114+
v.getUnderlyingType().isConst() and
104115
e = access and
105116
v = access.getTarget() and
106-
v.getUnderlyingType().isConst() and
107117
result = getValue(v.getAnAssignedValue())
108118
)
109119
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
void func_with_default_arg(const int n = 0) {
2+
if(n <= 10) {}
3+
}
4+
5+
struct A {
6+
const int int_member = 0;
7+
A(int n) : int_member(n) {
8+
if(int_member <= 10) {
9+
10+
}
11+
}
12+
};
13+
14+
struct B {
15+
B(const int n = 0) {
16+
if(n <= 10) {}
17+
}
18+
};
19+
20+
const volatile int volatile_const_global = 0;
21+
22+
void test1() {
23+
func_with_default_arg(100);
24+
25+
A a(100);
26+
if(a.int_member <= 10) {}
27+
28+
if(volatile_const_global <= 10) {}
29+
}

0 commit comments

Comments
 (0)