File tree Expand file tree Collapse file tree 10 files changed +82
-21
lines changed
common/src/codingstandards/cpp/deadcode Expand file tree Collapse file tree 10 files changed +82
-21
lines changed Original file line number Diff line number Diff line change 1+ - ` M0-1-3 ` - ` UnusedMemberVariable.ql ` , ` UnusedGlobalOrNamespaceVariable.ql ` :
2+ - Address FP reported in #384 . Exclude variables with compile time values that may have been used as a template argument.
3+ - Exclude uninstantiated template members.
4+ - Reformat the alert message to adhere to the style-guide.
Original file line number Diff line number Diff line change @@ -22,5 +22,7 @@ from PotentiallyUnusedGlobalOrNamespaceVariable v
2222where
2323 not isExcluded ( v , DeadCodePackage:: unusedGlobalOrNamespaceVariableQuery ( ) ) and
2424 // No variable access
25- not exists ( v .getAnAccess ( ) )
26- select v , "Variable " + v .getQualifiedName ( ) + " is unused."
25+ not exists ( v .getAnAccess ( ) ) and
26+ // Exclude members whose value is compile time and is potentially used to inintialize a template
27+ not maybeACompileTimeTemplateArgument ( v )
28+ select v , "Variable '" + v .getQualifiedName ( ) + "' is unused."
Original file line number Diff line number Diff line change 5050 // Local variable is never accessed
5151 not exists ( v .getAnAccess ( ) ) and
5252 getUseCountConservatively ( v ) = 0
53- select v , "Local variable " + v .getName ( ) + " in " + v .getFunction ( ) .getName ( ) + " is not used."
53+ select v , "Local variable ' " + v .getName ( ) + "' in ' " + v .getFunction ( ) .getName ( ) + "' is not used."
Original file line number Diff line number Diff line change 2525 // No variable access
2626 not exists ( v .getAnAccess ( ) ) and
2727 // No explicit initialization in a constructor
28- not exists ( UserProvidedConstructorFieldInit cfi | cfi .getTarget ( ) = v )
29- select v , "Member variable " + v .getName ( ) + " is unused."
28+ not exists ( UserProvidedConstructorFieldInit cfi | cfi .getTarget ( ) = v ) and
29+ // Exclude members whose value is compile time and is potentially used to inintialize a template
30+ not maybeACompileTimeTemplateArgument ( v )
31+ select v , "Member variable '" + v .getName ( ) + "' is unused."
Original file line number Diff line number Diff line change 1- | test_global_or_namespace.cpp:3:5:3:6 | g3 | Variable g3 is unused. |
2- | test_global_or_namespace.cpp:18:4:18:4 | a | Variable a is unused. |
3- | test_global_or_namespace.cpp:26:5:26:6 | x3 | Variable N1::x3 is unused. |
4- | test_global_or_namespace.cpp:36:5:36:5 | a | Variable N1::a is unused. |
1+ | test_global_or_namespace.cpp:3:5:3:6 | g3 | Variable 'g3' is unused. |
2+ | test_global_or_namespace.cpp:18:4:18:4 | a | Variable 'a' is unused. |
3+ | test_global_or_namespace.cpp:26:5:26:6 | x3 | Variable ' N1::x3' is unused. |
4+ | test_global_or_namespace.cpp:36:5:36:5 | a | Variable ' N1::a' is unused. |
Original file line number Diff line number Diff line change 1- | test.cpp:7:7:7:7 | y | Local variable y in test_simple is not used. |
2- | test.cpp:14:13:14:13 | y | Local variable y in test_const is not used. |
3- | test.cpp:17:7:17:7 | z | Local variable z in test_const is not used. |
4- | test.cpp:23:5:23:5 | t | Local variable t in f1 is not used. |
5- | test.cpp:23:5:23:5 | t | Local variable t in f1 is not used. |
6- | test.cpp:44:6:44:6 | a | Local variable a in test_side_effect_init is not used. |
1+ | test.cpp:7:7:7:7 | y | Local variable 'y' in ' test_simple' is not used. |
2+ | test.cpp:14:13:14:13 | y | Local variable 'y' in ' test_const' is not used. |
3+ | test.cpp:17:7:17:7 | z | Local variable 'z' in ' test_const' is not used. |
4+ | test.cpp:23:5:23:5 | t | Local variable 't' in 'f1' is not used. |
5+ | test.cpp:23:5:23:5 | t | Local variable 't' in 'f1' is not used. |
6+ | test.cpp:44:6:44:6 | a | Local variable 'a' in ' test_side_effect_init' is not used. |
Original file line number Diff line number Diff line change 1- | test_member.cpp:4:7:4:8 | m1 | Member variable m1 is unused. |
2- | test_member.cpp:17:9:17:11 | pad | Member variable pad is unused. |
3- | test_member.cpp:19:9:19:11 | sm2 | Member variable sm2 is unused. |
4- | test_member.cpp:31:7:31:8 | m1 | Member variable m1 is unused. |
1+ | test_member.cpp:4:7:4:8 | m1 | Member variable 'm1' is unused. |
2+ | test_member.cpp:17:9:17:11 | pad | Member variable ' pad' is unused. |
3+ | test_member.cpp:19:9:19:11 | sm2 | Member variable ' sm2' is unused. |
4+ | test_member.cpp:31:7:31:8 | m1 | Member variable 'm1' is unused. |
Original file line number Diff line number Diff line change @@ -41,4 +41,22 @@ void test_ns() { x2 = 1; }
4141m1 (); // ignore dead code in macros
4242} // namespace N1
4343
44- int test_access_variable () { return N1::x5; }
44+ int test_access_variable () { return N1::x5; }
45+
46+ template <int t> struct C1 {
47+ int array[t]; // COMPLIANT
48+ };
49+
50+ constexpr int g5 = 1 ; // COMPLIANT - used as template parameter
51+
52+ namespace ns1 {
53+ constexpr int m1 = 1 ; // COMPLIANT - used a template parameter
54+ }
55+
56+ void test_fp_reported_in_384 () {
57+ struct C1 <g5> l1;
58+ struct C1 <ns1::m1> l2;
59+
60+ l1.array [0 ] = 1 ;
61+ l2.array [0 ] = 1 ;
62+ }
Original file line number Diff line number Diff line change @@ -47,4 +47,18 @@ void test_d() {
4747 d.getT ();
4848}
4949
50+ template <int t> struct C1 {
51+ int array[t]; // COMPLIANT
52+ };
53+
54+ struct C2 {
55+ static constexpr int m1 = 1 ; // COMPLIANT - used as template parameter
56+ };
57+
58+ void test_fp_reported_in_384 () {
59+ struct C1 <C2::m1> l1;
60+
61+ l1.array [0 ] = 1 ;
62+ }
63+
5064} // namespace test
Original file line number Diff line number Diff line change 11import cpp
22import codingstandards.cpp.FunctionEquivalence
3+ import codingstandards.cpp.Scope
34
45/**
56 * A type that contains a template parameter type (doesn't count pointers or references).
@@ -92,7 +93,9 @@ class PotentiallyUnusedMemberVariable extends MemberVariable {
9293 // Must be in a fully defined class, otherwise one of the undefined functions may use the variable
9394 getDeclaringType ( ) instanceof FullyDefinedClass and
9495 // Lambda captures are not "real" member variables - it's an implementation detail that they are represented that way
95- not this = any ( LambdaCapture lc ) .getField ( )
96+ not this = any ( LambdaCapture lc ) .getField ( ) and
97+ // exclude uninstantiated template members
98+ not this .isFromUninstantiatedTemplate ( _)
9699 }
97100}
98101
@@ -119,3 +122,21 @@ class UserProvidedConstructorFieldInit extends ConstructorFieldInit {
119122 not getEnclosingFunction ( ) .isCompilerGenerated ( )
120123 }
121124}
125+
126+ /**
127+ * Holds if `v` may hold a compile time value and is accessible to a template instantiation that
128+ * receives a constant value as an argument equal to the value of `v`.
129+ */
130+ predicate maybeACompileTimeTemplateArgument ( Variable v ) {
131+ v .isConstexpr ( ) and
132+ exists ( ClassTemplateInstantiation cti , TranslationUnit tu |
133+ cti .getATemplateArgument ( ) .( Expr ) .getValue ( ) = v .getInitializer ( ) .getExpr ( ) .getValue ( ) and
134+ (
135+ cti .getFile ( ) = tu and
136+ (
137+ v .getADeclarationEntry ( ) .getFile ( ) = tu or
138+ tu .getATransitivelyIncludedFile ( ) = v .getADeclarationEntry ( ) .getFile ( )
139+ )
140+ )
141+ )
142+ }
You can’t perform that action at this time.
0 commit comments