diff --git a/cfg/std.cfg b/cfg/std.cfg index 86dede187..e6fc7c9cd 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -8672,6 +8672,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init std::basic_ofstream std::insert_iterator std::lock_guard + std::scoped_lock std::unique_lock std::shared_lock std::pair diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 827d8f656..8a94ad892 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2105,11 +2105,14 @@ void CheckOther::checkMisusedScopedObject() if (ctorTok && (((ctorTok->type() || ctorTok->isStandardType() || (ctorTok->function() && ctorTok->function()->isConstructor())) // TODO: The rhs of || should be removed; It is a workaround for a symboldatabase bug && (!ctorTok->function() || ctorTok->function()->isConstructor()) // // is not a function on this scope or is function in this scope and it's a ctor && ctorTok->str() != "void") || isLibraryConstructor(tok->next(), typeStr))) { - if (const Token* arg = ctorTok->next()->astOperand2()) { + const Token* parTok = ctorTok->next(); + if (Token::simpleMatch(parTok, "<") && parTok->link()) + parTok = parTok->link()->next(); + if (const Token* arg = parTok->astOperand2()) { if (!isConstStatement(arg, mTokenizer->isCPP())) continue; - if (ctorTok->strAt(1) == "(") { - if (arg->varId()) // TODO: check if this is a declaration + if (parTok->str() == "(") { + if (arg->varId() && !(arg->variable() && arg->variable()->nameToken() != arg)) continue; const Token* rml = nextAfterAstRightmostLeaf(arg); if (rml && rml->previous() && rml->previous()->varId()) diff --git a/test/testother.cpp b/test/testother.cpp index 8a060de4c..4c315320c 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -5140,9 +5140,17 @@ private: " void f() {\n" " std::lock_guard(m);\n" " }\n" + " void g() {\n" + " std::scoped_lock(m);\n" + " }\n" + " void h() {\n" + " std::scoped_lock(m);\n" + " }\n" " std::mutex m;\n" "}\n", "test.cpp"); - ASSERT_EQUALS("[test.cpp:3]: (style) Instance of 'std::lock_guard' object is destroyed immediately.\n", + ASSERT_EQUALS("[test.cpp:3]: (style) Instance of 'std::lock_guard' object is destroyed immediately.\n" + "[test.cpp:6]: (style) Instance of 'std::scoped_lock' object is destroyed immediately.\n" + "[test.cpp:9]: (style) Instance of 'std::scoped_lock' object is destroyed immediately.\n", errout.str()); }