Skip to content

Commit e43fbbc

Browse files
authored
Merge pull request #350 from rak3-sh/rp/m0-1-3-false-positives-fix
Fixes false positives for M0-1-3.
2 parents efe6b63 + 7804c40 commit e43fbbc

File tree

5 files changed

+69
-4
lines changed

5 files changed

+69
-4
lines changed

Diff for: change_notes/2023-07-26-unused-local-variable.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- `M0-1-3` - Consider constexpr variables used in template instantiations as "used".

Diff for: cpp/autosar/src/rules/M0-1-3/UnusedLocalVariable.ql

+28
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,37 @@ import cpp
1818
import codingstandards.cpp.autosar
1919
import codingstandards.cpp.deadcode.UnusedVariables
2020

21+
/** Gets the constant value of a constexpr variable. */
22+
private string getConstExprValue(Variable v) {
23+
result = v.getInitializer().getExpr().getValue() and
24+
v.isConstexpr()
25+
}
26+
27+
// This predicate is similar to getUseCount for M0-1-4 except that it also
28+
// considers static_asserts. This was created to cater for M0-1-3 specifically
29+
// and hence, doesn't attempt to reuse the M0-1-4 specific predicate
30+
// - getUseCount()
31+
int getUseCountConservatively(Variable v) {
32+
result =
33+
count(VariableAccess access | access = v.getAnAccess())
34+
+ count(UserProvidedConstructorFieldInit cfi | cfi.getTarget() = v) +
35+
// For constexpr variables used as template arguments, we don't see accesses (just the
36+
// appropriate literals). We therefore take a conservative approach and count the number of
37+
// template instantiations that use the given constant, and consider each one to be a use
38+
// of the variable
39+
count(ClassTemplateInstantiation cti |
40+
cti.getTemplateArgument(_).(Expr).getValue() = getConstExprValue(v)
41+
)
42+
// For static asserts too, check if there is a child which has the same value
43+
// as the constexpr variable.
44+
+ count(StaticAssert s |
45+
s.getCondition().getAChild*().getValue() = getConstExprValue(v))
46+
}
47+
2148
from PotentiallyUnusedLocalVariable v
2249
where
2350
not isExcluded(v, DeadCodePackage::unusedLocalVariableQuery()) and
2451
// Local variable is never accessed
2552
not exists(v.getAnAccess())
53+
and getUseCountConservatively(v) = 0
2654
select v, "Local variable " + v.getName() + " in " + v.getFunction().getName() + " is not used."

Diff for: cpp/autosar/test/rules/M0-1-3/test.cpp

+34-1
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,37 @@ void test_side_effect_init() {
4444
LA a; // NON_COMPLIANT - no constructor called
4545
LC c; // COMPLIANT - constructor called which is considered to potentially
4646
// have side effects
47-
}
47+
}
48+
49+
#include <array>
50+
#include <cstdio>
51+
template <int t> class CharBuffer {
52+
public:
53+
int member[t];
54+
CharBuffer() : member{0} {}
55+
};
56+
57+
int test_constexpr_in_template_inst() {
58+
constexpr int line_length = 1024U; // COMPLIANT - used in template inst.
59+
// of buffer.
60+
CharBuffer<line_length> buffer{};
61+
return buffer.member[0];
62+
}
63+
64+
enum DataType : unsigned char {
65+
int8,
66+
int16,
67+
};
68+
69+
template <typename... Types> int test_constexpr_in_static_assert() {
70+
const std::array<DataType, sizeof...(Types)> lldts{int8};
71+
const std::array<DataType, sizeof...(Types)> llams{int16};
72+
constexpr std::size_t mssu = 64 * 1024; // COMPLIANT - used in static assert.
73+
static_assert((sizeof(lldts) + sizeof(llams)) <= mssu, "assert");
74+
return 0;
75+
}
76+
77+
int baz() {
78+
test_constexpr_in_static_assert<int>();
79+
return 0;
80+
}

Diff for: rule_packages/cpp/DeadCode.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,10 @@
238238
"tags": [
239239
"readability",
240240
"maintainability"
241-
]
241+
],
242+
"implementation_scope": {
243+
"description": "In limited cases, this query can raise false-positives for variables that are defined as constexpr and used in an expression to instantiate a template."
244+
}
242245
},
243246
{
244247
"description": "Unused variables complicate the program and can indicate a possible mistake on the part of the programmer.",
@@ -344,4 +347,4 @@
344347
"title": "There shall be no dead code."
345348
}
346349
}
347-
}
350+
}

Diff for: rule_packages/cpp/Templates.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,4 @@
192192
"title": "In a class template with a dependent base, any name that may be found in that dependent base shall be referred to using a qualified-id or this->."
193193
}
194194
}
195-
}
195+
}

0 commit comments

Comments
 (0)