@@ -184,114 +184,95 @@ module MisraCpp23BuiltInTypes {
184
184
}
185
185
186
186
predicate isPreConversionAssignment ( Expr source , Type targetType , string context ) {
187
- // Assignment expression (which excludes compound assignments)
188
- exists ( AssignExpr assign |
189
- assign .getRValue ( ) = source and
190
- context = "assignment"
191
- |
192
- if isAssignedToBitfield ( source , _)
193
- then
194
- // For the MISRA type rules we treat bit fields as a special case
195
- exists ( BitField bf |
196
- isAssignedToBitfield ( source , bf ) and
197
- targetType = getBitFieldType ( bf )
198
- )
199
- else
187
+ if isAssignedToBitfield ( source , _)
188
+ then
189
+ // For the MISRA type rules we treat bit fields as a special case
190
+ exists ( BitField bf |
191
+ isAssignedToBitfield ( source , bf ) and
192
+ targetType = getBitFieldType ( bf ) and
193
+ context = "assignment to bitfield"
194
+ )
195
+ else (
196
+ // Assignment expression (which excludes compound assignments)
197
+ exists ( AssignExpr assign |
198
+ assign .getRValue ( ) = source and
199
+ context = "assignment"
200
+ |
200
201
exists ( Type t | t = assign .getLValue ( ) .getType ( ) |
201
202
// Unwrap PointerToMemberType e.g `l1.*l2 = x;`
202
203
if t instanceof PointerToMemberType
203
204
then targetType = t .( PointerToMemberType ) .getBaseType ( )
204
205
else targetType = t
205
206
)
206
- )
207
- or
208
- // Variable initialization
209
- exists ( Variable v , Initializer init |
210
- init .getExpr ( ) = source and
211
- v .getInitializer ( ) = init and
212
- context = "initialization"
213
- |
214
- // For the MISRA type rules we treat bit fields as a special case
215
- if v instanceof BitField
216
- then targetType = getBitFieldType ( v )
217
- else
218
- // Regular variable initialization
207
+ )
208
+ or
209
+ // Variable initialization
210
+ exists ( Variable v , Initializer init |
211
+ init .getExpr ( ) = source and
212
+ v .getInitializer ( ) = init and
213
+ context = "initialization"
214
+ |
219
215
targetType = v .getType ( )
220
- )
221
- or
222
- exists ( ConstructorFieldInit fi |
223
- fi .getExpr ( ) = source and
224
- context = "constructor field initialization"
225
- |
226
- // For the MISRA type rules we treat bit fields as a special case
227
- if fi .getTarget ( ) instanceof BitField
228
- then targetType = getBitFieldType ( fi .getTarget ( ) )
229
- else
230
- // Regular variable initialization
216
+ )
217
+ or
218
+ exists ( ConstructorFieldInit fi |
219
+ fi .getExpr ( ) = source and
220
+ context = "constructor field initialization"
221
+ |
231
222
targetType = fi .getTarget ( ) .getType ( )
232
- )
233
- or
234
- // Passing a function parameter by value
235
- exists ( Call call , int i |
236
- call .getArgument ( i ) = source and
237
- not targetType .stripTopLevelSpecifiers ( ) instanceof ReferenceType and
238
- context = "function argument"
239
- |
240
- // A regular function call
241
- targetType = call .getTarget ( ) .getParameter ( i ) .getType ( )
223
+ )
242
224
or
243
- // A function call where the argument is passed as varargs
244
- call .getTarget ( ) .getNumberOfParameters ( ) <= i and
245
- // The rule states that the type should match the "adjusted" type of the argument
246
- targetType = source .getFullyConverted ( ) .getType ( )
225
+ // Passing a function parameter by value
226
+ exists ( Call call , int i |
227
+ call .getArgument ( i ) = source and
228
+ not targetType .stripTopLevelSpecifiers ( ) instanceof ReferenceType and
229
+ context = "function argument"
230
+ |
231
+ // A regular function call
232
+ targetType = call .getTarget ( ) .getParameter ( i ) .getType ( )
233
+ or
234
+ // A function call where the argument is passed as varargs
235
+ call .getTarget ( ) .getNumberOfParameters ( ) <= i and
236
+ // The rule states that the type should match the "adjusted" type of the argument
237
+ targetType = source .getFullyConverted ( ) .getType ( )
238
+ or
239
+ // An expression call - get the function type, then the parameter type
240
+ targetType = getExprCallFunctionType ( call ) .getParameterType ( i )
241
+ )
247
242
or
248
- // An expression call - get the function type, then the parameter type
249
- targetType = getExprCallFunctionType ( call ) .getParameterType ( i )
250
- )
251
- or
252
- // Return statement
253
- exists ( ReturnStmt ret , Function f |
254
- ret .getExpr ( ) = source and
255
- ret .getEnclosingFunction ( ) = f and
256
- targetType = f .getType ( ) and
257
- not targetType .stripTopLevelSpecifiers ( ) instanceof ReferenceType and
258
- context = "return"
259
- )
260
- or
261
- // Switch case
262
- exists ( SwitchCase case , SwitchStmt switch |
263
- case .getExpr ( ) = source and
264
- case .getSwitchStmt ( ) = switch and
265
- context = "switch case"
266
- |
267
- if switch .getExpr ( ) .( FieldAccess ) .getTarget ( ) instanceof BitField
268
- then
269
- // For the MISRA type rules we treat bit fields as a special case
270
- targetType = getBitFieldType ( switch .getExpr ( ) .( FieldAccess ) .getTarget ( ) )
271
- else
272
- // Regular variable initialization
243
+ // Return statement
244
+ exists ( ReturnStmt ret , Function f |
245
+ ret .getExpr ( ) = source and
246
+ ret .getEnclosingFunction ( ) = f and
247
+ targetType = f .getType ( ) and
248
+ not targetType .stripTopLevelSpecifiers ( ) instanceof ReferenceType and
249
+ context = "return"
250
+ )
251
+ or
252
+ // Switch case
253
+ exists ( SwitchCase case , SwitchStmt switch |
254
+ case .getExpr ( ) = source and
255
+ case .getSwitchStmt ( ) = switch and
256
+ context = "switch case"
257
+ |
273
258
// Get the type of the switch expression, which is the type of the case expression
274
259
targetType = switch .getExpr ( ) .getFullyConverted ( ) .getType ( )
275
- )
276
- or
277
- // Class aggregate literal initialization
278
- exists ( ClassAggregateLiteral al , Field f |
279
- source = al .getAFieldExpr ( f ) and
280
- context = "class aggregate literal"
281
- |
282
- // For the MISRA type rules we treat bit fields as a special case
283
- if f instanceof BitField
284
- then targetType = getBitFieldType ( f )
285
- else
286
- // Regular variable initialization
260
+ )
261
+ or
262
+ // Class aggregate literal initialization
263
+ exists ( ClassAggregateLiteral al , Field f |
264
+ source = al .getAFieldExpr ( f ) and
265
+ context = "class aggregate literal"
266
+ |
287
267
targetType = f .getType ( )
288
- )
289
- or
290
- // Array or vector aggregate literal initialization
291
- exists ( ArrayOrVectorAggregateLiteral vl |
292
- source = vl .getAnElementExpr ( _) and
293
- targetType = vl .getElementType ( ) and
294
- context = "array or vector aggregate literal"
268
+ )
269
+ or
270
+ // Array or vector aggregate literal initialization
271
+ exists ( ArrayOrVectorAggregateLiteral vl |
272
+ source = vl .getAnElementExpr ( _) and
273
+ targetType = vl .getElementType ( ) and
274
+ context = "array or vector aggregate literal"
275
+ )
295
276
)
296
277
}
297
278
@@ -315,11 +296,16 @@ module MisraCpp23BuiltInTypes {
315
296
)
316
297
)
317
298
}
318
- }
319
299
320
- /**
321
- * Holds if the `source` expression is assigned to a bit field.
322
- */
323
- predicate isAssignedToBitfield ( Expr source , BitField bf ) {
324
- source = bf .getAnAssignedValue ( ) .getExplicitlyConverted ( )
300
+ /**
301
+ * Holds if the `source` expression is "assigned" to a bit field per MISRA C++ 2023.
302
+ */
303
+ predicate isAssignedToBitfield ( Expr source , BitField bf ) {
304
+ source = bf .getAnAssignedValue ( ) .getExplicitlyConverted ( )
305
+ or
306
+ exists ( SwitchStmt switch , SwitchCase case |
307
+ bf = switch .getExpr ( ) .( FieldAccess ) .getTarget ( ) and
308
+ source = case .getExpr ( )
309
+ )
310
+ }
325
311
}
0 commit comments