@@ -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