Bitfields are special. Due to integral promotion conv.prom/5 bitfield
member access expressions are frequently wrapped by an implicit cast to
int if that type can represent all the values of the bitfield.
Consider these examples:
struct SmallBitfield { unsigned int id : 4; }; x.id & 1; (case-1) x.id & 1u; (case-2) x.id << 1u; (case-3) (unsigned)x.id << 1; (case-4)
Due to the promotion rules, we would get a warning for case-1. It's
debatable how useful this is, but the user at least has a convenient way of
'fixing' it by adding the u unsigned-suffix to the literal as
demonstrated by case-2. However, this won't work for shift operators like
the one in case-3. In case of a normal binary operator, both operands
contribute to the result type. However, the type of the shift expression is
the promoted type of the left operand. One could still suppress this
superfluous warning by explicitly casting the bitfield member access as
case-4 demonstrates, but why? The compiler already knew that the value from
the member access should safely fit into an int, why do we have this
warning in the first place? So, hereby we suppress this specific scenario, when a bitfield's value is implicitly cast to int (likely due to integral promotion).
Note that the e.g. bitshift operations might invoke unspecified/undefined
behavior, but that's another topic, this checker is about detecting
conversion-related defects.
Example AST for x.id << 1:
BinaryOperator 'int' '<<' |-ImplicitCastExpr 'int' <IntegralCast> <--- due to integral promotion | `-ImplicitCastExpr 'unsigned int' <LValueToRValue> | `-MemberExpr 'unsigned int' lvalue bitfield .id | `-DeclRefExpr 'SmallBitfield' lvalue ParmVar 'x' 'SmallBitfield' `-IntegerLiteral 'int' 1
(Terminology... 😕)