@@ -54,26 +54,17 @@ class NumericType extends Type {
5454}
5555
5656predicate isAssignment ( Expr source , NumericType targetType , string context ) {
57- // Assignment operator (but not compound assignment )
57+ // Assignment expression (which excludes compound assignments )
5858 exists ( AssignExpr assign |
5959 assign .getRValue ( ) = source and
6060 context = "assignment"
6161 |
62- // TODO generalize to variable init (do we need this for bitfields?) and extract
6362 if isAssignedToBitfield ( source , _)
6463 then
64+ // For the MISRA type rules we treat bit fields as a special case
6565 exists ( BitField bf |
6666 isAssignedToBitfield ( source , bf ) and
67- // TODO integral after numeric?
68- targetType .( IntegralType ) .( NumericType ) .getSignedness ( ) =
69- bf .getType ( ) .( NumericType ) .getSignedness ( ) and
70- // smallest integral type that can hold the bit field value
71- targetType .getRealSize ( ) * 8 >= bf .getNumBits ( ) and
72- not exists ( IntegralType other |
73- other .getSize ( ) * 8 >= bf .getNumBits ( ) and
74- other .( NumericType ) .getSignedness ( ) = targetType .getSignedness ( ) and
75- other .getSize ( ) < targetType .getRealSize ( )
76- )
67+ targetType = getBitFieldType ( bf )
7768 )
7869 else targetType = assign .getLValue ( ) .getType ( )
7970 )
@@ -82,8 +73,14 @@ predicate isAssignment(Expr source, NumericType targetType, string context) {
8273 exists ( Variable v , Initializer init |
8374 init .getExpr ( ) = source and
8475 v .getInitializer ( ) = init and
85- targetType = v .getType ( ) and
8676 context = "initialization"
77+ |
78+ // For the MISRA type rules we treat bit fields as a special case
79+ if v instanceof BitField
80+ then targetType = getBitFieldType ( v )
81+ else
82+ // Regular variable initialization
83+ targetType = v .getType ( )
8784 )
8885 or
8986 // Passing a function parameter by value
@@ -117,6 +114,30 @@ predicate isAssignment(Expr source, NumericType targetType, string context) {
117114 )
118115}
119116
117+ /**
118+ * Gets the smallest integral type that can hold the value of a bit field.
119+ *
120+ * The type is determined by the signedness of the bit field and the number of bits.
121+ */
122+ NumericType getBitFieldType ( BitField bf ) {
123+ exists ( NumericType bitfieldActualType |
124+ bitfieldActualType = bf .getType ( ) and
125+ // Integral type with the same signedness as the bit field, and big enough to hold the bit field value
126+ result instanceof IntegralType and
127+ result .getSignedness ( ) = bitfieldActualType .getSignedness ( ) and
128+ result .getSize ( ) * 8 >= bf .getNumBits ( ) and
129+ // No smaller integral type can hold the bit field value
130+ not exists ( IntegralType other |
131+ other .getSize ( ) * 8 >= bf .getNumBits ( ) and
132+ other .( NumericType ) .getSignedness ( ) = result .getSignedness ( ) and
133+ other .getSize ( ) < result .getRealSize ( )
134+ )
135+ )
136+ }
137+
138+ /**
139+ * Holds if the `source` expression is assigned to a bit field.
140+ */
120141predicate isAssignedToBitfield ( Expr source , BitField bf ) {
121142 exists ( Assignment assign |
122143 assign .getRValue ( ) = source and
0 commit comments