Skip to content

Commit f1502d6

Browse files
committed
Rule 7.0.5: Add test cases for enum conversions
1 parent 4be88a3 commit f1502d6

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

cpp/misra/test/rules/RULE-7-0-5/NoSignednessChangeFromPromotion.expected

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,34 @@
7777
| test.cpp:200:9:200:10 | l2 | Usual arithmetic conversion from 'uint32_t' to 'float' changes type category. |
7878
| test.cpp:201:9:201:10 | l2 | Usual arithmetic conversion from 'uint32_t' to 'float' changes signedness. |
7979
| test.cpp:201:9:201:10 | l2 | Usual arithmetic conversion from 'uint32_t' to 'float' changes type category. |
80+
| test.cpp:270:3:270:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
81+
| test.cpp:270:8:270:9 | l4 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
82+
| test.cpp:271:3:271:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
83+
| test.cpp:271:7:271:8 | l4 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
84+
| test.cpp:272:3:272:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
85+
| test.cpp:272:8:272:9 | l4 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
86+
| test.cpp:273:3:273:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
87+
| test.cpp:273:8:273:9 | l4 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
88+
| test.cpp:274:3:274:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
89+
| test.cpp:274:8:274:9 | l4 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
90+
| test.cpp:275:3:275:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
91+
| test.cpp:275:8:275:9 | l4 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
92+
| test.cpp:278:3:278:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
93+
| test.cpp:278:8:278:9 | l7 | Usual arithmetic conversion from 'uint8_t' to 'int' changes signedness. |
94+
| test.cpp:279:3:279:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
95+
| test.cpp:279:7:279:8 | l7 | Usual arithmetic conversion from 'uint8_t' to 'int' changes signedness. |
96+
| test.cpp:280:3:280:4 | l7 | Usual arithmetic conversion from 'uint8_t' to 'int' changes signedness. |
97+
| test.cpp:280:8:280:9 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
98+
| test.cpp:286:4:286:5 | l3 | Integer promotion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
99+
| test.cpp:287:4:287:5 | l3 | Integer promotion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
100+
| test.cpp:288:4:288:5 | l3 | Integer promotion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
101+
| test.cpp:294:3:294:31 | static_cast<uint8_t>... | Usual arithmetic conversion from 'uint8_t' to 'int' changes signedness. |
102+
| test.cpp:295:7:296:46 | static_cast<uint8_t>... | Usual arithmetic conversion from 'uint8_t' to 'int' changes signedness. |
103+
| test.cpp:299:3:299:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
104+
| test.cpp:299:8:299:9 | l4 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
105+
| test.cpp:300:3:300:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
106+
| test.cpp:300:9:300:10 | l4 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
107+
| test.cpp:301:3:301:4 | l3 | Usual arithmetic conversion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
108+
| test.cpp:301:9:301:10 | l7 | Usual arithmetic conversion from 'uint8_t' to 'int' changes signedness. |
109+
| test.cpp:304:3:304:4 | l3 | Integer promotion from 'UnscopedEnumExplicit' to 'int' changes signedness. |
110+
| test.cpp:305:3:305:4 | l3 | Integer promotion from 'UnscopedEnumExplicit' to 'int' changes signedness. |

cpp/misra/test/rules/RULE-7-0-5/test.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,77 @@ void test_pointer_assignment_arithmetic() {
238238
l5 -= l4; // COMPLIANT - rule does not apply to pointer arithmetic
239239
}
240240

241+
// Enum types for testing
242+
enum UnscopedEnum { VALUE1, VALUE2, VALUE3 };
243+
enum class ScopedEnum { VALUE1, VALUE2, VALUE3 };
244+
enum UnscopedEnumExplicit : std::uint8_t {
245+
EXPLICIT_VALUE1 = 1,
246+
EXPLICIT_VALUE2 = 2
247+
};
248+
enum class ScopedEnumExplicit : std::uint8_t {
249+
EXPLICIT_VALUE1 = 1,
250+
EXPLICIT_VALUE2 = 2
251+
};
252+
253+
void test_enum_types() {
254+
UnscopedEnum l1 = VALUE1;
255+
UnscopedEnum l2 = VALUE2;
256+
UnscopedEnumExplicit l3 = EXPLICIT_VALUE1;
257+
UnscopedEnumExplicit l4 = EXPLICIT_VALUE2;
258+
ScopedEnum l5 = ScopedEnum::VALUE1;
259+
ScopedEnumExplicit l6 = ScopedEnumExplicit::EXPLICIT_VALUE1;
260+
std::uint8_t l7 = 5;
261+
std::uint32_t l8 = 10;
262+
263+
// Unscoped enum without explicit underlying type - not considered numeric
264+
// type
265+
l1 + l2; // COMPLIANT - rule does not apply
266+
l1 *l2; // COMPLIANT - rule does not apply
267+
l1 & l2; // COMPLIANT - rule does not apply
268+
269+
// Unscoped enum with explicit underlying type - considered numeric type
270+
l3 + l4; // NON_COMPLIANT - uint8_t + uint8_t -> signed int
271+
l3 *l4; // NON_COMPLIANT - uint8_t * uint8_t -> signed int
272+
l3 & l4; // NON_COMPLIANT - uint8_t & uint8_t -> signed int
273+
l3 - l4; // NON_COMPLIANT - uint8_t - uint8_t -> signed int
274+
l3 | l4; // NON_COMPLIANT - uint8_t | uint8_t -> signed int
275+
l3 ^ l4; // NON_COMPLIANT - uint8_t ^ uint8_t -> signed int
276+
277+
// Mixed enum and integer arithmetic
278+
l3 + l7; // NON_COMPLIANT - uint8_t + uint8_t -> signed int
279+
l3 *l7; // NON_COMPLIANT - uint8_t * uint8_t -> signed int
280+
l7 - l3; // NON_COMPLIANT - uint8_t - uint8_t -> signed int
281+
282+
l3 + l8; // COMPLIANT - uint8_t -> signed int (matches l8)
283+
l8 *l3; // COMPLIANT - uint8_t -> signed int (matches l8)
284+
285+
// Unary operations on enum with explicit underlying type
286+
~l3; // NON_COMPLIANT - uint8_t -> signed int
287+
-l3; // NON_COMPLIANT - uint8_t -> signed int
288+
+l3; // NON_COMPLIANT - uint8_t -> signed int
289+
290+
// Scoped enums - not considered numeric type regardless of underlying type
291+
static_cast<int>(l5) +
292+
static_cast<int>(ScopedEnum::VALUE2); // COMPLIANT - rule does not apply
293+
// to explicit casts
294+
static_cast<std::uint8_t>(l6) + // NON_COMPLIANT
295+
static_cast<std::uint8_t>( // NON_COMPLIANT
296+
ScopedEnumExplicit::EXPLICIT_VALUE2);
297+
298+
// Comparison operations with enum
299+
l3 > l4; // NON_COMPLIANT - uint8_t > uint8_t -> signed int
300+
l3 == l4; // NON_COMPLIANT - uint8_t == uint8_t -> signed int
301+
l3 != l7; // NON_COMPLIANT - uint8_t != uint8_t -> signed int
302+
303+
// Shift operations with enum
304+
l3 << 1; // NON_COMPLIANT - uint8_t -> signed int
305+
l3 >> 1; // NON_COMPLIANT - uint8_t -> signed int
306+
307+
// Conditional operator with enum
308+
true ? l3 : l4; // COMPLIANT - same types, no conversion
309+
true ? l3 : l8; // COMPLIANT - same underlying types, no conversion
310+
}
311+
241312
#define A 100LL // intmax_t
242313
#define B 200LL // intmax_t
243314
#define C 300ULL // uintmax_t

0 commit comments

Comments
 (0)