@@ -18,29 +18,46 @@ import cpp
1818import codingstandards.cpp.autosar
1919import codingstandards.cpp.deadcode.UnusedVariables
2020
21- // This predicate is similar to getUseCount for M0-1-4 except that it also
22- // considers static_asserts. This was created to cater for M0-1-3 specifically
23- // and hence, doesn't attempt to reuse the M0-1-4 specific predicate
24- // - getUseCount()
21+ // Collect constant values that we should use to exclude otherwise unused constexpr variables.
22+ //
23+ // For constexpr variables used as template arguments or in static_asserts, we don't see accesses
24+ // (just the appropriate literals). We therefore take a conservative approach and do not report
25+ // constexpr variables whose values are used in such contexts.
26+ //
27+ // For performance reasons, these special values should be collected in a single pass.
28+ predicate excludedConstantValue ( string value ) {
29+ value = any ( ClassTemplateInstantiation cti ) .getTemplateArgument ( _) .( Expr ) .getValue ( )
30+ or
31+ value = any ( StaticAssert sa ) .getCondition ( ) .getAChild * ( ) .getValue ( )
32+ }
33+
34+ /**
35+ * Defines the local variables that should be excluded from the unused variable analysis based
36+ * on their constant value.
37+ *
38+ * See `excludedConstantValue` for more details.
39+ */
40+ predicate excludeVariableByValue ( Variable variable ) {
41+ variable .isConstexpr ( ) and
42+ excludedConstantValue ( getConstExprValue ( variable ) )
43+ }
44+
45+ // TODO: This predicate may be possible to merge with M0-1-4's getUseCount(). These two rules
46+ // diverged to handle `excludeVariableByValue`, but may be possible to merge.
2547int getUseCountConservatively ( Variable v ) {
2648 result =
2749 count ( VariableAccess access | access = v .getAnAccess ( ) ) +
2850 count ( UserProvidedConstructorFieldInit cfi | cfi .getTarget ( ) = v ) +
29- // For constexpr variables used as template arguments, we don't see accesses (just the
30- // appropriate literals). We therefore take a conservative approach and count the number of
31- // template instantiations that use the given constant, and consider each one to be a use
32- // of the variable
33- count ( ClassTemplateInstantiation cti |
34- cti .getTemplateArgument ( _) .( Expr ) .getValue ( ) = getConstExprValue ( v )
35- ) +
36- // For static asserts too, check if there is a child which has the same value
37- // as the constexpr variable.
38- count ( StaticAssert s | s .getCondition ( ) .getAChild * ( ) .getValue ( ) = getConstExprValue ( v ) ) +
3951 // In case an array type uses a constant in the same scope as the constexpr variable,
4052 // consider it as used.
4153 countUsesInLocalArraySize ( v )
4254}
4355
56+ predicate isConservativelyUnused ( Variable v ) {
57+ getUseCountConservatively ( v ) = 0 and
58+ not excludeVariableByValue ( v )
59+ }
60+
4461from PotentiallyUnusedLocalVariable v
4562where
4663 not isExcluded ( v , DeadCodePackage:: unusedLocalVariableQuery ( ) ) and
5471 exists ( another .getAnAccess ( ) ) and
5572 another != v
5673 ) and
57- getUseCountConservatively ( v ) = 0
74+ isConservativelyUnused ( v )
5875select v , "Local variable '" + v .getName ( ) + "' in '" + v .getFunction ( ) .getName ( ) + "' is not used."
0 commit comments