Handle FPs: mutexes being locked at different scopes
This commit is contained in:
parent
7d9220e96c
commit
caabe56f14
|
@ -2430,19 +2430,28 @@ void CheckStl::localMutexError(const Token* tok)
|
||||||
void CheckStl::checkMutexes()
|
void CheckStl::checkMutexes()
|
||||||
{
|
{
|
||||||
for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) {
|
for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) {
|
||||||
|
std::set<nonneg int> checkedVars;
|
||||||
for (const Token *tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) {
|
for (const Token *tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) {
|
||||||
|
if (!Token::Match(tok, "%var%"))
|
||||||
|
continue;
|
||||||
const Variable* var = tok->variable();
|
const Variable* var = tok->variable();
|
||||||
if (!var)
|
if (!var)
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok, "%var% . lock ( )")) {
|
if (Token::Match(tok, "%var% . lock ( )")) {
|
||||||
if (!isMutex(var))
|
if (!isMutex(var))
|
||||||
continue;
|
continue;
|
||||||
|
if (!checkedVars.insert(var->declarationId()).second)
|
||||||
|
continue;
|
||||||
if (isLocalMutex(var, tok->scope()))
|
if (isLocalMutex(var, tok->scope()))
|
||||||
localMutexError(tok);
|
localMutexError(tok);
|
||||||
} else if (Token::Match(tok, "%var% (|{ %var% )|}|,")) {
|
} else if (Token::Match(tok, "%var% (|{ %var% )|}|,")) {
|
||||||
if (!isLockGuard(var))
|
if (!isLockGuard(var))
|
||||||
continue;
|
continue;
|
||||||
const Variable* mvar = tok->tokAt(2)->variable();
|
const Variable* mvar = tok->tokAt(2)->variable();
|
||||||
|
if (!mvar)
|
||||||
|
continue;
|
||||||
|
if (!checkedVars.insert(mvar->declarationId()).second)
|
||||||
|
continue;
|
||||||
if (var->isStatic() || var->isGlobal())
|
if (var->isStatic() || var->isGlobal())
|
||||||
globalLockGuardError(tok);
|
globalLockGuardError(tok);
|
||||||
else if (isLocalMutex(mvar, tok->scope()))
|
else if (isLocalMutex(mvar, tok->scope()))
|
||||||
|
|
|
@ -4554,6 +4554,36 @@ private:
|
||||||
"}\n",
|
"}\n",
|
||||||
true);
|
true);
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (warning) The lock is ineffective because the mutex is locked at the same scope as the mutex itself.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (warning) The lock is ineffective because the mutex is locked at the same scope as the mutex itself.\n", errout.str());
|
||||||
|
|
||||||
|
check("void foo();\n"
|
||||||
|
"void bar();\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" std::mutex m;\n"
|
||||||
|
" std::thread t([&m](){\n"
|
||||||
|
" m.lock();\n"
|
||||||
|
" foo();\n"
|
||||||
|
" m.unlock();\n"
|
||||||
|
" });\n"
|
||||||
|
" m.lock();\n"
|
||||||
|
" bar();\n"
|
||||||
|
" m.unlock();\n"
|
||||||
|
"}\n",
|
||||||
|
true);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void foo();\n"
|
||||||
|
"void bar();\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" std::mutex m;\n"
|
||||||
|
" std::thread t([&m](){\n"
|
||||||
|
" std::unique_lock<std::mutex> g{m};\n"
|
||||||
|
" foo();\n"
|
||||||
|
" });\n"
|
||||||
|
" std::unique_lock<std::mutex> g{m};\n"
|
||||||
|
" bar();\n"
|
||||||
|
"}\n",
|
||||||
|
true);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue