diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 6d51bd928..ebeb7f44f 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2439,7 +2439,7 @@ void CheckStl::checkMutexes() continue; if (isLocalMutex(var, tok->scope())) localMutexError(tok); - } else if (Token::Match(tok, "%var% (|{ %var% )|}")) { + } else if (Token::Match(tok, "%var% (|{ %var% )|}|,")) { if (!isLockGuard(var)) continue; const Variable* mvar = tok->tokAt(2)->variable(); diff --git a/test/teststl.cpp b/test/teststl.cpp index 677efae2a..240e20709 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4429,6 +4429,22 @@ private: true); ASSERT_EQUALS("", errout.str()); + check("void f() {\n" + " static std::mutex m;\n" + " static std::unique_lock g(m, std::defer_lock);\n" + " static std::lock(g);\n" + "}\n", + true); + ASSERT_EQUALS("[test.cpp:3]: (warning) Lock guard is defined globally. Lock guards are intended to be local. A global lock guard could lead to a deadlock since it won't unlock until the end of the program.\n", errout.str()); + + check("void f() {\n" + " static std::mutex m;\n" + " std::unique_lock g(m, std::defer_lock);\n" + " std::lock(g);\n" + "}\n", + true); + ASSERT_EQUALS("", errout.str()); + check("void f() {\n" " std::mutex m;\n" " std::lock_guard g(m);\n" @@ -4436,6 +4452,21 @@ private: true); ASSERT_EQUALS("[test.cpp:3]: (warning) The lock is ineffective because the mutex is locked at the same scope as the mutex itself.\n", errout.str()); + check("void f() {\n" + " std::mutex m;\n" + " std::unique_lock g(m);\n" + "}\n", + true); + ASSERT_EQUALS("[test.cpp:3]: (warning) The lock is ineffective because the mutex is locked at the same scope as the mutex itself.\n", errout.str()); + + check("void f() {\n" + " std::mutex m;\n" + " std::unique_lock g(m, std::defer_lock);\n" + " std::lock(g);\n" + "}\n", + true); + ASSERT_EQUALS("[test.cpp:3]: (warning) The lock is ineffective because the mutex is locked at the same scope as the mutex itself.\n", errout.str()); + check("void g();\n" "void f() {\n" " static std::mutex m;\n"