File tree 10 files changed +82
-21
lines changed
common/src/codingstandards/cpp/deadcode
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
22
22
where
23
23
not isExcluded ( v , DeadCodePackage:: unusedGlobalOrNamespaceVariableQuery ( ) ) and
24
24
// 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 50
50
// Local variable is never accessed
51
51
not exists ( v .getAnAccess ( ) ) and
52
52
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 25
25
// No variable access
26
26
not exists ( v .getAnAccess ( ) ) and
27
27
// 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; }
41
41
m1 (); // ignore dead code in macros
42
42
} // namespace N1
43
43
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() {
47
47
d.getT ();
48
48
}
49
49
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
+
50
64
} // namespace test
Original file line number Diff line number Diff line change 1
1
import cpp
2
2
import codingstandards.cpp.FunctionEquivalence
3
+ import codingstandards.cpp.Scope
3
4
4
5
/**
5
6
* A type that contains a template parameter type (doesn't count pointers or references).
@@ -92,7 +93,9 @@ class PotentiallyUnusedMemberVariable extends MemberVariable {
92
93
// Must be in a fully defined class, otherwise one of the undefined functions may use the variable
93
94
getDeclaringType ( ) instanceof FullyDefinedClass and
94
95
// 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 ( _)
96
99
}
97
100
}
98
101
@@ -119,3 +122,21 @@ class UserProvidedConstructorFieldInit extends ConstructorFieldInit {
119
122
not getEnclosingFunction ( ) .isCompilerGenerated ( )
120
123
}
121
124
}
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