Skip to content

Commit

Permalink
Merge pull request #660 from rak3-sh/fix-m0-1-3-658
Browse files Browse the repository at this point in the history
M0-1-3: Consider local variable usages in array size and template function arguments
  • Loading branch information
lcartey authored Aug 28, 2024
2 parents 2b1c295 + 3b062af commit 6e090fe
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 13 deletions.
2 changes: 2 additions & 0 deletions change_notes/2024-08-06-fix-fp-658-M0-1-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- `M0-1-3` - `UnusedLocalVariable.ql`:
- Fixes #658. Considers usage of const/constexpr variables in array size and function parameters that are used in arguments of template functions.
21 changes: 18 additions & 3 deletions cpp/autosar/src/rules/M0-1-3/UnusedLocalVariable.ql
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.deadcode.UnusedVariables

/** Gets the constant value of a constexpr variable. */
/** Gets the constant value of a constexpr/const variable. */
private string getConstExprValue(Variable v) {
result = v.getInitializer().getExpr().getValue() and
v.isConstexpr()
(v.isConst() or v.isConstexpr())
}

// This predicate is similar to getUseCount for M0-1-4 except that it also
Expand All @@ -41,13 +41,28 @@ int getUseCountConservatively(Variable v) {
) +
// For static asserts too, check if there is a child which has the same value
// as the constexpr variable.
count(StaticAssert s | s.getCondition().getAChild*().getValue() = getConstExprValue(v))
count(StaticAssert s | s.getCondition().getAChild*().getValue() = getConstExprValue(v)) +
// In case an array type uses a constant in the same scope as the constexpr variable,
// consider it as used.
count(ArrayType at, LocalVariable arrayVariable |
arrayVariable.getType().resolveTypedefs() = at and
v.(PotentiallyUnusedLocalVariable).getFunction() = arrayVariable.getFunction() and
at.getArraySize().toString() = getConstExprValue(v)
)
}

from PotentiallyUnusedLocalVariable v
where
not isExcluded(v, DeadCodePackage::unusedLocalVariableQuery()) and
// Local variable is never accessed
not exists(v.getAnAccess()) and
// Sometimes multiple objects representing the same entities are created in
// the AST. Check if those are not accessed as well. Refer issue #658
not exists(LocalScopeVariable another |
another.getDefinitionLocation() = v.getDefinitionLocation() and
another.hasName(v.getName()) and
exists(another.getAnAccess()) and
another != v
) and
getUseCountConservatively(v) = 0
select v, "Local variable '" + v.getName() + "' in '" + v.getFunction().getName() + "' is not used."
11 changes: 5 additions & 6 deletions cpp/autosar/test/rules/M0-1-3/UnusedLocalVariable.expected
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
| test.cpp:7:7:7:7 | y | Local variable 'y' in 'test_simple' is not used. |
| test.cpp:14:13:14:13 | y | Local variable 'y' in 'test_const' is not used. |
| test.cpp:17:7:17:7 | z | Local variable 'z' in 'test_const' is not used. |
| test.cpp:23:5:23:5 | t | Local variable 't' in 'f1' is not used. |
| test.cpp:23:5:23:5 | t | Local variable 't' in 'f1' is not used. |
| test.cpp:44:6:44:6 | a | Local variable 'a' in 'test_side_effect_init' is not used. |
| test.cpp:91:5:91:5 | t | Local variable 't' in 'template_function' is not used. |
| test.cpp:15:7:15:7 | z | Local variable 'z' in 'test_const' is not used. |
| test.cpp:21:5:21:5 | t | Local variable 't' in 'f1' is not used. |
| test.cpp:21:5:21:5 | t | Local variable 't' in 'f1' is not used. |
| test.cpp:42:6:42:6 | a | Local variable 'a' in 'test_side_effect_init' is not used. |
| test.cpp:89:5:89:5 | t | Local variable 't' in 'template_function' is not used. |
22 changes: 18 additions & 4 deletions cpp/autosar/test/rules/M0-1-3/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ int test_simple() {

int test_const() {
const int x = 1; // COMPLIANT - used below
const int y = 2; // COMPLIANT[FALSE_POSITIVE] - used in array initialization,
// but the database does not contain sufficient information
// for this case
const int y = 2; // COMPLIANT - used in array initialization,
int z[y]; // NON_COMPLIANT - never used
return x;
}
Expand Down Expand Up @@ -98,4 +96,20 @@ class ClassT {
void test() {}
};

void test_template_function() { template_function<ClassT>(); }
void test_template_function() { template_function<ClassT>(); }

int foo() {
constexpr int arrayDim = 10; // COMPLIANT - used in array size below
static int array[arrayDim]{};
return array[4];
}

template <typename T> static T another_templ_function() { return T(); }

template <typename T, typename First, typename... Rest>
static T another_templ_function(const First &first, const Rest &...rest) {
return first +
another_templ_function<T>(rest...); // COMPLIANT - 'rest' is used here
}

static int templ_fnc2() { return another_templ_function<int>(1, 2, 3, 4, 5); }

0 comments on commit 6e090fe

Please sign in to comment.