@@ -238,6 +238,77 @@ void test_pointer_assignment_arithmetic() {
238
238
l5 -= l4; // COMPLIANT - rule does not apply to pointer arithmetic
239
239
}
240
240
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
+
241
312
#define A 100LL // intmax_t
242
313
#define B 200LL // intmax_t
243
314
#define C 300ULL // uintmax_t
0 commit comments