Skip to content

Commit 78625b7

Browse files
committed
C++: Add test for bitwise and ranges
1 parent 48c6f34 commit 78625b7

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
typedef unsigned char uint8_t;
2+
typedef signed char int8_t;
3+
typedef unsigned uint32_t;
4+
typedef signed long long int64_t;
5+
6+
void test_assign_operator(uint8_t x) {
7+
x &= 7; // [0 .. 7]
8+
}
9+
10+
void test_non_negative_const(uint8_t x) {
11+
uint8_t unsigned_const = 7;
12+
13+
// Non-negative range operand and non-negative constant. The operands are promoted
14+
// to signed ints.
15+
x & 0; // [0 .. 0]
16+
x & 7; // [0 .. 7]
17+
x & unsigned_const; // [0 .. 7]
18+
19+
// This tests what happens when both arguments are promoted to `unsigned int` instead
20+
// of `int`, and when the constant is larger than the max bound
21+
x & 0xFFFFFFFF; // [0 .. 255]
22+
}
23+
24+
void test_non_const(uint8_t a, uint8_t b, uint32_t c, uint32_t d) {
25+
if (b <= 100) {
26+
// `a` and `b` are promoted to signed ints, meaning neither the range analysis library
27+
// nor this extension handle it
28+
a & b; // [-2147483648 .. 2147483647]
29+
}
30+
if (d <= 100) {
31+
// Handled by the range analysis library
32+
c & d; // [0 .. 100]
33+
}
34+
}
35+
36+
void test_negative_operand(uint8_t x, int8_t y) {
37+
uint8_t unsigned_const = 7;
38+
int8_t signed_const = -7;
39+
40+
// The right operand can be negative
41+
x & -7; // [-2147483648 .. 2147483647]
42+
x & signed_const; // [-2147483648 .. 2147483647]
43+
x & y; // [-2147483648 .. 2147483647]
44+
45+
// The left operand can be negative
46+
y & 7; // [-2147483648 .. 2147483647]
47+
y & unsigned_const; // [-2147483648 .. 2147483647]
48+
y & 0xFFFFFFFF; // [0 .. 4294967295]
49+
(int64_t)y & 0xFFFFFFFF; // [-9223372036854776000 .. 9223372036854776000]
50+
y & x; // [-2147483648 .. 2147483647]
51+
52+
// Both can be negative
53+
y & -7; // [-2147483648 .. 2147483647]
54+
y & signed_const; // [-2147483648 .. 2147483647]
55+
signed_const & -7; // [-2147483648 .. 2147483647]
56+
signed_const & y; // [-2147483648 .. 2147483647]
57+
-7 & y; // [-2147483648 .. 2147483647]
58+
-7 & signed_const; // [-2147483648 .. 2147483647]
59+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
| bitwiseand.cpp:7:3:7:8 | ... &= ... | 0.0 | 255.0 |
2+
| bitwiseand.cpp:15:3:15:7 | ... & ... | -2.147483648E9 | 2.147483647E9 |
3+
| bitwiseand.cpp:16:3:16:7 | ... & ... | -2.147483648E9 | 2.147483647E9 |
4+
| bitwiseand.cpp:17:3:17:20 | ... & ... | -2.147483648E9 | 2.147483647E9 |
5+
| bitwiseand.cpp:21:3:21:16 | ... & ... | 0.0 | 255.0 |
6+
| bitwiseand.cpp:28:5:28:9 | ... & ... | -2.147483648E9 | 2.147483647E9 |
7+
| bitwiseand.cpp:32:5:32:9 | ... & ... | 0.0 | 100.0 |
8+
| bitwiseand.cpp:41:3:41:8 | ... & ... | -2.147483648E9 | 2.147483647E9 |
9+
| bitwiseand.cpp:42:3:42:18 | ... & ... | -2.147483648E9 | 2.147483647E9 |
10+
| bitwiseand.cpp:43:3:43:7 | ... & ... | -2.147483648E9 | 2.147483647E9 |
11+
| bitwiseand.cpp:46:3:46:7 | ... & ... | -2.147483648E9 | 2.147483647E9 |
12+
| bitwiseand.cpp:47:3:47:20 | ... & ... | -2.147483648E9 | 2.147483647E9 |
13+
| bitwiseand.cpp:48:3:48:16 | ... & ... | 0.0 | 4.294967295E9 |
14+
| bitwiseand.cpp:49:3:49:25 | ... & ... | -9.223372036854776E18 | 9.223372036854776E18 |
15+
| bitwiseand.cpp:50:3:50:7 | ... & ... | -2.147483648E9 | 2.147483647E9 |
16+
| bitwiseand.cpp:53:3:53:8 | ... & ... | -2.147483648E9 | 2.147483647E9 |
17+
| bitwiseand.cpp:54:3:54:18 | ... & ... | -2.147483648E9 | 2.147483647E9 |
18+
| bitwiseand.cpp:55:3:55:19 | ... & ... | -2.147483648E9 | 2.147483647E9 |
19+
| bitwiseand.cpp:56:3:56:18 | ... & ... | -2.147483648E9 | 2.147483647E9 |
20+
| bitwiseand.cpp:57:3:57:8 | ... & ... | -2.147483648E9 | 2.147483647E9 |
21+
| bitwiseand.cpp:58:3:58:19 | ... & ... | -2.147483648E9 | 2.147483647E9 |
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import experimental.semmle.code.cpp.rangeanalysis.ExtendedRangeAnalysis
2+
3+
from Operation expr, float lower, float upper
4+
where
5+
(expr instanceof BitwiseAndExpr or expr instanceof AssignAndExpr) and
6+
lower = lowerBound(expr) and
7+
upper = upperBound(expr)
8+
select expr, lower, upper

0 commit comments

Comments
 (0)