diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index 528c825a7..983500bda 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -1035,7 +1035,6 @@ bool ProjectFile::write(const QString &filename) for (const QString &tag: tags) { xmlWriter.writeStartElement(CppcheckXml::TagWarningsElementName); xmlWriter.writeAttribute(CppcheckXml::TagAttributeName, tag); - QStringList warnings; for (const auto& wt: mWarningTags) { if (wt.second == tag) { xmlWriter.writeStartElement(CppcheckXml::WarningElementName); diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 282d16a9c..a68a94eec 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -709,6 +709,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const else if (mTokenizer->isC() || i->typeEndToken()->isStandardType() || isRecordTypeWithoutSideEffects(i->type()) || + mSettings->library.detectContainer(i->typeStartToken(), /*iterator*/ false) || (i->isStlType() && !Token::Match(i->typeStartToken()->tokAt(2), "lock_guard|unique_lock|shared_ptr|unique_ptr|auto_ptr|shared_lock"))) type = Variables::standard; @@ -728,7 +729,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const 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()); if (i->isArray() && Token::Match(i->nameToken(), "%name% [ %var% ]")) // Array index variable read. variables.read(i->nameToken()->tokAt(2)->varId(), i->nameToken()); @@ -1176,7 +1178,7 @@ void CheckUnusedVar::checkFunctionVariableUsage() } // not assignment/initialization/increment => continue 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); if (!isAssignment && !isInitialization && !isIncrementOrDecrement) continue; diff --git a/test/cfg/qt.cpp b/test/cfg/qt.cpp index f8c38765b..45885eb70 100644 --- a/test/cfg/qt.cpp +++ b/test/cfg/qt.cpp @@ -49,6 +49,12 @@ QString::iterator QString3() return it; } +void QString4() +{ + // cppcheck-suppress unusedVariable + QString qs; +} + void QByteArray1(QByteArray byteArrayArg) { for (int i = 0; i <= byteArrayArg.size(); ++i) { @@ -136,6 +142,7 @@ QList::iterator QList3() void QLinkedList1() { + // cppcheck-suppress unreadVariable QLinkedList qstringLinkedList1{"one", "two"}; QLinkedList qstringLinkedList2 = {"one", "two"}; diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index bb6e5230b..5b2ad0751 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -5230,6 +5230,16 @@ private: " return s;\n" "}"); 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 @@ -5627,6 +5637,11 @@ private: " std::array X; X.dostuff();\n" "}"); ASSERT_EQUALS("", errout.str()); + + functionVariableUsage("void f() {\n" // #10686 + " std::array a;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: a\n", errout.str()); } void localvarFuncPtr() {