Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / enum-cast-out-of-range.cpp
blob0eb740664ecdc7c8009ef0b04a8214036794e7bd
1 // RUN: %clang_analyze_cc1 \
2 // RUN: -analyzer-checker=core,alpha.cplusplus.EnumCastOutOfRange \
3 // RUN: -std=c++11 -verify %s
5 // expected-note@+1 + {{enum declared here}}
6 enum unscoped_unspecified_t {
7 unscoped_unspecified_0 = -4,
8 unscoped_unspecified_1,
9 unscoped_unspecified_2 = 1,
10 unscoped_unspecified_3,
11 unscoped_unspecified_4 = 4
14 // expected-note@+1 + {{enum declared here}}
15 enum unscoped_specified_t : int {
16 unscoped_specified_0 = -4,
17 unscoped_specified_1,
18 unscoped_specified_2 = 1,
19 unscoped_specified_3,
20 unscoped_specified_4 = 4
23 // expected-note@+1 + {{enum declared here}}
24 enum class scoped_unspecified_t {
25 scoped_unspecified_0 = -4,
26 scoped_unspecified_1,
27 scoped_unspecified_2 = 1,
28 scoped_unspecified_3,
29 scoped_unspecified_4 = 4
32 // expected-note@+1 + {{enum declared here}}
33 enum class scoped_specified_t : int {
34 scoped_specified_0 = -4,
35 scoped_specified_1,
36 scoped_specified_2 = 1,
37 scoped_specified_3,
38 scoped_specified_4 = 4
41 struct S {
42 unscoped_unspecified_t E : 5;
45 void unscopedUnspecified() {
46 unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast<unscoped_unspecified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
47 unscoped_unspecified_t ValidNegativeValue1 = static_cast<unscoped_unspecified_t>(-4); // OK.
48 unscoped_unspecified_t ValidNegativeValue2 = static_cast<unscoped_unspecified_t>(-3); // OK.
49 unscoped_unspecified_t InvalidInsideRange1 = static_cast<unscoped_unspecified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
50 unscoped_unspecified_t InvalidInsideRange2 = static_cast<unscoped_unspecified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
51 unscoped_unspecified_t InvalidInsideRange3 = static_cast<unscoped_unspecified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
52 unscoped_unspecified_t ValidPositiveValue1 = static_cast<unscoped_unspecified_t>(1); // OK.
53 unscoped_unspecified_t ValidPositiveValue2 = static_cast<unscoped_unspecified_t>(2); // OK.
54 unscoped_unspecified_t InvalidInsideRange4 = static_cast<unscoped_unspecified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
55 unscoped_unspecified_t ValidPositiveValue3 = static_cast<unscoped_unspecified_t>(4); // OK.
56 unscoped_unspecified_t InvalidAfterRangeEnd = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
59 void unscopedSpecified() {
60 unscoped_specified_t InvalidBeforeRangeBegin = static_cast<unscoped_specified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
61 unscoped_specified_t ValidNegativeValue1 = static_cast<unscoped_specified_t>(-4); // OK.
62 unscoped_specified_t ValidNegativeValue2 = static_cast<unscoped_specified_t>(-3); // OK.
63 unscoped_specified_t InvalidInsideRange1 = static_cast<unscoped_specified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
64 unscoped_specified_t InvalidInsideRange2 = static_cast<unscoped_specified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
65 unscoped_specified_t InvalidInsideRange3 = static_cast<unscoped_specified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
66 unscoped_specified_t ValidPositiveValue1 = static_cast<unscoped_specified_t>(1); // OK.
67 unscoped_specified_t ValidPositiveValue2 = static_cast<unscoped_specified_t>(2); // OK.
68 unscoped_specified_t InvalidInsideRange4 = static_cast<unscoped_specified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
69 unscoped_specified_t ValidPositiveValue3 = static_cast<unscoped_specified_t>(4); // OK.
70 unscoped_specified_t InvalidAfterRangeEnd = static_cast<unscoped_specified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
73 void scopedUnspecified() {
74 scoped_unspecified_t InvalidBeforeRangeBegin = static_cast<scoped_unspecified_t>(-5); // expected-warning{{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
75 scoped_unspecified_t ValidNegativeValue1 = static_cast<scoped_unspecified_t>(-4); // OK.
76 scoped_unspecified_t ValidNegativeValue2 = static_cast<scoped_unspecified_t>(-3); // OK.
77 scoped_unspecified_t InvalidInsideRange1 = static_cast<scoped_unspecified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
78 scoped_unspecified_t InvalidInsideRange2 = static_cast<scoped_unspecified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
79 scoped_unspecified_t InvalidInsideRange3 = static_cast<scoped_unspecified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
80 scoped_unspecified_t ValidPositiveValue1 = static_cast<scoped_unspecified_t>(1); // OK.
81 scoped_unspecified_t ValidPositiveValue2 = static_cast<scoped_unspecified_t>(2); // OK.
82 scoped_unspecified_t InvalidInsideRange4 = static_cast<scoped_unspecified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
83 scoped_unspecified_t ValidPositiveValue3 = static_cast<scoped_unspecified_t>(4); // OK.
84 scoped_unspecified_t InvalidAfterRangeEnd = static_cast<scoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
87 void scopedSpecified() {
88 scoped_specified_t InvalidBeforeRangeBegin = static_cast<scoped_specified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
89 scoped_specified_t ValidNegativeValue1 = static_cast<scoped_specified_t>(-4); // OK.
90 scoped_specified_t ValidNegativeValue2 = static_cast<scoped_specified_t>(-3); // OK.
91 scoped_specified_t InvalidInsideRange1 = static_cast<scoped_specified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
92 scoped_specified_t InvalidInsideRange2 = static_cast<scoped_specified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
93 scoped_specified_t InvalidInsideRange3 = static_cast<scoped_specified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
94 scoped_specified_t ValidPositiveValue1 = static_cast<scoped_specified_t>(1); // OK.
95 scoped_specified_t ValidPositiveValue2 = static_cast<scoped_specified_t>(2); // OK.
96 scoped_specified_t InvalidInsideRange4 = static_cast<scoped_specified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
97 scoped_specified_t ValidPositiveValue3 = static_cast<scoped_specified_t>(4); // OK.
98 scoped_specified_t InvalidAfterRangeEnd = static_cast<scoped_specified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
101 void unscopedUnspecifiedCStyle() {
102 unscoped_unspecified_t InvalidBeforeRangeBegin = (unscoped_unspecified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
103 unscoped_unspecified_t ValidNegativeValue1 = (unscoped_unspecified_t)(-4); // OK.
104 unscoped_unspecified_t ValidNegativeValue2 = (unscoped_unspecified_t)(-3); // OK.
105 unscoped_unspecified_t InvalidInsideRange1 = (unscoped_unspecified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
106 unscoped_unspecified_t InvalidInsideRange2 = (unscoped_unspecified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
107 unscoped_unspecified_t InvalidInsideRange3 = (unscoped_unspecified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
108 unscoped_unspecified_t ValidPositiveValue1 = (unscoped_unspecified_t)(1); // OK.
109 unscoped_unspecified_t ValidPositiveValue2 = (unscoped_unspecified_t)(2); // OK.
110 unscoped_unspecified_t InvalidInsideRange4 = (unscoped_unspecified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
111 unscoped_unspecified_t ValidPositiveValue3 = (unscoped_unspecified_t)(4); // OK.
112 unscoped_unspecified_t InvalidAfterRangeEnd = (unscoped_unspecified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
115 void unscopedSpecifiedCStyle() {
116 unscoped_specified_t InvalidBeforeRangeBegin = (unscoped_specified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
117 unscoped_specified_t ValidNegativeValue1 = (unscoped_specified_t)(-4); // OK.
118 unscoped_specified_t ValidNegativeValue2 = (unscoped_specified_t)(-3); // OK.
119 unscoped_specified_t InvalidInsideRange1 = (unscoped_specified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
120 unscoped_specified_t InvalidInsideRange2 = (unscoped_specified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
121 unscoped_specified_t InvalidInsideRange3 = (unscoped_specified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
122 unscoped_specified_t ValidPositiveValue1 = (unscoped_specified_t)(1); // OK.
123 unscoped_specified_t ValidPositiveValue2 = (unscoped_specified_t)(2); // OK.
124 unscoped_specified_t InvalidInsideRange4 = (unscoped_specified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
125 unscoped_specified_t ValidPositiveValue3 = (unscoped_specified_t)(4); // OK.
126 unscoped_specified_t InvalidAfterRangeEnd = (unscoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
129 void scopedUnspecifiedCStyle() {
130 scoped_unspecified_t InvalidBeforeRangeBegin = (scoped_unspecified_t)(-5); // expected-warning{{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
131 scoped_unspecified_t ValidNegativeValue1 = (scoped_unspecified_t)(-4); // OK.
132 scoped_unspecified_t ValidNegativeValue2 = (scoped_unspecified_t)(-3); // OK.
133 scoped_unspecified_t InvalidInsideRange1 = (scoped_unspecified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
134 scoped_unspecified_t InvalidInsideRange2 = (scoped_unspecified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
135 scoped_unspecified_t InvalidInsideRange3 = (scoped_unspecified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
136 scoped_unspecified_t ValidPositiveValue1 = (scoped_unspecified_t)(1); // OK.
137 scoped_unspecified_t ValidPositiveValue2 = (scoped_unspecified_t)(2); // OK.
138 scoped_unspecified_t InvalidInsideRange4 = (scoped_unspecified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
139 scoped_unspecified_t ValidPositiveValue3 = (scoped_unspecified_t)(4); // OK.
140 scoped_unspecified_t InvalidAfterRangeEnd = (scoped_unspecified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
143 void scopedSpecifiedCStyle() {
144 scoped_specified_t InvalidBeforeRangeBegin = (scoped_specified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
145 scoped_specified_t ValidNegativeValue1 = (scoped_specified_t)(-4); // OK.
146 scoped_specified_t ValidNegativeValue2 = (scoped_specified_t)(-3); // OK.
147 scoped_specified_t InvalidInsideRange1 = (scoped_specified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
148 scoped_specified_t InvalidInsideRange2 = (scoped_specified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
149 scoped_specified_t InvalidInsideRange3 = (scoped_specified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
150 scoped_specified_t ValidPositiveValue1 = (scoped_specified_t)(1); // OK.
151 scoped_specified_t ValidPositiveValue2 = (scoped_specified_t)(2); // OK.
152 scoped_specified_t InvalidInsideRange4 = (scoped_specified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
153 scoped_specified_t ValidPositiveValue3 = (scoped_specified_t)(4); // OK.
154 scoped_specified_t InvalidAfterRangeEnd = (scoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
157 unscoped_unspecified_t unused;
158 void unusedExpr() {
159 // following line is not something that EnumCastOutOfRangeChecker should evaluate. checker should either ignore this line
160 // or process it without producing any warnings. However, compilation will (and should) still generate a warning having
161 // nothing to do with this checker.
162 unused; // expected-warning {{expression result unused}}
165 void rangeConstrained1(int input) {
166 if (input > -5 && input < 5)
167 auto value = static_cast<scoped_specified_t>(input); // OK. Being conservative, this is a possibly good value.
170 void rangeConstrained2(int input) {
171 if (input < -5)
172 auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
175 void rangeConstrained3(int input) {
176 if (input >= -2 && input <= -1)
177 auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
180 void rangeConstrained4(int input) {
181 if (input >= -2 && input <= 1)
182 auto value = static_cast<scoped_specified_t>(input); // OK. Possibly 1.
185 void rangeConstrained5(int input) {
186 if (input >= 1 && input <= 2)
187 auto value = static_cast<scoped_specified_t>(input); // OK. Strict inner matching.
190 void rangeConstrained6(int input) {
191 if (input >= 2 && input <= 4)
192 auto value = static_cast<scoped_specified_t>(input); // OK. The value is possibly 2 or 4, dont warn.
195 void rangeConstrained7(int input) {
196 if (input >= 3 && input <= 3)
197 auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
200 void enumBitFieldAssignment() {
201 S s;
202 s.E = static_cast<unscoped_unspecified_t>(4); // OK.
203 s.E = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
207 enum class empty_unspecified {};
209 enum class empty_specified: char {};
211 enum class empty_specified_unsigned: unsigned char {};
213 void ignore_unused(...);
215 void empty_enums_init_with_zero_should_not_warn() {
216 auto eu = static_cast<empty_unspecified>(0); //should always be OK to zero initialize any enum
217 auto ef = static_cast<empty_specified>(0);
218 auto efu = static_cast<empty_specified_unsigned>(0);
220 ignore_unused(eu, ef, efu);