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,
18 unscoped_specified_2
= 1,
20 unscoped_specified_4
= 4
23 // expected-note@+1 + {{enum declared here}}
24 enum class scoped_unspecified_t
{
25 scoped_unspecified_0
= -4,
27 scoped_unspecified_2
= 1,
29 scoped_unspecified_4
= 4
32 // expected-note@+1 + {{enum declared here}}
33 enum class scoped_specified_t
: int {
34 scoped_specified_0
= -4,
36 scoped_specified_2
= 1,
38 scoped_specified_4
= 4
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
;
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
) {
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() {
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
);