[clang-tidy] Ignore narrowing conversions in case of bitfields
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 bitshift operation 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> | `-ImplicitCastExpr 'unsigned int' <LValueToRValue> | `-MemberExpr 'unsigned int' lvalue bitfield .id | `-DeclRefExpr 'SmallBitfield' lvalue ParmVar 'x' 'SmallBitfield' `-IntegerLiteral 'int' 1 Reviewed By: courbet Differential Revision: https://reviews.llvm.org/D114105
Loading
Please sign in to comment