Skip to content

Commit 5fecde1

Browse files
Partial fix for #8433 FN unusedVariable not detected when there is lambda (regression) (danmar#6685)
1 parent c3fc22a commit 5fecde1

File tree

4 files changed

+27
-7
lines changed

4 files changed

+27
-7
lines changed

lib/checkunusedvar.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,8 +1183,8 @@ void CheckUnusedVar::checkFunctionVariableUsage()
11831183
for (const Scope * scope : symbolDatabase->functionScopes) {
11841184
// Bailout when there are lambdas or inline functions
11851185
// TODO: Handle lambdas and inline functions properly
1186-
if (scope->hasInlineOrLambdaFunction())
1187-
continue;
1186+
const Token* lambdaOrInlineStart{};
1187+
const bool hasLambdaOrInline = scope->hasInlineOrLambdaFunction(&lambdaOrInlineStart);
11881188

11891189
for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
11901190
if (findLambdaEndToken(tok))
@@ -1264,6 +1264,13 @@ void CheckUnusedVar::checkFunctionVariableUsage()
12641264
const Variable *op1Var = op1tok ? op1tok->variable() : nullptr;
12651265
if (!op1Var && Token::Match(tok, "(|{") && tok->previous() && tok->previous()->variable())
12661266
op1Var = tok->previous()->variable();
1267+
if (hasLambdaOrInline) {
1268+
if (!op1Var || !lambdaOrInlineStart)
1269+
continue;
1270+
if (precedes(op1Var->nameToken(), lambdaOrInlineStart))
1271+
continue;
1272+
}
1273+
12671274
std::string bailoutTypeName;
12681275
if (op1Var) {
12691276
if (op1Var->isReference() && op1Var->nameToken() != tok->astOperand1())

lib/symboldatabase.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5514,16 +5514,22 @@ static bool hasEmptyCaptureList(const Token* tok) {
55145514
return Token::simpleMatch(listTok, "[ ]");
55155515
}
55165516

5517-
bool Scope::hasInlineOrLambdaFunction() const
5517+
bool Scope::hasInlineOrLambdaFunction(const Token** tokStart) const
55185518
{
55195519
return std::any_of(nestedList.begin(), nestedList.end(), [&](const Scope* s) {
55205520
// Inline function
5521-
if (s->type == Scope::eUnconditional && Token::simpleMatch(s->bodyStart->previous(), ") {"))
5521+
if (s->type == Scope::eUnconditional && Token::simpleMatch(s->bodyStart->previous(), ") {")) {
5522+
if (tokStart)
5523+
*tokStart = nullptr; // bailout for e.g. loop-like macros
55225524
return true;
5525+
}
55235526
// Lambda function
5524-
if (s->type == Scope::eLambda && !hasEmptyCaptureList(s->bodyStart))
5527+
if (s->type == Scope::eLambda && !hasEmptyCaptureList(s->bodyStart)) {
5528+
if (tokStart)
5529+
*tokStart = s->bodyStart;
55255530
return true;
5526-
if (s->hasInlineOrLambdaFunction())
5531+
}
5532+
if (s->hasInlineOrLambdaFunction(tokStart))
55275533
return true;
55285534
return false;
55295535
});

lib/symboldatabase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ class CPPCHECKLIB Scope {
11201120
}
11211121

11221122
// Is there lambda/inline function(s) in this scope?
1123-
bool hasInlineOrLambdaFunction() const;
1123+
bool hasInlineOrLambdaFunction(const Token** tokStart = nullptr) const;
11241124

11251125
/**
11261126
* @brief find a function

test/testunusedvar.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6980,6 +6980,13 @@ class TestUnusedVar : public TestFixture {
69806980
" std::for_each(ints.begin(), ints.end(), [&x](int i){ x += i; });\n"
69816981
"}");
69826982
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", "", errout_str());
6983+
6984+
functionVariableUsage("int f(const std::vector<int>& v) {\n"
6985+
" auto it = std::find_if(v.begin(), v.end(), [&](int i) { return i > 0 && i < 7; });\n"
6986+
" std::unordered_map<std::string, std::vector<int*>> exprs;\n"
6987+
" return *it;\n"
6988+
"}");
6989+
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: exprs\n", errout_str());
69836990
}
69846991

69856992
void namespaces() { // #7557

0 commit comments

Comments
 (0)