Fix #10083 FN unusedScopedObject: temporary lock 'std::lock_guard<std::mutex>(m)' (#4522)

* Fix #10083 FN unusedScopedObject: temporary lock 'std::lock_guard<std::mutex>(m)'

* Format

* Fix cppcheck-cfg.rng

* Format
This commit is contained in:
chrchr-github 2022-09-30 07:25:33 +02:00 committed by GitHub
parent 40b5521bf0
commit 4d13266e99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 28 additions and 16 deletions

View File

@ -551,6 +551,9 @@
<element name="suppress">
<ref name="DATA-EXTNAME"/>
</element>
<element name="checkFiniteLifetime">
<ref name="DATA-EXTNAME"/>
</element>
</choice>
</zeroOrMore>
</element>

View File

@ -8664,16 +8664,16 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
<smart-pointer class-name="std::weak_ptr"/>
<type-checks>
<unusedvar>
<suppress>std::insert_iterator</suppress>
<suppress>std::lock_guard</suppress>
<suppress>std::unique_lock</suppress>
<suppress>std::shared_lock</suppress>
<suppress>std::fstream</suppress>
<suppress>std::wfstream</suppress>
<suppress>std::ofstream</suppress>
<suppress>std::wofstream</suppress>
<suppress>std::basic_fstream</suppress>
<suppress>std::basic_ofstream</suppress>
<checkFiniteLifetime>std::insert_iterator</checkFiniteLifetime>
<checkFiniteLifetime>std::lock_guard</checkFiniteLifetime>
<checkFiniteLifetime>std::unique_lock</checkFiniteLifetime>
<checkFiniteLifetime>std::shared_lock</checkFiniteLifetime>
<check>std::pair</check>
<check>std::exception</check>
<check>std::logic_error</check>

View File

@ -2077,7 +2077,7 @@ void CheckOther::checkMisusedScopedObject()
const Token* endTok = tok;
if (Token::Match(endTok, "%name% <"))
endTok = endTok->linkAt(1);
if (Token::Match(endTok, "%name%|> (|{") && Token::Match(endTok->linkAt(1), ")|} ; !!}") &&
if (Token::Match(endTok, "%name%|> (|{") && Token::Match(endTok->linkAt(1), ")|} ;") &&
!Token::simpleMatch(endTok->next()->astParent(), ";")) { // for loop condition
return tok;
}
@ -2085,7 +2085,8 @@ void CheckOther::checkMisusedScopedObject()
};
auto isLibraryConstructor = [&](const Token* tok, const std::string& typeStr) -> bool {
if (mSettings->library.getTypeCheck("unusedvar", typeStr) == Library::TypeCheck::check)
const Library::TypeCheck typeCheck = mSettings->library.getTypeCheck("unusedvar", typeStr);
if (typeCheck == Library::TypeCheck::check || typeCheck == Library::TypeCheck::checkFiniteLifetime)
return true;
return mSettings->library.detectContainerOrIterator(tok);
};

View File

@ -1268,6 +1268,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
case Library::TypeCheck::check:
break;
case Library::TypeCheck::suppress:
case Library::TypeCheck::checkFiniteLifetime:
continue;
}
}
@ -1365,6 +1366,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
case Library::TypeCheck::check:
break;
case Library::TypeCheck::suppress:
case Library::TypeCheck::checkFiniteLifetime:
error = false;
}
}

View File

@ -553,6 +553,8 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc)
mTypeChecks[std::pair<std::string,std::string>(checkName, typeName)] = TypeCheck::check;
else if (checkTypeName == "suppress")
mTypeChecks[std::pair<std::string,std::string>(checkName, typeName)] = TypeCheck::suppress;
else if (checkTypeName == "checkFiniteLifetime")
mTypeChecks[std::pair<std::string,std::string>(checkName, typeName)] = TypeCheck::checkFiniteLifetime;
}
}
}

View File

@ -554,7 +554,11 @@ public:
static bool isContainerYield(const Token * const cond, Library::Container::Yield y, const std::string& fallback=emptyString);
/** Suppress/check a type */
enum class TypeCheck { def, check, suppress };
enum class TypeCheck { def,
check,
suppress,
checkFiniteLifetime, // (unusedvar) object has side effects, but immediate destruction is wrong
};
TypeCheck getTypeCheck(std::string check, std::string typeName) const;
private:

View File

@ -138,7 +138,6 @@ private:
TEST_CASE(testMisusedScopeObjectDoesNotPickPureC);
TEST_CASE(testMisusedScopeObjectDoesNotPickNestedClass);
TEST_CASE(testMisusedScopeObjectInConstructor);
TEST_CASE(testMisusedScopeObjectNoCodeAfter);
TEST_CASE(testMisusedScopeObjectStandardType);
TEST_CASE(testMisusedScopeObjectNamespace);
TEST_CASE(trac2071);
@ -5044,14 +5043,6 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (style) Instance of 'Foo' object is destroyed immediately.\n", errout.str());
}
void testMisusedScopeObjectNoCodeAfter() {
check("class Foo {};\n"
"void f() {\n"
" Foo();\n" // No code after class => don't warn
"}", "test.cpp");
ASSERT_EQUALS("", errout.str());
}
void testMisusedScopeObjectStandardType() {
check("int g();\n"
"void f(int i) {\n"
@ -5111,6 +5102,15 @@ private:
"[test.cpp:3]: (style) Instance of 'std::string' object is destroyed immediately.\n"
"[test.cpp:4]: (style) Instance of 'std::pair' object is destroyed immediately.\n",
errout.str());
check("struct S {\n" // #10083
" void f() {\n"
" std::lock_guard<std::mutex>(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",
errout.str());
}
void trac2084() {