Fix #10682 Unused QString / #10686 unused std::array / #10005 unused variable with c++11 braced initializer not detected (#3684)

This commit is contained in:
chrchr-github 2022-01-10 07:36:49 +01:00 committed by GitHub
parent 4ef20f8f1e
commit df3da38483
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 3 deletions

View File

@ -1035,7 +1035,6 @@ bool ProjectFile::write(const QString &filename)
for (const QString &tag: tags) { for (const QString &tag: tags) {
xmlWriter.writeStartElement(CppcheckXml::TagWarningsElementName); xmlWriter.writeStartElement(CppcheckXml::TagWarningsElementName);
xmlWriter.writeAttribute(CppcheckXml::TagAttributeName, tag); xmlWriter.writeAttribute(CppcheckXml::TagAttributeName, tag);
QStringList warnings;
for (const auto& wt: mWarningTags) { for (const auto& wt: mWarningTags) {
if (wt.second == tag) { if (wt.second == tag) {
xmlWriter.writeStartElement(CppcheckXml::WarningElementName); xmlWriter.writeStartElement(CppcheckXml::WarningElementName);

View File

@ -709,6 +709,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
else if (mTokenizer->isC() || else if (mTokenizer->isC() ||
i->typeEndToken()->isStandardType() || i->typeEndToken()->isStandardType() ||
isRecordTypeWithoutSideEffects(i->type()) || isRecordTypeWithoutSideEffects(i->type()) ||
mSettings->library.detectContainer(i->typeStartToken(), /*iterator*/ false) ||
(i->isStlType() && (i->isStlType() &&
!Token::Match(i->typeStartToken()->tokAt(2), "lock_guard|unique_lock|shared_ptr|unique_ptr|auto_ptr|shared_lock"))) !Token::Match(i->typeStartToken()->tokAt(2), "lock_guard|unique_lock|shared_ptr|unique_ptr|auto_ptr|shared_lock")))
type = Variables::standard; type = Variables::standard;
@ -728,7 +729,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
break; break;
} }
} }
if (i->isArray() && i->isClass()) // Array of class/struct members. Initialized by ctor. if (i->isArray() && i->isClass() && // Array of class/struct members. Initialized by ctor except for std::array
!(i->isStlType() && i->valueType() && i->valueType()->containerTypeToken && i->valueType()->containerTypeToken->isStandardType()))
variables.write(i->declarationId(), i->nameToken()); variables.write(i->declarationId(), i->nameToken());
if (i->isArray() && Token::Match(i->nameToken(), "%name% [ %var% ]")) // Array index variable read. if (i->isArray() && Token::Match(i->nameToken(), "%name% [ %var% ]")) // Array index variable read.
variables.read(i->nameToken()->tokAt(2)->varId(), i->nameToken()); variables.read(i->nameToken()->tokAt(2)->varId(), i->nameToken());
@ -1176,7 +1178,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
} }
// not assignment/initialization/increment => continue // not assignment/initialization/increment => continue
const bool isAssignment = tok->isAssignmentOp() && tok->astOperand1(); const bool isAssignment = tok->isAssignmentOp() && tok->astOperand1();
const bool isInitialization = (Token::Match(tok, "%var% (") && tok->variable() && tok->variable()->nameToken() == tok); const bool isInitialization = (Token::Match(tok, "%var% (|{") && tok->variable() && tok->variable()->nameToken() == tok);
const bool isIncrementOrDecrement = (tok->tokType() == Token::Type::eIncDecOp); const bool isIncrementOrDecrement = (tok->tokType() == Token::Type::eIncDecOp);
if (!isAssignment && !isInitialization && !isIncrementOrDecrement) if (!isAssignment && !isInitialization && !isIncrementOrDecrement)
continue; continue;

View File

@ -49,6 +49,12 @@ QString::iterator QString3()
return it; return it;
} }
void QString4()
{
// cppcheck-suppress unusedVariable
QString qs;
}
void QByteArray1(QByteArray byteArrayArg) void QByteArray1(QByteArray byteArrayArg)
{ {
for (int i = 0; i <= byteArrayArg.size(); ++i) { for (int i = 0; i <= byteArrayArg.size(); ++i) {
@ -136,6 +142,7 @@ QList<int>::iterator QList3()
void QLinkedList1() void QLinkedList1()
{ {
// cppcheck-suppress unreadVariable
QLinkedList<QString> qstringLinkedList1{"one", "two"}; QLinkedList<QString> qstringLinkedList1{"one", "two"};
QLinkedList<QString> qstringLinkedList2 = {"one", "two"}; QLinkedList<QString> qstringLinkedList2 = {"one", "two"};

View File

@ -5230,6 +5230,16 @@ private:
" return s;\n" " return s;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n"
" std::string s(\"foo\");\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void f() {\n"
" std::string s{ \"foo\" };\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
} }
void localvarstring2() { // ticket #2929 void localvarstring2() { // ticket #2929
@ -5627,6 +5637,11 @@ private:
" std::array<int, ArraySize> X; X.dostuff();\n" " std::array<int, ArraySize> X; X.dostuff();\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n" // #10686
" std::array<int, 1> a;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: a\n", errout.str());
} }
void localvarFuncPtr() { void localvarFuncPtr() {