|
16 | 16 |
|
17 | 17 | import cpp |
18 | 18 | import codingstandards.cpp.autosar |
19 | | -import codingstandards.cpp.DynamicCallGraph |
20 | | -import codingstandards.cpp.deadcode.UnusedFunctions |
| 19 | +import codingstandards.cpp.rules.unusedlocalfunction.UnusedLocalFunction |
21 | 20 |
|
22 | | -/** |
23 | | - * Checks if an overloaded function of |
24 | | - * the function passed in the arguments, is called. |
25 | | - */ |
26 | | -predicate overloadedFunctionIsCalled(Function unusedFunction) { |
27 | | - exists(Function f | f = unusedFunction.getAnOverload() and f = getTarget(_)) |
28 | | -} |
29 | | - |
30 | | -/** Checks if a Function's address was taken. */ |
31 | | -predicate addressBeenTaken(Function unusedFunction) { |
32 | | - exists(FunctionAccess fa | fa.getTarget() = unusedFunction) |
33 | | -} |
34 | | - |
35 | | -/** A `Function` nested in an anonymous namespace. */ |
36 | | -class AnonymousNamespaceFunction extends Function { |
37 | | - AnonymousNamespaceFunction() { getNamespace().getParentNamespace*().isAnonymous() } |
38 | | -} |
39 | | - |
40 | | -/** |
41 | | - * A function which is "local" to a particular scope or translation unit. |
42 | | - */ |
43 | | -class LocalFunction extends UnusedFunctions::UsableFunction { |
44 | | - string localFunctionType; |
45 | | - |
46 | | - LocalFunction() { |
47 | | - this.(MemberFunction).isPrivate() and |
48 | | - localFunctionType = "Private member" |
49 | | - or |
50 | | - // A function in an anonymous namespace (which is deduced to have internal linkage) |
51 | | - this instanceof AnonymousNamespaceFunction and |
52 | | - // Not member functions, which don't have internal linkage |
53 | | - not this instanceof MemberFunction and |
54 | | - localFunctionType = "Anonymous namespace" |
55 | | - or |
56 | | - // Static functions with internal linkage |
57 | | - this.isStatic() and |
58 | | - // Member functions never have internal linkage |
59 | | - not this instanceof MemberFunction and |
60 | | - // Functions in anonymous namespaces automatically have the "static" specifier added by the |
61 | | - // extractor. We therefore excluded them from this case, and instead report them in the |
62 | | - // anonymous namespace, as we don't know whether the "static" specifier was explicitly |
63 | | - // provided by the user. |
64 | | - not this instanceof AnonymousNamespaceFunction and |
65 | | - localFunctionType = "Static" |
66 | | - } |
67 | | - |
68 | | - /** Gets the type of local function. */ |
69 | | - string getLocalFunctionType() { result = localFunctionType } |
| 21 | +module UnusedLocalFunctionConfig implements UnusedLocalFunctionConfigSig { |
| 22 | + Query getQuery() { result = DeadCodePackage::unusedLocalFunctionQuery() } |
70 | 23 | } |
71 | 24 |
|
72 | | -from LocalFunction unusedLocalFunction, string name |
73 | | -where |
74 | | - not isExcluded(unusedLocalFunction, DeadCodePackage::unusedLocalFunctionQuery()) and |
75 | | - // No static or dynamic call target for this function |
76 | | - not unusedLocalFunction = getTarget(_) and |
77 | | - // If this is a TemplateFunction or an instantiation of a template, then only report it as unused |
78 | | - // if all other instantiations of the template are unused |
79 | | - not exists( |
80 | | - Function functionFromUninstantiatedTemplate, Function functionFromInstantiatedTemplate |
81 | | - | |
82 | | - // `unusedLocalFunction` is a template instantiation from `functionFromUninstantiatedTemplate` |
83 | | - unusedLocalFunction.isConstructedFrom(functionFromUninstantiatedTemplate) |
84 | | - or |
85 | | - // `unusedLocalFunction` is from an uninstantiated template |
86 | | - unusedLocalFunction = functionFromUninstantiatedTemplate |
87 | | - | |
88 | | - // There exists an instantiation which is called |
89 | | - functionFromInstantiatedTemplate.isConstructedFrom(functionFromUninstantiatedTemplate) and |
90 | | - functionFromInstantiatedTemplate = getTarget(_) |
91 | | - ) and |
92 | | - // A function is defined as "used" if any one of the following holds true: |
93 | | - // - It's an explicitly deleted functions e.g. =delete |
94 | | - // - It's annotated as "[[maybe_unused]]" |
95 | | - // - It's part of an overloaded set and any one of the overloaded instance |
96 | | - // is called. |
97 | | - // - It's an operand of an expression in an unevaluated context. |
98 | | - not unusedLocalFunction.isDeleted() and |
99 | | - not unusedLocalFunction.getAnAttribute().getName() = "maybe_unused" and |
100 | | - not overloadedFunctionIsCalled(unusedLocalFunction) and |
101 | | - not addressBeenTaken(unusedLocalFunction) and |
102 | | - // Get a printable name |
103 | | - ( |
104 | | - if exists(unusedLocalFunction.getQualifiedName()) |
105 | | - then name = unusedLocalFunction.getQualifiedName() |
106 | | - else name = unusedLocalFunction.getName() |
107 | | - ) |
108 | | -select unusedLocalFunction, |
109 | | - unusedLocalFunction.getLocalFunctionType() + " function " + name + |
110 | | - " is not statically called, or is in an unused template." |
| 25 | +import UnusedLocalFunction<UnusedLocalFunctionConfig> |
0 commit comments