File tree Expand file tree Collapse file tree 4 files changed +27
-7
lines changed Expand file tree Collapse file tree 4 files changed +27
-7
lines changed Original file line number Diff line number Diff line change @@ -1183,8 +1183,8 @@ void CheckUnusedVar::checkFunctionVariableUsage()
1183
1183
for (const Scope * scope : symbolDatabase->functionScopes ) {
1184
1184
// Bailout when there are lambdas or inline functions
1185
1185
// TODO: Handle lambdas and inline functions properly
1186
- if (scope-> hasInlineOrLambdaFunction ())
1187
- continue ;
1186
+ const Token* lambdaOrInlineStart{};
1187
+ const bool hasLambdaOrInline = scope-> hasInlineOrLambdaFunction (&lambdaOrInlineStart) ;
1188
1188
1189
1189
for (const Token *tok = scope->bodyStart ; tok != scope->bodyEnd ; tok = tok->next ()) {
1190
1190
if (findLambdaEndToken (tok))
@@ -1264,6 +1264,13 @@ void CheckUnusedVar::checkFunctionVariableUsage()
1264
1264
const Variable *op1Var = op1tok ? op1tok->variable () : nullptr ;
1265
1265
if (!op1Var && Token::Match (tok, " (|{" ) && tok->previous () && tok->previous ()->variable ())
1266
1266
op1Var = tok->previous ()->variable ();
1267
+ if (hasLambdaOrInline) {
1268
+ if (!op1Var || !lambdaOrInlineStart)
1269
+ continue ;
1270
+ if (precedes (op1Var->nameToken (), lambdaOrInlineStart))
1271
+ continue ;
1272
+ }
1273
+
1267
1274
std::string bailoutTypeName;
1268
1275
if (op1Var) {
1269
1276
if (op1Var->isReference () && op1Var->nameToken () != tok->astOperand1 ())
Original file line number Diff line number Diff line change @@ -5514,16 +5514,22 @@ static bool hasEmptyCaptureList(const Token* tok) {
5514
5514
return Token::simpleMatch (listTok, " [ ]" );
5515
5515
}
5516
5516
5517
- bool Scope::hasInlineOrLambdaFunction () const
5517
+ bool Scope::hasInlineOrLambdaFunction (const Token** tokStart ) const
5518
5518
{
5519
5519
return std::any_of (nestedList.begin (), nestedList.end (), [&](const Scope* s) {
5520
5520
// 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
5522
5524
return true ;
5525
+ }
5523
5526
// 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 ;
5525
5530
return true ;
5526
- if (s->hasInlineOrLambdaFunction ())
5531
+ }
5532
+ if (s->hasInlineOrLambdaFunction (tokStart))
5527
5533
return true ;
5528
5534
return false ;
5529
5535
});
Original file line number Diff line number Diff line change @@ -1120,7 +1120,7 @@ class CPPCHECKLIB Scope {
1120
1120
}
1121
1121
1122
1122
// Is there lambda/inline function(s) in this scope?
1123
- bool hasInlineOrLambdaFunction () const ;
1123
+ bool hasInlineOrLambdaFunction (const Token** tokStart = nullptr ) const ;
1124
1124
1125
1125
/* *
1126
1126
* @brief find a function
Original file line number Diff line number Diff line change @@ -6980,6 +6980,13 @@ class TestUnusedVar : public TestFixture {
6980
6980
" std::for_each(ints.begin(), ints.end(), [&x](int i){ x += i; });\n "
6981
6981
" }" );
6982
6982
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 ());
6983
6990
}
6984
6991
6985
6992
void namespaces () { // #7557
You can’t perform that action at this time.
0 commit comments