Skip to content

Commit 5710289

Browse files
Gulshan Singhgsingh93
authored andcommitted
Add bitshift test
1 parent cd59640 commit 5710289

File tree

3 files changed

+214
-0
lines changed

3 files changed

+214
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
| bitshift.cpp:23:3:23:9 | ... <<= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
2+
| bitshift.cpp:25:5:25:11 | ... <<= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
3+
| bitshift.cpp:29:3:29:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
4+
| bitshift.cpp:32:3:32:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
5+
| bitshift.cpp:35:3:35:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
6+
| bitshift.cpp:38:3:38:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
7+
| bitshift.cpp:39:3:39:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
8+
| bitshift.cpp:40:3:40:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
9+
| bitshift.cpp:43:3:43:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
10+
| bitshift.cpp:46:3:46:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
11+
| bitshift.cpp:49:3:49:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
12+
| bitshift.cpp:52:5:52:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
13+
| bitshift.cpp:57:3:57:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
14+
| bitshift.cpp:58:3:58:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
15+
| bitshift.cpp:59:3:59:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
16+
| bitshift.cpp:60:3:60:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
17+
| bitshift.cpp:61:3:61:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
18+
| bitshift.cpp:64:3:64:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
19+
| bitshift.cpp:67:3:67:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
20+
| bitshift.cpp:70:5:70:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
21+
| bitshift.cpp:75:5:75:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
22+
| bitshift.cpp:76:5:76:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
23+
| bitshift.cpp:90:3:90:9 | ... >>= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
24+
| bitshift.cpp:92:5:92:11 | ... >>= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
25+
| bitshift.cpp:96:3:96:8 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
26+
| bitshift.cpp:99:3:99:9 | ... >> ... | 0.0 | 0.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
27+
| bitshift.cpp:103:3:103:9 | ... >> ... | 0.0 | 0.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
28+
| bitshift.cpp:106:3:106:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
29+
| bitshift.cpp:107:3:107:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
30+
| bitshift.cpp:108:3:108:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
31+
| bitshift.cpp:111:3:111:19 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
32+
| bitshift.cpp:114:3:114:24 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
33+
| bitshift.cpp:117:3:117:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
34+
| bitshift.cpp:120:5:120:12 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
35+
| bitshift.cpp:126:3:126:8 | ... >> ... | -32.0 | 31.0 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
36+
| bitshift.cpp:127:3:127:9 | ... >> ... | -1.0 | 0.0 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
37+
| bitshift.cpp:128:3:128:9 | ... >> ... | -1.0 | 0.0 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
38+
| bitshift.cpp:129:3:129:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
39+
| bitshift.cpp:130:3:130:19 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
40+
| bitshift.cpp:133:3:133:21 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
41+
| bitshift.cpp:136:3:136:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
42+
| bitshift.cpp:139:5:139:12 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
43+
| bitshift.cpp:144:5:144:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
44+
| bitshift.cpp:145:5:145:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import cpp
2+
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
3+
4+
Expr getLOp(Operation o) {
5+
result = o.(BinaryOperation).getLeftOperand() or
6+
result = o.(Assignment).getLValue()
7+
}
8+
9+
Expr getROp(Operation o) {
10+
result = o.(BinaryOperation).getRightOperand() or
11+
result = o.(Assignment).getRValue()
12+
}
13+
14+
from Operation o
15+
where
16+
(
17+
o instanceof BinaryBitwiseOperation
18+
or
19+
o instanceof AssignBitwiseOperation
20+
)
21+
select o, lowerBound(o), upperBound(o), getLOp(o).getUnderlyingType(),
22+
getROp(o).getUnderlyingType(), getLOp(o).getFullyConverted().getUnderlyingType(),
23+
getROp(o).getFullyConverted().getUnderlyingType()
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
typedef signed char int8_t;
2+
typedef short int16_t;
3+
typedef int int32_t;
4+
typedef long int64_t;
5+
6+
typedef unsigned char uint8_t;
7+
typedef unsigned short uint16_t;
8+
typedef unsigned int uint32_t;
9+
typedef unsigned long uint64_t;
10+
11+
extern uint8_t value_known_at_runtime8();
12+
13+
void testLShiftOperator() {
14+
uint8_t unsigned_const1 = 7;
15+
uint8_t unsigned_const2(7);
16+
uint8_t unsigned_const3{7};
17+
int8_t signed_const = -7;
18+
uint8_t x = value_known_at_runtime8();
19+
int8_t y = (int8_t)value_known_at_runtime8();
20+
uint8_t z = value_known_at_runtime8();
21+
22+
// An assign left shift operator. Note that no promotion occurs here
23+
z <<= 2; // [0, 255]
24+
if (z <= 60) {
25+
z <<= 2; // [0, 240]
26+
}
27+
28+
// A normal shift
29+
x << 2; // [0, 1020]
30+
31+
// Possible to exceed the maximum size
32+
x << 25; // [-2147483648, 2147483648]
33+
34+
// Undefined behavior
35+
x << 34; // [-2147483648, 2147483648]
36+
37+
// A normal shift by a constant in a variable
38+
x << unsigned_const1; // [0, 32640]
39+
x << unsigned_const2; // [0, 32640]
40+
x << unsigned_const3; // [0, 32640]
41+
42+
// Negative shifts are undefined
43+
x << signed_const; // [-2147483648, 2147483648]
44+
45+
// Now the left operand is a constant
46+
1 << unsigned_const1; // [128, 128]
47+
48+
// x could be large enough to cause undefined behavior
49+
1 << x; // [-2147483648, 2147483647]
50+
if (x < 8) {
51+
// x is now constrained so the shift is defined
52+
1 << x; // [1, 128]
53+
}
54+
55+
// We don't support shifting negative values (and some of these are undefined
56+
// anyway)
57+
y << 2; // [-2147483648, 2147483647]
58+
y << 25; // [-2147483648, 2147483648]
59+
y << 34; // [-2147483648, 2147483648]
60+
y << unsigned_const1; // [-2147483648, 2147483647]
61+
y << signed_const; // [-2147483648, 2147483648]
62+
63+
// Negative shifts are undefined
64+
1 << signed_const; // [-2147483648, 2147483648]
65+
66+
// We don't handle cases where the shift range could be negative
67+
1 << y; // [-2147483648, 2147483648]
68+
if (y >= 0 && y < 8) {
69+
// The shift range is now positive
70+
1 << y; // [1, 128]
71+
}
72+
73+
if (x > 0 and x < 2 and y > 0 and x < 2) {
74+
// We don't support shifts where neither operand is a constant at the moment
75+
x << y; // [-2147483648, 2147483648]
76+
y << x; // [-2147483648, 2147483648]
77+
}
78+
}
79+
80+
void testRShiftOperator() {
81+
uint8_t unsigned_const1 = 2;
82+
uint8_t unsigned_const2(2);
83+
uint8_t unsigned_const3{2};
84+
int8_t signed_const = -2;
85+
uint8_t x = value_known_at_runtime8();
86+
int8_t y = (int8_t)value_known_at_runtime8();
87+
uint8_t z = value_known_at_runtime8();
88+
89+
// An assign right shift operator. Note that no promotion occurs here
90+
z >>= 2; // [0, 63]
91+
if (z <= 60) {
92+
z >>= 2; // [0, 15]
93+
}
94+
95+
// A normal shift
96+
x >> 2; // [0, 63]
97+
98+
// Possible to exceed the maximum size
99+
x >> 25; // [0, 0]
100+
101+
// Undefined behavior, but this case is handled by the SimpleRangeAnalysis
102+
// library and sets the the bounds to [0, 0], which is fine
103+
x >> 34; // [0, 0]
104+
105+
// A normal shift by a constant in a variable
106+
x >> unsigned_const1; // [0, 63]
107+
x >> unsigned_const2; // [0, 63]
108+
x >> unsigned_const3; // [0, 63]
109+
110+
// Negative shifts are undefined
111+
x >> signed_const; // [-2147483648, 2147483648]
112+
113+
// Now the left operand is a constant
114+
128 >> unsigned_const1; // [32, 32]
115+
116+
// x could be large enough to cause undefined behavior
117+
128 >> x; // [-2147483648, 2147483647]
118+
if (x < 3) {
119+
// x is now constrained so the shift is defined
120+
128 >> x; // [32, 128]
121+
}
122+
123+
// We don't support shifting negative values, but the SimpleRangeAnalysis
124+
// library handles the first three cases even though they're implementation
125+
// defined or undefined behavior (TODO: Check ideone)
126+
y >> 2; // [-2147483648, 2147483647] (Default is [-32, 31])
127+
y >> 25; // -2147483648, 2147483647] (Default is [-1, 0])
128+
y >> 34; // [-1, 0] (My code doesn't touch this, so default code is used)
129+
y >> unsigned_const1; // [-2147483648, 2147483647]
130+
y >> signed_const; // [-2147483648, 2147483648]
131+
132+
// Negative shifts are undefined
133+
128 >> signed_const; // [-2147483648, 2147483648]
134+
135+
// We don't handle cases where the shift range could be negative
136+
128 >> y; // [-2147483648, 2147483648]
137+
if (y >= 0 && y < 3) {
138+
// The shift range is now positive
139+
128 >> y; // [32, 128]
140+
}
141+
142+
if (x > 0 and x < 2 and y > 0 and x < 2) {
143+
// We don't support shifts where neither operand is a constant at the moment
144+
x >> y; // [-2147483648, 2147483648]
145+
y >> x; // [-2147483648, 2147483648]
146+
}
147+
}

0 commit comments

Comments
 (0)