1 | // RUN: %clang_analyze_cc1 \ |
2 | // RUN: -analyzer-checker=core,alpha.cplusplus.EnumCastOutOfRange \ |
3 | // RUN: -std=c++11 -verify %s |
4 | |
5 | enum unscoped_unspecified_t { |
6 | unscoped_unspecified_0 = -4, |
7 | unscoped_unspecified_1, |
8 | unscoped_unspecified_2 = 1, |
9 | unscoped_unspecified_3, |
10 | unscoped_unspecified_4 = 4 |
11 | }; |
12 | |
13 | enum unscoped_specified_t : int { |
14 | unscoped_specified_0 = -4, |
15 | unscoped_specified_1, |
16 | unscoped_specified_2 = 1, |
17 | unscoped_specified_3, |
18 | unscoped_specified_4 = 4 |
19 | }; |
20 | |
21 | enum class scoped_unspecified_t { |
22 | scoped_unspecified_0 = -4, |
23 | scoped_unspecified_1, |
24 | scoped_unspecified_2 = 1, |
25 | scoped_unspecified_3, |
26 | scoped_unspecified_4 = 4 |
27 | }; |
28 | |
29 | enum class scoped_specified_t : int { |
30 | scoped_specified_0 = -4, |
31 | scoped_specified_1, |
32 | scoped_specified_2 = 1, |
33 | scoped_specified_3, |
34 | scoped_specified_4 = 4 |
35 | }; |
36 | |
37 | struct S { |
38 | unscoped_unspecified_t E : 5; |
39 | }; |
40 | |
41 | void unscopedUnspecified() { |
42 | 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 the enum}} |
43 | unscoped_unspecified_t ValidNegativeValue1 = static_cast<unscoped_unspecified_t>(-4); // OK. |
44 | unscoped_unspecified_t ValidNegativeValue2 = static_cast<unscoped_unspecified_t>(-3); // OK. |
45 | 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 the enum}} |
46 | 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 the enum}} |
47 | 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 the enum}} |
48 | unscoped_unspecified_t ValidPositiveValue1 = static_cast<unscoped_unspecified_t>(1); // OK. |
49 | unscoped_unspecified_t ValidPositiveValue2 = static_cast<unscoped_unspecified_t>(2); // OK. |
50 | 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 the enum}} |
51 | unscoped_unspecified_t ValidPositiveValue3 = static_cast<unscoped_unspecified_t>(4); // OK. |
52 | 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 the enum}} |
53 | } |
54 | |
55 | void unscopedSpecified() { |
56 | 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 the enum}} |
57 | unscoped_specified_t ValidNegativeValue1 = static_cast<unscoped_specified_t>(-4); // OK. |
58 | unscoped_specified_t ValidNegativeValue2 = static_cast<unscoped_specified_t>(-3); // OK. |
59 | 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 the enum}} |
60 | 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 the enum}} |
61 | 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 the enum}} |
62 | unscoped_specified_t ValidPositiveValue1 = static_cast<unscoped_specified_t>(1); // OK. |
63 | unscoped_specified_t ValidPositiveValue2 = static_cast<unscoped_specified_t>(2); // OK. |
64 | 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 the enum}} |
65 | unscoped_specified_t ValidPositiveValue3 = static_cast<unscoped_specified_t>(4); // OK. |
66 | 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 the enum}} |
67 | } |
68 | |
69 | void scopedUnspecified() { |
70 | 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 the enum}} |
71 | scoped_unspecified_t ValidNegativeValue1 = static_cast<scoped_unspecified_t>(-4); // OK. |
72 | scoped_unspecified_t ValidNegativeValue2 = static_cast<scoped_unspecified_t>(-3); // OK. |
73 | 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 the enum}} |
74 | 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 the enum}} |
75 | 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 the enum}} |
76 | scoped_unspecified_t ValidPositiveValue1 = static_cast<scoped_unspecified_t>(1); // OK. |
77 | scoped_unspecified_t ValidPositiveValue2 = static_cast<scoped_unspecified_t>(2); // OK. |
78 | 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 the enum}} |
79 | scoped_unspecified_t ValidPositiveValue3 = static_cast<scoped_unspecified_t>(4); // OK. |
80 | 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 the enum}} |
81 | } |
82 | |
83 | void scopedSpecified() { |
84 | 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 the enum}} |
85 | scoped_specified_t ValidNegativeValue1 = static_cast<scoped_specified_t>(-4); // OK. |
86 | scoped_specified_t ValidNegativeValue2 = static_cast<scoped_specified_t>(-3); // OK. |
87 | 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 the enum}} |
88 | 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 the enum}} |
89 | 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 the enum}} |
90 | scoped_specified_t ValidPositiveValue1 = static_cast<scoped_specified_t>(1); // OK. |
91 | scoped_specified_t ValidPositiveValue2 = static_cast<scoped_specified_t>(2); // OK. |
92 | 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 the enum}} |
93 | scoped_specified_t ValidPositiveValue3 = static_cast<scoped_specified_t>(4); // OK. |
94 | 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 the enum}} |
95 | } |
96 | |
97 | void unscopedUnspecifiedCStyle() { |
98 | 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 the enum}} |
99 | unscoped_unspecified_t ValidNegativeValue1 = (unscoped_unspecified_t)(-4); // OK. |
100 | unscoped_unspecified_t ValidNegativeValue2 = (unscoped_unspecified_t)(-3); // OK. |
101 | 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 the enum}} |
102 | 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 the enum}} |
103 | 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 the enum}} |
104 | unscoped_unspecified_t ValidPositiveValue1 = (unscoped_unspecified_t)(1); // OK. |
105 | unscoped_unspecified_t ValidPositiveValue2 = (unscoped_unspecified_t)(2); // OK. |
106 | 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 the enum}} |
107 | unscoped_unspecified_t ValidPositiveValue3 = (unscoped_unspecified_t)(4); // OK. |
108 | 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 the enum}} |
109 | } |
110 | |
111 | void unscopedSpecifiedCStyle() { |
112 | 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 the enum}} |
113 | unscoped_specified_t ValidNegativeValue1 = (unscoped_specified_t)(-4); // OK. |
114 | unscoped_specified_t ValidNegativeValue2 = (unscoped_specified_t)(-3); // OK. |
115 | 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 the enum}} |
116 | 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 the enum}} |
117 | 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 the enum}} |
118 | unscoped_specified_t ValidPositiveValue1 = (unscoped_specified_t)(1); // OK. |
119 | unscoped_specified_t ValidPositiveValue2 = (unscoped_specified_t)(2); // OK. |
120 | 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 the enum}} |
121 | unscoped_specified_t ValidPositiveValue3 = (unscoped_specified_t)(4); // OK. |
122 | 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 the enum}} |
123 | } |
124 | |
125 | void scopedUnspecifiedCStyle() { |
126 | 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 the enum}} |
127 | scoped_unspecified_t ValidNegativeValue1 = (scoped_unspecified_t)(-4); // OK. |
128 | scoped_unspecified_t ValidNegativeValue2 = (scoped_unspecified_t)(-3); // OK. |
129 | 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 the enum}} |
130 | 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 the enum}} |
131 | 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 the enum}} |
132 | scoped_unspecified_t ValidPositiveValue1 = (scoped_unspecified_t)(1); // OK. |
133 | scoped_unspecified_t ValidPositiveValue2 = (scoped_unspecified_t)(2); // OK. |
134 | 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 the enum}} |
135 | scoped_unspecified_t ValidPositiveValue3 = (scoped_unspecified_t)(4); // OK. |
136 | 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 the enum}} |
137 | } |
138 | |
139 | void scopedSpecifiedCStyle() { |
140 | 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 the enum}} |
141 | scoped_specified_t ValidNegativeValue1 = (scoped_specified_t)(-4); // OK. |
142 | scoped_specified_t ValidNegativeValue2 = (scoped_specified_t)(-3); // OK. |
143 | 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 the enum}} |
144 | 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 the enum}} |
145 | 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 the enum}} |
146 | scoped_specified_t ValidPositiveValue1 = (scoped_specified_t)(1); // OK. |
147 | scoped_specified_t ValidPositiveValue2 = (scoped_specified_t)(2); // OK. |
148 | 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 the enum}} |
149 | scoped_specified_t ValidPositiveValue3 = (scoped_specified_t)(4); // OK. |
150 | 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 the enum}} |
151 | } |
152 | |
153 | void rangeContstrained1(int input) { |
154 | if (input > -5 && input < 5) |
155 | auto value = static_cast<scoped_specified_t>(input); // OK. Being conservative, this is a possibly good value. |
156 | } |
157 | |
158 | void rangeConstrained2(int input) { |
159 | if (input < -5) |
160 | 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 the enum}} |
161 | } |
162 | |
163 | void rangeConstrained3(int input) { |
164 | if (input >= -2 && input <= -1) |
165 | 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 the enum}} |
166 | } |
167 | |
168 | void rangeConstrained4(int input) { |
169 | if (input >= -2 && input <= 1) |
170 | auto value = static_cast<scoped_specified_t>(input); // OK. Possibly 1. |
171 | } |
172 | |
173 | void rangeConstrained5(int input) { |
174 | if (input >= 1 && input <= 2) |
175 | auto value = static_cast<scoped_specified_t>(input); // OK. Strict inner matching. |
176 | } |
177 | |
178 | void rangeConstrained6(int input) { |
179 | if (input >= 2 && input <= 4) |
180 | auto value = static_cast<scoped_specified_t>(input); // OK. The value is possibly 2 or 4, dont warn. |
181 | } |
182 | |
183 | void rangeConstrained7(int input) { |
184 | if (input >= 3 && input <= 3) |
185 | 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 the enum}} |
186 | } |
187 | |
188 | void enumBitFieldAssignment() { |
189 | S s; |
190 | s.E = static_cast<unscoped_unspecified_t>(4); // OK. |
191 | 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 the enum}} |
192 | } |
193 | |