@@ -54,26 +54,17 @@ class NumericType extends Type {
54
54
}
55
55
56
56
predicate isAssignment ( Expr source , NumericType targetType , string context ) {
57
- // Assignment operator (but not compound assignment )
57
+ // Assignment expression (which excludes compound assignments )
58
58
exists ( AssignExpr assign |
59
59
assign .getRValue ( ) = source and
60
60
context = "assignment"
61
61
|
62
- // TODO generalize to variable init (do we need this for bitfields?) and extract
63
62
if isAssignedToBitfield ( source , _)
64
63
then
64
+ // For the MISRA type rules we treat bit fields as a special case
65
65
exists ( BitField bf |
66
66
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 )
77
68
)
78
69
else targetType = assign .getLValue ( ) .getType ( )
79
70
)
@@ -82,8 +73,14 @@ predicate isAssignment(Expr source, NumericType targetType, string context) {
82
73
exists ( Variable v , Initializer init |
83
74
init .getExpr ( ) = source and
84
75
v .getInitializer ( ) = init and
85
- targetType = v .getType ( ) and
86
76
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 ( )
87
84
)
88
85
or
89
86
// Passing a function parameter by value
@@ -117,6 +114,30 @@ predicate isAssignment(Expr source, NumericType targetType, string context) {
117
114
)
118
115
}
119
116
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
+ */
120
141
predicate isAssignedToBitfield ( Expr source , BitField bf ) {
121
142
exists ( Assignment assign |
122
143
assign .getRValue ( ) = source and
0 commit comments