1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
// RUN: -analyzer-config core.BitwiseShift:Pedantic=true \
// RUN: -verify=expected,pedantic \
// RUN: -triple x86_64-pc-linux-gnu -x c %s \
// RUN: -Wno-shift-count-negative -Wno-shift-negative-value \
// RUN: -Wno-shift-count-overflow -Wno-shift-overflow \
// RUN: -Wno-shift-sign-overflow
//
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
// RUN: -analyzer-config core.BitwiseShift:Pedantic=true \
// RUN: -verify=expected,pedantic \
// RUN: -triple x86_64-pc-linux-gnu -x c++ -std=c++14 %s \
// RUN: -Wno-shift-count-negative -Wno-shift-negative-value \
// RUN: -Wno-shift-count-overflow -Wno-shift-overflow \
// RUN: -Wno-shift-sign-overflow
//
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
// RUN: -verify=expected \
// RUN: -triple x86_64-pc-linux-gnu -x c++ -std=c++20 %s \
// RUN: -Wno-shift-count-negative -Wno-shift-negative-value \
// RUN: -Wno-shift-count-overflow -Wno-shift-overflow \
// RUN: -Wno-shift-sign-overflow
// This test file verifies that the BitwiseShift checker does not crash or
// report false positives (at least on the cases that are listed here...)
// Other core checkers are also enabled to see interactions with e.g.
// core.UndefinedBinaryOperatorResult.
// For the sake of brevity, 'note' output is not checked in this file.
// TEST OBVIOUSLY CORRECT CODE
//===----------------------------------------------------------------------===//
unsigned shift_unsigned(void) {
// Shifts of unsigned LHS may overflow, even if the RHS is signed.
// In shifts the type of the right operand does not affect the type of the
// calculation and the result.
return 1024u << 25ll; // no-warning
}
int shift_zeroes(void) {
return 0 << 0; // no-warning
}
int no_info(int left, int right) {
return left << right; // no-warning
}
int all_okay(int left, int right) {
if (left < 0 || right < 0)
return 42;
return (left << right) + (left >> right); // no-warning
}
// DOCUMENT A LIMITATION OF THE ANALYZER ENGINE
//===----------------------------------------------------------------------===//
int signed_arithmetic_good(int left, int right) {
if (right >= 32)
return 0;
return left << (right - 32);
// expected-warning@-1 {{Right operand is negative in left shift}}
}
int signed_arithmetic_bad(int left, int right) {
// FIXME: The analyzer engine handles overflow of signed values as if it was
// a valid code path, so in this case it will think that that (right + 32) is
// either at least 32 *or* very negative after an overflow.
// As checkOvershift() is called before checkOperandNegative(), the checker
// will first rule out the case when (right + 32) is larger than 32 and then
// it reports that it's negative. Swapping the order of the two checks would
// trigger an analogous fault in signed_aritmetic_good().
if (right < 0)
return 0;
return left << (right + 32);
// expected-warning@-1 {{Right operand is negative in left shift}}
// FIXME: we should rather have {{Left shift overflows the capacity of 'int'}}
}
// TEST THE EXAMPLES FROM THE DOCUMENTATION
//===----------------------------------------------------------------------===//
void basic_examples(int a, int b) {
if (b < 0) {
b = a << b; // expected-warning {{Right operand is negative in left shift}}
} else if (b >= 32) {
b = a >> b; // expected-warning {{Right shift overflows the capacity of 'int'}}
}
}
int pedantic_examples(int a, int b) {
if (a < 0) {
return a >> b; // pedantic-warning {{Left operand is negative in right shift}}
}
a = 1000u << 31; // OK, overflow of unsigned shift is well-defined, a == 0
if (b > 10) {
a = b << 31; // this is UB before C++20, but the checker doesn't warn because
// it doesn't know the exact value of b
}
return 1000 << 31; // pedantic-warning {{The shift '1000 << 31' overflows the capacity of 'int'}}
}
// TEST UNUSUAL CODE THAT SHOULD NOT CRASH
//===----------------------------------------------------------------------===//
__int128 large_left(void) {
// Ensure that we do not crash when the left operand doesn't fit in 64 bits.
return (__int128) 1 << 63 << 10 << 10; // no-crash
}
int large_right(void) {
// Ensure that we do not crash when the right operand doesn't fit in 64 bits.
return 1 << ((__int128) 1 << 118); // no-crash
// expected-warning@-1 {{Left shift by '332306998946228968225951765070086144' overflows the capacity of 'int'}}
}
void doubles_cast_to_integer(int *c) {
*c = 1 << (int)1.5; // no-crash
*c = ((int)1.5) << 1; // no-crash
*c = ((int)1.5) << (int)1.5; // no-crash
}
// TEST CODE THAT WAS TRIGGERING BUGS IN EARLIER REVISIONS
//===----------------------------------------------------------------------===//
unsigned int strange_cast(unsigned short sh) {
// This testcase triggers a bug in the constant folding (it "forgets" the
// cast), which is silenced in SimpleSValBuilder::evalBinOpNN() with an ugly
// workaround, because otherwise it would lead to a false positive from
// core.UndefinedBinaryOperatorResult.
unsigned int i;
sh++;
for (i=0; i<sh; i++) {}
return (unsigned int) ( ((unsigned int) sh) << 16 ); // no-warning
}
|