@@ -184,114 +184,95 @@ module MisraCpp23BuiltInTypes {
184184 }
185185
186186 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+ |
200201 exists ( Type t | t = assign .getLValue ( ) .getType ( ) |
201202 // Unwrap PointerToMemberType e.g `l1.*l2 = x;`
202203 if t instanceof PointerToMemberType
203204 then targetType = t .( PointerToMemberType ) .getBaseType ( )
204205 else targetType = t
205206 )
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+ |
219215 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+ |
231222 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+ )
242224 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+ )
247242 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+ |
273258 // Get the type of the switch expression, which is the type of the case expression
274259 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+ |
287267 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+ )
295276 )
296277 }
297278
@@ -315,11 +296,16 @@ module MisraCpp23BuiltInTypes {
315296 )
316297 )
317298 }
318- }
319299
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+ }
325311}
0 commit comments