@@ -19,6 +19,44 @@ import codingstandards.cpp.autosar
1919import codingstandards.cpp.DynamicCallGraph
2020import codingstandards.cpp.deadcode.UnusedFunctions
2121
22+ /** Checks if a function call exists to the function
23+ * passed in the arguments.
24+ */
25+ predicate isCalled ( Function unusedFunction ) {
26+ exists ( FunctionCall f | unusedFunction .getACallToThisFunction ( ) = f )
27+ }
28+
29+ /** Checks if an overloaded function of
30+ * the function passed in the arguments, is called.
31+ */
32+ predicate overloadedFunctionIsCalled ( Function unusedFunction ) {
33+ exists ( Function f | f = unusedFunction .getAnOverload * ( ) and isCalled ( f ) )
34+ or
35+ unusedFunction .getNamespace ( ) .isAnonymous ( ) and
36+ exists ( TopLevelFunction overloadedFunction |
37+ overloadedFunction != unusedFunction and
38+ ( ( overloadedFunction .getName ( ) = unusedFunction .getName ( ) ) or
39+ ( overloadedFunction .getQualifiedName ( ) =
40+ unusedFunction .getQualifiedName ( ) ) )
41+ )
42+ }
43+
44+ /** Checks if a Function is part of an unevaluated context. */
45+ predicate partOfUnevalutedContexts ( Function unusedFunction ) {
46+ exists ( Expr e , FunctionCall f | ( ( e instanceof TypeidOperator or
47+ e instanceof SizeofOperator or
48+ e instanceof NoExceptExpr ) and
49+ e .getAChild * ( ) = f and f .getTarget ( ) = unusedFunction
50+ )
51+ )
52+ }
53+
54+ /** Checks if a Function's address was taken. */
55+ predicate addressBeenTaken ( Function unusedFunction )
56+ {
57+ exists ( FunctionAccess fa | fa .getTarget ( ) = unusedFunction )
58+ }
59+
2260/** A `Function` nested in an anonymous namespace. */
2361class AnonymousNamespaceFunction extends Function {
2462 AnonymousNamespaceFunction ( ) { getNamespace ( ) .getParentNamespace * ( ) .isAnonymous ( ) }
@@ -75,7 +113,22 @@ where
75113 // There exists an instantiation which is called
76114 functionFromInstantiatedTemplate .isConstructedFrom ( functionFromUninstantiatedTemplate ) and
77115 functionFromInstantiatedTemplate = getTarget ( _)
78- ) and
116+ )
117+ and
118+ // A function is defined as "used" if any one of the following holds true:
119+ // - It's an explicitly deleted functions e.g. =delete
120+ // - It's annotated as "[[maybe_unused]]"
121+ // - It's part of an overloaded set and any one of the overloaded instance
122+ // is called.
123+ // - It's an operand of an expression in an unevaluated context.
124+ (
125+ not unusedLocalFunction .isDeleted ( ) and
126+ not unusedLocalFunction .getAnAttribute ( ) .getName ( ) = "maybe_unused" and
127+ not overloadedFunctionIsCalled ( unusedLocalFunction ) and
128+ not addressBeenTaken ( unusedLocalFunction ) and
129+ not partOfUnevalutedContexts ( unusedLocalFunction )
130+ )
131+ and
79132 // Get a printable name
80133 (
81134 if exists ( unusedLocalFunction .getQualifiedName ( ) )
0 commit comments