From 01fd500d7ce9664d31a22c377c8160ee85b4577f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 14 Apr 2026 15:24:07 +0200 Subject: [PATCH 001/493] Fix #14643, #10965, #11704: false positive: unreadVariable for constructors with unknown side effects (#8420) --- lib/checkunusedvar.cpp | 8 ++++++++ test/testunusedvar.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index e4ea2625624..9e39e52b0ea 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1359,6 +1359,14 @@ void CheckUnusedVar::checkFunctionVariableUsage() if (tok->previous() && tok->previous()->variable() && tok->previous()->variable()->nameToken()->scope()->type == ScopeType::eUnion) continue; + if (expr->valueType() && + expr->valueType()->type == ValueType::RECORD && + !expr->valueType()->pointer && + expr->valueType()->typeScope && + expr->valueType()->typeScope->definedType && + !symbolDatabase->isRecordTypeWithoutSideEffects(expr->valueType()->typeScope->definedType)) + continue; + FwdAnalysis fwdAnalysis(*mSettings); const Token* scopeEnd = ValueFlow::getEndOfExprScope(expr, scope, /*smallest*/ false); if (fwdAnalysis.unusedValue(expr, start, scopeEnd)) { diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 0a29731e085..1b81618eff0 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -6681,6 +6681,34 @@ class TestUnusedVar : public TestFixture { " C c(12);\n" "}"); ASSERT_EQUALS("", errout_str()); + + // #14643 + functionVariableUsage("class S { S(int); };\n" + "void f() { S s = 0; }\n"); + ASSERT_EQUALS("", errout_str()); + + // #10965 + functionVariableUsage("class A {\n" + "public:\n" + " A();\n" + "};\n" + "extern A cb();\n" + "void f() { const A c = cb(); }\n"); + ASSERT_EQUALS("", errout_str()); + + // #11704 + functionVariableUsage("class S {\n" + "public:\n" + " S();\n" + "};\n" + "class C {\n" + " S &s();\n" + " void f() {\n" + " const S s1 = s(); // warning\n" + " const S s2; // no warning\n" + " }\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); } void localVarSmartPtr() { From 085cc68f96bb39f1e034338ceae9661505604fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 14 Apr 2026 15:27:32 +0200 Subject: [PATCH 002/493] Fix #14535: false positive: unreadVariable (array access after pointer cast) (#8324) --- lib/astutils.cpp | 32 +++++++++++++++++++------------- test/testunusedvar.cpp | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index ac9795a8ff1..2a4de18b2c0 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3696,21 +3696,27 @@ bool isGlobalData(const Token *expr) globalData = true; return ChildrenToVisit::none; } - if (Token::Match(tok, "[*[]") && tok->astOperand1() && tok->astOperand1()->variable()) { + if (Token::Match(tok, "[*[]") && tok->astOperand1()) { // TODO check if pointer points at local data - const Variable *lhsvar = tok->astOperand1()->variable(); - const ValueType *lhstype = tok->astOperand1()->valueType(); - if (lhsvar->isPointer() || !lhstype || lhstype->type == ValueType::Type::ITERATOR) { - globalData = true; - return ChildrenToVisit::none; - } - if (lhsvar->isArgument() && lhsvar->isArray()) { - globalData = true; - return ChildrenToVisit::none; + const Token *lhs = tok->astOperand1(); + if (lhs->isCast()) { + lhs = lhs->astOperand2() ? lhs->astOperand2() : lhs->astOperand1(); } - if (lhsvar->isArgument() && lhstype->type <= ValueType::Type::VOID && !lhstype->container) { - globalData = true; - return ChildrenToVisit::none; + if (lhs && lhs->variable()) { + const Variable *lhsvar = lhs->variable(); + const ValueType *lhstype = lhs->valueType(); + if (lhsvar->isPointer() || !lhstype || lhstype->type == ValueType::Type::ITERATOR) { + globalData = true; + return ChildrenToVisit::none; + } + if (lhsvar->isArgument() && lhsvar->isArray()) { + globalData = true; + return ChildrenToVisit::none; + } + if (lhsvar->isArgument() && lhstype->type <= ValueType::Type::VOID && !lhstype->container) { + globalData = true; + return ChildrenToVisit::none; + } } } if (tok->varId() == 0 && tok->isName() && tok->strAt(-1) != ".") { diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 1b81618eff0..dd017b6dcf0 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -271,6 +271,9 @@ class TestUnusedVar : public TestFixture { TEST_CASE(globalData); TEST_CASE(structuredBinding); // #13269 + + TEST_CASE(pointerCast1); // #14535 + TEST_CASE(pointerCast2); } struct FunctionVariableUsageOptions @@ -7359,6 +7362,24 @@ class TestUnusedVar : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); } + + void pointerCast1() { // #14535 + functionVariableUsage("void f(int* p)\n" + "{\n" + " int* p2 = p;\n" + " ((int *)(p2))[0] = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + + void pointerCast2() { + functionVariableUsage("void f(int* p)\n" + "{\n" + " int* p2 = p;\n" + " static_cast(p2)[0] = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } }; REGISTER_TEST(TestUnusedVar) From 30cdc637318cc08a1357457be2f40f99e8f8ed89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 14 Apr 2026 15:29:31 +0200 Subject: [PATCH 003/493] Fix #14539: false positive: constParameterPointer with type alias (#8310) --- lib/tokenize.cpp | 3 +++ test/testother.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8e76ff6a422..40dbdf88f9d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3013,6 +3013,9 @@ bool Tokenizer::simplifyUsing() if (!usingEnd) continue; + for (Token *typeTok = start; typeTok != usingEnd; typeTok = typeTok->next()) + typeTok->isSimplifiedTypedef(true); + // Move struct defined in using out of using. // using T = struct t { }; => struct t { }; using T = struct t; // fixme: this doesn't handle attributes diff --git a/test/testother.cpp b/test/testother.cpp index 22ee7ba63f9..bac5dfbdf7f 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4789,6 +4789,12 @@ class TestOther : public TestFixture { " return h(s ? s->gnc() : 1);\n" "}\n"); ASSERT_EQUALS("[test.cpp:5:11]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n", errout_str()); + + check("using IntPtr = int *;\n" + "int* foo(IntPtr bar) {\n" + " return bar = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void constArray() { From 69d89c5dc8a842d76320ad835cf6f6a8182c69f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 16 Apr 2026 09:51:48 +0200 Subject: [PATCH 004/493] Fix #14671 (GUI: add --include option to project file dialog) (#8454) --- .github/workflows/selfcheck.yml | 2 +- gui/mainwindow.cpp | 2 + gui/projectfile.cpp | 22 +++++++---- gui/projectfile.h | 11 ++++++ gui/projectfile.ui | 68 +++++++++++++++++++++++---------- gui/projectfiledialog.cpp | 18 +++++++++ gui/projectfiledialog.h | 5 +++ lib/importproject.cpp | 5 +++ lib/importproject.h | 1 + test/testimportproject.cpp | 3 ++ 10 files changed, 108 insertions(+), 29 deletions(-) diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 1adcc540cf9..389e39371ba 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -121,7 +121,7 @@ jobs: - name: Self check (unusedFunction / no test / no gui) run: | - supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1660 --suppress=unusedFunction:lib/importproject.cpp:1684" + supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1665 --suppress=unusedFunction:lib/importproject.cpp:1689" ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs env: DISABLE_VALUEFLOW: 1 diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 161eec381b3..c3ca1672768 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -1126,6 +1126,8 @@ bool MainWindow::getCppcheckSettings(Settings& settings, Suppressions& supprs) for (const QString& undefine : undefines) settings.userUndefs.insert(undefine.toStdString()); + settings.userIncludes.push_back(mProjectFile->getUserInclude().toStdString()); + const QStringList libraries = mProjectFile->getLibraries(); for (const QString& library : libraries) { settings.libraries.emplace_back(library.toStdString()); diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index b807723ceeb..ce2d066fd71 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -63,6 +63,7 @@ void ProjectFile::clear() mIncludeDirs.clear(); mDefines.clear(); mUndefines.clear(); + mUserInclude.clear(); mPaths.clear(); mExcludedPaths.clear(); mLibraries.clear(); @@ -166,6 +167,9 @@ bool ProjectFile::read(const QString &filename) if (xmlReader.name() == QString(CppcheckXml::UndefinesElementName)) readStringList(mUndefines, xmlReader, CppcheckXml::UndefineName); + if (xmlReader.name() == QString(CppcheckXml::UserIncludeElementName)) + mUserInclude = readString(xmlReader); + // Find exclude list from inside project element if (xmlReader.name() == QString(CppcheckXml::ExcludeElementName)) readExcludes(xmlReader); @@ -347,15 +351,13 @@ bool ProjectFile::readBool(QXmlStreamReader &reader) int ProjectFile::readInt(QXmlStreamReader &reader, int defaultValue) { - int ret = defaultValue; do { const QXmlStreamReader::TokenType type = reader.readNext(); switch (type) { case QXmlStreamReader::Characters: - ret = reader.text().toString().toInt(); - FALLTHROUGH; + return reader.text().toString().toInt(); case QXmlStreamReader::EndElement: - return ret; + return defaultValue; // Not handled case QXmlStreamReader::StartElement: case QXmlStreamReader::NoToken: @@ -373,15 +375,13 @@ int ProjectFile::readInt(QXmlStreamReader &reader, int defaultValue) QString ProjectFile::readString(QXmlStreamReader &reader) { - QString ret; do { const QXmlStreamReader::TokenType type = reader.readNext(); switch (type) { case QXmlStreamReader::Characters: - ret = reader.text().toString(); - FALLTHROUGH; + return reader.text().toString(); case QXmlStreamReader::EndElement: - return ret; + return {}; // Not handled case QXmlStreamReader::StartElement: case QXmlStreamReader::NoToken: @@ -910,6 +910,12 @@ bool ProjectFile::write(const QString &filename) xmlWriter.writeEndElement(); } + if (!mUserInclude.isEmpty()) { + xmlWriter.writeStartElement(CppcheckXml::UserIncludeElementName); + xmlWriter.writeCharacters(mUserInclude); + xmlWriter.writeEndElement(); + } + if (!mVsConfigurations.isEmpty()) { writeStringList(xmlWriter, mVsConfigurations, diff --git a/gui/projectfile.h b/gui/projectfile.h index e7f8d342180..f46374b74fa 100644 --- a/gui/projectfile.h +++ b/gui/projectfile.h @@ -141,6 +141,14 @@ class ProjectFile : public QObject { return mUndefines; } + const QString& getUserInclude() const { + return mUserInclude; + } + + void setUserInclude(const QString& userInclude) { + mUserInclude = userInclude; + } + /** * @brief Get list of paths to check. * @return list of paths. @@ -601,6 +609,9 @@ class ProjectFile : public QObject { */ QStringList mUndefines; + /** @brief --include file */ + QString mUserInclude; + /** * @brief List of paths to check. */ diff --git a/gui/projectfile.ui b/gui/projectfile.ui index 4bd01339d83..5543e67910c 100644 --- a/gui/projectfile.ui +++ b/gui/projectfile.ui @@ -7,7 +7,7 @@ 0 0 940 - 701 + 741 @@ -80,7 +80,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -95,7 +95,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -117,7 +117,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -151,7 +151,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -199,7 +199,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -269,7 +269,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -284,7 +284,7 @@ - QAbstractItemView::SelectRows + QAbstractItemView::SelectionBehavior::SelectRows @@ -314,7 +314,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -342,10 +342,38 @@ + + + + + + Include file + + + mEditUserInclude + + + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + + + Browse.. + + + + + - Qt::Vertical + Qt::Orientation::Vertical @@ -552,7 +580,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -586,7 +614,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -701,7 +729,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -744,7 +772,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -769,7 +797,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -856,7 +884,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -919,7 +947,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1018,7 +1046,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -1035,10 +1063,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index d46eb5c3489..82fc0aac7c4 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -235,6 +235,7 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, bool premium, QWi connect(mUI->mBtnBrowseBuildDir, &QPushButton::clicked, this, &ProjectFileDialog::browseBuildDir); connect(mUI->mBtnClearImportProject, &QPushButton::clicked, this, &ProjectFileDialog::clearImportProject); connect(mUI->mBtnBrowseImportProject, &QPushButton::clicked, this, &ProjectFileDialog::browseImportProject); + connect(mUI->mBtnBrowseUserInclude, &QPushButton::clicked, this, &ProjectFileDialog::browseUserInclude); connect(mUI->mBtnAddCheckPath, SIGNAL(clicked()), this, SLOT(addCheckPath())); connect(mUI->mBtnEditCheckPath, &QPushButton::clicked, this, &ProjectFileDialog::editCheckPath); connect(mUI->mBtnRemoveCheckPath, &QPushButton::clicked, this, &ProjectFileDialog::removeCheckPath); @@ -303,6 +304,7 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) setIncludepaths(projectFile->getIncludeDirs()); setDefines(projectFile->getDefines()); setUndefines(projectFile->getUndefines()); + mUI->mEditUserInclude->setText(projectFile->getUserInclude()); setCheckPaths(projectFile->getCheckPaths()); setImportProject(projectFile->getImportProject()); mUI->mChkAllVsConfigs->setChecked(projectFile->getAnalyzeAllVsConfigs()); @@ -481,6 +483,7 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const projectFile->setIncludes(getIncludePaths()); projectFile->setDefines(getDefines()); projectFile->setUndefines(getUndefines()); + projectFile->setUserInclude(mUI->mEditUserInclude->text()); projectFile->setCheckPaths(getCheckPaths()); projectFile->setExcludedPaths(getExcludedPaths()); projectFile->setLibraries(getLibraries()); @@ -643,6 +646,21 @@ void ProjectFileDialog::browseImportProject() } } +void ProjectFileDialog::browseUserInclude() +{ + const QFileInfo inf(mProjectFile->getFilename()); + const QDir &dir = inf.absoluteDir(); + QMap filters; + filters[tr("C/C++ header")] = "*.h"; + filters[tr("All files")] = "*.*"; + QString fileName = QFileDialog::getOpenFileName(this, tr("Include file"), + dir.canonicalPath(), + toFilterString(filters)); + if (!fileName.isEmpty()) { + mUI->mEditUserInclude->setText(dir.relativeFilePath(fileName)); + } +} + QStringList ProjectFileDialog::getProjectConfigurations() const { QStringList configs; diff --git a/gui/projectfiledialog.h b/gui/projectfiledialog.h index 68f62ea83e5..231d1f26ef3 100644 --- a/gui/projectfiledialog.h +++ b/gui/projectfiledialog.h @@ -201,6 +201,11 @@ private slots: */ void browseImportProject(); + /** + * @brief Browse for include file + */ + void browseUserInclude(); + /** * @brief Add new path to check. */ diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 401f1334b81..ac19db922ed 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1484,6 +1484,10 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings &setti else if (strcmp(name, CppcheckXml::UndefinesElementName) == 0) { for (const std::string &u : readXmlStringList(node, "", CppcheckXml::UndefineName, nullptr)) temp.userUndefs.insert(u); + } else if (strcmp(name, CppcheckXml::UserIncludeElementName) == 0) { + const char* i = node->GetText(); + if (i) + temp.userIncludes.emplace_back(i); } else if (strcmp(name, CppcheckXml::ImportProjectElementName) == 0) { const std::string t_str = empty_if_null(node->GetText()); if (!t_str.empty()) @@ -1605,6 +1609,7 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings &setti settings.includePaths = temp.includePaths; // TODO: append instead of overwrite settings.userDefines = temp.userDefines; // TODO: append instead of overwrite settings.userUndefs = temp.userUndefs; // TODO: append instead of overwrite + settings.userIncludes = temp.userIncludes; // TODO: append instead of overwrite for (const std::string &addon : temp.addons) settings.addons.emplace(addon); settings.clang = temp.clang; diff --git a/lib/importproject.h b/lib/importproject.h index 4a6e318c02d..fb724b5b454 100644 --- a/lib/importproject.h +++ b/lib/importproject.h @@ -151,6 +151,7 @@ namespace CppcheckXml { static constexpr char DefineNameAttrib[] = "name"; static constexpr char UndefinesElementName[] = "undefines"; static constexpr char UndefineName[] = "undefine"; + static constexpr char UserIncludeElementName[] = "user-include"; static constexpr char PathsElementName[] = "paths"; static constexpr char PathName[] = "dir"; static constexpr char PathNameAttrib[] = "name"; diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index f7c53f3d3a6..6f8633dbeea 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -482,6 +482,7 @@ class TestImportProject : public TestFixture { " \n" " \n" " \n" + " gcc-macros.h\n" " \n" " \n" " \n" @@ -497,6 +498,8 @@ class TestImportProject : public TestFixture { ASSERT_EQUALS("cli/", project.guiProject.pathNames[0]); ASSERT_EQUALS(1, s.includePaths.size()); ASSERT_EQUALS("lib/", s.includePaths.front()); + ASSERT_EQUALS(1, s.userIncludes.size()); + ASSERT_EQUALS("gcc-macros.h", s.userIncludes.front()); ASSERT_EQUALS(true, s.inlineSuppressions); } From 0589dca56617200936333d381d0d03e6b7463c0f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 16 Apr 2026 20:30:26 +0200 Subject: [PATCH 005/493] Fix #14160 FP unreadVariable for smart pointer (#8452) Co-authored-by: chrchr-github --- lib/checkunusedvar.cpp | 20 +++++++++++++------- test/testunusedvar.cpp | 7 +++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 9e39e52b0ea..04532e1ecb9 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1359,13 +1359,19 @@ void CheckUnusedVar::checkFunctionVariableUsage() if (tok->previous() && tok->previous()->variable() && tok->previous()->variable()->nameToken()->scope()->type == ScopeType::eUnion) continue; - if (expr->valueType() && - expr->valueType()->type == ValueType::RECORD && - !expr->valueType()->pointer && - expr->valueType()->typeScope && - expr->valueType()->typeScope->definedType && - !symbolDatabase->isRecordTypeWithoutSideEffects(expr->valueType()->typeScope->definedType)) - continue; + if (const ValueType *vt = expr->valueType()) { + if (vt->type == ValueType::RECORD && + !vt->pointer && + vt->typeScope && + vt->typeScope->definedType && + !symbolDatabase->isRecordTypeWithoutSideEffects(vt->typeScope->definedType)) + continue; + + if (vt->type == ValueType::SMART_POINTER && + vt->smartPointerType && + !symbolDatabase->isRecordTypeWithoutSideEffects(vt->smartPointerType)) + continue; + } FwdAnalysis fwdAnalysis(*mSettings); const Token* scopeEnd = ValueFlow::getEndOfExprScope(expr, scope, /*smallest*/ false); diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index dd017b6dcf0..9a116bdaa2b 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -6767,6 +6767,13 @@ class TestUnusedVar : public TestFixture { " p = nullptr;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + functionVariableUsage("struct S { S(); };\n" // #14160 + "void f() {\n" + " auto p = std::make_unique();\n" + " auto q = std::make_unique();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } // ticket #3104 - false positive when variable is read with "if (NOT var)" From 975a52dff3aeca98b9b76fe028360294fdcfef4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 17 Apr 2026 00:13:34 +0200 Subject: [PATCH 006/493] refs #11641 - removed snap configuration [skip ci] (#8453) the package is not maintained by us --- snap/gui/cppcheck-gui.desktop | 9 ------ snap/gui/cppcheck-gui.png | Bin 2543 -> 0 bytes snap/snapcraft.yaml | 50 ---------------------------------- 3 files changed, 59 deletions(-) delete mode 100644 snap/gui/cppcheck-gui.desktop delete mode 100644 snap/gui/cppcheck-gui.png delete mode 100644 snap/snapcraft.yaml diff --git a/snap/gui/cppcheck-gui.desktop b/snap/gui/cppcheck-gui.desktop deleted file mode 100644 index bd540376da2..00000000000 --- a/snap/gui/cppcheck-gui.desktop +++ /dev/null @@ -1,9 +0,0 @@ -[Desktop Entry] -Type=Application -Name=Cppcheck -Comment=A tool for static C/C++ code analysis -Exec=cppcheck-gui -Icon=${SNAP}/meta/gui/cppcheck-gui.png -Terminal=true -StartupNotify=true -Categories=Development;Debugger;Qt; diff --git a/snap/gui/cppcheck-gui.png b/snap/gui/cppcheck-gui.png deleted file mode 100644 index 25d7aef5f31c1b84351df253ff310a63274d842c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2543 zcmV?=cpjhPFPyw?>MD+H_#NVdpRgMPkbs+_3Sb*9 zK_D?PxujODJ~Cjyc1cQlMrO|ZNR}`EQ#NltBkR{6Q~y10-d8ed(yMBl7AeT5kvuA%IJ9l1_UAx3%+qYkq88hCO?%h{NnKDgi zGbn8!Cs7>%Q$bh^fz+(oTNW<-&eaJL&Zp9{Obk*ceBLB<a@VC5XOyrOzPDe>?nlAPzU6s_b*(ynr^f|JgG+@?c2`|xDcXn80rz`E`T|6KGO{z zKo~r!M&JojB;Z0wgu2H$D7X6c+oBu18=h8>4t&v~9|9_bk0Im7KjA2Zx^)NY2FJsj zdKfZv=`)Q|=ZhD&^W{wxonEu?hm#*T-- zj0Sasaqy;kLu?Ge$#gE-gmA%TyAd{jcG)I`b2i&qOO4*zjSU-)>&8yO+scnb8_gkh z%n)pigV-@cut7cNNq?|l!MA$HAK>q*1a-S@+<3yUZQDh4yYkTg6ew0}u6f9WD@vX^Z%?N>cjHCT_?6_it@H1rb;-4Jt zJay_@ddIi2QwT?(E)OR=PnhtM-tnc(3L$UaGK?X9G_Y8sj*eXgTJc`eoE(< zO$bM9w(D>6XQypK*l)9)^)F=Q%72`Mz`EgUy0O>b|H`7l($`>N^h-w}OrQQ<>Ka0J z3gJztZlV6WT1Ff zgir}Aj~8?l0@4mui@}@P2g$&KtOy|pN5QD^XZInP^Z#yMzQ>fXut=uT)ir%}2^!gj z(5zXa)UQ7@qY%Pfh0vwT5~)z3joU?)2O;g+&2$n1+s)Dqu7;;I1g!q{NNsP;nuEH% zvk3EG$vp%caR?I;?#q&UJxF9^JTt75ZbL{)dRjO50X(hU`tsK84Ih4&Zts;0`mDFo z8HxnF2+{Bth9el1wZvxMHpsBvf_hKrE(C(o3oF-A22Lv;2cX6qx;5~}aLC5+d zBsPJ|eK_-tLPi+hqX#^$j{42h(xtz;4We=5(fR{-!f9=TI%)M5${cqbM>O13YaE9Z zDq+d&otCVA#FCW{S<)wo4nDUL#z$xg&)*5qQL%t=-c<-{7RI`yCmm!vT%!XtMyHi4 zchGIDhr3F_6-br(mMpzj1z=cy|BWjnCf*3+71V*Fio-8ZJ+Zr&FuYFFA95K}5Q+2^ zjl3%PaSCn)mXxh# z9LL>=hhM7%nxi)oF&|4X8N<*Hx#6yA;2%h?e3nev;CldrCNuDhNj>?a=#7A_-Z%#- zRmqYCxBGVTi|;Z!KfH*7{#*%;fj?^@u0!gzQN6cM0gPQ_44cm(8GfrooW}vAARN9_ z6dneHC`-DH^8Up2P`POrPCN*f@(IepFO>&RLDKmHLlF#5t1v!;x@X5M@GXEz>ln}# zwbDL%7b6sYsW#XLiHfyk==2*sc7b9>7~i2goK}78hvY5Hbb5<#kG@VrEC~rsJ(gck z4}Pg|tkd^u>B{O+V|;l3391+Objmsy7a`?ps1D5Q0A}rAI$qKE{9TBKU#dJl*Y|4s zff>)%Ry?5YWfnEuPFaJo3Ib`;Sy4gar|fc3Zp36D?*#ig0~0nFHHNwKoVn&5gwAj_&Wo`67&$@@>xk4*pTHC_d- z1Na*)5HQsOUqbX!SMqZIo&5Y;EvZ=B==|OJ0Bf049|c}M=#lRu9X+|< Date: Fri, 17 Apr 2026 20:04:55 +0200 Subject: [PATCH 007/493] Fix #11617 FP constParameter with std::begin/end (#8427) Co-authored-by: chrchr-github --- lib/symboldatabase.cpp | 11 +++++++---- test/cfg/std.cpp | 9 ++++++++- test/testsymboldatabase.cpp | 12 ++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 7c125ea002d..9b42b799405 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -8035,10 +8035,13 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to } } //Is iterator fetching function called? - } else if (Token::simpleMatch(tok->astOperand1(), "::") && - tok->astOperand2() && - tok->astOperand2()->isVariable()) { - const auto* const paramVariable = tok->astOperand2()->variable(); + } else if (Token::simpleMatch(tok->astOperand1(), "::") && Token::Match(tok->astOperand2(), "%var%|.|[")) { + const Token* varTok = tok->astOperand2(); + while (Token::simpleMatch(varTok, "[")) + varTok = varTok->astOperand1(); + while (Token::simpleMatch(varTok, ".")) + varTok = varTok->astOperand2(); + const Variable* const paramVariable = varTok ? varTok->variable() : nullptr; if (!paramVariable || !paramVariable->valueType() || !paramVariable->valueType()->container) { diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index ea9ee17fa4f..abe952de075 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -5032,15 +5032,22 @@ struct T_constParameter_std_begin { std::vector v; }; +struct U_constParameter_std_begin { + std::vector v[1][1]; +}; + void f(S_constParameter_std_begin& s) { std::for_each(std::begin(s.a), std::end(s.a), [](int& i) { ++i; }); } -// cppcheck-suppress constParameterReference - FP void f(T_constParameter_std_begin& t) { std::for_each(std::begin(t.v), std::end(t.v), [](int& i) { ++i; }); } +void f(U_constParameter_std_begin& u) { + std::for_each(std::begin(u.v[0][0]), std::end(u.v[0][0]), [](int& i) { ++i; }); +} + void g_constVariable_std_begin(int* p) { *p = 0; } int f_constVariable_std_begin() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 05dd0ab9b8f..8348e0cd44b 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -9969,6 +9969,18 @@ class TestSymbolDatabase : public TestFixture { ASSERT(tok && tok->valueType()); ASSERT_EQUALS("iterator(std :: vector <)", tok->valueType()->str()); } + { + GET_SYMBOL_DB("struct S { std::vector v[1][1]; };\n" + "void f(S& s) {\n" + " auto it = std::begin(s.v[0][0]);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + const Token* tok = tokenizer.tokens(); + tok = Token::findsimplematch(tok, "auto"); + ASSERT(tok && tok->valueType()); + ASSERT_EQUALS("iterator(std :: vector <)", tok->valueType()->str()); + } { GET_SYMBOL_DB("void f(std::vector::iterator beg, std::vector::iterator end) {\n" " auto it = std::find(beg, end, 0);\n" From 79ca30abfea92df74138f960a74e0d546a21a828 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 20 Apr 2026 10:37:27 +0200 Subject: [PATCH 008/493] Partial fix for #10452 FN knownConditionTrueFalse with bool and float (#8438) The bailout was added in https://github.com/danmar/cppcheck/commit/bc3f5554a48a55ecfb8eeb14450f5a45b869bc95 but seems unrelated to that change. Also, we would still warn for e.g. `!b()` or `b() == false`. --------- Co-authored-by: chrchr-github --- gui/statsdialog.cpp | 1 + lib/checkcondition.cpp | 5 ----- test/testcondition.cpp | 9 +++++++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/gui/statsdialog.cpp b/gui/statsdialog.cpp index f16b6cba3b9..d3e15d87ad5 100644 --- a/gui/statsdialog.cpp +++ b/gui/statsdialog.cpp @@ -113,6 +113,7 @@ void StatsDialog::setProject(const ProjectFile* projectFile) if (!statsFile.isEmpty()) { QChartView *chartView = createChart(statsFile, "cppcheck"); mUI->mTabHistory->layout()->addWidget(chartView); + // cppcheck-suppress knownConditionTrueFalse - TODO in getClangAnalyzer() if (projectFile->getClangAnalyzer()) { chartView = createChart(statsFile, CLANG_ANALYZER); mUI->mTabHistory->layout()->addWidget(chartView); diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index cf54c882f34..570575b4682 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1524,11 +1524,6 @@ void CheckCondition::alwaysTrueFalse() } if (!tok->hasKnownIntValue()) continue; - if (Token::Match(tok->previous(), "%name% (") && tok->previous()->function()) { - const Function* f = tok->previous()->function(); - if (f->functionScope && Token::Match(f->functionScope->bodyStart, "{ return true|false ;")) - continue; - } const Token* condition = nullptr; { // is this a condition.. diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 421fa53e2bc..58475896ebe 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4852,6 +4852,15 @@ class TestCondition : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:6:9] -> [test.cpp:9:9]: (warning) Identical condition 'a', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); + + check("bool b() { return false; }\n" // #10452 + "void f() {\n" + " if (b()) {}\n" + " if (!b()) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:10]: (style) Condition 'b()' is always false [knownConditionTrueFalse]\n" + "[test.cpp:4:9]: (style) Condition '!b()' is always true [knownConditionTrueFalse]\n", + errout_str()); } void alwaysTrueSymbolic() From 1721485287557ab749f2899c914e302f4e8cfde0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 20 Apr 2026 17:06:08 +0200 Subject: [PATCH 009/493] Partial fix for #14576: Missing attribute alignas (aligned_storage case) (#8307) --- lib/tokenize.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++ lib/tokenize.h | 5 ++++ test/testtokenize.cpp | 16 +++++++++++++ 3 files changed, 77 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 40dbdf88f9d..ebccfc90687 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6011,6 +6011,9 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) // Link < with > createLinks2(); + // Handle std::aligned_storage<...> + simplifyAlignedStorage(); + // Mark C++ casts markCppCasts(); @@ -10361,6 +10364,8 @@ void Tokenizer::simplifyNamespaceStd() mSettings.library.podtype("std::" + tok->str()) || isStdContainerOrIterator(tok, mSettings)) insert = true; + else if (Token::simpleMatch(tok, "aligned_storage")) + insert = true; if (insert) { tok->previous()->insertToken("std"); @@ -11176,6 +11181,57 @@ void Tokenizer::simplifyNamespaceAliases() } } +void Tokenizer::simplifyAlignedStorage() +{ + if (!isCPP()) + return; + + const Standards::cppstd_t std = mSettings.standards.cpp; + if (std < Standards::CPP11 || std >= Standards::CPP23) + return; + + for (Token *tok = list.front(); tok; tok = tok->next()) { + if (!Token::simpleMatch(tok, "std :: aligned_storage <")) + continue; + + tok = tok->tokAt(3); + const Token *end = tok->link(); + tok = tok->next(); + + if (!tok) + break; + + if (!end) + continue; + + for (; tok != end; tok = tok->next()) { + if (Token::simpleMatch(tok, ",")) { + tok = tok->next(); + break; + } + + if (Token::Match(tok, "(|<")) + tok = tok->link(); + } + + std::string str; + for (; tok != end; tok = tok->next()) { + str += " " + tok->str(); + } + + if (str.empty()) + continue; + + if (!Token::Match(tok, "> :: type %name%")) + continue; + + str = str.substr(1); + + tok = tok->tokAt(3); + tok->addAttributeAlignas(str); + } +} + void Tokenizer::setDirectives(std::list directives) { mDirectives = std::move(directives); diff --git a/lib/tokenize.h b/lib/tokenize.h index 94f08f9f68e..9ee4b29466f 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -528,6 +528,11 @@ class CPPCHECKLIB Tokenizer { */ void simplifyNamespaceAliases(); + /** + * Handle std::aligned_storage<...> + */ + void simplifyAlignedStorage(); + /** * Convert C++17 style nested namespace to older style */ diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index d51f224d7f8..0798983c079 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -292,6 +292,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(attributeAlignasBefore); TEST_CASE(attributeAlignasAfter); + TEST_CASE(simplifyAlignedStorage); TEST_CASE(splitTemplateRightAngleBrackets); @@ -4380,6 +4381,21 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS(var->getAttributeAlignas()[0], "long"); } + void simplifyAlignedStorage() { + const char code[] = "std::aligned_storage::type buffer;"; + const char expected[] = "std :: aligned_storage < sizeof ( long ) , alignof ( long ) > :: type buffer ;"; + + SimpleTokenizer tokenizer(settings2, *this); + ASSERT(tokenizer.tokenize(code)); + + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + + const Token *buffer = Token::findsimplematch(tokenizer.tokens(), "buffer"); + ASSERT(buffer); + ASSERT(buffer->hasAttributeAlignas()); + ASSERT_EQUALS("alignof ( long )", buffer->getAttributeAlignas()[0]); + } + void splitTemplateRightAngleBrackets() { { const char code[] = "; z = x < 0 ? x >> y : x >> y;"; From 2feda0220715f7230f57b54652f5b4cda3aae2c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 21 Apr 2026 16:36:21 +0200 Subject: [PATCH 010/493] Fix #14678 (GUI: Remove option to generate compliance report) (#8470) --- gui/compliancereportdialog.cpp | 246 --------------------------------- gui/compliancereportdialog.h | 53 ------- gui/compliancereportdialog.ui | 104 -------------- gui/gui.pro | 3 - gui/mainwindow.cpp | 30 ---- gui/mainwindow.h | 3 - gui/mainwindow.ui | 1 - gui/projectfile.h | 4 - gui/resultsview.cpp | 11 -- gui/resultsview.h | 5 - 10 files changed, 460 deletions(-) delete mode 100644 gui/compliancereportdialog.cpp delete mode 100644 gui/compliancereportdialog.h delete mode 100644 gui/compliancereportdialog.ui diff --git a/gui/compliancereportdialog.cpp b/gui/compliancereportdialog.cpp deleted file mode 100644 index c61299e6e3c..00000000000 --- a/gui/compliancereportdialog.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "compliancereportdialog.h" - -#include "ui_compliancereportdialog.h" - -#include "errortypes.h" -#include "filelist.h" -#include "filesettings.h" -#include "importproject.h" -#include "projectfile.h" -#include "utils.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void addHeaders(const QString& file1, QSet &allFiles) { - if (allFiles.contains(file1)) - return; - QFile file(file1); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return; - allFiles << file1; - const QRegularExpression re("^#include[ ]*\"([^\">]+)\".*"); - QTextStream in(&file); - QString line = in.readLine(); - while (!in.atEnd()) { - if (line.startsWith("#include")) { - const QRegularExpressionMatch match = re.match(line); - if (match.hasMatch()) { - QString hfile = match.captured(1); - if (file1.contains("/")) - hfile = file1.mid(0,file1.lastIndexOf("/") + 1) + hfile; - addHeaders(hfile, allFiles); - } - } - line = in.readLine(); - } -} - -static std::vector toStdStringList(const QStringList& from) { - std::vector ret; - std::transform(from.cbegin(), from.cend(), std::back_inserter(ret), [](const QString& e) { - return e.toStdString(); - }); - return ret; -} - -ComplianceReportDialog::ComplianceReportDialog(ProjectFile* projectFile, QString resultsFile, QString checkersReport) - : QDialog(nullptr), - mUI(new Ui::ComplianceReportDialog), - mProjectFile(projectFile), - mResultsFile(std::move(resultsFile)), - mCheckersReport(std::move(checkersReport)) -{ - mUI->setupUi(this); - mUI->mEditProjectName->setText(projectFile->getProjectName()); - connect(mUI->buttonBox, &QDialogButtonBox::clicked, this, &ComplianceReportDialog::buttonClicked); - mUI->mCodingStandard->clear(); - if (!projectFile->getCodingStandards().contains("misra-c-2023") && projectFile->getAddons().contains("misra")) - mUI->mCodingStandard->addItem("Misra C 2012"); - for (QString std: projectFile->getCodingStandards()) { - std[0] = std[0].toUpper(); - std = std.replace("-", " ").replace(" c ", " C ").replace(" cpp ", " C++ ").replace(" c++ ", " C++ "); - mUI->mCodingStandard->addItem(std); - } -} - -ComplianceReportDialog::~ComplianceReportDialog() -{ - delete mUI; -} - -void ComplianceReportDialog::buttonClicked(QAbstractButton* button) -{ - switch (mUI->buttonBox->standardButton(button)) { - case QDialogButtonBox::StandardButton::Save: - save(); - break; - case QDialogButtonBox::StandardButton::Close: - close(); - break; - default: - break; - } -} - -void ComplianceReportDialog::save() -{ - const QString std(mUI->mCodingStandard->currentText().toLower().replace(" ", "-")); - - const QString outFile = QFileDialog::getSaveFileName(this, - tr("Compliance report"), - QDir::homePath() + "/" + std + "-compliance-report.html", - tr("HTML files (*.html)")); - if (outFile.isEmpty()) - return; - - close(); - - const QString& projectName = mUI->mEditProjectName->text(); - const QString& projectVersion = mUI->mEditProjectVersion->text(); - const bool files = mUI->mCheckFiles->isChecked(); - - if (projectName != mProjectFile->getProjectName()) { - mProjectFile->setProjectName(projectName); - mProjectFile->write(); - } - - QTemporaryFile tempCheckersReport; - if (tempCheckersReport.open()) { - QTextStream out(&tempCheckersReport); - out << mCheckersReport << "\n"; - tempCheckersReport.close(); - } - - QTemporaryFile tempFiles; - if (files && tempFiles.open()) { - QTextStream out(&tempFiles); - FileList fileList; - fileList.addPathList(mProjectFile->getCheckPaths()); - if (!mProjectFile->getImportProject().isEmpty()) { - QFileInfo inf(mProjectFile->getFilename()); - - QString prjfile; - if (QFileInfo(mProjectFile->getImportProject()).isAbsolute()) - prjfile = mProjectFile->getImportProject(); - else - prjfile = inf.canonicalPath() + '/' + mProjectFile->getImportProject(); - - ImportProject p; - try { - p.import(prjfile.toStdString()); - } catch (InternalError &e) { - QMessageBox msg(QMessageBox::Critical, - tr("Save compliance report"), - tr("Failed to import '%1' (%2), can not show files in compliance report").arg(prjfile).arg(QString::fromStdString(e.errorMessage)), - QMessageBox::Ok, - this); - msg.exec(); - return; - } - - p.ignorePaths(toStdStringList(mProjectFile->getExcludedPaths())); - - QDir dir(inf.absoluteDir()); - for (const FileSettings& fs: p.fileSettings) - fileList.addFile(dir.relativeFilePath(QString::fromStdString(fs.filename()))); - } - - QSet allFiles; - for (const QString &sourcefile: fileList.getFileList()) - addHeaders(sourcefile, allFiles); - for (const QString& fileName: utils::as_const(allFiles)) { - QFile f(fileName); - if (f.open(QFile::ReadOnly)) { - QCryptographicHash hash(QCryptographicHash::Algorithm::Md5); - if (hash.addData(&f)) { - for (auto b: hash.result()) - out << QString::number(static_cast(b),16); - out << " " << fileName << "\n"; - } - } - } - tempFiles.close(); - } - - QStringList suppressions; - for (const auto& suppression: mProjectFile->getSuppressions()) { - if (!suppression.errorId.empty()) - suppressions.append(QString::fromStdString(suppression.errorId)); - } - - QStringList args{"--project-name=" + projectName, - "--project-version=" + projectVersion, - "--output-file=" + outFile, - "--checkers-report=" + tempCheckersReport.fileName()}; - if (!suppressions.isEmpty()) - args << "--suppressions=" + suppressions.join(","); - - args << ("--" + std); - - if (files) - args << "--files=" + tempFiles.fileName(); - args << mResultsFile; - - const QString appPath = QFileInfo(QCoreApplication::applicationFilePath()).canonicalPath(); - - QProcess process; -#ifdef Q_OS_WIN - process.start(appPath + "/compliance-report.exe", args); -#else - process.start(appPath + "/compliance-report", args); -#endif - process.waitForFinished(); - const QString output = process.readAll(); - if (!output.isEmpty()) { - QMessageBox msg(QMessageBox::Critical, - tr("Save compliance report"), - output, - QMessageBox::Ok, - this); - msg.exec(); - } -} diff --git a/gui/compliancereportdialog.h b/gui/compliancereportdialog.h deleted file mode 100644 index c7ef27f1cc5..00000000000 --- a/gui/compliancereportdialog.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef COMPLIANCEREPORTDIALOG_H -#define COMPLIANCEREPORTDIALOG_H - -#include -#include -#include - -namespace Ui { - class ComplianceReportDialog; -} - -class ProjectFile; -class QAbstractButton; - -class ComplianceReportDialog final : public QDialog -{ - Q_OBJECT - -public: - explicit ComplianceReportDialog(ProjectFile* projectFile, QString resultsFile, QString checkersReport); - ~ComplianceReportDialog() final; - -private slots: - void buttonClicked(QAbstractButton* button); - -private: - void save(); - - Ui::ComplianceReportDialog *mUI; - ProjectFile* mProjectFile; - const QString mResultsFile; - const QString mCheckersReport; -}; - -#endif // COMPLIANCEREPORTDIALOG_H diff --git a/gui/compliancereportdialog.ui b/gui/compliancereportdialog.ui deleted file mode 100644 index b756ec7eab5..00000000000 --- a/gui/compliancereportdialog.ui +++ /dev/null @@ -1,104 +0,0 @@ - - - ComplianceReportDialog - - - - 0 - 0 - 403 - 199 - - - - Compliance Report - - - - - - - - Project version - - - - - - - Project name - - - - - - - - - - - - - Coding Standard - - - - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - - - - - - List of files with md5 checksums - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Close|QDialogButtonBox::Save - - - - - - - - diff --git a/gui/gui.pro b/gui/gui.pro index 8706e86c86e..37c70471b9a 100644 --- a/gui/gui.pro +++ b/gui/gui.pro @@ -58,7 +58,6 @@ win32 { RESOURCES = gui.qrc FORMS = about.ui \ applicationdialog.ui \ - compliancereportdialog.ui \ fileview.ui \ helpdialog.ui \ mainwindow.ui \ @@ -138,7 +137,6 @@ HEADERS += aboutdialog.h \ codeeditstyledialog.h \ codeeditor.h \ common.h \ - compliancereportdialog.h \ csvreport.h \ erroritem.h \ filelist.h \ @@ -181,7 +179,6 @@ SOURCES += aboutdialog.cpp \ codeeditstyledialog.cpp \ codeeditor.cpp \ common.cpp \ - compliancereportdialog.cpp \ csvreport.cpp \ erroritem.cpp \ filelist.cpp \ diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index c3ca1672768..8035b6da78b 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -30,7 +30,6 @@ #include "errortypes.h" #include "filelist.h" #include "filesettings.h" -#include "compliancereportdialog.h" #include "fileviewdialog.h" #include "helpdialog.h" #include "importproject.h" @@ -193,7 +192,6 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) : connect(mUI->mActionStop, &QAction::triggered, this, &MainWindow::stopAnalysis); connect(mUI->mActionSave, &QAction::triggered, this, &MainWindow::save); - connect(mUI->mActionComplianceReport, &QAction::triggered, this, &MainWindow::complianceReport); // About menu connect(mUI->mActionAbout, &QAction::triggered, this, &MainWindow::about); @@ -245,8 +243,6 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) : formatAndSetTitle(); } - mUI->mActionComplianceReport->setVisible(isCppcheckPremium()); - enableCheckButtons(true); mUI->mActionPrint->setShortcut(QKeySequence::Print); @@ -1530,10 +1526,6 @@ void MainWindow::enableCheckButtons(bool enable) } mUI->mActionAnalyzeDirectory->setEnabled(enable); - - if (isCppcheckPremium()) { - mUI->mActionComplianceReport->setEnabled(enable && mProjectFile && (mProjectFile->getAddons().contains("misra") || !mProjectFile->getCodingStandards().empty())); - } } void MainWindow::enableResultsButtons() @@ -1707,28 +1699,6 @@ void MainWindow::save() } } -void MainWindow::complianceReport() -{ - if (!mUI->mResults->isSuccess()) { - QMessageBox m(QMessageBox::Critical, - "Cppcheck", - tr("Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors."), - QMessageBox::Ok, - this); - m.exec(); - return; - } - - QTemporaryFile tempResults; - (void)tempResults.open(); // TODO: check result - tempResults.close(); - - mUI->mResults->save(tempResults.fileName(), Report::XMLV2, mCppcheckCfgProductName); - - ComplianceReportDialog dlg(mProjectFile, tempResults.fileName(), mUI->mResults->getStatistics()->getCheckersReport()); - dlg.exec(); -} - void MainWindow::resultsAdded() { enableResultsButtons(); diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 45506f3f6b8..3015a708836 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -176,9 +176,6 @@ public slots: /** @brief Slot to save results */ void save(); - /** @brief Slot to generate compliance report */ - void complianceReport(); - /** @brief Slot to create new project file */ void newProjectFile(); diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index 551874d3225..1f66d1a582a 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -140,7 +140,6 @@ - diff --git a/gui/projectfile.h b/gui/projectfile.h index f46374b74fa..9d3b22d15e4 100644 --- a/gui/projectfile.h +++ b/gui/projectfile.h @@ -189,10 +189,6 @@ class ProjectFile : public QObject { return mPlatform; } - const QString& getProjectName() const { - return mProjectName; - } - void setProjectName(QString projectName) { mProjectName = std::move(projectName); } diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index c6c54a2fd85..698b6e82018 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -134,8 +134,6 @@ void ResultsView::clear(bool results) mUI->mProgress->setFormat("%p%"); mUI->mLabelCriticalErrors->setVisible(false); - - mSuccess = false; } void ResultsView::clear(const QString &filename) @@ -319,7 +317,6 @@ void ResultsView::setCheckSettings(const Settings &settings) void ResultsView::checkingStarted(int count) { - mSuccess = true; mUI->mProgress->setVisible(true); mUI->mProgress->setMaximum(PROGRESS_MAX); mUI->mProgress->setValue(0); @@ -394,8 +391,6 @@ void ResultsView::translate() void ResultsView::readErrorsXml(const QString &filename) { - mSuccess = false; // Don't know if results come from an aborted analysis - const int version = XmlReport::determineVersion(filename); if (version == 0) { QMessageBox msgBox; @@ -545,7 +540,6 @@ void ResultsView::on_mListLog_customContextMenuRequested(const QPoint &pos) void ResultsView::stopAnalysis() { - mSuccess = false; mUI->mLabelCriticalErrors->setText(tr("Analysis was stopped")); mUI->mLabelCriticalErrors->setVisible(true); } @@ -568,10 +562,5 @@ void ResultsView::handleCriticalError(const ErrorItem &item) msg += ". " + tr("Analysis was aborted."); mUI->mLabelCriticalErrors->setText(msg); mUI->mLabelCriticalErrors->setVisible(true); - mSuccess = false; } } - -bool ResultsView::isSuccess() const { - return mSuccess; -} diff --git a/gui/resultsview.h b/gui/resultsview.h index 77b4610145c..9ef74666395 100644 --- a/gui/resultsview.h +++ b/gui/resultsview.h @@ -388,11 +388,6 @@ public slots: Settings* mCheckSettings = nullptr; - /** - * Set to true when checking finish successfully. Set to false whenever analysis starts. - */ - bool mSuccess = false; - /** Critical error ids */ QString mCriticalErrors; From e6807a4ff5b7fbc7fd63219466c5bc0d3dfef43b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 23 Apr 2026 12:01:25 +0200 Subject: [PATCH 011/493] fixed #14675 - provide proper error ID for `simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND` (#8462) --- lib/preprocessor.cpp | 4 +- test/cli/other_test.py | 130 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 9528360906e..273d8df6123 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -997,8 +997,9 @@ static std::string simplecppErrToId(simplecpp::Output::Type type) return "includeNestedTooDeeply"; case simplecpp::Output::FILE_NOT_FOUND: return "missingFile"; - // should never occur case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND: + return "missingIncludeExplicit"; + // should never occur case simplecpp::Output::DUI_ERROR: // handled separately case simplecpp::Output::MISSING_HEADER: @@ -1074,6 +1075,7 @@ void Preprocessor::getErrorMessages(ErrorLogger &errorLogger, const Settings &se preprocessor.error(loc, "message", simplecpp::Output::UNHANDLED_CHAR_ERROR); preprocessor.error(loc, "message", simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY); preprocessor.error(loc, "message", simplecpp::Output::FILE_NOT_FOUND); + preprocessor.error(loc, "message", simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND); preprocessor.invalidSuppression(loc, "message"); } diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 5c06bd07a94..e28a7305ce9 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4427,3 +4427,133 @@ def test_inline_block_suppr_builddir_twice(tmp_path): assert exitcode == 0 assert stdout == '' assert stderr == '' + + +def test_dui_include(tmp_path): + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() {}') + + inc_file = tmp_path / 'inc.h' + with open(inc_file, "w") as f: + f.write( +""" +void f_i() +{ + (void)(*((int*)0)); +} +""") + + args = [ + '-q', + '--template=simple', + f'--include={inc_file}', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + assert stdout == '' + assert stderr.splitlines() == [ + f'{inc_file}:4:14: error: Null pointer dereference: (int*)0 [nullPointer]' + ] + + +def test_dui_include_missing(tmp_path): # #14675 + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() {}') + + args = [ + '-q', + '--template=simple', + '--include=missing.h', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + assert stdout == '' + assert stderr.splitlines() == [ + f"{test_file}:0:0: error: Can not open include file 'missing.h' that is explicitly included. [missingIncludeExplicit]" + ] + + +def test_dui_include_relative(tmp_path): + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() {}') + + inc_file = tmp_path / 'inc.h' + with open(inc_file, "w") as f: + f.write( +""" +void f_i() +{ + (void)(*((int*)0)); +} +""") + + args = [ + '-q', + '--template=simple', + '--include=inc.h', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args, cwd=tmp_path) + assert exitcode == 0 + assert stdout == '' + assert stderr.splitlines() == [ + 'inc.h:4:14: error: Null pointer dereference: (int*)0 [nullPointer]' + ] + + +def test_dui_include_relative_missing(tmp_path): + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() {}') + + inc_file = tmp_path / 'inc.h' + with open(inc_file, "w") as f: + f.write( +""" +void f_i() +{ + (void)(*((int*)0)); +} +""") + + args = [ + '-q', + '--template=simple', + '--include=inc.h', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args,) + assert exitcode == 0 + assert stdout == '' + assert stderr.splitlines() == [ + f"{test_file}:0:0: error: Can not open include file 'inc.h' that is explicitly included. [missingIncludeExplicit]" + ] + + +def test_dui_include_absolute_missing(tmp_path): # #14675 + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() {}') + + args = [ + '-q', + '--template=simple', + '--include=/share/include/missing.h', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + assert stdout == '' + assert stderr.splitlines() == [ + f"{test_file}:0:0: error: Can not open include file '/share/include/missing.h' that is explicitly included. [missingIncludeExplicit]" + ] \ No newline at end of file From 4d12b1da2ef551a9a7a7db0958a6b700a2953dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 23 Apr 2026 14:12:29 +0200 Subject: [PATCH 012/493] Fix #14680: GUI: internalError with empty user includes (#8478) --- gui/mainwindow.cpp | 2 +- gui/projectfile.cpp | 6 ++++++ gui/projectfile.h | 7 ++++++- gui/test/projectfile/testprojectfile.cpp | 9 +++++++++ gui/test/projectfile/testprojectfile.h | 2 ++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 8035b6da78b..ff2b63d3a75 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -1122,7 +1122,7 @@ bool MainWindow::getCppcheckSettings(Settings& settings, Suppressions& supprs) for (const QString& undefine : undefines) settings.userUndefs.insert(undefine.toStdString()); - settings.userIncludes.push_back(mProjectFile->getUserInclude().toStdString()); + mProjectFile->setSettingsUserIncludes(settings); const QStringList libraries = mProjectFile->getLibraries(); for (const QString& library : libraries) { diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index ce2d066fd71..d2b468443fa 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -1078,6 +1078,12 @@ void ProjectFile::writeStringList(QXmlStreamWriter &xmlWriter, const QStringList xmlWriter.writeEndElement(); } +void ProjectFile::setSettingsUserIncludes(Settings &settings) const +{ + if (!mUserInclude.isEmpty()) + settings.userIncludes.push_back(mUserInclude.toStdString()); +} + QStringList ProjectFile::fromNativeSeparators(const QStringList &paths) { QStringList ret; diff --git a/gui/projectfile.h b/gui/projectfile.h index 9d3b22d15e4..0dd68b58453 100644 --- a/gui/projectfile.h +++ b/gui/projectfile.h @@ -146,7 +146,7 @@ class ProjectFile : public QObject { } void setUserInclude(const QString& userInclude) { - mUserInclude = userInclude; + mUserInclude = userInclude.trimmed(); } /** @@ -452,8 +452,13 @@ class ProjectFile : public QObject { /** Get paths where we should glob for certain files (dir="cfg"/"platforms"/etc */ QStringList getSearchPaths(const QString& dir) const; + static QStringList getSearchPaths(const QString& projectPath, const QString& appPath, const QString& datadir, const QString& dir); + /** Set user includes in settings if non-empty */ + void setSettingsUserIncludes(Settings &settings) const; + + protected: /** diff --git a/gui/test/projectfile/testprojectfile.cpp b/gui/test/projectfile/testprojectfile.cpp index b38de056ec3..dbc4cb51659 100644 --- a/gui/test/projectfile/testprojectfile.cpp +++ b/gui/test/projectfile/testprojectfile.cpp @@ -199,5 +199,14 @@ void TestProjectFile::getCheckingSuppressionsStar() const QCOMPARE(projectFile.getCheckingSuppressions()[0].fileName, "*.cpp"); } +void TestProjectFile::emptyUserInclude() const +{ + ProjectFile projectFile; + Settings settings; + projectFile.setUserInclude(" "); + projectFile.setSettingsUserIncludes(settings); + QCOMPARE(settings.userIncludes.size(), 0); +} + QTEST_MAIN(TestProjectFile) diff --git a/gui/test/projectfile/testprojectfile.h b/gui/test/projectfile/testprojectfile.h index 027c7069706..18f38d0eb39 100644 --- a/gui/test/projectfile/testprojectfile.h +++ b/gui/test/projectfile/testprojectfile.h @@ -36,4 +36,6 @@ private slots: void getCheckingSuppressionsRelative() const; void getCheckingSuppressionsAbsolute() const; void getCheckingSuppressionsStar() const; + + void emptyUserInclude() const; }; From 55493d078a3a9cfe911dd44b5a9d3429e7c7df54 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 23 Apr 2026 20:40:00 +0200 Subject: [PATCH 013/493] Fix #13812 value potentially truncated in ValueFlowAnalyzer::evaluteInt() (#8482) --- lib/vf_analyzers.cpp | 4 ++-- test/testvalueflow.cpp | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 58fbe0b6d61..24b1fea3274 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -676,7 +676,7 @@ struct ValueFlowAnalyzer : Analyzer { std::vector evaluateInt(const Token* tok, F getProgramMemory) const { if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) - return {static_cast(v->intvalue)}; + return {v->intvalue}; std::vector result; ProgramMemory pm = getProgramMemory(); if (Token::Match(tok, "&&|%oror%")) { @@ -717,7 +717,7 @@ struct ValueFlowAnalyzer : Analyzer { ProgramMemory pm = pms.get(tok, ctx, getProgramState()); MathLib::bigint out = 0; if (pm.getContainerEmptyValue(tok->exprId(), out)) - return {static_cast(out)}; + return {out}; return {}; } return {}; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 9586e4fdca2..b8b31e8d248 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -320,7 +320,7 @@ class TestValueFlow : public TestFixture { } #define testValueOfX(...) testValueOfX_(__FILE__, __LINE__, __VA_ARGS__) - bool testValueOfX_(const char* file, int line, const char code[], unsigned int linenr, int value, const Settings *s = nullptr) { + bool testValueOfX_(const char* file, int line, const char code[], unsigned int linenr, MathLib::bigint value, const Settings *s = nullptr) { const Settings *settings1 = s ? s : &settings; // Tokenize.. @@ -3973,6 +3973,14 @@ class TestValueFlow : public TestFixture { " return x;\n" "}"; ASSERT_EQUALS(true, testValueOfX(code, 4U, 246)); + + code = "int64_t f() {\n" + " const int64_t val = 1LL << 33;\n" + " int64_t x = val;\n" + " x += val;\n" + " return x;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 5U, 1LL << 34)); } void valueFlowForwardCorrelatedVariables() { From 23cc32e2e6efb7607c426b39d54ec57d7952fb71 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:22:44 +0200 Subject: [PATCH 014/493] Fix #14669 Typedef not simplified: typedef struct T* T; (#8450) Co-authored-by: chrchr-github --- lib/tokenize.cpp | 8 +++++--- test/testsimplifytypedef.cpp | 9 ++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index ebccfc90687..34cb997a636 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1028,10 +1028,12 @@ bool Tokenizer::isFunctionPointer(const Token* tok) { return Token::Match(tok, "%name% ) ("); } -static bool matchCurrentType(const std::string& typeStr, const std::map& types) +static bool matchCurrentType(const Token* tok, std::map& types) { + if (tok->isC()) + return false; return std::any_of(types.begin(), types.end(), [&](const std::pair& element) { - return typeStr == element.second; + return tok->str() == element.second; }); } @@ -1086,7 +1088,7 @@ void Tokenizer::simplifyTypedef() } auto it = typedefs.find(tok->str()); - if (it != typedefs.end() && it->second.canReplace(tok) && !matchCurrentType(tok->str(), inType)) { + if (it != typedefs.end() && it->second.canReplace(tok) && !matchCurrentType(tok, inType)) { std::set r; std::string originalname; while (it != typedefs.end() && r.insert(tok->str()).second) { diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 03ac9b45a9e..092c9e9df75 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -3824,7 +3824,7 @@ class TestSimplifyTypedef : public TestFixture { " explicit S2(int& i) : B(i) {}\n" " };\n" "}\n"; - const char exp[] = "struct S1 { } ; " + const char exp[] = "struct S1 { } ; " // #12623 "namespace N { " "struct B { " "explicit B ( int & i ) ; } ; " @@ -3833,6 +3833,13 @@ class TestSimplifyTypedef : public TestFixture { "} ; " "}"; ASSERT_EQUALS(exp, tok(code)); + + const char code2[] = "typedef stuct T* T;\n" // #14669 + "struct T {\n" + " T p;\n" + "};\n"; + const char exp2[] = "struct T { stuct T * p ; } ;"; + ASSERT_EQUALS(exp2, simplifyTypedefC(code2)); } void simplifyTypedefFunction1() { From 73579fdaa247272812cc0ad1e308bbf6e6ea9dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Apr 2026 21:38:49 +0200 Subject: [PATCH 015/493] Fix format, rendering, typos, syntax, content in manuals. (#8459) - Fix Markdown syntax. - Fix code rendering. - Sync content between manual and manual-premium. (Attempted to take the more recent pieces from each.) - I assume the premium version is supposed to be a trivial extension of the normal version, which should probably be automated by simply appending the extra section and changing the title. - Fix capitalisation of headings. - Fix capitalisation of abbreviations: XML, HTML, JSON, GCC. - Fix capitalisation of Cppcheck in prose. - Remove trailing spaces. - Fix missing commas after "If", "To". - Other English syntax fixes. - "etc" -> "etc." - "...." -> "..." --- man/manual-premium.md | 510 ++++++++++++++++++++++-------------------- man/manual.md | 407 +++++++++++++++++---------------- 2 files changed, 474 insertions(+), 443 deletions(-) diff --git a/man/manual-premium.md b/man/manual-premium.md index 9f2e5992537..8acfb3c0130 100644 --- a/man/manual-premium.md +++ b/man/manual-premium.md @@ -7,8 +7,8 @@ documentclass: report # Introduction -Cppcheck is an analysis tool for C/C++ code. It provides unique code analysis to detect bugs and focuses on detecting -undefined behaviour and dangerous coding constructs. The goal is to detect only real errors in the code, and generate +Cppcheck is an analysis tool for C/C++ code. It provides unique code analysis to detect bugs and focuses on detecting +undefined behaviour and dangerous coding constructs. The goal is to detect only real errors in the code, and generate as few false positives (wrongly reported warnings) as possible. Cppcheck is designed to analyze your C/C++ code even if it has non-standard syntax, as is common in for example embedded projects. @@ -16,7 +16,7 @@ Supported code and platforms: - Cppcheck checks non-standard code that contains various compiler extensions, inline assembly code, etc. - Cppcheck should be compilable by any compiler that supports C++11 or later. -- Cppcheck is cross platform and is used in various posix/windows/etc environments. +- Cppcheck is cross-platform and is used in various posix/windows/etc environments. The checks in Cppcheck are not perfect. There are bugs that should be found, that Cppcheck fails to detect. @@ -29,11 +29,11 @@ The kinds of bugs that you can find with static analysis are: - Coding style There are many bugs that you can not find with static analysis. Static analysis tools do not have human knowledge about -what your program is intended to do. If the output from your program is valid but unexpected then in most cases this is -not detected by static analysis tools. For instance, if your small program writes "Helo" on the screen instead of "Hello" +what your program is intended to do. If the output from your program is valid but unexpected, then in most cases this is +not detected by static analysis tools. For instance, if your small program writes "Helo" on the screen instead of "Hello", it is unlikely that any tool will complain about that. -Static analysis should be used as a complement in your quality assurance. It does not replace any of; +Static analysis should be used as a complement in your quality assurance. It does not replace any of: - Careful design - Testing @@ -69,7 +69,7 @@ Here is some simple code: return 0; } -If you save that into file1.c and execute: +If you save that into `file1.c` and execute: cppcheck file1.c @@ -84,7 +84,7 @@ Normally a program has many source files. Cppcheck can check all source files in cppcheck path -If "path" is a folder, then Cppcheck will recursively check all source files in this folder: +If `path` is a folder, then Cppcheck will recursively check all source files in this folder: Checking path/file1.cpp... 1/2 files checked 50% done @@ -93,21 +93,22 @@ If "path" is a folder, then Cppcheck will recursively check all source files in ### Check files manually or use project file -With Cppcheck you can check files manually by specifying files/paths to check and settings. Or you can use a build +With Cppcheck you can check files manually by specifying files/paths to check and settings. Or you can use a build environment, such as CMake or Visual Studio. -We don't know which approach (project file or manual configuration) will give you the best results. It is recommended -that you try both. It is possible that you will get different results so that to find the largest amount of bugs you +We don't know which approach (project file or manual configuration) will give you the best results. It is recommended +that you try both. It is possible that you will get different results so that to find the largest amount of bugs you need to use both approaches. Later chapters will describe this in more detail. ### Check files matching a given file filter With `--file-filter=` you can configure file filter(s) and then only those files matching the filter will be checked. -You can use `**`, `*` and `?` in the file filter pattern. -`**`: matches zero or more characters, including path separators -`*`: matches zero or more characters, excluding path separators -`?`: matches any single character except path separators +You can use `**`, `*` and `?` in the file filter pattern. + +- `**` matches zero or more characters, including path separators. +- `*` matches zero or more characters, excluding path separators. +- `?` matches any single character except path separators. For example, this command below means that `src/test1.cpp` could be checked, but `src/file2.cpp` and `src/test/file1.cpp` will not be checked: @@ -121,30 +122,33 @@ A common use case for `--file-filter` is to check a project, but only check cert cppcheck --project=compile_commands.json --file-filter=src/*.c Typically a `compile_commands.json` contains absolute paths. However no matter if `compile_commands.json` contains absolute paths or relative paths, the option `--file-filter=src/*.c` would mean that: - * a file with relative path `test1.c` is not checked. - * a file with relative path `src/test2.c` can be checked. - * a file with relative path `src/test3.cpp` is not checked. + +- a file with relative path `test1.c` is not checked. +- a file with relative path `src/test2.c` can be checked. +- a file with relative path `src/test3.cpp` is not checked. ### Ignore files matching a given pattern With `-i ` you can configure filename/directory patterns that should be ignored. -A file that is ignored will not be checked directly (the complete translation unit is skipped). Any header #include'd from a source file which is not ignored is checked indirectly, regardless if the header is ignored. +A file that is ignored will not be checked directly (the complete translation unit is skipped). Any header `#include`'d from a source file which is not ignored is checked indirectly, regardless if the header is ignored. + +> *Note*: If you want to filter out warnings for a header file, then `-i` will not work. Use suppressions instead. -> *Note*: If you want to filter out warnings for a header file then `-i` will not work. Use suppressions instead. +You can use `**`, `*` and `?` in the pattern to specify excluded folders/files. -You can use `**`, `*` and `?` in the pattern to specify excluded folders/files. -`**`: matches zero or more characters, including path separators -`*`: matches zero or more characters, excluding path separators -`?`: matches any single character except path separators +- `**` matches zero or more characters, including path separators. +- `*` matches zero or more characters, excluding path separators. +- `?` matches any single character except path separators. A use case for `-i` is to check a project, but exclude certain files/folders: cppcheck --project=compile_commands.json -itest Typically a `compile_commands.json` contains absolute paths. However no matter if `compile_commands.json` contains absolute paths or relative paths, the option `-itest` would mean that: - * a file with relative path `test1.cpp` can be checked. - * a file with relative path `test/somefile.cpp` is not checked + +- a file with relative path `test1.cpp` can be checked. +- a file with relative path `test/somefile.cpp` is not checked ### Clang parser (experimental) @@ -155,7 +159,7 @@ Install `clang`. Then use Cppcheck option `--clang`. Cppcheck executes clang with the -ast-dump option, imports the output, converts it to Cppcheck's internal format, and then performs standard analysis. -You can also pass a custom Clang executable to the option by using for example `--clang=clang-10`. You can also pass it +You can also pass a custom Clang executable to the option by using for example `--clang=clang-10`. You can also pass it with a path. On Windows it will append the `.exe` extension unless you use a path. ## Severities @@ -176,17 +180,17 @@ stylistic issues, such as unused functions, redundant code, constness, operator **performance** -run time performance suggestions based on common knowledge, though it is not certain any measurable speed difference +run time performance suggestions based on common knowledge, though it is not certain any measurable speed difference will be achieved by fixing these messages. **portability** -portability warnings. Implementation defined behavior. 64-bit portability. Some undefined behavior that probably works +portability warnings. Implementation defined behavior. 64-bit portability. Some undefined behavior that probably works "as you want", etc. **information** -configuration problems, which does not relate to the syntactical correctness, but the used Cppcheck configuration could +configuration problems, which does not relate to the syntactical correctness, but the used Cppcheck configuration could be improved. ## Possible speedup analysis of template code @@ -220,7 +224,7 @@ Cppcheck output: As you can see Cppcheck has instantiated `a` until `a<101>` was reached and then it bails out. -To limit template recursion you can: +To limit template recursion, you can: - add template specialisation - configure Cppcheck, which can be done in the GUI project file dialog @@ -244,7 +248,6 @@ Example code with template specialisation: You can pass `-D__cppcheck__` when checking this code. - # Cppcheck build folder Using a Cppcheck build folder is not mandatory but it is recommended. @@ -278,36 +281,44 @@ You can import and use Cppcheck GUI project files in the command line tool: cppcheck --project=foobar.cppcheck -The Cppcheck GUI has a few options that are not available in the command line directly. To use these options you can import a GUI project file. +The Cppcheck GUI has a few options that are not available in the command line directly. To use these options, you can import a GUI project file. The command line tool usage is kept intentionally simple and the options are therefore limited. -To ignore certain folders in the project you can use `-i`. This will skip the analysis of source files in the `foo` folder. +To ignore certain folders in the project, you can use `-i`. This will skip the analysis of source files in the `foo` folder. cppcheck --project=foobar.cppcheck -ifoo -## CMake +## Compilation database (CMake etc.) -Generate a compile database (a JSON file containing compilation commands for each source file): +Many build systems can generate a compilation database (a JSON file containing compilation commands for each source file). +Example `cmake` command to generate the file: cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . -The file `compile_commands.json` is created in the current folder. Now run Cppcheck like this: +When you have a `compile_commands.json` file, you can run Cppcheck like this: cppcheck --project=compile_commands.json +By default only 1 configuration is checked because that is consistent with the compilation. If you want to check more configurations, you can use `--max-configs` or `--force`. For example: + + cppcheck --project=compile_commands.json --force + To ignore certain folders you can use `-i`. This will skip analysis of source files in the `foo` folder. cppcheck --project=compile_commands.json -ifoo - ## Visual Studio -You can run Cppcheck on individual project files (\*.vcxproj) or on a whole solution (\*.sln) +You can run Cppcheck on individual project files (`*.vcxproj`) or on a whole solution (`*.sln`) or (`*.slnx`). Running Cppcheck on an entire Visual Studio solution: cppcheck --project=foobar.sln +Running Cppcheck on an entire Visual Studio 2026 solution: + + cppcheck --project=foobar.slnx + Running Cppcheck on a Visual Studio project: cppcheck --project=foobar.vcxproj @@ -319,7 +330,7 @@ Limiting on a single configuration: In the `Cppcheck GUI` you have the option to only analyze a single debug configuration. If you want to use this option on the command line, then create a `Cppcheck GUI` project with this activated and then import the GUI project file on the command line. -To ignore certain folders in the project you can use `-i`. This will skip analysis of source files in the `foo` folder. +To ignore certain folders in the project, you can use `-i`. This will skip analysis of source files in the `foo` folder. cppcheck --project=foobar.vcxproj -ifoo @@ -329,25 +340,28 @@ Running Cppcheck on a C++ Builder 6 project: cppcheck --project=foobar.bpr - -To ignore certain folders in the project you can use `-i`. This will skip analysis of source files in the `foo` folder. +To ignore certain folders in the project, you can use `-i`. This will skip analysis of source files in the `foo` folder. cppcheck --project=foobar.bpr -ifoo ## Other -If you can generate a compile database, then it is possible to import that in Cppcheck. +If you generate a compilation database, then it is possible to import that in Cppcheck. -In Linux you can use for instance the `bear` (build ear) utility to generate a compile database from arbitrary build tools: +### Makefile + +In Linux you can convert a Makefile to a `compile_commands.json` using for instance `bear` (build ear) utility: bear -- make -# Preprocessor Settings +If you don't use Linux, there are Python scripts that converts a Makefile into a compilation database. + +# Preprocessor settings -If you use `--project` then Cppcheck will automatically use the preprocessor settings in the imported project file and +If you use `--project`, then Cppcheck will automatically use the preprocessor settings in the imported project file and likely you don't have to configure anything extra. -If you don't use `--project` then a bit of manual preprocessor configuration might be required. However Cppcheck has +If you don't use `--project`, then a bit of manual preprocessor configuration might be required. However Cppcheck has automatic configuration of defines. ## Automatic configuration of preprocessor defines @@ -355,7 +369,7 @@ automatic configuration of defines. Cppcheck automatically test different combinations of preprocessor defines to achieve as high coverage in the analysis as possible. -Here is a file that has 3 bugs (when x,y,z are assigned). +Here is a file that has 3 bugs (when `x`, `y`, `z` are assigned). #ifdef A x=100/0; @@ -386,14 +400,14 @@ Example: cppcheck test.c # only test configuration "-DA" - # No bug is found (#error) + # No bug is found; because C is not defined the #error will cause a preprocessor error cppcheck -DA test.c # only test configuration "-DA -DC" # The first bug is found cppcheck -DA -DC test.c - # The configuration "-DC" is tested + # Test all configurations that does not define "A" # The last bug is found cppcheck -UA test.c @@ -401,20 +415,27 @@ Example: # The two first bugs are found cppcheck --force -DA test.c + # only test 1 valid configuration + # Bug(s) will be found + cppcheck --max-configs=1 test.c + + # test 2 valid configurations with "X" defined. + # Bug(s) will be found + cppcheck --max-configs=2 -DX test.c ## Include paths -To add an include path, use `-I`, followed by the path. +To add an include path, use `-I` followed by the path. -Cppcheck's preprocessor basically handles includes like any other preprocessor. However, while other preprocessors -stop working when they encounter a missing header, Cppcheck will just print an information message and continues +Cppcheck's preprocessor basically handles includes like any other preprocessor. However, while other preprocessors +stop working when they encounter a missing header, Cppcheck will just print an information message and continues parsing the code. -The purpose of this behaviour is that Cppcheck is meant to work without necessarily seeing the entire code. -Actually, it is recommended to not give all include paths. -While it is useful for Cppcheck to see the declaration of a class when checking the implementation of its members, -passing standard library headers is discouraged, because the analysis will not work fully and lead to a longer checking -time. For such cases, .cfg files are the preferred way to provide information about the implementation of functions and +The purpose of this behaviour is that Cppcheck is meant to work without necessarily seeing the entire code. +Actually, it is recommended to not give all include paths. +While it is useful for Cppcheck to see the declaration of a class when checking the implementation of its members, +passing standard library headers is discouraged, because the analysis will not work fully and lead to a longer checking +time. For such cases, `.cfg` files are the preferred way to provide information about the implementation of functions and types to Cppcheck, see below for more information. # Platform @@ -445,7 +466,7 @@ You can also create your own custom platform configuration in a XML file. Here i -# C/C++ Standard +# C/C++ standard Use `--std` on the command line to specify a C/C++ standard. @@ -474,7 +495,7 @@ the GUI, the build dir is configured in the project options. Rechecking code will be much faster. Cppcheck does not analyse unchanged code. The old warnings are loaded from the build dir and reported again. -Whole program analysis does not work when multiple threads are used; unless you use a cppcheck +Whole program analysis does not work when multiple threads are used unless you use a Cppcheck build dir. For instance, the unusedFunction warnings require whole program analysis. # Suppressions @@ -492,12 +513,13 @@ The format for an error suppression is one of: [error id]:[filename2] [error id] -The `error id` is the id that you want to suppress. The id of a warning is shown in brackets in the normal cppcheck text output. +The `error id` is the id that you want to suppress. The id of a warning is shown in brackets in the normal Cppcheck text output. -The `error id` and `filename` patterns may contain `**`, `*` or `?`. -`**`: matches zero or more characters, including path separators -`*`: matches zero or more characters, excluding path separators -`?`: matches any single character except path separators +The `error id` and `filename` patterns may contain `**`, `*` or `?`. + +- `**` matches zero or more characters, including path separators. +- `*` matches zero or more characters, excluding path separators. +- `?` matches any single character except path separators. It is recommended to use forward-slash `/` in the filename pattern as path separator on all operating systems. @@ -539,9 +561,10 @@ You can specify suppressions in a XML file, for example as follows: The `id` and `fileName` patterns may contain `**`, `*` or `?`. -`**`: matches zero or more characters, including path separators -`*`: matches zero or more characters, excluding path separators -`?`: matches any single character except path separators + +- `**` matches zero or more characters, including path separators. +- `*` matches zero or more characters, excluding path separators. +- `?` matches any single character except path separators. The XML format is extensible and may be extended with further attributes in the future. @@ -551,7 +574,7 @@ The usage of the suppressions file is as follows: ## Inline suppressions -Suppressions can also be added directly in the code by adding comments that contain special keywords. +Suppressions can also be added directly in the code by adding comments that contain special keywords. Note that adding comments sacrifices the readability of the code somewhat. This code will normally generate an error message: @@ -576,7 +599,7 @@ You can suppress a warning `aaaa` with: // cppcheck-suppress aaaa -Suppressing multiple ids in one comment by using []: +Suppressing multiple ids in one comment by using `[]`: // cppcheck-suppress [aaaa, bbbb] @@ -607,7 +630,6 @@ Suppressing warnings `aaaa` where macro is used: ... x = MACRO; // <- aaaa warnings are suppressed here - Suppressing multiple ids where macro is used: // cppcheck-suppress-macro [aaaa, bbbb] @@ -636,7 +658,21 @@ Or at the same line as the code: arr[10] = 0; // cppcheck-suppress arrayIndexOutOfBounds } -In this example there are 2 lines with code and 1 suppression comment. The suppression comment only applies to 1 line: `a = b + c;`. +The suppression comment and the line of code may be separated by additional comments or empty lines: + + void f() { + char arr[5]; + + // cppcheck-suppress arrayIndexOutOfBounds + + arr[10] = 0; + + // cppcheck-suppress arrayIndexOutOfBounds + // Set the tenth element of arr to zero + arr[10] = 0; + } + +In the example below there are 2 lines with code and 1 suppression comment. The suppression comment only applies to 1 line: `a = b + c;`. void f() { a = b + c; // cppcheck-suppress abc @@ -683,7 +719,6 @@ Suppression comment on the same line as the code: arr[10] = arr[10] / 0; // cppcheck-suppress[arrayIndexOutOfBounds,zerodiv] } - ### Symbol name You can specify that the inline suppression only applies to a specific symbol: @@ -783,7 +818,7 @@ If you want to reformat the output so that it looks different, then you can use ## Predefined output formats -To get Visual Studio compatible output you can use --template=vs: +To get Visual Studio compatible output, you can use `--template=vs`: cppcheck --template=vs samples/arrayIndexOutOfBounds/bad.c @@ -793,7 +828,7 @@ This output will look like this: samples/arrayIndexOutOfBounds/bad.c(6): error: Array 'a[2]' accessed at index 2, which is out of bounds. -To get gcc compatible output you can use --template=gcc: +To get GCC-compatible output, you can use `--template=gcc`: cppcheck --template=gcc samples/arrayIndexOutOfBounds/bad.c @@ -831,7 +866,7 @@ The output will look like this: samples/arrayIndexOutOfBounds/bad.c,6,error,arrayIndexOutOfBounds, Array 'a[2]' accessed at index 2, which is out of bounds. -## User defined output format (multi line) +## User defined output format (multi-line) Many warnings have multiple locations. Example code: @@ -847,9 +882,9 @@ Many warnings have multiple locations. Example code: return 0; } -There is a possible null pointer dereference at line 3. -Cppcheck can show how it came to that conclusion by showing extra location information. -You need to use both --template and --template-location at the command line, for example: +There is a possible null pointer dereference at line 3. +Cppcheck can show how it came to that conclusion by showing extra location information. +You need to use both `--template` and `--template-location` at the command line, for example: cppcheck \ --template="{file}:{line}: {severity}: {message}\n{code}" \ @@ -871,13 +906,13 @@ The output from Cppcheck is: *p = 3; ^ -The first line in the warning is formatted by the --template format. +The first line in the warning is formatted by the `--template` format. -The other lines in the warning are formatted by the --template-location format. +The other lines in the warning are formatted by the `--template-location` format. -### Format specifiers for --template +### Format specifiers for `--template` -The available specifiers for --template are: +The available specifiers for `--template` are: **{file}** @@ -893,11 +928,11 @@ Column number **{callstack}** -Write all locations. Each location is written in [{file}:{line}] format and the locations are separated by ->. For instance it might look like: [multiline.c:8] -> [multiline.c:9] -> [multiline.c:3] +Write all locations. Each location is written in `[{file}:{line}]` format and the locations are separated by `->`. For instance it might look like: `[multiline.c:8] -> [multiline.c:9] -> [multiline.c:3]` **{inconclusive:text}** -If warning is inconclusive, then the given text is written. The given text can be any text that does not contain }. Example: {inconclusive:inconclusive,} +If warning is inconclusive, then the given text is written. The given text can be any text that does not contain `}`. Example: `{inconclusive:inconclusive,}` **{severity}** @@ -931,7 +966,7 @@ Newline Carriage return -### Format specifiers for --template-location +### Format specifiers for `--template-location` The available specifiers for `--template-location` are: @@ -983,7 +1018,7 @@ Example code: int x = 0; } -In Cppcheck text output the remarks are not shown by default, you can use `--template` option `{remark}` to show remarks: +In Cppcheck text output, the remarks are not shown by default, you can use `--template` option `{remark}` to show remarks: $ ./cppcheck --enable=style \ --template="{file}:{line}: {message} [{id}]\\n{remark}" test1.c @@ -992,12 +1027,12 @@ In Cppcheck text output the remarks are not shown by default, you can use `--tem test1.c:4: Variable 'x' is assigned a value that is never used. [unreadVariable] Initialize x with 0 -In xml output the comment text is provided in a "remark" attribute: +In XML output, the comment text is provided in a `remark` attribute: $ ./cppcheck --enable=style --xml test1.c - .... + ... remark="Initialize x with 0" - .... + ... # Addons @@ -1007,52 +1042,51 @@ Cppcheck is distributed with a few addons which are listed below. ## Supported addons -### namingng.py +### `namingng.py` -[namingng.py](https://github.com/danmar/cppcheck/blob/main/addons/namingng.py) allows you to configure and check naming conventions. +[`namingng.py`](https://github.com/danmar/cppcheck/blob/main/addons/namingng.py) allows you to configure and check naming conventions. You need to have a configuration file that defines your naming conventions. By default the filename `namingng.config.json` is used but there is an option so you can use any filename you want. Example configuration of naming conventions: -``` -{ - "RE_VARNAME": ["[a-z]*[a-zA-Z0-9_]*\\Z"], - "RE_PRIVATE_MEMBER_VARIABLE": null, - "RE_FUNCTIONNAME": ["[a-z0-9A-Z]*\\Z"], - "_comment": "comments can be added to the config with underscore-prefixed keys", - "include_guard": { - "input": "path", - "prefix": "GUARD_", - "case": "upper", - "max_linenr": 5, - "RE_HEADERFILE": "[^/].*\\.h\\Z", - "required": true - }, - "var_prefixes": {"uint32_t": "ui32"}, - "function_prefixes": {"uint16_t": "ui16", - "uint32_t": "ui32"} -} -``` - -### threadsafety.py - -[threadsafety.py](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py) analyses Cppcheck dump files to locate thread safety issues like static local objects used by multiple threads. - -### y2038.py - -[y2038.py](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py) checks source code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. - -## Running Addons + + { + "RE_VARNAME": ["[a-z]*[a-zA-Z0-9_]*\\Z"], + "RE_PRIVATE_MEMBER_VARIABLE": null, + "RE_FUNCTIONNAME": ["[a-z0-9A-Z]*\\Z"], + "_comment": "comments can be added to the config with underscore-prefixed keys", + "include_guard": { + "input": "path", + "prefix": "GUARD_", + "case": "upper", + "max_linenr": 5, + "RE_HEADERFILE": "[^/].*\\.h\\Z", + "required": true + }, + "var_prefixes": {"uint32_t": "ui32"}, + "function_prefixes": {"uint16_t": "ui16", + "uint32_t": "ui32"} + } + +### `threadsafety.py` + +[`threadsafety.py`](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py) analyses Cppcheck dump files to locate thread safety issues like static local objects used by multiple threads. + +### `y2038.py` + +[`y2038.py`](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py) checks source code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. + +## Running addons Addons can be executed with the `--addon` option: cppcheck --addon=namingng.py somefile.c -Likewise, if you have created your own script you can execute that: +Likewise, if you have created your own script, you can execute that: cppcheck --addon=mychecks.py somefile.c -You can configure how you want to execute an addon in a json file. For example: +You can configure how you want to execute an addon in a JSON file. For example: { "script": "mychecks.py", @@ -1062,7 +1096,7 @@ You can configure how you want to execute an addon in a json file. For example: "ctu": false } -To use that json file to execute your addon use the --addon option: +To use that JSON file to execute your addon, use the `--addon` option: cppcheck --addon=mychecks.json somefile.c @@ -1072,75 +1106,74 @@ Cppcheck search for addons in the local folder first and then in the installatio # Library configuration -When external libraries are used, such as WinAPI, POSIX, gtk, Qt, etc, Cppcheck has no information about functions, types, or macros contained in those libraries. Cppcheck then fails to detect various problems in the code, or might even abort the analysis. But this can be fixed by using the appropriate configuration files. - -Cppcheck already contains configurations for several libraries. They can be loaded as described below. Note that the configuration for the standard libraries of C and C++, std.cfg, is always loaded by cppcheck. If you create or update a configuration file for a popular library, we would appreciate if you supplied it to the cppcheck project. - -## Using a .cfg file - -To use a .cfg file shipped with cppcheck, pass the `--library=` option. The table below shows the currently existing libraries: - -| .cfg file | Library | Comment | -| ----------------- | ------------- | ------------- | -| avr.cfg | | | -| bento4.cfg | [Bento4](http://www.bento4.com/) | | -| boost.cfg | [Boost](http://www.boost.org/) | | -| bsd.cfg | [BSD](https://www.freebsd.org/) | | -| cairo.cfg | [cairo](https://www.cairographics.org/) | | -| cppcheck-lib.cfg | [Cppcheck](http://cppcheck.net/) | Used in selfcheck of | -| | |the Cppcheck code base | -| cppunit.cfg | [CppUnit](https://sourceforge.net/projects/cppunit/) | | -| dpdk.cfg | | | -| embedded_sql.cfg | | | -| emscripten.cfg | | | -| ginac.cfg | | | -| gnu.cfg | [GNU](https://www.gnu.org/) | | -| googletest.cfg | [GoogleTest](https://github.com/google/googletest) | | -| gtk.cfg | [GTK](https://www.gtk.org/) | | -| icu.cfg | | | -| kde.cfg | [KDE](https://kde.org/) | | -| libcerror.cfg | [libcerror](https://github.com/libyal/libcerror) | | -| libcurl.cfg | [libcurl](https://curl.se/libcurl/) | | -| libsigc++.cfg | [libsigc++](https://github.com/libsigcplusplus/libsigcplusplus) | | -| lua.cfg | | | -| mfc.cfg | [MFC](https://learn.microsoft.com/en-us/cpp/mfc/mfc-desktop-applications) | | -| microsoft_atl.cfg | [ATL](https://learn.microsoft.com/en-us/cpp/atl/active-template-library-atl-concepts) | | -| microsoft_sal.cfg | [SAL annotations](https://learn.microsoft.com/en-us/cpp/c-runtime-library/sal-annotations) | | -| microsoft_unittest.cfg | [CppUnitTest](https://learn.microsoft.com/en-us/visualstudio/test/microsoft-visualstudio-testtools-cppunittestframework-api-reference) | | -| motif.cfg | | | -| nspr.cfg | | | -| ntl.cfg | | | -| opencv2.cfg | [OpenCV](https://opencv.org/) | | -| opengl.cfg | [OpenGL](https://opengl.org/) | | -| openmp.cfg | [OpenMP](https://www.openmp.org/) | | -| openssl.cfg | [OpenSSL](https://www.openssl.org/) | | -| pcre.cfg | [PCRE](https://pcre.org/) | | -| posix.cfg | [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/) | | -| python.cfg | | | -| qt.cfg | [Qt](https://doc.qt.io/qt.html) | | -| ruby.cfg | | | -| sdl.cfg | | | -| sfml.cfg | | | -| sqlite3.cfg | [SQLite](https://www.sqlite.org/) | | -| std.cfg | C/C++ standard library | Loaded by default | -| tinyxml2.cfg | [TinyXML-2](https://github.com/leethomason/tinyxml2) | | -| vcl.cfg | | | -| windows.cfg | [Win32 API](https://learn.microsoft.com/en-us/windows/win32/) | | -| wxsqlite3.cfg | | | -| wxsvg.cfg | | | -| wxwidgets.cfg | [wxWidgets](https://www.wxwidgets.org/) | | -| zephyr.cfg | | | -| zlib.cfg | [zlib](https://www.zlib.net) | | - -## Creating a custom .cfg file - -You can create and use your own .cfg files for your projects. Use `--check-library` to get hints about what you should configure. +When external libraries are used, such as WinAPI, POSIX, gtk, Qt, etc., Cppcheck has no information about functions, types, or macros contained in those libraries. Cppcheck then fails to detect various problems in the code, or might even abort the analysis. But this can be fixed by using the appropriate configuration files. + +Cppcheck already contains configurations for several libraries. They can be loaded as described below. Note that the configuration for the standard libraries of C and C++, `std.cfg`, is always loaded by Cppcheck. If you create or update a configuration file for a popular library, we would appreciate if you supplied it to the Cppcheck project. + +## Using a `.cfg` file + +To use a `.cfg` file shipped with Cppcheck, pass the `--library=` option. The table below shows the currently existing libraries: + +| `.cfg` file | Library | Comment | +| --- | --- | --- | +| `avr.cfg` | | | +| `bento4.cfg` | [Bento4](http://www.bento4.com/) | | +| `boost.cfg` | [Boost](http://www.boost.org/) | | +| `bsd.cfg` | [BSD](https://www.freebsd.org/) | | +| `cairo.cfg` | [cairo](https://www.cairographics.org/) | | +| `cppcheck-lib.cfg` | [Cppcheck](http://cppcheck.net/) | Used in selfcheck of the Cppcheck code base | +| `cppunit.cfg` | [CppUnit](https://sourceforge.net/projects/cppunit/) | | +| `dpdk.cfg` | | | +| `embedded_sql.cfg` | | | +| `emscripten.cfg` | | | +| `ginac.cfg` | | | +| `gnu.cfg` | [GNU](https://www.gnu.org/) | | +| `googletest.cfg` | [GoogleTest](https://github.com/google/googletest) | | +| `gtk.cfg` | [GTK](https://www.gtk.org/) | | +| `icu.cfg` | | | +| `kde.cfg` | [KDE](https://kde.org/) | | +| `libcerror.cfg` | [libcerror](https://github.com/libyal/libcerror) | | +| `libcurl.cfg` | [libcurl](https://curl.se/libcurl/) | | +| `libsigc++.cfg` | [libsigc++](https://github.com/libsigcplusplus/libsigcplusplus) | | +| `lua.cfg` | | | +| `mfc.cfg` | [MFC](https://learn.microsoft.com/en-us/cpp/mfc/mfc-desktop-applications) | | +| `microsoft_atl.cfg` | [ATL](https://learn.microsoft.com/en-us/cpp/atl/active-template-library-atl-concepts) | | +| `microsoft_sal.cfg` | [SAL annotations](https://learn.microsoft.com/en-us/cpp/c-runtime-library/sal-annotations) | | +| `microsoft_unittest.cfg` | [CppUnitTest](https://learn.microsoft.com/en-us/visualstudio/test/microsoft-visualstudio-testtools-cppunittestframework-api-reference) | | +| `motif.cfg` | | | +| `nspr.cfg` | | | +| `ntl.cfg` | | | +| `opencv2.cfg` | [OpenCV](https://opencv.org/) | | +| `opengl.cfg` | [OpenGL](https://opengl.org/) | | +| `openmp.cfg` | [OpenMP](https://www.openmp.org/) | | +| `openssl.cfg` | [OpenSSL](https://www.openssl.org/) | | +| `pcre.cfg` | [PCRE](https://pcre.org/) | | +| `posix.cfg` | [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/) | | +| `python.cfg` | | | +| `qt.cfg` | [Qt](https://doc.qt.io/qt.html) | | +| `ruby.cfg` | | | +| `sdl.cfg` | | | +| `sfml.cfg` | | | +| `sqlite3.cfg` | [SQLite](https://www.sqlite.org/) | | +| `std.cfg` | C/C++ standard library | Loaded by default | +| `tinyxml2.cfg` | [TinyXML-2](https://github.com/leethomason/tinyxml2) | | +| `vcl.cfg` | | | +| `windows.cfg` | [Win32 API](https://learn.microsoft.com/en-us/windows/win32/) | | +| `wxsqlite3.cfg` | | | +| `wxsvg.cfg` | | | +| `wxwidgets.cfg` | [wxWidgets](https://www.wxwidgets.org/) | | +| `zephyr.cfg` | | | +| `zlib.cfg` | [zlib](https://www.zlib.net) | | + +## Creating a custom `.cfg` file + +You can create and use your own `.cfg` files for your projects. Use `--check-library` to get hints about what you should configure. You can use the `Library Editor` in the `Cppcheck GUI` to edit configuration files. It is available in the `View` menu. -The .cfg file format is documented in the `Reference: Cppcheck .cfg format` (https://cppcheck.sourceforge.io/reference-cfg-format.pdf) document. +The `.cfg` file format is documented in the `Reference: Cppcheck .cfg format` () document. -# HTML Report +# HTML report You can convert the XML output from Cppcheck into a HTML report. You'll need Python and the pygments module () for this to work. In the Cppcheck source tree there is a folder htmlreport that contains a script that transforms a Cppcheck XML file into HTML output. @@ -1170,15 +1203,17 @@ Example usage: cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=. or + cppcheck gui/test.cpp --xml 2> err.xml cppcheck-htmlreport --file=err.xml --report-dir=test1 \ --source-dir=https://github.com///blob// -## Choosing Between Local Annotated HTML and Remote Repository Links +## Choosing between local annotated HTML and remote repository links + +`cppcheck-htmlreport` supports two modes for linking to source files: -cppcheck-htmlreport supports two modes for linking to source files: - - Local annotated HTML files (default when `--source-dir` is a filesystem path) - - Remote GitHub/GitLab links (when `--source-dir` is a URL) +- Local annotated HTML files (default when `--source-dir` is a filesystem path) +- Remote GitHub/GitLab links (when `--source-dir` is a URL) Pointing `--source-dir` to a filesystem path generates local annotated HTML files. This is useful when you need a fully self-contained report that works offline, @@ -1193,13 +1228,13 @@ handled by the hosting service. In general, local mode fits air-gapped environments, while remote mode works best for CI workflows and large or private repositories. -# Check Level +# Check level ## Reduced The "reduced" check level performs a limited data flow analysis. If developers -want to run cppcheck directly during development and require faster results -than "normal" provides then this reduced checking can be an option. +want to run Cppcheck directly during development and require faster results +than "normal" provides, then this reduced checking can be an option. ## Normal @@ -1209,7 +1244,7 @@ The "normal" check level should be useful during active development: - checking files while you edit them. - block changes to the repo -- etc +- etc. ## Exhaustive @@ -1218,7 +1253,7 @@ When you can wait longer for the results you can enable the "exhaustive" checkin Exhaustive checking level should be useful for scenarios where you can wait for results. For instance: - nightly builds -- etc +- etc. # Speeding up analysis @@ -1226,18 +1261,17 @@ Exhaustive checking level should be useful for scenarios where you can wait for For performance reasons it might be a good idea to limit preprocessor configurations to check. -## Limit ValueFlow: max if count +## Limit ValueFlow: max `if` count -The command line option `--performance-valueflow-max-if-count` adjusts the max count for number of if in a function. +The command line option `--performance-valueflow-max-if-count` adjusts the max count for number of `if` in a function. -When that limit is exceeded there is a limitation of data flow in that function. It is not drastic: +When that limit is exceeded, there is a limitation of data flow in that function. It is not drastic: - Analysis of other functions are not affected. - It's only for some specific data flow analysis, we have data flow analysis that is always executed. - All checks are always executed. There can still be plenty of warnings in the limited function. -There is data flow analysis that slows down exponentially when number of if increase. And the limit is intended to avoid that -analysis time explodes. +There is data flow analysis that slows down exponentially when number of `if` increase. And the limit is intended to avoid that analysis time explodes. ## GUI options @@ -1248,13 +1282,13 @@ In the GUI: - Open the project dialog. - In the "Analysis" tab there are several options. -If you want to use these limitations on the command line also you can import the GUI project file with --project. +If you want to use these limitations on the command line too, you can import the GUI project file with `--project`. # Cppcheck Premium ## Bug hunting -This is analysis that is more noisy than normal analysis. Most warnings will be false positives (cppcheck will wrongly claim that there are bugs). The design goal is to not have more than roughly 5 - 10 false positives in each file. +This is analysis that is more noisy than normal analysis. Most warnings will be false positives (Cppcheck will wrongly claim that there are bugs). The design goal is to not have more than roughly 5 to 10 false positives in each file. It is not intended to be used in normal CI or regular static analysis by developers. The noise makes it useless for that. @@ -1262,7 +1296,7 @@ It is intended to be used when you are looking for bugs and you really can accep - You have developed a brand new feature and want to ensure that there are no bugs. - Maybe as part of release testing your product you can run bug hunting on modified files. -- Etc +- Etc. Technically, analysis that is "sound" will detect all bugs. Analysis that is "soundy" has the goal to detect most bugs and it tries to keep the noise at an reasonable level. @@ -1270,41 +1304,41 @@ The Cppcheck bug hunting analysis is "soundy". Command: - cppcheck --premium=bughunting .... + cppcheck --premium=bughunting ... ## Coding standards Command to activate Autosar checkers: - cppcheck --premium=autosar .... + cppcheck --premium=autosar ... Command to activate Cert C checkers: - cppcheck --premium=cert-c .... + cppcheck --premium=cert-c ... Command to activate Cert C++ checkers: - cppcheck --premium=cert-c++ .... + cppcheck --premium=cert-c++ ... Command to activate Misra C 2012 checkers: - cppcheck --premium=misra-c-2012 .... + cppcheck --premium=misra-c-2012 ... Command to activate Misra C 2023 checkers: - cppcheck --premium=misra-c-2023 .... + cppcheck --premium=misra-c-2023 ... Command to activate Misra C 2025 checkers: - cppcheck --premium=misra-c-2025 .... + cppcheck --premium=misra-c-2025 ... Command to activate Misra C++ 2008 checkers: - cppcheck --premium=misra-c++-2008 .... + cppcheck --premium=misra-c++-2008 ... Command to activate Misra C++ 2023 checkers: - cppcheck --premium=misra-c++-2023 .... + cppcheck --premium=misra-c++-2023 ... ### Checking all C and C++ files @@ -1312,7 +1346,7 @@ The `cert-c` and `misra-c-*` coding standards target C and therefore the checker The `autosar`, `cert-c++` and `misra-c++-*` coding standards target C++ and therefore the checkers only check C++ files by default. -If you want to check all files you can append ":all" to the coding standard. Example: +If you want to check all files, you can append `:all` to the coding standard. Example: # Misra C checkers are executed on C files, not on C++ files cppcheck --premium=misra-c-2025 path @@ -1320,7 +1354,6 @@ If you want to check all files you can append ":all" to the coding standard. Exa # Misra C checkers are executed on C and C++ files cppcheck --premium=misra-c-2025:all path - ## Compliance report ### Graphical user interface @@ -1331,7 +1364,7 @@ the `Compliance report...` in the `File` menu. ### Command line There is a tool `compliance-report` that is distributed with Cppcheck Premium. To see -all available options run `compliance-report` in a terminal with no options. +all available options, run `compliance-report` in a terminal with no options. Below is example usage to generate a Misra C 2012 compliance report. @@ -1344,12 +1377,12 @@ Description of the options: - `--misra-c-2012`: Generate a compliance report for misra-c-2012 - `--project-name`: The name of the project - `--project-version`: The version of the project -- `--output-file`: html filename that the report should be written to -- `results.xml`: The xml output from cppcheck +- `--output-file`: HTML filename that the report should be written to +- `results.xml`: The XML output from Cppcheck ## Metrics -To generate metrics add option `--premium=metrics`. The metrics are saved in the xml v3 report. +To generate metrics, add option `--premium=metrics`. The metrics are saved in the XML v3 report. Example: cppcheck --premium=metrics test.c --xml-version=3 2> res.xml @@ -1358,41 +1391,41 @@ We provide a small simple python script that creates a metrics report in CSV for python3 HISReport.py -f res.xml -j path/to/cppcheck-id-mapping.json -o test.csv -the `cppcheck-id-mapping.json` is provided in the cppcheck premium installation folder, i.e. +The `cppcheck-id-mapping.json` is provided in the Cppcheck premium installation folder, i.e. `/opt/cppcheckpremium` or `C:\Program Files\Cppcheck Premium`. -We do not have a ready-made solution to generate a html/pdf report. You can easily tweak our -HISReport.py script so that it generates html and get the report exactly as you want. +We do not have a ready-made solution to generate a HTML/pdf report. You can easily tweak our +`HISReport.py` script so that it generates HTML and get the report exactly as you want. ## Licenses -### Commercial Terms +### Commercial terms Information about Cppcheck Premium licenses: -https://www.cppcheck.com/plans-pricing + -### Installation / Registration +### Installation / registration This is described on the Cppcheck Premium website: -https://www.cppcheck.com + ### License file path There are predefined paths where the premium addon search for license files. If you want to -provide an arbitrary license file path on the command line you can use the option +provide an arbitrary license file path on the command line, you can use the option `--premium-license-file`. Example: cppcheck --premium-license-file=path/to/file.lic test.cpp -If an explicit path is provided like this then premium addon does not search for license +If an explicit path is provided like this, then premium addon does not search for license files in the predefined paths. ### Troubleshooting -#### Step 1: check premiumaddon debug output +#### Step 1: check `premiumaddon` debug output -If your license does not work you can get some details about the license validation by executing -premiumaddon binary with the `--debug` option. +If your license does not work, you can get some details about the license validation by executing +`premiumaddon` binary with the `--debug` option. Windows: @@ -1404,18 +1437,17 @@ Linux/Mac: These commands can be executed from an arbitrary folder. -#### Step 2: clean up cppcheck build dir +#### Step 2: clean up Cppcheck build dir Command line: -If you use --cppcheck-build-dir then remove all files in the specified folder and recheck. +If you use `--cppcheck-build-dir`, then remove all files in the specified folder and recheck. Cppcheck GUI: -The GUI normally by default creates a cppcheck build dir. Clear all results and recheck. +The GUI normally by default creates a Cppcheck build dir. Clear all results and recheck. You can clear all results by clicking on the brush icon in the toolbar. Or by open `Edit` menu and selecting menu item `Clear results`. -#### Step 3: remove cppcheck-premium-loc files +#### Step 3: remove `cppcheck-premium-loc` files -If you have cppcheck-premium-loc files in your project folders those should be removed. +If you have `cppcheck-premium-loc` files in your project folders, those should be removed. If such files are generated during analysis, then review your scripts to check why those files are generated. - diff --git a/man/manual.md b/man/manual.md index 5b2f43eb047..de59afe562c 100644 --- a/man/manual.md +++ b/man/manual.md @@ -8,8 +8,8 @@ documentclass: report # Introduction -Cppcheck is an analysis tool for C/C++ code. It provides unique code analysis to detect bugs and focuses on detecting -undefined behaviour and dangerous coding constructs. The goal is to detect only real errors in the code, and generate +Cppcheck is an analysis tool for C/C++ code. It provides unique code analysis to detect bugs and focuses on detecting +undefined behaviour and dangerous coding constructs. The goal is to detect only real errors in the code, and generate as few false positives (wrongly reported warnings) as possible. Cppcheck is designed to analyze your C/C++ code even if it has non-standard syntax, as is common in for example embedded projects. @@ -17,7 +17,7 @@ Supported code and platforms: - Cppcheck checks non-standard code that contains various compiler extensions, inline assembly code, etc. - Cppcheck should be compilable by any compiler that supports C++11 or later. -- Cppcheck is cross platform and is used in various posix/windows/etc environments. +- Cppcheck is cross-platform and is used in various posix/windows/etc environments. The checks in Cppcheck are not perfect. There are bugs that should be found, that Cppcheck fails to detect. @@ -30,11 +30,11 @@ The kinds of bugs that you can find with static analysis are: - Coding style There are many bugs that you can not find with static analysis. Static analysis tools do not have human knowledge about -what your program is intended to do. If the output from your program is valid but unexpected then in most cases this is -not detected by static analysis tools. For instance, if your small program writes "Helo" on the screen instead of "Hello" +what your program is intended to do. If the output from your program is valid but unexpected, then in most cases this is +not detected by static analysis tools. For instance, if your small program writes "Helo" on the screen instead of "Hello", it is unlikely that any tool will complain about that. -Static analysis should be used as a complement in your quality assurance. It does not replace any of; +Static analysis should be used as a complement in your quality assurance. It does not replace any of: - Careful design - Testing @@ -70,7 +70,7 @@ Here is some simple code: return 0; } -If you save that into file1.c and execute: +If you save that into `file1.c` and execute: cppcheck file1.c @@ -85,7 +85,7 @@ Normally a program has many source files. Cppcheck can check all source files in cppcheck path -If "path" is a folder, then Cppcheck will recursively check all source files in this folder: +If `path` is a folder, then Cppcheck will recursively check all source files in this folder: Checking path/file1.cpp... 1/2 files checked 50% done @@ -94,21 +94,22 @@ If "path" is a folder, then Cppcheck will recursively check all source files in ### Check files manually or use project file -With Cppcheck you can check files manually by specifying files/paths to check and settings. Or you can use a build +With Cppcheck you can check files manually by specifying files/paths to check and settings. Or you can use a build environment, such as CMake or Visual Studio. -We don't know which approach (project file or manual configuration) will give you the best results. It is recommended -that you try both. It is possible that you will get different results so that to find the largest amount of bugs you +We don't know which approach (project file or manual configuration) will give you the best results. It is recommended +that you try both. It is possible that you will get different results so that to find the largest amount of bugs you need to use both approaches. Later chapters will describe this in more detail. ### Check files matching a given file filter With `--file-filter=` you can configure file filter(s) and then only those files matching the filter will be checked. -You can use `**`, `*` and `?` in the file filter pattern. -`**`: matches zero or more characters, including path separators -`*`: matches zero or more characters, excluding path separators -`?`: matches any single character except path separators +You can use `**`, `*` and `?` in the file filter pattern. + +- `**` matches zero or more characters, including path separators. +- `*` matches zero or more characters, excluding path separators. +- `?` matches any single character except path separators. For example, this command below means that `src/test1.cpp` could be checked, but `src/file2.cpp` and `src/test/file1.cpp` will not be checked: @@ -122,22 +123,24 @@ A common use case for `--file-filter` is to check a project, but only check cert cppcheck --project=compile_commands.json --file-filter=src/*.c Typically a `compile_commands.json` contains absolute paths. However no matter if `compile_commands.json` contains absolute paths or relative paths, the option `--file-filter=src/*.c` would mean that: - * a file with relative path `test1.c` is not checked. - * a file with relative path `src/test2.c` can be checked. - * a file with relative path `src/test3.cpp` is not checked. + +- a file with relative path `test1.c` is not checked. +- a file with relative path `src/test2.c` can be checked. +- a file with relative path `src/test3.cpp` is not checked. ### Ignore files matching a given pattern With `-i ` you can configure filename/directory patterns that should be ignored. -A file that is ignored will not be checked directly (the complete translation unit is skipped). Any header #include'd from a source file which is not ignored is checked indirectly, regardless if the header is ignored. +A file that is ignored will not be checked directly (the complete translation unit is skipped). Any header `#include`'d from a source file which is not ignored is checked indirectly, regardless if the header is ignored. + +> *Note*: If you want to filter out warnings for a header file, then `-i` will not work. Use suppressions instead. -> *Note*: If you want to filter out warnings for a header file then `-i` will not work. Use suppressions instead. +You can use `**`, `*` and `?` in the pattern to specify excluded folders/files. -You can use `**`, `*` and `?` in the pattern to specify excluded folders/files. -`**`: matches zero or more characters, including path separators -`*`: matches zero or more characters, excluding path separators -`?`: matches any single character except path separators +- `**` matches zero or more characters, including path separators. +- `*` matches zero or more characters, excluding path separators. +- `?` matches any single character except path separators. A use case for `-i` is to check a project, but exclude certain files/folders: @@ -145,8 +148,8 @@ A use case for `-i` is to check a project, but exclude certain files/folders: Typically a `compile_commands.json` contains absolute paths. However no matter if `compile_commands.json` contains absolute paths or relative paths, the option `-itest` would mean that: - * a file with relative path `test1.cpp` can be checked. - * a file with relative path `test/somefile.cpp` is not checked +- a file with relative path `test1.cpp` can be checked. +- a file with relative path `test/somefile.cpp` is not checked ### Clang parser (experimental) @@ -157,7 +160,7 @@ Install `clang`. Then use Cppcheck option `--clang`. Cppcheck executes clang with the -ast-dump option, imports the output, converts it to Cppcheck's internal format, and then performs standard analysis. -You can also pass a custom Clang executable to the option by using for example `--clang=clang-10`. You can also pass it +You can also pass a custom Clang executable to the option by using for example `--clang=clang-10`. You can also pass it with a path. On Windows it will append the `.exe` extension unless you use a path. ## Severities @@ -178,17 +181,17 @@ stylistic issues, such as unused functions, redundant code, constness, operator **performance** -run time performance suggestions based on common knowledge, though it is not certain any measurable speed difference +run time performance suggestions based on common knowledge, though it is not certain any measurable speed difference will be achieved by fixing these messages. **portability** -portability warnings. Implementation defined behavior. 64-bit portability. Some undefined behavior that probably works +portability warnings. Implementation defined behavior. 64-bit portability. Some undefined behavior that probably works "as you want", etc. **information** -configuration problems, which does not relate to the syntactical correctness, but the used Cppcheck configuration could +configuration problems, which does not relate to the syntactical correctness, but the used Cppcheck configuration could be improved. ## Possible speedup analysis of template code @@ -222,7 +225,7 @@ Cppcheck output: As you can see Cppcheck has instantiated `a` until `a<101>` was reached and then it bails out. -To limit template recursion you can: +To limit template recursion, you can: - add template specialisation - configure Cppcheck, which can be done in the GUI project file dialog @@ -246,7 +249,6 @@ Example code with template specialisation: You can pass `-D__cppcheck__` when checking this code. - # Cppcheck build folder Using a Cppcheck build folder is not mandatory but it is recommended. @@ -280,25 +282,25 @@ You can import and use Cppcheck GUI project files in the command line tool: cppcheck --project=foobar.cppcheck -The Cppcheck GUI has a few options that are not available in the command line directly. To use these options you can import a GUI project file. +The Cppcheck GUI has a few options that are not available in the command line directly. To use these options, you can import a GUI project file. The command line tool usage is kept intentionally simple and the options are therefore limited. -To ignore certain folders in the project you can use `-i`. This will skip the analysis of source files in the `foo` folder. +To ignore certain folders in the project, you can use `-i`. This will skip the analysis of source files in the `foo` folder. cppcheck --project=foobar.cppcheck -ifoo -## Compilation database (cmake etc) +## Compilation database (CMake etc.) Many build systems can generate a compilation database (a JSON file containing compilation commands for each source file). Example `cmake` command to generate the file: cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . -When you have a `compile_commands.json` file you can run Cppcheck like this: +When you have a `compile_commands.json` file, you can run Cppcheck like this: cppcheck --project=compile_commands.json -By default only 1 configuration is checked because that is consistent with the compilation. If you want to check more configurations you can use `--max-configs` or `--force`. For example: +By default only 1 configuration is checked because that is consistent with the compilation. If you want to check more configurations, you can use `--max-configs` or `--force`. For example: cppcheck --project=compile_commands.json --force @@ -306,10 +308,9 @@ To ignore certain folders you can use `-i`. This will skip analysis of source fi cppcheck --project=compile_commands.json -ifoo - ## Visual Studio -You can run Cppcheck on individual project files (\*.vcxproj) or on a whole solution (\*.sln) or (\*.slnx) +You can run Cppcheck on individual project files (`*.vcxproj`) or on a whole solution (`*.sln`) or (`*.slnx`). Running Cppcheck on an entire Visual Studio solution: @@ -330,7 +331,7 @@ Limiting on a single configuration: In the `Cppcheck GUI` you have the option to only analyze a single debug configuration. If you want to use this option on the command line, then create a `Cppcheck GUI` project with this activated and then import the GUI project file on the command line. -To ignore certain folders in the project you can use `-i`. This will skip analysis of source files in the `foo` folder. +To ignore certain folders in the project, you can use `-i`. This will skip analysis of source files in the `foo` folder. cppcheck --project=foobar.vcxproj -ifoo @@ -340,8 +341,7 @@ Running Cppcheck on a C++ Builder 6 project: cppcheck --project=foobar.bpr - -To ignore certain folders in the project you can use `-i`. This will skip analysis of source files in the `foo` folder. +To ignore certain folders in the project, you can use `-i`. This will skip analysis of source files in the `foo` folder. cppcheck --project=foobar.bpr -ifoo @@ -351,18 +351,18 @@ If you generate a compilation database, then it is possible to import that in Cp ### Makefile -In Linux you can convert a Makefile to a compile_commands.json using for instance `bear` (build ear) utility: +In Linux you can convert a Makefile to a `compile_commands.json` using for instance `bear` (build ear) utility: bear -- make -If you don't use Linux; there are python scripts that converts a Makefile into a compilation database. +If you don't use Linux, there are Python scripts that converts a Makefile into a compilation database. -# Preprocessor Settings +# Preprocessor settings -If you use `--project` then Cppcheck will automatically use the preprocessor settings in the imported project file and +If you use `--project`, then Cppcheck will automatically use the preprocessor settings in the imported project file and likely you don't have to configure anything extra. -If you don't use `--project` then a bit of manual preprocessor configuration might be required. However Cppcheck has +If you don't use `--project`, then a bit of manual preprocessor configuration might be required. However Cppcheck has automatic configuration of defines. ## Automatic configuration of preprocessor defines @@ -370,7 +370,7 @@ automatic configuration of defines. Cppcheck automatically test different combinations of preprocessor defines to achieve as high coverage in the analysis as possible. -Here is a file that has 3 bugs (when x,y,z are assigned). +Here is a file that has 3 bugs (when `x`, `y`, `z` are assigned). #ifdef A x=100/0; @@ -426,17 +426,17 @@ Example: ## Include paths -To add an include path, use `-I`, followed by the path. +To add an include path, use `-I` followed by the path. -Cppcheck's preprocessor basically handles includes like any other preprocessor. However, while other preprocessors -stop working when they encounter a missing header, Cppcheck will just print an information message and continues +Cppcheck's preprocessor basically handles includes like any other preprocessor. However, while other preprocessors +stop working when they encounter a missing header, Cppcheck will just print an information message and continues parsing the code. -The purpose of this behaviour is that Cppcheck is meant to work without necessarily seeing the entire code. -Actually, it is recommended to not give all include paths. -While it is useful for Cppcheck to see the declaration of a class when checking the implementation of its members, -passing standard library headers is discouraged, because the analysis will not work fully and lead to a longer checking -time. For such cases, .cfg files are the preferred way to provide information about the implementation of functions and +The purpose of this behaviour is that Cppcheck is meant to work without necessarily seeing the entire code. +Actually, it is recommended to not give all include paths. +While it is useful for Cppcheck to see the declaration of a class when checking the implementation of its members, +passing standard library headers is discouraged, because the analysis will not work fully and lead to a longer checking +time. For such cases, `.cfg` files are the preferred way to provide information about the implementation of functions and types to Cppcheck, see below for more information. # Platform @@ -467,7 +467,7 @@ You can also create your own custom platform configuration in a XML file. Here i -# C/C++ Standard +# C/C++ standard Use `--std` on the command line to specify a C/C++ standard. @@ -496,7 +496,7 @@ the GUI, the build dir is configured in the project options. Rechecking code will be much faster. Cppcheck does not analyse unchanged code. The old warnings are loaded from the build dir and reported again. -Whole program analysis does not work when multiple threads are used; unless you use a cppcheck +Whole program analysis does not work when multiple threads are used unless you use a Cppcheck build dir. For instance, the unusedFunction warnings require whole program analysis. # Suppressions @@ -514,12 +514,13 @@ The format for an error suppression is one of: [error id]:[filename2] [error id] -The `error id` is the id that you want to suppress. The id of a warning is shown in brackets in the normal cppcheck text output. +The `error id` is the id that you want to suppress. The id of a warning is shown in brackets in the normal Cppcheck text output. -The `error id` and `filename` patterns may contain `**`, `*` or `?`. -`**`: matches zero or more characters, including path separators -`*`: matches zero or more characters, excluding path separators -`?`: matches any single character except path separators +The `error id` and `filename` patterns may contain `**`, `*` or `?`. + +- `**` matches zero or more characters, including path separators. +- `*` matches zero or more characters, excluding path separators. +- `?` matches any single character except path separators. It is recommended to use forward-slash `/` in the filename pattern as path separator on all operating systems. @@ -561,9 +562,10 @@ You can specify suppressions in a XML file, for example as follows: The `id` and `fileName` patterns may contain `**`, `*` or `?`. -`**`: matches zero or more characters, including path separators -`*`: matches zero or more characters, excluding path separators -`?`: matches any single character except path separators + +- `**` matches zero or more characters, including path separators. +- `*` matches zero or more characters, excluding path separators. +- `?` matches any single character except path separators. The XML format is extensible and may be extended with further attributes in the future. @@ -573,7 +575,7 @@ The usage of the suppressions file is as follows: ## Inline suppressions -Suppressions can also be added directly in the code by adding comments that contain special keywords. +Suppressions can also be added directly in the code by adding comments that contain special keywords. Note that adding comments sacrifices the readability of the code somewhat. This code will normally generate an error message: @@ -598,7 +600,7 @@ You can suppress a warning `aaaa` with: // cppcheck-suppress aaaa -Suppressing multiple ids in one comment by using []: +Suppressing multiple ids in one comment by using `[]`: // cppcheck-suppress [aaaa, bbbb] @@ -629,7 +631,6 @@ Suppressing warnings `aaaa` where macro is used: ... x = MACRO; // <- aaaa warnings are suppressed here - Suppressing multiple ids where macro is used: // cppcheck-suppress-macro [aaaa, bbbb] @@ -719,7 +720,6 @@ Suppression comment on the same line as the code: arr[10] = arr[10] / 0; // cppcheck-suppress[arrayIndexOutOfBounds,zerodiv] } - ### Symbol name You can specify that the inline suppression only applies to a specific symbol: @@ -819,7 +819,7 @@ If you want to reformat the output so that it looks different, then you can use ## Predefined output formats -To get Visual Studio compatible output you can use --template=vs: +To get Visual Studio compatible output, you can use `--template=vs`: cppcheck --template=vs samples/arrayIndexOutOfBounds/bad.c @@ -829,7 +829,7 @@ This output will look like this: samples/arrayIndexOutOfBounds/bad.c(6): error: Array 'a[2]' accessed at index 2, which is out of bounds. -To get gcc compatible output you can use --template=gcc: +To get GCC-compatible output, you can use `--template=gcc`: cppcheck --template=gcc samples/arrayIndexOutOfBounds/bad.c @@ -867,7 +867,7 @@ The output will look like this: samples/arrayIndexOutOfBounds/bad.c,6,error,arrayIndexOutOfBounds, Array 'a[2]' accessed at index 2, which is out of bounds. -## User defined output format (multi line) +## User defined output format (multi-line) Many warnings have multiple locations. Example code: @@ -883,9 +883,9 @@ Many warnings have multiple locations. Example code: return 0; } -There is a possible null pointer dereference at line 3. -Cppcheck can show how it came to that conclusion by showing extra location information. -You need to use both --template and --template-location at the command line, for example: +There is a possible null pointer dereference at line 3. +Cppcheck can show how it came to that conclusion by showing extra location information. +You need to use both `--template` and `--template-location` at the command line, for example: cppcheck \ --template="{file}:{line}: {severity}: {message}\n{code}" \ @@ -907,13 +907,13 @@ The output from Cppcheck is: *p = 3; ^ -The first line in the warning is formatted by the --template format. +The first line in the warning is formatted by the `--template` format. -The other lines in the warning are formatted by the --template-location format. +The other lines in the warning are formatted by the `--template-location` format. -### Format specifiers for --template +### Format specifiers for `--template` -The available specifiers for --template are: +The available specifiers for `--template` are: **{file}** @@ -929,11 +929,11 @@ Column number **{callstack}** -Write all locations. Each location is written in [{file}:{line}] format and the locations are separated by ->. For instance it might look like: [multiline.c:8] -> [multiline.c:9] -> [multiline.c:3] +Write all locations. Each location is written in `[{file}:{line}]` format and the locations are separated by `->`. For instance it might look like: `[multiline.c:8] -> [multiline.c:9] -> [multiline.c:3]` **{inconclusive:text}** -If warning is inconclusive, then the given text is written. The given text can be any text that does not contain }. Example: {inconclusive:inconclusive,} +If warning is inconclusive, then the given text is written. The given text can be any text that does not contain `}`. Example: `{inconclusive:inconclusive,}` **{severity}** @@ -967,7 +967,7 @@ Newline Carriage return -### Format specifiers for --template-location +### Format specifiers for `--template-location` The available specifiers for `--template-location` are: @@ -1019,7 +1019,7 @@ Example code: int x = 0; } -In Cppcheck text output the remarks are not shown by default, you can use `--template` option `{remark}` to show remarks: +In Cppcheck text output, the remarks are not shown by default, you can use `--template` option `{remark}` to show remarks: $ ./cppcheck --enable=style \ --template="{file}:{line}: {message} [{id}]\\n{remark}" test1.c @@ -1028,12 +1028,12 @@ In Cppcheck text output the remarks are not shown by default, you can use `--tem test1.c:4: Variable 'x' is assigned a value that is never used. [unreadVariable] Initialize x with 0 -In xml output the comment text is provided in a "remark" attribute: +In XML output, the comment text is provided in a `remark` attribute: $ ./cppcheck --enable=style --xml test1.c - .... + ... remark="Initialize x with 0" - .... + ... # Addons @@ -1043,11 +1043,11 @@ Cppcheck is distributed with a few addons which are listed below. ## Supported addons -### misra.py +### `misra.py` -[misra.py](https://github.com/danmar/cppcheck/blob/main/addons/misra.py) is used to verify compliance with MISRA C 2012, a proprietary set of guidelines to avoid questionable code, developed for embedded systems. +[`misra.py`](https://github.com/danmar/cppcheck/blob/main/addons/misra.py) is used to verify compliance with MISRA C 2012, a proprietary set of guidelines to avoid questionable code, developed for embedded systems. -The misra.py script does not provide rule texts, those should be downloaded from [MISRA](https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/tools) +The `misra.py` script does not provide rule texts, those should be downloaded from [MISRA](https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/tools). To load the rule texts, create a configuration file. Example `misra.json`: @@ -1065,52 +1065,51 @@ To use that `misra.json` in Cppcheck analysis, use option `--addon=misra.json`: Misra checkers in open source Cppcheck only cover MISRA rules partially and for full coverage use Cppcheck Premium. -### namingng.py +### `namingng.py` -[namingng.py](https://github.com/danmar/cppcheck/blob/main/addons/namingng.py) allows you to configure and check naming conventions. +[`namingng.py`](https://github.com/danmar/cppcheck/blob/main/addons/namingng.py) allows you to configure and check naming conventions. You need to have a configuration file that defines your naming conventions. By default the filename `namingng.config.json` is used but there is an option so you can use any filename you want. Example configuration of naming conventions: -``` -{ - "RE_VARNAME": ["[a-z]*[a-zA-Z0-9_]*\\Z"], - "RE_PRIVATE_MEMBER_VARIABLE": null, - "RE_FUNCTIONNAME": ["[a-z0-9A-Z]*\\Z"], - "_comment": "comments can be added to the config with underscore-prefixed keys", - "include_guard": { - "input": "path", - "prefix": "GUARD_", - "case": "upper", - "max_linenr": 5, - "RE_HEADERFILE": "[^/].*\\.h\\Z", - "required": true - }, - "var_prefixes": {"uint32_t": "ui32"}, - "function_prefixes": {"uint16_t": "ui16", - "uint32_t": "ui32"} -} -``` - -### threadsafety.py - -[threadsafety.py](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py) analyses Cppcheck dump files to locate thread safety issues like static local objects used by multiple threads. - -### y2038.py - -[y2038.py](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py) checks source code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. - -## Running Addons + + { + "RE_VARNAME": ["[a-z]*[a-zA-Z0-9_]*\\Z"], + "RE_PRIVATE_MEMBER_VARIABLE": null, + "RE_FUNCTIONNAME": ["[a-z0-9A-Z]*\\Z"], + "_comment": "comments can be added to the config with underscore-prefixed keys", + "include_guard": { + "input": "path", + "prefix": "GUARD_", + "case": "upper", + "max_linenr": 5, + "RE_HEADERFILE": "[^/].*\\.h\\Z", + "required": true + }, + "var_prefixes": {"uint32_t": "ui32"}, + "function_prefixes": {"uint16_t": "ui16", + "uint32_t": "ui32"} + } + +### `threadsafety.py` + +[`threadsafety.py`](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py) analyses Cppcheck dump files to locate thread safety issues like static local objects used by multiple threads. + +### `y2038.py` + +[`y2038.py`](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py) checks source code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. + +## Running addons Addons can be executed with the `--addon` option: cppcheck --addon=namingng.py somefile.c -Likewise, if you have created your own script you can execute that: +Likewise, if you have created your own script, you can execute that: cppcheck --addon=mychecks.py somefile.c -You can configure how you want to execute an addon in a json file. For example: +You can configure how you want to execute an addon in a JSON file. For example: { "script": "mychecks.py", @@ -1120,7 +1119,7 @@ You can configure how you want to execute an addon in a json file. For example: "ctu": false } -To use that json file to execute your addon use the --addon option: +To use that JSON file to execute your addon, use the `--addon` option: cppcheck --addon=mychecks.json somefile.c @@ -1130,75 +1129,74 @@ Cppcheck search for addons in the local folder first and then in the installatio # Library configuration -When external libraries are used, such as WinAPI, POSIX, gtk, Qt, etc, Cppcheck has no information about functions, types, or macros contained in those libraries. Cppcheck then fails to detect various problems in the code, or might even abort the analysis. But this can be fixed by using the appropriate configuration files. - -Cppcheck already contains configurations for several libraries. They can be loaded as described below. Note that the configuration for the standard libraries of C and C++, std.cfg, is always loaded by cppcheck. If you create or update a configuration file for a popular library, we would appreciate if you supplied it to the cppcheck project. - -## Using a .cfg file - -To use a .cfg file shipped with cppcheck, pass the `--library=` option. The table below shows the currently existing libraries: - -| .cfg file | Library | Comment | -| ----------------- | ------------- | ------------- | -| avr.cfg | | | -| bento4.cfg | [Bento4](http://www.bento4.com/) | | -| boost.cfg | [Boost](http://www.boost.org/) | | -| bsd.cfg | [BSD](https://www.freebsd.org/) | | -| cairo.cfg | [cairo](https://www.cairographics.org/) | | -| cppcheck-lib.cfg | [Cppcheck](http://cppcheck.net/) | Used in selfcheck of | -| | |the Cppcheck code base | -| cppunit.cfg | [CppUnit](https://sourceforge.net/projects/cppunit/) | | -| dpdk.cfg | | | -| embedded_sql.cfg | | | -| emscripten.cfg | | | -| ginac.cfg | | | -| gnu.cfg | [GNU](https://www.gnu.org/) | | -| googletest.cfg | [GoogleTest](https://github.com/google/googletest) | | -| gtk.cfg | [GTK](https://www.gtk.org/) | | -| icu.cfg | | | -| kde.cfg | [KDE](https://kde.org/) | | -| libcerror.cfg | [libcerror](https://github.com/libyal/libcerror) | | -| libcurl.cfg | [libcurl](https://curl.se/libcurl/) | | -| libsigc++.cfg | [libsigc++](https://github.com/libsigcplusplus/libsigcplusplus) | | -| lua.cfg | | | -| mfc.cfg | [MFC](https://learn.microsoft.com/en-us/cpp/mfc/mfc-desktop-applications) | | -| microsoft_atl.cfg | [ATL](https://learn.microsoft.com/en-us/cpp/atl/active-template-library-atl-concepts) | | -| microsoft_sal.cfg | [SAL annotations](https://learn.microsoft.com/en-us/cpp/c-runtime-library/sal-annotations) | | -| microsoft_unittest.cfg | [CppUnitTest](https://learn.microsoft.com/en-us/visualstudio/test/microsoft-visualstudio-testtools-cppunittestframework-api-reference) | | -| motif.cfg | | | -| nspr.cfg | | | -| ntl.cfg | | | -| opencv2.cfg | [OpenCV](https://opencv.org/) | | -| opengl.cfg | [OpenGL](https://opengl.org/) | | -| openmp.cfg | [OpenMP](https://www.openmp.org/) | | -| openssl.cfg | [OpenSSL](https://www.openssl.org/) | | -| pcre.cfg | [PCRE](https://pcre.org/) | | -| posix.cfg | [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/) | | -| python.cfg | | | -| qt.cfg | [Qt](https://doc.qt.io/qt.html) | | -| ruby.cfg | | | -| sdl.cfg | | | -| sfml.cfg | | | -| sqlite3.cfg | [SQLite](https://www.sqlite.org/) | | -| std.cfg | C/C++ standard library | Loaded by default | -| tinyxml2.cfg | [TinyXML-2](https://github.com/leethomason/tinyxml2) | | -| vcl.cfg | | | -| windows.cfg | [Win32 API](https://learn.microsoft.com/en-us/windows/win32/) | | -| wxsqlite3.cfg | | | -| wxsvg.cfg | | | -| wxwidgets.cfg | [wxWidgets](https://www.wxwidgets.org/) | | -| zephyr.cfg | | | -| zlib.cfg | [zlib](https://www.zlib.net) | | - -## Creating a custom .cfg file - -You can create and use your own .cfg files for your projects. Use `--check-library` to get hints about what you should configure. +When external libraries are used, such as WinAPI, POSIX, gtk, Qt, etc., Cppcheck has no information about functions, types, or macros contained in those libraries. Cppcheck then fails to detect various problems in the code, or might even abort the analysis. But this can be fixed by using the appropriate configuration files. + +Cppcheck already contains configurations for several libraries. They can be loaded as described below. Note that the configuration for the standard libraries of C and C++, `std.cfg`, is always loaded by Cppcheck. If you create or update a configuration file for a popular library, we would appreciate if you supplied it to the Cppcheck project. + +## Using a `.cfg` file + +To use a `.cfg` file shipped with Cppcheck, pass the `--library=` option. The table below shows the currently existing libraries: + +| `.cfg` file | Library | Comment | +| --- | --- | --- | +| `avr.cfg` | | | +| `bento4.cfg` | [Bento4](http://www.bento4.com/) | | +| `boost.cfg` | [Boost](http://www.boost.org/) | | +| `bsd.cfg` | [BSD](https://www.freebsd.org/) | | +| `cairo.cfg` | [cairo](https://www.cairographics.org/) | | +| `cppcheck-lib.cfg` | [Cppcheck](http://cppcheck.net/) | Used in selfcheck of the Cppcheck code base | +| `cppunit.cfg` | [CppUnit](https://sourceforge.net/projects/cppunit/) | | +| `dpdk.cfg` | | | +| `embedded_sql.cfg` | | | +| `emscripten.cfg` | | | +| `ginac.cfg` | | | +| `gnu.cfg` | [GNU](https://www.gnu.org/) | | +| `googletest.cfg` | [GoogleTest](https://github.com/google/googletest) | | +| `gtk.cfg` | [GTK](https://www.gtk.org/) | | +| `icu.cfg` | | | +| `kde.cfg` | [KDE](https://kde.org/) | | +| `libcerror.cfg` | [libcerror](https://github.com/libyal/libcerror) | | +| `libcurl.cfg` | [libcurl](https://curl.se/libcurl/) | | +| `libsigc++.cfg` | [libsigc++](https://github.com/libsigcplusplus/libsigcplusplus) | | +| `lua.cfg` | | | +| `mfc.cfg` | [MFC](https://learn.microsoft.com/en-us/cpp/mfc/mfc-desktop-applications) | | +| `microsoft_atl.cfg` | [ATL](https://learn.microsoft.com/en-us/cpp/atl/active-template-library-atl-concepts) | | +| `microsoft_sal.cfg` | [SAL annotations](https://learn.microsoft.com/en-us/cpp/c-runtime-library/sal-annotations) | | +| `microsoft_unittest.cfg` | [CppUnitTest](https://learn.microsoft.com/en-us/visualstudio/test/microsoft-visualstudio-testtools-cppunittestframework-api-reference) | | +| `motif.cfg` | | | +| `nspr.cfg` | | | +| `ntl.cfg` | | | +| `opencv2.cfg` | [OpenCV](https://opencv.org/) | | +| `opengl.cfg` | [OpenGL](https://opengl.org/) | | +| `openmp.cfg` | [OpenMP](https://www.openmp.org/) | | +| `openssl.cfg` | [OpenSSL](https://www.openssl.org/) | | +| `pcre.cfg` | [PCRE](https://pcre.org/) | | +| `posix.cfg` | [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/) | | +| `python.cfg` | | | +| `qt.cfg` | [Qt](https://doc.qt.io/qt.html) | | +| `ruby.cfg` | | | +| `sdl.cfg` | | | +| `sfml.cfg` | | | +| `sqlite3.cfg` | [SQLite](https://www.sqlite.org/) | | +| `std.cfg` | C/C++ standard library | Loaded by default | +| `tinyxml2.cfg` | [TinyXML-2](https://github.com/leethomason/tinyxml2) | | +| `vcl.cfg` | | | +| `windows.cfg` | [Win32 API](https://learn.microsoft.com/en-us/windows/win32/) | | +| `wxsqlite3.cfg` | | | +| `wxsvg.cfg` | | | +| `wxwidgets.cfg` | [wxWidgets](https://www.wxwidgets.org/) | | +| `zephyr.cfg` | | | +| `zlib.cfg` | [zlib](https://www.zlib.net) | | + +## Creating a custom `.cfg` file + +You can create and use your own `.cfg` files for your projects. Use `--check-library` to get hints about what you should configure. You can use the `Library Editor` in the `Cppcheck GUI` to edit configuration files. It is available in the `View` menu. -The .cfg file format is documented in the `Reference: Cppcheck .cfg format` (https://cppcheck.sourceforge.io/reference-cfg-format.pdf) document. +The `.cfg` file format is documented in the `Reference: Cppcheck .cfg format` () document. -# HTML Report +# HTML report You can convert the XML output from Cppcheck into a HTML report. You'll need Python and the pygments module () for this to work. In the Cppcheck source tree there is a folder htmlreport that contains a script that transforms a Cppcheck XML file into HTML output. @@ -1228,15 +1226,17 @@ Example usage: cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=. or + cppcheck gui/test.cpp --xml 2> err.xml cppcheck-htmlreport --file=err.xml --report-dir=test1 \ --source-dir=https://github.com///blob// -## Choosing Between Local Annotated HTML and Remote Repository Links +## Choosing between local annotated HTML and remote repository links + +`cppcheck-htmlreport` supports two modes for linking to source files: -cppcheck-htmlreport supports two modes for linking to source files: - - Local annotated HTML files (default when `--source-dir` is a filesystem path) - - Remote GitHub/GitLab links (when `--source-dir` is a URL) +- Local annotated HTML files (default when `--source-dir` is a filesystem path) +- Remote GitHub/GitLab links (when `--source-dir` is a URL) Pointing `--source-dir` to a filesystem path generates local annotated HTML files. This is useful when you need a fully self-contained report that works offline, @@ -1251,13 +1251,13 @@ handled by the hosting service. In general, local mode fits air-gapped environments, while remote mode works best for CI workflows and large or private repositories. -# Check Level +# Check level ## Reduced The "reduced" check level performs a limited data flow analysis. If developers -want to run cppcheck directly during development and require faster results -than "normal" provides then this reduced checking can be an option. +want to run Cppcheck directly during development and require faster results +than "normal" provides, then this reduced checking can be an option. ## Normal @@ -1267,7 +1267,7 @@ The "normal" check level should be useful during active development: - checking files while you edit them. - block changes to the repo -- etc +- etc. ## Exhaustive @@ -1276,7 +1276,7 @@ When you can wait longer for the results you can enable the "exhaustive" checkin Exhaustive checking level should be useful for scenarios where you can wait for results. For instance: - nightly builds -- etc +- etc. # Speeding up analysis @@ -1284,18 +1284,17 @@ Exhaustive checking level should be useful for scenarios where you can wait for For performance reasons it might be a good idea to limit preprocessor configurations to check. -## Limit ValueFlow: max if count +## Limit ValueFlow: max `if` count -The command line option `--performance-valueflow-max-if-count` adjusts the max count for number of if in a function. +The command line option `--performance-valueflow-max-if-count` adjusts the max count for number of `if` in a function. -When that limit is exceeded there is a limitation of data flow in that function. It is not drastic: +When that limit is exceeded, there is a limitation of data flow in that function. It is not drastic: - Analysis of other functions are not affected. - It's only for some specific data flow analysis, we have data flow analysis that is always executed. - All checks are always executed. There can still be plenty of warnings in the limited function. -There is data flow analysis that slows down exponentially when number of if increase. And the limit is intended to avoid that -analysis time explodes. +There is data flow analysis that slows down exponentially when number of `if` increase. And the limit is intended to avoid that analysis time explodes. ## GUI options @@ -1306,4 +1305,4 @@ In the GUI: - Open the project dialog. - In the "Analysis" tab there are several options. -If you want to use these limitations on the command line also you can import the GUI project file with --project. +If you want to use these limitations on the command line too, you can import the GUI project file with `--project`. From 7f43d0b60ecf916c64ebca9821670fba9a5ac8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 24 Apr 2026 21:42:47 +0200 Subject: [PATCH 016/493] AUTHORS: Add vkucera [ci skip] (#8487) --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 1104b24fd2b..d9c8a8c78fb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -428,6 +428,7 @@ Vesa Pikki Ville-Pekka Vahteala Ville Skyttä Vincent Le Garrec +Vít Kučera Vladimir Petrigo Wang Haoyu Wang Yang From b0eed57dfc75a1c8cbebfecbaebf6186eb172074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Fri, 24 Apr 2026 21:54:50 +0200 Subject: [PATCH 017/493] Report overlappingInnerCondition errors (#8448) Signed-off-by: Francois Berder --- lib/checkcondition.cpp | 20 +++++++++++++++++++- lib/checkcondition.h | 3 ++- test/testcondition.cpp | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 570575b4682..4bd200adec3 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -602,7 +602,7 @@ void CheckCondition::oppositeElseIfConditionError(const Token *ifCond, const Tok //--------------------------------------------------------------------------- // - Opposite inner conditions => always false -// - (TODO) Same/Overlapping inner condition => always true +// - Same/Overlapping inner condition => always true // - same condition after early exit => always false //--------------------------------------------------------------------------- @@ -759,6 +759,8 @@ void CheckCondition::multiCondition2() oppositeInnerConditionError(firstCondition, cond2, errorPath); } else if (!isReturnVar && isSameExpression(true, firstCondition, cond2, *mSettings, true, true, &errorPath)) { identicalInnerConditionError(firstCondition, cond2, errorPath); + } else if (!isReturnVar && isOverlappingCond(cond2, firstCondition, true)) { + overlappingInnerConditionError(firstCondition, cond2, errorPath); } } return ChildrenToVisit::none; @@ -879,6 +881,21 @@ void CheckCondition::oppositeInnerConditionError(const Token *tok1, const Token* reportError(std::move(errorPath), Severity::warning, "oppositeInnerCondition", msg, CWE398, Certainty::normal); } +void CheckCondition::overlappingInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) +{ + if (diag(tok1, tok2)) + return; + const std::string s1(tok1 ? tok1->expressionString() : "x"); + const std::string s2(tok2 ? tok2->expressionString() : "x"); + const std::string innerSmt = innerSmtString(tok2); + errorPath.emplace_back(tok1, "outer condition: " + s1); + errorPath.emplace_back(tok2, "overlapping inner condition: " + s2); + + const std::string msg("Overlapping inner '" + innerSmt + "' condition is always true.\n" + "Overlapping inner '" + innerSmt + "' condition is always true (outer condition is '" + s1 + "' and inner condition is '" + s2 + "')."); + reportError(std::move(errorPath), Severity::warning, "overlappingInnerCondition", msg, CWE398, Certainty::normal); +} + void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) { if (diag(tok1, tok2)) @@ -2106,6 +2123,7 @@ void CheckCondition::getErrorMessages(ErrorLogger *errorLogger, const Settings * c.comparisonError(nullptr, "&", 6, "==", 1, false); c.duplicateConditionError(nullptr, nullptr, ErrorPath{}); c.overlappingElseIfConditionError(nullptr, 1); + c.overlappingInnerConditionError(nullptr, nullptr, ErrorPath()); c.mismatchingBitAndError(nullptr, 0xf0, nullptr, 1); c.oppositeInnerConditionError(nullptr, nullptr, ErrorPath{}); c.identicalInnerConditionError(nullptr, nullptr, ErrorPath{}); diff --git a/lib/checkcondition.h b/lib/checkcondition.h index dac3ba8d0de..2c010cd7c5a 100644 --- a/lib/checkcondition.h +++ b/lib/checkcondition.h @@ -84,7 +84,7 @@ class CPPCHECKLIB CheckCondition : public Check { /** * multiconditions #2 * - Opposite inner conditions => always false - * - (TODO) Same/Overlapping inner condition => always true + * - Same/Overlapping inner condition => always true * - same condition after early exit => always false **/ void multiCondition2(); @@ -130,6 +130,7 @@ class CPPCHECKLIB CheckCondition : public Check { bool result); void duplicateConditionError(const Token *tok1, const Token *tok2, ErrorPath errorPath); void overlappingElseIfConditionError(const Token *tok, nonneg int line1); + void overlappingInnerConditionError(const Token *tok1, const Token *tok2, ErrorPath errorPath); void oppositeElseIfConditionError(const Token *ifCond, const Token *elseIfCond, ErrorPath errorPath); void oppositeInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath); diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 58475896ebe..5dceb392b45 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -94,6 +94,8 @@ class TestCondition : public TestFixture { TEST_CASE(identicalConditionAfterEarlyExit); TEST_CASE(innerConditionModified); + TEST_CASE(overlappingInnerCondition); + TEST_CASE(clarifyCondition1); // if (a = b() < 0) TEST_CASE(clarifyCondition2); // if (a & b == c) TEST_CASE(clarifyCondition3); // if (! a & b) @@ -3022,6 +3024,22 @@ class TestCondition : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void overlappingInnerCondition() { + check("void f(int x) {\n" + " if (x == 1) {\n" + " if (x & 7) {}\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:15]: (warning) Overlapping inner 'if' condition is always true. [overlappingInnerCondition]\n", errout_str()); + + check("void f(int x) {\n" + " if (x & 7) {\n" + " if (x == 1) {}\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout_str()); + } + // clarify conditions with = and comparison void clarifyCondition1() { check("void f() {\n" From 2d44419030092f304b6eb232abe28ac7e4396044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 24 Apr 2026 22:05:07 +0200 Subject: [PATCH 018/493] Fix format, rendering, typos, syntax in the readme (#8461) --- readme.md | 105 +++++++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/readme.md b/readme.md index a34dad2a57a..7bacadd3456 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,8 @@ -# **Cppcheck** +# **Cppcheck** |release-windows|OSS-Fuzz|Coverity Scan Build Status|include-what-you-use|License| |:--:|:--:|:--:|:--:|:--:| -|[![release-windows](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml/badge.svg?branch=main)](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml)|[![OSS-Fuzz](https://oss-fuzz-build-logs.storage.googleapis.com/badges/cppcheck.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:cppcheck)|[![Coverity Scan Build Status](https://img.shields.io/coverity/scan/512.svg)](https://scan.coverity.com/projects/512)|[![include-what-you-use](https://github.com/danmar/cppcheck/actions/workflows/iwyu.yml/badge.svg?branch=main)](https://github.com/danmar/cppcheck/actions/workflows/iwyu.yml)|[![License](https://img.shields.io/badge/license-GPL3.0-blue.svg)](https://opensource.org/licenses/GPL-3.0) - +|[![release-windows](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml/badge.svg?branch=main)](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml)|[![OSS-Fuzz](https://oss-fuzz-build-logs.storage.googleapis.com/badges/cppcheck.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:cppcheck)|[![Coverity Scan Build Status](https://img.shields.io/coverity/scan/512.svg)](https://scan.coverity.com/projects/512)|[![include-what-you-use](https://github.com/danmar/cppcheck/actions/workflows/iwyu.yml/badge.svg?branch=main)](https://github.com/danmar/cppcheck/actions/workflows/iwyu.yml)|[![License](https://img.shields.io/badge/license-GPL3.0-blue.svg)](https://opensource.org/licenses/GPL-3.0)| ## About the name @@ -21,7 +20,8 @@ Cppcheck is a hobby project with limited resources. You can help us by donating 1. Download (and extract) Cppcheck source code. 2. Run (Linux/MacOS example): - ``` + + ```shell cd cppcheck/ python3 -m venv .venv source .venv/bin/activate @@ -30,9 +30,9 @@ Cppcheck is a hobby project with limited resources. You can help us by donating ./tools/donate-cpu.py ``` -The script will analyse debian source code and upload the results to a cppcheck server. We need these results both to improve Cppcheck and to detect regressions. +The script will analyse Debian source code and upload the results to a Cppcheck server. We need these results both to improve Cppcheck and to detect regressions. -You can stop the script whenever you like with Ctrl C. +You can stop the script whenever you like with Ctrl+C. ## Compiling @@ -43,6 +43,7 @@ To build the GUI application, you need to use the CMake build system. When building the command line tool, [PCRE](http://www.pcre.org/) is optional. It is used if you build with rules. There are multiple compilation choices: + * CMake - cross platform build tool * (Windows) Visual Studio * (Windows) Qt Creator + MinGW @@ -62,22 +63,22 @@ cmake --build build ``` If you want to compile the GUI you can use the flag. --DBUILD_GUI=ON +`-DBUILD_GUI=ON` For rules support (requires pcre) use the flag. --DHAVE_RULES=ON +`-DHAVE_RULES=ON` For release builds it is recommended that you use: --DUSE_MATCHCOMPILER=ON +`-DUSE_MATCHCOMPILER=ON` For building the tests use the flag. --DBUILD_TESTING=ON +`-DBUILD_TESTING=ON` -Using cmake you can generate project files for Visual Studio,XCode,etc. +Using CMake you can generate project files for Visual Studio, XCode, etc. #### Building a specific configuration -For single-configuration generators (like "Unix Makefiles") you can generate and build a specific configuration (e.g. "RelWithDebInfo") using: +For single-configuration generators (like "Unix Makefiles") you can generate and build a specific configuration (e.g. "`RelWithDebInfo`") using: ```shell cmake -S . -B build_RelWithDebInfo -DCMAKE_BUILD_TYPE=RelWithDebInfo .. @@ -93,13 +94,13 @@ cmake --build build --config RelWithDebInfo ### Visual Studio -Use the cppcheck.sln file. The file is configured for Visual Studio 2019, but the platform toolset can be changed easily to older or newer versions. The solution contains platform targets for both x86 and x64. +Use the `cppcheck.sln` file. The file is configured for Visual Studio 2019, but the platform toolset can be changed easily to older or newer versions. The solution contains platform targets for both x86 and x64. -To compile with rules, select "Release-PCRE" or "Debug-PCRE" configuration. pcre.lib (pcre64.lib for x64 builds) and pcre.h are expected to be in /externals then. A current version of PCRE for Visual Studio can be obtained using [vcpkg](https://github.com/microsoft/vcpkg). +To compile with rules, select "`Release-PCRE`" or "`Debug-PCRE`" configuration. `pcre.lib` (`pcre64.lib` for x64 builds) and `pcre.h` are expected to be in `/externals` then. A current version of PCRE for Visual Studio can be obtained using [vcpkg](https://github.com/microsoft/vcpkg). ### Visual Studio (from command line) -If you do not wish to use the Visual Studio IDE, you can compile cppcheck from the command line the following command. +If you do not wish to use the Visual Studio IDE, you can compile Cppcheck from the command line the following command. ```shell msbuild cppcheck.sln @@ -107,10 +108,10 @@ msbuild cppcheck.sln ### VS Code (on Windows) -Install MSYS2 to get GNU toolchain with g++ and gdb (https://www.msys2.org/). -Create a settings.json file in the .vscode folder with the following content (adjust path as necessary): +Install MSYS2 to get GNU toolchain with g++ and gdb (). +Create a `settings.json` file in the `.vscode` folder with the following content (adjust path as necessary): -``` +```json { "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe", "terminal.integrated.shellArgs.windows": [ @@ -123,11 +124,11 @@ Create a settings.json file in the .vscode folder with the following content (ad } ``` -Run "make" in the terminal to build cppcheck. +Run `make` in the terminal to build Cppcheck. -For debugging create a launch.json file in the .vscode folder with the following content, which covers configuration for debugging cppcheck and misra.py: +For debugging create a `launch.json` file in the `.vscode` folder with the following content, which covers configuration for debugging Cppcheck and `misra.py`: -``` +```json { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. @@ -174,7 +175,7 @@ For debugging create a launch.json file in the .vscode folder with the following ### Qt Creator + MinGW The PCRE dll is needed to build the CLI. It can be downloaded here: -http://software-download.name/pcre-library-windows/ + ### GNU compilers @@ -204,22 +205,22 @@ g++ -o cppcheck -std=c++11 -Iexternals -Iexternals/simplecpp -Iexternals/tinyxml #### Flags -- `MATCHCOMPILER=yes` +* `MATCHCOMPILER=yes` Several `Token` matching patterns are converted into more efficient C++ code at compile time (requires Python to be installed). -- `FILESDIR=/usr/share/cppcheck` - Specifies the folder where cppcheck files (addons, cfg, platform) are installed to. +* `FILESDIR=/usr/share/cppcheck` + Specifies the folder where Cppcheck files (addons, cfg, platform) are installed to. -- `HAVE_RULES=yes` +* `HAVE_RULES=yes` Enables rules (requires PCRE to be installed). -- `CXXOPTS="-O2"` +* `CXXOPTS="-O2"` Enables most compiler optimizations. -- `CPPOPTS="-DNDEBUG"` +* `CPPOPTS="-DNDEBUG"` Disables assertions. -- `HAVE_BOOST=yes` +* `HAVE_BOOST=yes` Enables usage of more efficient container from Boost (requires Boost to be installed). ### MinGW @@ -230,7 +231,7 @@ mingw32-make If you encounter the following error with `MATCHCOMPILER=yes` you need to specify your Python interpreter via `PYTHON_INTERPRETER`. -``` +```text process_begin: CreateProcess(NULL, which python3, ...) failed. makefile:24: pipe: No error process_begin: CreateProcess(NULL, which python, ...) failed. @@ -238,10 +239,10 @@ makefile:27: pipe: No error makefile:30: *** Did not find a Python interpreter. Stop. ``` -### Other Compiler/IDE +### Other compiler/IDE 1. Create an empty project file / makefile. -2. Add all cpp files in the cppcheck cli and lib folders to the project file / makefile. +2. Add all cpp files in the Cppcheck cli and lib folders to the project file / makefile. 3. Add all cpp files in the externals folders to the project file / makefile. 4. Compile. @@ -255,17 +256,17 @@ mv cppcheck cppcheck.exe ## Packages -Besides building yourself on the platform of your choice there are also several ways to obtain pre-built packages.
+Besides building yourself on the platform of your choice there are also several ways to obtain pre-built packages. ### Official Official packages are maintained by the Cppcheck team. -- (Windows) An official Windows installer is available via the official Cppcheck SourceForge page: https://cppcheck.sourceforge.io. -- (Windows) Official builds of the current development versions are available via the [release-windows](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml) workflow. They are built nightly for the `main` branch and for each commit for release branches. As these are development versions please refrain from using these in production environments! - - A portable package (i.e. does not require installation) is available as the `portable` artifact. This is still a work-in-progress - see https://trac.cppcheck.net/ticket/10771 for details. - - An installer is available via the `installer` artifact. -- (Multi-Platform) A premium version with additional features provided by the original author of Cppcheck is available for purchase via https://www.cppcheck.com. +* (Windows) An official Windows installer is available via the official Cppcheck SourceForge page: . +* (Windows) Official builds of the current development versions are available via the [release-windows](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml) workflow. They are built nightly for the `main` branch and for each commit for release branches. As these are development versions please refrain from using these in production environments! + * A portable package (i.e. does not require installation) is available as the `portable` artifact. This is still a work-in-progress - see for details. + * An installer is available via the `installer` artifact. +* (Multi-Platform) A premium version with additional features provided by the original author of Cppcheck is available for purchase via . ### Third-party @@ -273,23 +274,23 @@ Third-party packages are ***not*** maintained by the Cppcheck team but their res *Note:* The following list is purely informational and listed in no particular order. -*Note:* Please always try to obtain the package from the primary official source of your operating system/distro first and make sure you are getting the latest released/tagged version (see https://github.com/danmar/cppcheck/tags). Some packages might not carry the latest patch version though. +*Note:* Please always try to obtain the package from the primary official source of your operating system/distro first and make sure you are getting the latest released/tagged version (see ). Some packages might not carry the latest patch version though. *Note:* Some issues might be related to additional patches carried by the builds in these packages or by the packaging itself. Please try to verify the issue with an official build before reporting it upstream. Otherwise you might need toreport it to the respective maintainer of the package. -- (Windows / Outdated) A portable package is available via https://portableapps.com/apps/development/cppcheck-portable. -- (Windows / Outdated) A package is available via https://community.chocolatey.org/packages/cppcheck. -- (Windows / Outdated) A package is available via https://winget.run/pkg/Cppcheck/Cppcheck. -- (Windows) A package is available via https://scoop.sh/#/apps?q=cppcheck. -- (Linux/Unix) Many major distros offer Cppcheck packages via their integrated package managers (`yum`, `apt`, `pacman`, etc.). See https://pkgs.org/search/?q=cppcheck or https://repology.org/project/cppcheck for an overview. -- (Linux/Unix) Unless you are using a "rolling" distro, it is likely that they are not carrying the latest version. There are several external (mainly unsupported) repositories like AUR (ArchLinux), PPA (ubuntu), EPEL (CentOS/Fedora) etc. which might provide up-to-date packages. -- (Linux/Unix / Outdated) The Canonical Snapcraft packages (https://snapcraft.io/cppcheck / https://snapcraft.io/cppcheckgui) are unmaintained and contain very old (development) versions. Please refrain from using them! See https://trac.cppcheck.net/ticket/11641 for more details. -- (MacOS) A package is available via Homebrew (`brew`). See https://formulae.brew.sh/formula/cppcheck. -- (MacOS) A package is available via https://ports.macports.org/port/cppcheck. -- (Multi-Platform) A package is available via https://anaconda.org/conda-forge/cppcheck. -- (Multi-Platform) A package is available via https://conan.io/center/recipes/cppcheck. -- Packages are also available from various download portals (mainly the Windows installer - sometimes re-packaged). +* (Windows / Outdated) A portable package is available via . +* (Windows / Outdated) A package is available via . +* (Windows / Outdated) A package is available via . +* (Windows) A package is available via . +* (Linux/Unix) Many major distros offer Cppcheck packages via their integrated package managers (`yum`, `apt`, `pacman`, etc.). See or for an overview. +* (Linux/Unix) Unless you are using a "rolling" distro, it is likely that they are not carrying the latest version. There are several external (mainly unsupported) repositories like AUR (ArchLinux), PPA (Ubuntu), EPEL (CentOS/Fedora) etc. which might provide up-to-date packages. +* (Linux/Unix / Outdated) The Canonical Snapcraft packages ( / ) are unmaintained and contain very old (development) versions. Please refrain from using them! See for more details. +* (MacOS) A package is available via Homebrew (`brew`). See . +* (MacOS) A package is available via . +* (Multi-Platform) A package is available via . +* (Multi-Platform) A package is available via . +* Packages are also available from various download portals (mainly the Windows installer - sometimes re-packaged). ## Webpage -https://cppcheck.sourceforge.io/ + From 9d746d0b953d246908254426c6c626b2d5a727b7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 25 Apr 2026 01:34:02 +0200 Subject: [PATCH 019/493] Fix #14632 FN funcArgNamesDifferent when argument is unnamed (#8399) Co-authored-by: chrchr-github --- .selfcheck_suppressions | 37 +++++++++++++++++++++++++++++++++++++ gui/codeeditor.h | 4 ++-- gui/librarydialog.h | 6 +++--- gui/projectfiledialog.h | 2 +- gui/threadresult.h | 2 +- lib/checkclass.h | 2 +- lib/checkmemoryleak.h | 2 +- lib/checkother.cpp | 11 +++++++---- lib/checkstl.cpp | 6 +++--- lib/checkstl.h | 2 +- lib/symboldatabase.h | 2 +- releasenotes.txt | 1 + test/fixture.h | 2 +- test/testother.cpp | 26 ++++++++++++++++++-------- 14 files changed, 78 insertions(+), 27 deletions(-) diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index 171a5a997d7..5dbce0afc79 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -3,12 +3,46 @@ missingIncludeSystem checkersReport # warnings in Qt generated code we cannot fix +funcArgNamesDifferentUnnamed:*/moc_aboutdialog.cpp +funcArgNamesDifferentUnnamed:*/moc_applicationdialog.cpp +funcArgNamesDifferentUnnamed:*/moc_applicationlist.cpp funcArgNamesDifferent:*/moc_checkthread.cpp +funcArgNamesDifferentUnnamed:*/moc_checkthread.cpp +funcArgNamesDifferentUnnamed:*/moc_codeeditor.cpp funcArgNamesDifferent:*/moc_codeeditstylecontrols.cpp +funcArgNamesDifferentUnnamed:*/moc_codeeditstylecontrols.cpp +funcArgNamesDifferentUnnamed:*/moc_compliancereportdialog.cpp +funcArgNamesDifferentUnnamed:*/moc_codeeditstyledialog.cpp +funcArgNamesDifferentUnnamed:*/moc_fileviewdialog.cpp +funcArgNamesDifferentUnnamed:*/moc_helpdialog.cpp +funcArgNamesDifferentUnnamed:*/moc_libraryaddfunctiondialog.cpp +funcArgNamesDifferentUnnamed:*/moc_librarydialog.cpp +funcArgNamesDifferentUnnamed:*/moc_libraryeditargdialog.cpp +funcArgNamesDifferentUnnamed:*/moc_mainwindow.cpp +funcArgNamesDifferentUnnamed:*/moc_newsuppressiondialog.cpp +funcArgNamesDifferentUnnamed:*/moc_platforms.cpp +funcArgNamesDifferentUnnamed:*/moc_projectfile.cpp +funcArgNamesDifferentUnnamed:*/moc_projectfiledialog.cpp funcArgNamesDifferent:*/moc_resultstree.cpp +funcArgNamesDifferentUnnamed:*/moc_resultstree.cpp funcArgNamesDifferent:*/moc_resultsview.cpp +funcArgNamesDifferentUnnamed:*/moc_resultsview.cpp +funcArgNamesDifferentUnnamed:*/moc_scratchpad.cpp +funcArgNamesDifferentUnnamed:*/moc_settingsdialog.cpp +funcArgNamesDifferentUnnamed:*/moc_statsdialog.cpp +funcArgNamesDifferentUnnamed:*/moc_testcppchecklibrarydata.cpp +funcArgNamesDifferentUnnamed:*/moc_testfilelist.cpp +funcArgNamesDifferentUnnamed:*/moc_testprojectfile.cpp +funcArgNamesDifferentUnnamed:*/moc_testresultstree.cpp +funcArgNamesDifferentUnnamed:*/moc_testtranslationhandler.cpp +funcArgNamesDifferentUnnamed:*/moc_testxmlreportv2.cpp +funcArgNamesDifferentUnnamed:*/moc_threaddetails.cpp funcArgNamesDifferent:*/moc_threadhandler.cpp +funcArgNamesDifferentUnnamed:*/moc_threadhandler.cpp funcArgNamesDifferent:*/moc_threadresult.cpp +funcArgNamesDifferentUnnamed:*/moc_threadresult.cpp +funcArgNamesDifferentUnnamed:*/moc_translationhandler.cpp +funcArgNamesDifferentUnnamed:*/moc_txtreport.cpp naming-varname:*/gui/ui_*.h functionStatic:*/gui/ui_*.h @@ -37,7 +71,10 @@ invalidPrintfArgType_sint:externals/tinyxml2/tinyxml2.h naming-privateMemberVariable:externals/tinyxml2/tinyxml2.h functionStatic:externals/tinyxml2/tinyxml2.cpp funcArgNamesDifferent:externals/tinyxml2/tinyxml2.cpp +funcArgNamesDifferentUnnamed:externals/tinyxml2/tinyxml2.cpp +funcArgNamesDifferentUnnamed:externals/tinyxml2/tinyxml2.h nullPointerRedundantCheck:externals/tinyxml2/tinyxml2.cpp knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp useStlAlgorithm:externals/simplecpp/simplecpp.cpp +funcArgNamesDifferentUnnamed:externals/simplecpp/simplecpp.h missingMemberCopy:externals/simplecpp/simplecpp.h diff --git a/gui/codeeditor.h b/gui/codeeditor.h index 4dfbaa66047..00205d1c4e1 100644 --- a/gui/codeeditor.h +++ b/gui/codeeditor.h @@ -129,9 +129,9 @@ class CodeEditor : public QPlainTextEdit { void resizeEvent(QResizeEvent *event) override; private slots: - void updateLineNumberAreaWidth(int newBlockCount); + void updateLineNumberAreaWidth(int /*newBlockCount*/); void highlightErrorLine(); - void updateLineNumberArea(const QRect & /*rect*/, int /*dy*/); + void updateLineNumberArea(const QRect& rect, int dy); private: QString generateStyleString(); diff --git a/gui/librarydialog.h b/gui/librarydialog.h index 285d36a820a..6737da638c8 100644 --- a/gui/librarydialog.h +++ b/gui/librarydialog.h @@ -47,10 +47,10 @@ private slots: void addFunction(); void changeFunction(); void editArg(); - void editFunctionName(QListWidgetItem* /*item*/); - void filterFunctions(const QString& /*filter*/); + void editFunctionName(QListWidgetItem* item); + void filterFunctions(const QString& filter); void selectFunction(); - void sortFunctions(bool /*sort*/); + void sortFunctions(bool sort); private: Ui::LibraryDialog *mUi; diff --git a/gui/projectfiledialog.h b/gui/projectfiledialog.h index 231d1f26ef3..af21685b675 100644 --- a/gui/projectfiledialog.h +++ b/gui/projectfiledialog.h @@ -280,7 +280,7 @@ private slots: /** * @brief Edit suppression (double clicking on suppression) */ - void editSuppression(const QModelIndex &index); + void editSuppression(const QModelIndex& /*index*/); /** * @brief Browse for misra file diff --git a/gui/threadresult.h b/gui/threadresult.h index 1224b3c539d..87560e87d78 100644 --- a/gui/threadresult.h +++ b/gui/threadresult.h @@ -79,7 +79,7 @@ class ThreadResult : public QObject, public ErrorLogger { /** * ErrorLogger methods */ - void reportOut(const std::string &outmsg, Color c = Color::Reset) override; + void reportOut(const std::string &outmsg, Color /*c*/ = Color::Reset) override; void reportErr(const ErrorMessage &msg) override; void reportMetric(const std::string &metric) override { diff --git a/lib/checkclass.h b/lib/checkclass.h index 1276b212518..6cdea8d581c 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -138,7 +138,7 @@ class CPPCHECKLIB CheckClass : public Check { void checkUnsafeClassRefMember(); /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& currentConfig) const override; + Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings& /*settings*/, const std::string& currentConfig) const override; Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index cf8cc4c11a2..c9fb2274252 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -266,7 +266,7 @@ class CPPCHECKLIB CheckMemoryLeakStructMember : public Check, private CheckMemor void checkStructVariable(const Variable* variable) const; - void getErrorMessages(ErrorLogger * errorLogger, const Settings * settings) const override; + void getErrorMessages(ErrorLogger* /*errorLogger*/, const Settings* /*settings*/) const override; static std::string myName() { return "Memory leaks (struct members)"; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 13ad6d29577..9cd5dba4469 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4061,7 +4061,9 @@ void CheckOther::checkFuncArgNamesDifferent() // check for different argument names if (style && inconclusive) { for (int j = 0; j < function->argCount(); ++j) { - if (declarations[j] && definitions[j] && declarations[j]->str() != definitions[j]->str()) + const bool warn = (declarations[j] != nullptr) != (definitions[j] != nullptr) || + (declarations[j] && definitions[j] && declarations[j]->str() != definitions[j]->str()); + if (warn) funcArgNamesDifferent(function->name(), j, declarations[j], definitions[j]); } } @@ -4072,11 +4074,12 @@ void CheckOther::funcArgNamesDifferent(const std::string & functionName, nonneg const Token* declaration, const Token* definition) { std::list tokens = { declaration,definition }; - reportError(tokens, Severity::style, "funcArgNamesDifferent", + const std::string id = (declaration != nullptr) == (definition != nullptr) ? "funcArgNamesDifferent" : "funcArgNamesDifferentUnnamed"; + reportError(tokens, Severity::style, id, "$symbol:" + functionName + "\n" "Function '$symbol' argument " + std::to_string(index + 1) + " names different: declaration '" + - (declaration ? declaration->str() : std::string("A")) + "' definition '" + - (definition ? definition->str() : std::string("B")) + "'.", CWE628, Certainty::inconclusive); + (declaration ? declaration->str() : "") + "' definition '" + + (definition ? definition->str() : "") + "'.", CWE628, Certainty::inconclusive); } void CheckOther::funcArgOrderDifferent(const std::string & functionName, diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 65bf3792615..faa6f25911d 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1227,7 +1227,7 @@ void CheckStl::invalidContainer() errorPath.insert(errorPath.end(), info.errorPath.cbegin(), info.errorPath.cend()); errorPath.insert(errorPath.end(), r.errorPath.cbegin(), r.errorPath.cend()); if (v) { - invalidContainerError(info.tok, r.tok, v, std::move(errorPath)); + invalidContainerError(info.tok, v, std::move(errorPath)); } else { invalidContainerReferenceError(info.tok, r.tok, std::move(errorPath)); } @@ -1252,7 +1252,7 @@ void CheckStl::invalidContainerLoopError(const Token* tok, const Token* loopTok, reportError(std::move(errorPath), Severity::error, "invalidContainerLoop", msg, CWE664, Certainty::normal); } -void CheckStl::invalidContainerError(const Token *tok, const Token * /*contTok*/, const ValueFlow::Value *val, ErrorPath errorPath) +void CheckStl::invalidContainerError(const Token *tok, const ValueFlow::Value *val, ErrorPath errorPath) { const bool inconclusive = val ? val->isInconclusive() : false; if (val) @@ -3504,7 +3504,7 @@ void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings* settin c.iteratorsError(nullptr, "container1", "container2"); c.iteratorsError(nullptr, nullptr, "container"); c.invalidContainerLoopError(nullptr, nullptr, ErrorPath{}); - c.invalidContainerError(nullptr, nullptr, nullptr, ErrorPath{}); + c.invalidContainerError(nullptr, nullptr, ErrorPath{}); c.invalidContainerReferenceError(nullptr, nullptr, ErrorPath{}); c.mismatchingContainerIteratorError(nullptr, nullptr, nullptr); c.mismatchingContainersError(nullptr, nullptr); diff --git a/lib/checkstl.h b/lib/checkstl.h index 60b9d4c7000..03a634f1ed1 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -187,7 +187,7 @@ class CPPCHECKLIB CheckStl : public Check { void sizeError(const Token* tok); void redundantIfRemoveError(const Token* tok); void invalidContainerLoopError(const Token* tok, const Token* loopTok, ErrorPath errorPath); - void invalidContainerError(const Token *tok, const Token * contTok, const ValueFlow::Value *val, ErrorPath errorPath); + void invalidContainerError(const Token *tok, const ValueFlow::Value *val, ErrorPath errorPath); void invalidContainerReferenceError(const Token* tok, const Token* contTok, ErrorPath errorPath); void uselessCallsReturnValueError(const Token* tok, const std::string& varname, const std::string& function); diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index a4cdfc5370a..1ba1aeb0b13 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1430,7 +1430,7 @@ class CPPCHECKLIB SymbolDatabase { /* returns the opening { if tok points to enum */ static const Token* isEnumDefinition(const Token* tok); - static void getErrorMessages(ErrorLogger &errorLogger); + static void getErrorMessages(ErrorLogger& /*errorLogger*/); // check if type has no side effects (no constructors and no members with constructors) /** @todo false negative: check constructors for side effects */ diff --git a/releasenotes.txt b/releasenotes.txt index 6a5d917fa10..38a9e1a41ae 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -6,6 +6,7 @@ Major bug fixes & crashes: New checks: - MISRA C 2012 rule 10.3 now warns on assigning integer literals 0 and 1 to bool in C99 and later while preserving the existing C89 behavior. +- funcArgNamesDifferentUnnamed warns on function declarations/definitions where a parameter in either location is unnamed C/C++ support: - diff --git a/test/fixture.h b/test/fixture.h index a564a54e399..fe767a3a16a 100644 --- a/test/fixture.h +++ b/test/fixture.h @@ -291,7 +291,7 @@ class TestFixture : public ErrorLogger { std::unique_ptr mTimer; - void reportOut(const std::string &outmsg, Color c = Color::Reset) override; + void reportOut(const std::string &outmsg, Color /*c*/ = Color::Reset) override; void reportErr(const ErrorMessage &msg) override; void reportMetric(const std::string &metric) override { diff --git a/test/testother.cpp b/test/testother.cpp index bac5dfbdf7f..64278f95a77 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1794,7 +1794,7 @@ class TestOther : public TestFixture { void varScope39() { check("struct S {\n" // #12405 - " void f(const std::string&) const;\n" + " void f(const std::string& s) const;\n" " const int* g(std::string&) const;\n" "};\n" "void h(int);\n" @@ -3623,7 +3623,7 @@ class TestOther : public TestFixture { "class D\n" "{\n" "public:\n" - " explicit D(int&);\n" + " explicit D(int& i);\n" "\n" "private:\n" " C c;\n" @@ -3644,7 +3644,7 @@ class TestOther : public TestFixture { "class D\n" "{\n" "public:\n" - " explicit D(int&) noexcept;\n" + " explicit D(int& i) noexcept;\n" "\n" "private:\n" " C c;\n" @@ -3664,7 +3664,7 @@ class TestOther : public TestFixture { "class D\n" "{\n" "public:\n" - " explicit D(int&);\n" + " explicit D(int& i);\n" "\n" "private:\n" " C c;\n" @@ -3685,7 +3685,7 @@ class TestOther : public TestFixture { "class D\n" "{\n" "public:\n" - " explicit D(int&);\n" + " explicit D(int& i);\n" "\n" "private:\n" " C c;\n" @@ -3706,7 +3706,7 @@ class TestOther : public TestFixture { "class D\n" "{\n" "public:\n" - " explicit D(int&);\n" + " explicit D(int& i);\n" "\n" "private:\n" " C c;\n" @@ -6784,7 +6784,7 @@ class TestOther : public TestFixture { " AMethodObject(double, double, double);\n" "};\n" "struct S {\n" - " static void A(double, double, double);\n" + " static void A(double a1, double a2, double a3);\n" "};\n" "void S::A(double const a1, double const a2, double const a3) {\n" " AMethodObject(a1, a2, a3);\n" @@ -8021,7 +8021,7 @@ class TestOther : public TestFixture { "public:\n" " double getScale() const { return m_range * m_zoom; }\n" " void setZoom(double z) { m_zoom = z; }\n" - " void dostuff(int);\n" + " void dostuff(int x);\n" "private:\n" " double m_zoom;\n" " double m_range;\n" @@ -12822,6 +12822,16 @@ class TestOther : public TestFixture { "[test.cpp:7:15] -> [test.cpp:8:15]: (style, inconclusive) Function 'h' argument 1 names different: declaration 'a' definition 'b'. [funcArgNamesDifferent]\n", errout_str()); + check("void f(int a);\n" // #14632 + "void f(int) {}\n" + "void g(int);\n" + "void g(int b) {}\n" + "void h(int);\n" + "void h(int) {}\n"); + ASSERT_EQUALS( + "[test.cpp:1:12]: (style, inconclusive) Function 'f' argument 1 names different: declaration 'a' definition ''. [funcArgNamesDifferentUnnamed]\n" + "[test.cpp:4:12]: (style, inconclusive) Function 'g' argument 1 names different: declaration '' definition 'b'. [funcArgNamesDifferentUnnamed]\n", + errout_str()); } void funcArgOrderDifferent() { From eb00a4287e82ebffa780b3c2bf2620e9c58c2112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sat, 25 Apr 2026 08:29:20 +0200 Subject: [PATCH 020/493] refs #14668 - aligned the selfcheck scripts (#8443) --- selfcheck.sh | 68 +++++++++++++++++++++++++++++++++++------------- selfcheck_san.sh | 20 +++++++------- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/selfcheck.sh b/selfcheck.sh index 7f919334c18..e9a39ec43cb 100755 --- a/selfcheck.sh +++ b/selfcheck.sh @@ -1,14 +1,16 @@ #!/bin/sh +cmake_output=cmake.output +selfcheck_options_extra="$1" + +cppcheck_bin=./cppcheck + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=file-total -D__GNUC__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,information --exception-handling --debug-warnings --check-level=exhaustive" +selfcheck_options="$selfcheck_options $selfcheck_options_extra" cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2" -gui_options="-DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt" +qt_options="--library=qt -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_MOC_HAS_STRINGDATA" # TODO: use 69 as revision naming_options="--addon-python=$(command -v python) --addon=naming.json" -if [ -n "$1" ]; then - selfcheck_options="$selfcheck_options $1" -fi - mkdir_cmd=$(command -v mkdir) rm_cmd=$(command -v rm) @@ -17,21 +19,51 @@ export PATH= ec=0 -# self check externals -./cppcheck $selfcheck_options externals || ec=1 -# self check lib/cli +$cppcheck_bin $selfcheck_options \ + externals \ + || ec=1 + $mkdir_cmd b1 -./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 $naming_options frontend || ec=1 -./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 $naming_options -Ifrontend cli || ec=1 -./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 $naming_options --enable=internal lib || ec=1 -# check gui with qt settings + +$cppcheck_bin $selfcheck_options $cppcheck_options $naming_options \ + --cppcheck-build-dir=b1 \ + frontend \ + || ec=1 + +$cppcheck_bin $selfcheck_options $cppcheck_options $naming_options \ + --cppcheck-build-dir=b1 \ + -Ifrontend \ + cli \ + || ec=1 + +$cppcheck_bin $selfcheck_options $cppcheck_options $naming_options \ + --cppcheck-build-dir=b1 --enable=internal \ + lib \ + || ec=1 + $mkdir_cmd b2 -./cppcheck $selfcheck_options $cppcheck_options $gui_options --cppcheck-build-dir=b2 $naming_options -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui || ec=1 -# self check test and tools -./cppcheck $selfcheck_options $cppcheck_options -Ifrontend -Icli test/*.cpp || ec=1 -./cppcheck $selfcheck_options $cppcheck_options -Icli tools/dmake/*.cpp || ec=1 -# triage -./cppcheck $selfcheck_options $cppcheck_options $gui_options -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage || ec=1 + +$cppcheck_bin $selfcheck_options $cppcheck_options $naming_options $qt_options \ + --cppcheck-build-dir=b2 \ + -DQT_CHARTS_LIB \ + -I$cmake_output/gui -Ifrontend -Igui \ + gui/*.cpp $cmake_output/gui \ + || ec=1 + +$cppcheck_bin $selfcheck_options $cppcheck_options \ + -Ifrontend -Icli \ + test/*.cpp \ + || ec=1 + +$cppcheck_bin $selfcheck_options $cppcheck_options \ + -Icli \ + tools/dmake/*.cpp \ + || ec=1 + +$cppcheck_bin $selfcheck_options $cppcheck_options $qt_options \ + -I$cmake_output/tools/triage -Igui \ + tools/triage/*.cpp $cmake_output/tools/triage \ + || ec=1 $rm_cmd -rf b2 $rm_cmd -rf b1 diff --git a/selfcheck_san.sh b/selfcheck_san.sh index 5c8fef353c2..92e34ba6e4f 100755 --- a/selfcheck_san.sh +++ b/selfcheck_san.sh @@ -3,6 +3,8 @@ cmake_output="$1" selfcheck_options_extra="$2" +cppcheck_bin=$cmake_output/bin/cppcheck + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=file-total -D__GNUC__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,information --exception-handling --debug-warnings --check-level=exhaustive" selfcheck_options="$selfcheck_options $selfcheck_options_extra" cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2" @@ -15,42 +17,42 @@ export PATH= ec=0 -$cmake_output/bin/cppcheck $selfcheck_options \ +$cppcheck_bin $selfcheck_options \ externals \ || ec=1 -$cmake_output/bin/cppcheck $selfcheck_options $cppcheck_options $naming_options \ +$cppcheck_bin $selfcheck_options $cppcheck_options $naming_options \ frontend \ || ec=1 -$cmake_output/bin/cppcheck $selfcheck_options $cppcheck_options $naming_options \ +$cppcheck_bin $selfcheck_options $cppcheck_options $naming_options \ -Ifrontend \ cli \ || ec=1 -$cmake_output/bin/cppcheck $selfcheck_options $cppcheck_options $naming_options \ +$cppcheck_bin $selfcheck_options $cppcheck_options $naming_options \ --enable=internal \ lib \ || ec=1 -$cmake_output/bin/cppcheck $selfcheck_options $cppcheck_options $naming_options $qt_options \ +$cppcheck_bin $selfcheck_options $cppcheck_options $naming_options $qt_options \ --suppress=constVariablePointer:*/moc_*.cpp \ -DQT_CHARTS_LIB \ -I$cmake_output/gui -Ifrontend -Igui \ gui/*.cpp $cmake_output/gui \ || ec=1 -$cmake_output/bin/cppcheck $selfcheck_options $cppcheck_options \ - -Icli -Ifrontend \ +$cppcheck_bin $selfcheck_options $cppcheck_options \ + -Ifrontend -Icli \ test/*.cpp \ || ec=1 -$cmake_output/bin/cppcheck $selfcheck_options $cppcheck_options \ +$cppcheck_bin $selfcheck_options $cppcheck_options \ -Icli \ tools/dmake/*.cpp \ || ec=1 -$cmake_output/bin/cppcheck $selfcheck_options $cppcheck_options $qt_options \ +$cppcheck_bin $selfcheck_options $cppcheck_options $qt_options \ -I$cmake_output/tools/triage -Igui \ tools/triage/*.cpp $cmake_output/tools/triage \ || ec=1 From 742df6068e08ebb3d4a902fe46375c5d039c5f13 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 25 Apr 2026 11:06:16 +0200 Subject: [PATCH 021/493] Refs #13814 FP compareValueOutOfTypeRangeError with INT_MAX (#8483) --- lib/checkcondition.cpp | 2 ++ test/cfg/std.c | 2 +- test/testcondition.cpp | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 4bd200adec3..f4aed747de9 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1987,6 +1987,8 @@ void CheckCondition::checkCompareValueOutOfTypeRange() continue; if (valueTok->getKnownIntValue() < 0 && valueTok->valueType() && valueTok->valueType()->sign != ValueType::Sign::SIGNED) continue; + if (typeTok->isLiteral()) + continue; std::uint8_t bits = 0; switch (typeTok->valueType()->type) { case ValueType::Type::BOOL: diff --git a/test/cfg/std.c b/test/cfg/std.c index af0b30e03b2..e8dcec1be6c 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -45,7 +45,7 @@ void test_int32_min() { } void test_int64_min() { - // cppcheck-suppress compareValueOutOfTypeRangeError ; tests that INT64_MIN is a signed expression + // TODO cppcheck-suppress knownConditionTrueFalse // #13814 if (INT64_MIN < 0) {} } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 5dceb392b45..990f105d941 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -6393,6 +6393,13 @@ class TestCondition : public TestFixture { ASSERT_EQUALS("[test.cpp:3:14]: (style) Comparing expression of type 'const unsigned int &' against value 4294967295. Condition is always true. [compareValueOutOfTypeRangeError]\n" "[test.cpp:4:13]: (style) Comparing expression of type 'const unsigned int &' against value 4294967295. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); + + check("void f() {\n" + " long long ll = 1024 * 1024 * 1024;\n" + " if (ll * 8 < INT_MAX) {}\n" + " if (INT_MAX > ll * 8) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void knownConditionCast() { From ef910222c87fd8183d9f7ff576fffe2bfb5d8e92 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 25 Apr 2026 11:08:47 +0200 Subject: [PATCH 022/493] Fix #13179 FP Access of moved variable in while loop (#8469) --- lib/astutils.cpp | 2 -- test/testother.cpp | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 2a4de18b2c0..8712800a867 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2518,8 +2518,6 @@ bool isMutableExpression(const Token* tok) if (tok->astOperand1() && Token::simpleMatch(tok, "[")) return isMutableExpression(tok->astOperand1()); if (const Variable* var = tok->variable()) { - if (var->nameToken() == tok) - return false; if (var->isConst() && !var->isPointer() && (!var->isArray() || !var->isArgument())) return false; } diff --git a/test/testother.cpp b/test/testother.cpp index 64278f95a77..cf83ee08f38 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -12651,6 +12651,24 @@ class TestOther : public TestFixture { " }\n" "}\n"); ASSERT_EQUALS("[test.cpp:4:36]: (warning) Access of moved variable 'l'. [accessMoved]\n", errout_str()); + + check("struct S {\n" // #13179 + " operator bool() const { return !m.empty(); }\n" + " std::string m;\n" + "};\n" + "S get();\n" + "void set(S);\n" + "void f() {\n" + " while (S s = get()) {\n" + " set(std::move(s));\n" + " }\n" + "}\n" + "void g() {\n" + " while (S s{ get() }) {\n" + " set(std::move(s));\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void moveCallback() From 61d83ea04ddafa12291ed20713c996ae4b7735ed Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 25 Apr 2026 13:12:27 +0200 Subject: [PATCH 023/493] Fix #11290 FP uninitdata with array member (#8464) --- lib/checkuninitvar.cpp | 2 ++ test/testuninitvar.cpp | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index ecaed652c5e..3d1a0ecccc5 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1422,6 +1422,8 @@ int CheckUninitVar::isFunctionParUsage(const Token *vartok, const Library& libra const bool isnullbad = library.isnullargbad(start->previous(), argumentNumber + 1); if (indirect == 0 && pointer && !address && isnullbad && alloc == NO_ALLOC) return 1; + if (vartok->varId() == 0 && vartok->valueType()) + indirect = vartok->valueType()->pointer; bool hasIndirect = false; const bool isuninitbad = library.isuninitargbad(start->previous(), argumentNumber + 1, indirect, &hasIndirect); if (alloc != NO_ALLOC) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index d04f3c62e8e..960fee4ee87 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -2173,6 +2173,14 @@ class TestUninitVar : public TestFixture { " return p;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + checkUninitVar("struct S { char c[10]; };\n" // #11290 + "S* f() {\n" + " S* s = (S*)malloc(sizeof(S));\n" + " sprintf(s->c, \"abc\");\n" + " return s;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } // class / struct.. From 2c03f19c1875762dc3c09bb5082e184239a97e75 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 25 Apr 2026 13:13:37 +0200 Subject: [PATCH 024/493] Fix #12196 FP knownConditionTrueFalse when object is modified through another object / partial fix for #12795 FP knownConditionTrueFalse (#8485) --- lib/astutils.cpp | 3 +-- test/testcondition.cpp | 31 ++++++++++++++++++++++++++++++ test/testother.cpp | 43 +++++++++++++++++++++++++++++++++--------- 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 8712800a867..37360519474 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3099,8 +3099,7 @@ static const Token* findExpressionChangedImpl(const Token* expr, } bool global = false; if (tok->variable()) { - global = !tok->variable()->isLocal() && !tok->variable()->isArgument() && - !(tok->variable()->isMember() && !tok->variable()->isStatic()); + global = !tok->variable()->isLocal() && !tok->variable()->isArgument(); } else if (tok->isIncompleteVar() && !tok->isIncompleteConstant()) { global = true; } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 990f105d941..afbcf14ca6d 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -5112,6 +5112,37 @@ class TestCondition : public TestFixture { " if (i < 0) {}\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct A { int x; int y; };" + "void use(int);\n" + "void test(A a) {\n" + " int i = a.x;\n" + " int j = a.x;\n" + " use(j);\n" + " if (i == j) {}\n" + " if (i == a.x) {}\n" + " if (j == a.x) {}\n" + "}"); + ASSERT_EQUALS("[test.cpp:6:11]: (style) Condition 'i==j' is always true [knownConditionTrueFalse]\n" + "[test.cpp:7:11]: (style) Condition 'i==a.x' is always true [knownConditionTrueFalse]\n" + "[test.cpp:8:11]: (style) Condition 'j==a.x' is always true [knownConditionTrueFalse]\n", + errout_str()); + + check("struct S { int i; };\n" // #12795 + "struct T {\n" + " std::map m;\n" + " S* get(const std::string& s) { return m[s]; }\n" + " void modify() { for (const auto& e : m) e.second->i = 0; }\n" + "};\n" + "void f(T& t) {\n" + " const S* p = t.get(\"abc\");\n" + " const int o = p->i;\n" + " t.modify();\n" + " if (p->i == o) {}\n" + "}\n"); + TODO_ASSERT_EQUALS("", + "[test.cpp:11:14]: (style) Condition 'p->i==o' is always true [knownConditionTrueFalse]\n", + errout_str()); } void alwaysTrueInfer() { diff --git a/test/testother.cpp b/test/testother.cpp index cf83ee08f38..54676cc6814 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -200,6 +200,7 @@ class TestOther : public TestFixture { TEST_CASE(duplicateExpression18); TEST_CASE(duplicateExpression19); TEST_CASE(duplicateExpression20); + TEST_CASE(duplicateExpression21); TEST_CASE(duplicateExpressionLoop); TEST_CASE(duplicateValueTernary); TEST_CASE(duplicateValueTernarySizeof); // #13773 @@ -8186,6 +8187,35 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void duplicateExpression21() { + check("struct S { int i; };\n" // #12795 + "struct T {\n" + " std::map m;\n" + " S* get(const std::string& s) { return m[s]; }\n" + " void modify() { for (const auto& e : m) e.second->i = 0; }\n" + "};\n" + "void f(T& t) {\n" + " const S* p = t.get(\"abc\");\n" + " const int o = p->i;\n" + " t.modify();\n" + " if (p->i == o) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S { int i; };\n" + " struct T {\n" + " std::vector m;\n" + " void modify() { for (auto e : m) e->i = 0; }\n" + "};\n" + "void f(T& t) {\n" + " const S* p = t.m[0];\n" + " const int o = p->i;\n" + " t.modify();\n" + " if (p->i == o) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void duplicateExpressionLoop() { check("void f() {\n" " int a = 1;\n" @@ -8897,8 +8927,7 @@ class TestOther : public TestFixture { " if (i == j) {}\n" "}"); ASSERT_EQUALS( - "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n" - "[test.cpp:3:14] -> [test.cpp:4:14] -> [test.cpp:6:11]: (style) The comparison 'i == j' is always true because 'i' and 'j' represent the same value. [knownConditionTrueFalse]\n", + "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct A { int x; int y; };" @@ -8910,8 +8939,7 @@ class TestOther : public TestFixture { " if (i == a.x) {}\n" "}"); ASSERT_EQUALS( - "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n" - "[test.cpp:3:14] -> [test.cpp:6:11]: (style) The comparison 'i == a.x' is always true because 'i' and 'a.x' represent the same value. [knownConditionTrueFalse]\n", + "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct A { int x; int y; };" @@ -8923,8 +8951,7 @@ class TestOther : public TestFixture { " if (j == a.x) {}\n" "}"); ASSERT_EQUALS( - "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n" - "[test.cpp:4:14] -> [test.cpp:6:11]: (style) The comparison 'j == a.x' is always true because 'j' and 'a.x' represent the same value. [knownConditionTrueFalse]\n", + "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); // Issue #8612 @@ -9992,9 +10019,7 @@ class TestOther : public TestFixture { " u.g();\n" " if (c == m->get()) {}\n" "}\n"); - TODO_ASSERT_EQUALS("", - "[test.cpp:16:33] -> [test.cpp:18:11]: (style) The comparison 'c == m->get()' is always true because 'c' and 'm->get()' represent the same value. [knownConditionTrueFalse]\n", - errout_str()); + ASSERT_EQUALS("", errout_str()); check("struct S {\n" // #12925 " const std::string & f() const { return str; }\n" From 9988cd55ba2db159520b4a7daeaff6859c00767a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 25 Apr 2026 16:39:57 +0200 Subject: [PATCH 025/493] Partial fix for #6710 FN nullPointerRedundantCheck after pointer usage in for init statement (#8471) --- lib/reverseanalyzer.cpp | 7 +++++-- test/testnullpointer.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 50aad01fdd9..4afd2556a24 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -110,8 +110,11 @@ namespace { { if (Token::simpleMatch(tok->tokAt(-2), "} else {")) tok = tok->linkAt(-2); - if (Token::simpleMatch(tok->previous(), ") {")) + if (Token::simpleMatch(tok->previous(), ") {")) { + if (Token::simpleMatch(tok->linkAt(-1)->astOperand2(), ";")) + return tok->linkAt(-1)->astOperand2(); return tok->linkAt(-1); + } if (Token::simpleMatch(tok->previous(), "do {")) return tok->previous(); return tok; @@ -232,7 +235,7 @@ namespace { if (!Token::Match(assignTop->astOperand1(), "%assign%")) { continueB &= updateRecursive(assignTop->astOperand1()); } - if (!assignTop->astParent()) + if (!assignTop->astParent() || Token::simpleMatch(assignTop->astParent(), ";")) break; assignTop = assignTop->astParent(); } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index a9ce5ff6f38..83a19c40805 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -3710,6 +3710,19 @@ class TestNullPointer : public TestFixture { " i++;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f(const int* p) {\n" // #6710 + " for (int i = *p; i < 5; ++i) {}\n" + " if (p) {}\n" + "}\n" + "struct S { int a; };\n" + "void g(const S* s) {\n" + " for (int i = s->a; i < 5; ++i) {}\n" + " if (s) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:19]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n" + "[test.cpp:8:9] -> [test.cpp:7:18]: (warning) Either the condition 's' is redundant or there is possible null pointer dereference: s. [nullPointerRedundantCheck]\n", + errout_str()); } void nullpointerDeadCode() { From 6d28ccf9541290b4f94bae75a0ea7f31be90409b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sat, 25 Apr 2026 16:54:39 +0200 Subject: [PATCH 026/493] Add test for #14509 (#8480) This was fixed by b599bb40488bd274d7ad2351a7f7622b05300ba5. --- test/testunusedvar.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 9a116bdaa2b..b857844db68 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -249,6 +249,7 @@ class TestUnusedVar : public TestFixture { TEST_CASE(localvarDelete); TEST_CASE(localvarLambda); // #8941, #8948 TEST_CASE(localvarStructuredBinding); // #10368 + TEST_CASE(localvarPtrToPtr); TEST_CASE(localvarCppInitialization); TEST_CASE(localvarCpp11Initialization); @@ -6958,6 +6959,16 @@ class TestUnusedVar : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void localvarPtrToPtr() { + functionVariableUsage("int main() {\n" + " int *p, **pp = &p;\n" + " int i = 123;\n" + " *pp = &i;\n" + " return *p;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void localvarCppInitialization() { functionVariableUsage("void foo() {\n" " int buf[6];\n" From 034ad1c6e02d7d0b258ed474c78eebb5fce6cb6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sat, 25 Apr 2026 16:56:15 +0200 Subject: [PATCH 027/493] Fix #14468: Missing varid for nested struct members with designated initializers (#8466) --- lib/tokenize.cpp | 4 ++++ test/testvarid.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 34cb997a636..8ff6b972bbe 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4496,6 +4496,10 @@ static void setVarIdStructMembers(Token *&tok1, tok->varId(it->second); } } + if (Token::Match(tok, "%name% = { . %name% =|{")) { + setVarIdStructMembers(tok, structMembers, varId); + tok = tok->linkAt(2); + } tok = tok->next(); } diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 007e16ffb29..64b7b6664be 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -4500,7 +4500,7 @@ class TestVarID : public TestFixture { "2: struct T { struct S s ; } ;\n" "3: struct U { struct T t ; } ;\n" "4: void f ( ) {\n" - "5: struct U u@4 ; u@4 = { .@UNIQUE t@5 = { . s = { . s = 1 } } } ;\n" + "5: struct U u@4 ; u@4 = { .@UNIQUE t@5 = { .@UNIQUE s@6 = { .@UNIQUE s@7 = 1 } } } ;\n" "6: }\n"; ASSERT_EQUALS(exp, tokenizeExpr(code)); } From e9d97293b48ea27b30de30afc5a4ed2039b66587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sat, 25 Apr 2026 16:56:30 +0200 Subject: [PATCH 028/493] Fix #14572: GUI: refresh warning details when rechecking code (#8479) --- gui/resultsview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index 698b6e82018..496c0793157 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -123,6 +123,7 @@ void ResultsView::clear(bool results) } mUI->mDetails->setText(QString()); + mUI->mCode->clear(); mStatistics->clear(); delete mCheckSettings; From cf3f0fac90cb21981f1e0ddb0bf9948e86abbb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sat, 25 Apr 2026 16:57:56 +0200 Subject: [PATCH 029/493] Fix #14676: Syntax error: qRow<> variable template (#8465) --- lib/tokenize.cpp | 2 +- test/testgarbage.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8ff6b972bbe..0efc4e5bb7a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9004,7 +9004,7 @@ void Tokenizer::findGarbageCode() const syntaxError(tok); if (Token::Match(tok, "[;([{] %comp%|%oror%|%or%|%|/")) syntaxError(tok); - if (Token::Match(tok, "%cop%|= ]") && !Token::simpleMatch(tok, "*") && !(cpp && Token::Match(tok->previous(), "%type%|[|,|%num% &|=|> ]"))) + if (Token::Match(tok, "%cop%|= ]") && !Token::simpleMatch(tok, "*") && !(cpp && Token::Match(tok->previous(), "<|%type%|[|,|%num% &|=|> ]"))) syntaxError(tok); if (Token::Match(tok, "[+-] [;,)]}]") && !(cpp && Token::simpleMatch(tok->previous(), "operator"))) syntaxError(tok); diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 5f6b67867f7..68715b78ae8 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -320,7 +320,6 @@ class TestGarbage : public TestFixture { void final_class_x() { - const char code[] = "class __declspec(dllexport) x final { };"; SimpleTokenizer tokenizer(settings, *this); ASSERT(tokenizer.tokenize(code)); @@ -1897,6 +1896,12 @@ class TestGarbage : public TestFixture { // #13892 ASSERT_NO_THROW(checkCode("void foovm(int x[const *]);")); + + // #14676 + ASSERT_NO_THROW(checkCode("int main() {\n" + " auto value = m[1 + qRow<>];\n" + "}\n")); + ignore_errout(); } }; From 58cbb3331cb967423b200e798ff80687bd807efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sat, 25 Apr 2026 16:58:45 +0200 Subject: [PATCH 030/493] Fix #14590: Missing id in DumpData type-info (#8451) --- lib/tokenize.cpp | 22 ++++++++++++++++------ lib/tokenize.h | 1 + test/cli/other_test.py | 4 ++-- test/testsimplifytypedef.cpp | 8 ++++---- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 0efc4e5bb7a..e173aabc30d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1115,14 +1115,18 @@ void Tokenizer::simplifyTypedef() syntaxError(t.second.getTypedefToken()); } else { const Token* const typedefToken = t.second.getTypedefToken(); + const Token* const nameToken = t.second.nameToken(); TypedefInfo typedefInfo; typedefInfo.name = t.second.name(); - typedefInfo.filename = list.file(typedefToken); - typedefInfo.lineNumber = typedefToken->linenr(); - typedefInfo.column = typedefToken->column(); - if (Token::Match(typedefToken->next(), "struct|enum|class|union %name% {") && typedefToken->strAt(2) == typedefInfo.name) { - typedefInfo.tagLine = typedefToken->tokAt(2)->linenr(); - typedefInfo.tagColumn = typedefToken->tokAt(2)->column(); + typedefInfo.filename = list.file(nameToken); + typedefInfo.lineNumber = nameToken->linenr(); + typedefInfo.column = nameToken->column(); + if (Token::Match(typedefToken->next(), "struct|enum|class|union %name% {")) { + typedefInfo.originalName = typedefToken->strAt(2); + if (typedefToken->strAt(2) == typedefInfo.name) { + typedefInfo.tagLine = typedefToken->tokAt(2)->linenr(); + typedefInfo.tagColumn = typedefToken->tokAt(2)->column(); + } } typedefInfo.used = t.second.isUsed(); typedefInfo.isFunctionPointer = isFunctionPointer(t.second.nameToken()); @@ -6380,6 +6384,12 @@ std::string Tokenizer::dumpTypedefInfo() const outs += typedefInfo.name; outs += "\""; + if (!typedefInfo.originalName.empty()) { + outs += " originalName=\""; + outs += typedefInfo.originalName; + outs += "\""; + } + outs += " file=\""; outs += ErrorLogger::toxml(typedefInfo.filename); outs += "\""; diff --git a/lib/tokenize.h b/lib/tokenize.h index 9ee4b29466f..16cd88fa30e 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -698,6 +698,7 @@ class CPPCHECKLIB Tokenizer { }; struct TypedefInfo { std::string name; + std::string originalName; std::string filename; int lineNumber; int column; diff --git a/test/cli/other_test.py b/test/cli/other_test.py index e28a7305ce9..d10cb541e5b 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -420,7 +420,7 @@ def test_addon_misra(tmpdir): assert lines == [ 'Checking {} ...'.format(test_file) ] - assert stderr == '{}:2:1: style: misra violation (use --rule-texts= to get proper output) [misra-c2012-2.3]\ntypedef int MISRA_5_6_VIOLATION;\n^\n'.format(test_file) + assert stderr == '{}:2:13: style: misra violation (use --rule-texts= to get proper output) [misra-c2012-2.3]\ntypedef int MISRA_5_6_VIOLATION;\n ^\n'.format(test_file) def test_addon_y2038(tmpdir): @@ -2674,7 +2674,7 @@ def __test_addon_suppr(tmp_path, extra_args): assert exitcode == 0, stdout assert stdout == '' assert stderr.splitlines() == [ - '{}:4:1: style: misra violation (use --rule-texts= to get proper output) [misra-c2012-2.3]'.format(test_file), + '{}:4:13: style: misra violation (use --rule-texts= to get proper output) [misra-c2012-2.3]'.format(test_file), ] diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 092c9e9df75..342cda59dc8 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -4615,7 +4615,7 @@ class TestSimplifyTypedef : public TestFixture { void typedefInfo1() { const std::string xml = dumpTypedefInfo("typedef int A;\nA x;"); ASSERT_EQUALS(" \n" - " \n" + " \n" " \n", xml); } @@ -4627,7 +4627,7 @@ class TestSimplifyTypedef : public TestFixture { " typedef fp16 ( *pfp16 ) ( void );\n" "}\n"); ASSERT_EQUALS(" \n" - " \n" + " \n" " \n" " \n" " \n" @@ -4639,7 +4639,7 @@ class TestSimplifyTypedef : public TestFixture { " \n" " \n" " \n" - " \n" + " \n" " \n" " \n" " \n" @@ -4677,7 +4677,7 @@ class TestSimplifyTypedef : public TestFixture { "} coord;\n" "coord c;"); ASSERT_EQUALS(" \n" - " \n" + " \n" " \n", xml); } }; From 92d9735221527dfa456a018fe26bb586fc1e0f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sat, 25 Apr 2026 16:59:41 +0200 Subject: [PATCH 031/493] Fix #14637: FP unassignedVariable with reference to array (#8441) --- lib/checkunusedvar.cpp | 4 +++- test/testunusedvar.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 04532e1ecb9..6dd98de078e 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -565,7 +565,7 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de variables.readAll(varid2, tok); } } - } else if (var1->mType == Variables::reference) { + } else if (var1->mType == Variables::reference || var1->mType == Variables::referenceArray) { variables.alias(varid1, varid2, true); } else if (var1->mType == Variables::standard && addressOf) { variables.alias(varid1, varid2, true); @@ -738,6 +738,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const if (type == Variables::none || isPartOfClassStructUnion(i->typeStartToken())) continue; const Token* defValTok = i->nameToken()->next(); + if (Token::Match(i->nameToken()->previous(), "& %var% )")) + defValTok = defValTok->next(); while (defValTok && defValTok->str() == "[") defValTok = defValTok->link()->next(); if (Token::simpleMatch(defValTok, ") (")) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index b857844db68..13d288a3fdd 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -198,6 +198,7 @@ class TestUnusedVar : public TestFixture { TEST_CASE(localvarreturn); // ticket #9167 TEST_CASE(localvarmaybeunused); TEST_CASE(localvarrvalue); // ticket #13977 + TEST_CASE(localvarreferencearray); // ticket #14637 TEST_CASE(localvarthrow); // ticket #3687 @@ -6558,6 +6559,16 @@ class TestUnusedVar : public TestFixture { ASSERT_EQUALS("[test.cpp:3:21]: (style) Variable 'm' is assigned a value that is never used. [unreadVariable]\n", errout_str()); } + void localvarreferencearray() { // ticket #14637 + functionVariableUsage("int f() {\n" + " int a[1];\n" + " int(&r)[1] = a;\n" + " r[0] = 0;\n" + " return r[0];\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void localvarthrow() { // ticket #3687 functionVariableUsage("void foo() {\n" " try {}" From bafada0751cdcf780d4a1f654a5f846fa7c764f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 25 Apr 2026 18:26:12 +0200 Subject: [PATCH 032/493] Fix #14688 (test-my-pr.py: run against the debian ftp server directly) (#8491) --- tools/test-my-pr.py | 135 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 24 deletions(-) diff --git a/tools/test-my-pr.py b/tools/test-my-pr.py index 4a40f544ee1..e0ed773afef 100755 --- a/tools/test-my-pr.py +++ b/tools/test-my-pr.py @@ -8,9 +8,13 @@ import donate_cpu_lib as lib import argparse import glob +import gzip +import natsort import os import sys import random +import re +import requests import subprocess @@ -20,6 +24,100 @@ def format_float(a, b=1): return 'N/A' +def ftp_get(url): + try: + response = requests.get(url, timeout=300) + response.raise_for_status() + return response.content + except requests.RequestException as err: + print('Failed to fetch {}: {}'.format(url, err)) + return None + + +def latestvername(names): + s = natsort.natsorted(names, key=lambda x: x[x.index('_')+1:x.index('.orig.tar')]) + return s[-1] + + +def getpackages(): + debian = 'https://ftp.debian.org/debian/' + + data = ftp_get(debian + 'ls-lR.gz') + if data is None: + print('Failed to fetch ls-lR.gz') + sys.exit(1) + + lines = gzip.decompress(data).decode('utf-8', errors='replace').splitlines() + + # Example content in ls-lR: + #./pool/main/0/0xffff: + #total 1452 + #-rw-r--r-- 2 dak debadmin 6524 Dec 25 2016 0xffff_0.7-2.debian.tar.xz + #-rw-r--r-- 2 dak debadmin 1791 Dec 25 2016 0xffff_0.7-2.dsc + #-rw-r--r-- 2 dak debadmin 57168 Dec 25 2016 0xffff_0.7-2_amd64.deb + #-rw-r--r-- 2 dak debadmin 48578 Dec 26 2016 0xffff_0.7-2_arm64.deb + #-rw-r--r-- 2 dak debadmin 56730 Dec 26 2016 0xffff_0.7-2_armel.deb + #-rw-r--r-- 2 dak debadmin 57296 Dec 26 2016 0xffff_0.7-2_armhf.deb + #-rw-r--r-- 2 dak debadmin 60254 Dec 26 2016 0xffff_0.7-2_i386.deb + #-rw-r--r-- 2 dak debadmin 53130 Dec 26 2016 0xffff_0.7-2_mips.deb + #-rw-r--r-- 2 dak debadmin 52542 Dec 26 2016 0xffff_0.7-2_mips64el.deb + #-rw-r--r-- 2 dak debadmin 53712 Dec 26 2016 0xffff_0.7-2_mipsel.deb + #-rw-r--r-- 2 dak debadmin 51908 Dec 26 2016 0xffff_0.7-2_ppc64el.deb + #-rw-r--r-- 2 dak debadmin 53548 Dec 26 2016 0xffff_0.7-2_s390x.deb + #-rw-r--r-- 2 dak debadmin 65248 Dec 25 2016 0xffff_0.7.orig.tar.gz + #-rw-r--r-- 2 dak debadmin 6884 Jul 19 19:08 0xffff_0.8-1.debian.tar.xz + #-rw-r--r-- 2 dak debadmin 1807 Jul 19 19:08 0xffff_0.8-1.dsc + #-rw-r--r-- 2 dak debadmin 58908 Jul 19 19:08 0xffff_0.8-1_amd64.deb + #-rw-r--r-- 2 dak debadmin 51340 Jul 19 19:58 0xffff_0.8-1_arm64.deb + #-rw-r--r-- 2 dak debadmin 57612 Jul 19 20:13 0xffff_0.8-1_armel.deb + #-rw-r--r-- 2 dak debadmin 58584 Jul 19 19:58 0xffff_0.8-1_armhf.deb + #-rw-r--r-- 2 dak debadmin 57544 Jul 19 20:23 0xffff_0.8-1_hurd-i386.deb + #-rw-r--r-- 2 dak debadmin 62048 Jul 19 23:54 0xffff_0.8-1_i386.deb + #-rw-r--r-- 2 dak debadmin 55080 Jul 23 19:07 0xffff_0.8-1_kfreebsd-amd64.deb + #-rw-r--r-- 2 dak debadmin 58392 Jul 23 19:07 0xffff_0.8-1_kfreebsd-i386.deb + #-rw-r--r-- 2 dak debadmin 54144 Jul 19 22:28 0xffff_0.8-1_mips.deb + #-rw-r--r-- 2 dak debadmin 53648 Jul 20 00:56 0xffff_0.8-1_mips64el.deb + #-rw-r--r-- 2 dak debadmin 54740 Jul 19 22:58 0xffff_0.8-1_mipsel.deb + #-rw-r--r-- 2 dak debadmin 57424 Jul 19 19:58 0xffff_0.8-1_ppc64el.deb + #-rw-r--r-- 2 dak debadmin 53764 Jul 19 22:28 0xffff_0.8-1_s390x.deb + #-rw-r--r-- 2 dak debadmin 64504 Jul 19 19:08 0xffff_0.8.orig.tar.gz + # + + path = None + previous_path = '' + archives = [] + filename = None + filenames = [] + for line in lines: + line = line.strip() + if len(line) < 4: + if filename: + res1 = re.match(r'(.*)-[0-9.]+$', path) + if res1 is None: + res1 = re.match(r'(.*)[-.][0-9.]+$', path) + res2 = re.match(r'(.*)-[0-9.]+$', previous_path) + if res2 is None: + res2 = re.match(r'(.*)[-.][0-9.]+$', previous_path) + if res1 is None or res2 is None or res1.group(1) != res2.group(1): + archives.append(path + '/' + latestvername(filenames)) + else: + archives[-1] = path + '/' + latestvername(filenames) + if path: + previous_path = path + path = None + filename = None + filenames = [] + elif line.startswith('./pool/main/'): + path = debian + line[2:-1] + elif path and line.endswith(('.orig.tar.gz', '.orig.tar.bz2', '.orig.tar.xz')): + filename = line[1 + line.rfind(' '):] + filenames.append(filename) + + return archives + + + + if __name__ == "__main__": __my_script_name = os.path.splitext(os.path.basename(sys.argv[0]))[0] __work_path = os.path.expanduser(os.path.join('~', 'cppcheck-' + __my_script_name + '-workfolder')) @@ -40,6 +138,16 @@ def format_float(a, b=1): print(args) + if args.packages_path: + # You can download packages using daca2-download.py + args.packages = glob.glob(os.path.join(args.packages_path, '*.tar.xz')) + random.shuffle(args.packages) + elif args.packages is None: + args.packages = getpackages() + random.shuffle(args.packages) + + print('\n'.join(args.packages[:20])) + if not lib.check_requirements(): print("Error: Check requirements") sys.exit(1) @@ -100,35 +208,14 @@ def format_float(a, b=1): print('Failed to compile your version of Cppcheck') sys.exit(1) - if args.packages_path: - # You can download packages using daca2-download.py - args.packages = glob.glob(os.path.join(args.packages_path, '*.tar.xz')) - args.p = len(args.packages) - packages_idxs = list(range(args.p)) - random.shuffle(packages_idxs) - elif args.packages: - args.p = len(args.packages) - packages_idxs = [] - else: - packages_count = lib.get_packages_count() - if not packages_count: - print("network or server might be temporarily down..") - sys.exit(1) - - packages_idxs = list(range(packages_count)) - random.shuffle(packages_idxs) - packages_processed = 0 crashes = [] timeouts = [] - while (packages_processed < args.p and len(packages_idxs) > 0) or args.packages: - if args.packages: - package = args.packages.pop() - else: - package = lib.get_package(packages_idxs.pop()) + while packages_processed < args.p and args.packages: + package = args.packages.pop() - if package.startswith('ftp://') or package.startswith('http://'): + if package.startswith('ftp://') or package.startswith('https://'): tgz = lib.download_package(work_path, package, None) if tgz is None: print("No package downloaded") From 4e0a5688cefb0dae05acd955bc53f12ff82992f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Sat, 25 Apr 2026 19:26:32 +0200 Subject: [PATCH 033/493] Fix #14369: Move boolean literal evaluation to valueFlowSetConstantValue (#8468) Previously, boolean literals were processed in a separate loop after valueFlowSetConstantValue. This triggered nullPointer FP with code such as: int f() { const int* p = true ? new int() : nullptr; return *p; // nullPointer FP } Because the condition token had no known value, both branches of the ternary operator were treated as possible, leaking a spurious null value. --------- Signed-off-by: Francois Berder --- lib/valueflow.cpp | 7 +------ lib/vf_common.cpp | 5 +++++ test/testvalueflow.cpp | 10 ++++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 74763fde027..0f1c8a20ce7 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -430,12 +430,7 @@ static void valueFlowNumber(TokenList &tokenlist, const Settings& settings) if (tokenlist.isCPP() || settings.standards.c >= Standards::C23) { for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->isName() && !tok->varId() && Token::Match(tok, "%bool%")) { - ValueFlow::Value value(tok->str() == "true"); - if (!tok->isTemplateArg()) - value.setKnown(); - setTokenValue(tok, std::move(value), settings); - } else if (Token::Match(tok, "[(,] NULL [,)]")) { + if (Token::Match(tok, "[(,] NULL [,)]")) { // NULL function parameters are not simplified in the // normal tokenlist ValueFlow::Value value(0); diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index ab01acc0f16..d6c6088b34b 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -154,6 +154,11 @@ namespace ValueFlow if (!tok->isTemplateArg()) value.setKnown(); setTokenValue(tok, std::move(value), settings); + } else if ((tok->isCpp() || settings.standards.c >= Standards::C23) && (tok->isName() && tok->varId() == 0 && Token::Match(tok, "%bool%"))) { + Value value(tok->str() == "true"); + if (!tok->isTemplateArg()) + value.setKnown(); + setTokenValue(tok, std::move(value), settings); } else if (Token::simpleMatch(tok, "sizeof (")) { if (tok->next()->astOperand2() && !tok->next()->astOperand2()->isLiteral() && tok->next()->astOperand2()->valueType() && (tok->next()->astOperand2()->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index b8b31e8d248..d8a5b533bf3 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1207,6 +1207,16 @@ class TestValueFlow : public TestFixture { ASSERT_EQUALS(1U, values.size()); ASSERT_EQUALS(123, values.empty() ? 0 : values.front().intvalue); + code = "x = true ? 2 : 3;\n"; // #14369 + values = tokenValues(code, "?"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(2, values.empty() ? 0 : values.front().intvalue); + + code = "x = false ? 2 : 3;\n"; // #14369 + values = tokenValues(code, "?"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(3, values.empty() ? 0 : values.front().intvalue); + code = "int f() {\n" " const int i = 1;\n" " int x = i < 0 ? 0 : 1;\n" From 950567e8f7c1b9eaa749a96d6c985b990eebbc7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 25 Apr 2026 20:19:59 +0200 Subject: [PATCH 034/493] Fix #14672 (GUI: cfg files in current folder are not shown) (#8455) --- gui/manualtest/projectfiledialog.md | 11 +++++++++-- gui/projectfile.cpp | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gui/manualtest/projectfiledialog.md b/gui/manualtest/projectfiledialog.md index eb76109e53e..f11b030f246 100644 --- a/gui/manualtest/projectfiledialog.md +++ b/gui/manualtest/projectfiledialog.md @@ -4,8 +4,7 @@ Some manual testing in the project file dialog interface - -## Test: Platform files +## Test: Platform file pic8.xml Ticket: #14489 @@ -14,6 +13,14 @@ EXPECTED: In the project file dialog it should be possible to select xml files i TODO: can this test be automated +## Test: Custom cfg file + +Ticket: #14672 + +1. Copy addons/avr.cfg to a file "aa.cfg" in same folder as a cppcheck GUI project file + +EXPECTED: It should not be possible to activate "aa.cfg" in the project file dialog, it should appear in alphabetical order. + ## Test: Misra C checkbox diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index d2b468443fa..a77c1a0fc94 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -1207,5 +1207,5 @@ QStringList ProjectFile::getSearchPaths(const QString& dir) const { const QString applicationFilePath = QCoreApplication::applicationFilePath(); const QString appPath = QFileInfo(applicationFilePath).canonicalPath(); const QString datadir = getDataDir(); - return getSearchPaths(inf.canonicalFilePath(), appPath, datadir, dir); + return getSearchPaths(inf.canonicalPath(), appPath, datadir, dir); } From 3c377a9faab86c03ae746c13cecee6c253f3d5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 25 Apr 2026 22:45:23 +0200 Subject: [PATCH 035/493] Fix #14687 (Move repository from danmar to cppcheck-opensource) (#8486) --- .github/workflows/cifuzz.yml | 2 +- .github/workflows/coverity.yml | 2 +- .github/workflows/iwyu.yml | 4 ++-- .github/workflows/release-windows.yml | 2 +- .github/workflows/selfcheck.yml | 2 +- CONTRIBUTING.md | 6 +++--- addons/README.md | 20 ++++++++++---------- createrelease | 4 ++-- htmlreport/setup.py | 2 +- man/manual-ja.docbook | 4 ++-- man/manual-premium.md | 6 +++--- man/manual.md | 8 ++++---- readme.md | 6 +++--- readmeja.md | 2 +- releasenotes.txt | 2 +- tools/bisect/bisect.sh | 2 +- tools/donate_cpu_lib.py | 6 +++--- 17 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 7b462c688f0..c54d47da4f1 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -10,7 +10,7 @@ permissions: jobs: Fuzzing: runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'danmar' }} + if: ${{ github.repository_owner == 'cppcheck-opensource' }} steps: - name: Build Fuzzers id: build diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 3c07b61d7c7..006160c7779 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -12,7 +12,7 @@ permissions: jobs: scan: runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'danmar' }} + if: ${{ github.repository_owner == 'cppcheck-opensource' }} steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/iwyu.yml b/.github/workflows/iwyu.yml index ed6971128f5..05d5643bdf7 100644 --- a/.github/workflows/iwyu.yml +++ b/.github/workflows/iwyu.yml @@ -30,7 +30,7 @@ jobs: fail-fast: false runs-on: ${{ matrix.os }} - if: ${{ github.repository_owner == 'danmar' }} + if: ${{ github.repository_owner == 'cppcheck-opensource' }} container: image: ${{ matrix.image }} @@ -192,7 +192,7 @@ jobs: fail-fast: false runs-on: ubuntu-22.04 - if: ${{ github.repository_owner == 'danmar' }} + if: ${{ github.repository_owner == 'cppcheck-opensource' }} env: QT_VERSION: 6.10.0 diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index 607c8434baa..3b5036ff29e 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -22,7 +22,7 @@ jobs: build: runs-on: windows-2025 - if: ${{ github.repository_owner == 'danmar' }} + if: ${{ github.repository_owner == 'cppcheck-opensource' }} env: PYTHON_VERSION: 3.14 diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 389e39371ba..cfd1107e92d 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -172,7 +172,7 @@ jobs: - name: Fetch corpus run: | - wget https://github.com/danmar/cppcheck/archive/refs/tags/2.8.tar.gz + wget https://github.com/cppcheck-opensource/cppcheck/archive/refs/tags/2.8.tar.gz tar xvf 2.8.tar.gz - name: CMake (corpus / no test) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 715a913b6fc..09e88f021e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ These are some guidelines *any* contributor should follow. They will help to mak ## Code Changes -Code contributions are handled via GitHub pull requests: https://github.com/danmar/cppcheck/pulls. +Code contributions are handled via GitHub pull requests: https://github.com/cppcheck-opensource/cppcheck/pulls. If you file a pull request you might not get a reply immediately. We are a very small team and it might not fit in the current scope or time. @@ -18,7 +18,7 @@ Also after you filed a pull request please be ready to reply to questions and fe Please do not be discouraged if your change was rejected or if the review process might not have been as smooth as it could have been. -Each change should be accompanied with a unit ([C++](https://github.com/danmar/cppcheck/tree/main/test)) or integration ([Python](https://github.com/danmar/cppcheck/tree/main/test/cli)) test to ensure that it doesn't regress with future changes. Negative tests (testing the opposite behavior) would be favorable but might not be required or might already exist depending on the change. Tests which introduce `TODO_ASSERT_` or `@pytest.mark.skip`/`@pytest.mark.xfail` should have tickets filed. +Each change should be accompanied with a unit ([C++](https://github.com/cppcheck-opensource/cppcheck/tree/main/test)) or integration ([Python](https://github.com/cppcheck-opensource/cppcheck/tree/main/test/cli)) test to ensure that it doesn't regress with future changes. Negative tests (testing the opposite behavior) would be favorable but might not be required or might already exist depending on the change. Tests which introduce `TODO_ASSERT_` or `@pytest.mark.skip`/`@pytest.mark.xfail` should have tickets filed. If the change is modifying existing behavior (i.e. adding a feature or fixing a bug) it should be accompanied by an issue in the [tracker](https://trac.cppcheck.net) (if you do not have access we can assist with that). Depending on the change it might also warrant an entry in `releasenotes.txt`. @@ -56,7 +56,7 @@ So if you start spending a lot of time on these, you might want to get into touc ## simplecpp -At its core Cppcheck is relying on the `simplecpp` library which is a preprocessor implementation which was spun off into its [separate project](https://github.com/danmar/simplecpp) with its own [bug tracker](https://github.com/danmar/simplecpp/issues). This is also maintained by the Cppcheck developers and contributions to it are also welcome. +At its core Cppcheck is relying on the `simplecpp` library which is a preprocessor implementation which was spun off into its [separate project](https://github.com/cppcheck-opensource/simplecpp) with its own [bug tracker](https://github.com/cppcheck-opensource/simplecpp/issues). This is also maintained by the Cppcheck developers and contributions to it are also welcome. ## Translations diff --git a/addons/README.md b/addons/README.md index 8df8229b970..05502f547b6 100644 --- a/addons/README.md +++ b/addons/README.md @@ -4,19 +4,19 @@ Addons are scripts that analyses Cppcheck dump files to check compatibility with ## Supported addons -+ [misra.py](https://github.com/danmar/cppcheck/blob/main/addons/misra.py) - Used to verify compliance with MISRA C 2012 - a proprietary set of guidelines to avoid such questionable code, developed for embedded systems. Since this standard is proprietary, cppcheck does not display error text by specifying only the number of violated rules (for example, [c2012-21.3]). If you want to display full texts for violated rules, you will need to create a text file containing MISRA rules, which you will have to pass when calling the script with `--rule-texts` key. Some examples of rule texts files available in [tests directory](https://github.com/danmar/cppcheck/blob/main/addons/test/misra/). -+ [y2038.py](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py) - Checks code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. See complete description [here](https://github.com/danmar/cppcheck/blob/main/addons/doc/y2038.md). -+ [threadsafety.py](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py) ++ [misra.py](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/misra.py) + Used to verify compliance with MISRA C 2012 - a proprietary set of guidelines to avoid such questionable code, developed for embedded systems. Since this standard is proprietary, cppcheck does not display error text by specifying only the number of violated rules (for example, [c2012-21.3]). If you want to display full texts for violated rules, you will need to create a text file containing MISRA rules, which you will have to pass when calling the script with `--rule-texts` key. Some examples of rule texts files available in [tests directory](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/test/misra/). ++ [y2038.py](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/y2038.py) + Checks code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. See complete description [here](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/doc/y2038.md). ++ [threadsafety.py](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/threadsafety.py) Analyse Cppcheck dump files to locate threadsafety issues like static local objects used by multiple threads. -+ [naming.py](https://github.com/danmar/cppcheck/blob/main/addons/naming.py) ++ [naming.py](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/naming.py) Enforces naming conventions across the code. -+ [namingng.py](https://github.com/danmar/cppcheck/blob/main/addons/namingng.py) ++ [namingng.py](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/namingng.py) Enforces naming conventions across the code. Enhanced version with support for type prefixes in variable and function names. -+ [findcasts.py](https://github.com/danmar/cppcheck/blob/main/addons/findcasts.py) ++ [findcasts.py](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/findcasts.py) Locates casts in the code. -+ [misc.py](https://github.com/danmar/cppcheck/blob/main/addons/misc.py) ++ [misc.py](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/misc.py) Performs miscellaneous checks. ### Other files @@ -68,5 +68,5 @@ This allows you to add additional parameters when calling the script (for exampl When using the graphical interface `cppcheck-gui`, the selection and configuration of addons is carried out on the tab `Addons and tools` in the project settings (`Edit Project File`): -![Screenshot](https://raw.githubusercontent.com/danmar/cppcheck/main/addons/doc/img/cppcheck-gui-addons.png) +![Screenshot](https://raw.githubusercontent.com/cppcheck-opensource/cppcheck/main/addons/doc/img/cppcheck-gui-addons.png) diff --git a/createrelease b/createrelease index 9dd79333119..de85d64395b 100755 --- a/createrelease +++ b/createrelease @@ -52,7 +52,7 @@ # Create 2.18.x branch # git checkout -b 2.18.x ; git push -u origin 2.18.x # in fork: -# * add upstream: git remote add upstream git@github.com:danmar/cppcheck.git +# * add upstream: git remote add upstream git@github.com:/cppcheck-opensource//cppcheck.git # * add branch: git fetch upstream 2.19.x # # Release notes: @@ -124,7 +124,7 @@ # * daca: cd /var && nice tar -cJf ~/daca.tar.xz daca@home # * git: git checkout -f && git checkout main && git pull && tar -cJf git.tar.xz .git # * git log 2.16.0..2.17.0 > Changelog -# * mkdir out && python3 ~/cppchecksolutions/release/getWorkflowAndIssueLogs.py -r danmar/cppcheck -t 2.15.0 -p out +# * mkdir out && python3 ~/cppchecksolutions/release/getWorkflowAndIssueLogs.py -r /cppcheck-opensource//cppcheck -t 2.15.0 -p out # Folder/tag to use folder=$1 diff --git a/htmlreport/setup.py b/htmlreport/setup.py index 3e049181ce6..9f85000a090 100755 --- a/htmlreport/setup.py +++ b/htmlreport/setup.py @@ -16,7 +16,7 @@ ), long_description=readme, author="Cppcheck Team", - url="https://github.com/danmar/cppcheck", + url="https://github.com/cppcheck-opensource/cppcheck", license="GPL", packages=find_packages(exclude=("tests", "docs")), use_scm_version={"root": ".."}, diff --git a/man/manual-ja.docbook b/man/manual-ja.docbook index 1c13d3d0526..0b2a39cc59e 100644 --- a/man/manual-ja.docbook +++ b/man/manual-ja.docbook @@ -1702,11 +1702,11 @@ Checking unusedvar.cpp... - Cppcheck プロジェクトはいくつかのアドオンを以下の場所で提供しています。: http://github.com/danmar/cppcheck/blob/master/addons + Cppcheck プロジェクトはいくつかのアドオンを以下の場所で提供しています。: http://github.com/cppcheck-opensource/cppcheck/blob/master/addons - ublinterは規格で定義されていない未定義動作に注力した"lint"です。: http://github.com/danmar/ublinter + ublinterは規格で定義されていない未定義動作に注力した"lint"です。: http://github.com/cppcheck-opensource/ublinter diff --git a/man/manual-premium.md b/man/manual-premium.md index 8acfb3c0130..4c30dc6d4b3 100644 --- a/man/manual-premium.md +++ b/man/manual-premium.md @@ -1044,7 +1044,7 @@ Cppcheck is distributed with a few addons which are listed below. ### `namingng.py` -[`namingng.py`](https://github.com/danmar/cppcheck/blob/main/addons/namingng.py) allows you to configure and check naming conventions. +[`namingng.py`](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/namingng.py) allows you to configure and check naming conventions. You need to have a configuration file that defines your naming conventions. By default the filename `namingng.config.json` is used but there is an option so you can use any filename you want. @@ -1070,11 +1070,11 @@ Example configuration of naming conventions: ### `threadsafety.py` -[`threadsafety.py`](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py) analyses Cppcheck dump files to locate thread safety issues like static local objects used by multiple threads. +[`threadsafety.py`](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/threadsafety.py) analyses Cppcheck dump files to locate thread safety issues like static local objects used by multiple threads. ### `y2038.py` -[`y2038.py`](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py) checks source code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. +[`y2038.py`](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/y2038.py) checks source code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. ## Running addons diff --git a/man/manual.md b/man/manual.md index de59afe562c..8d8d5b22350 100644 --- a/man/manual.md +++ b/man/manual.md @@ -1045,7 +1045,7 @@ Cppcheck is distributed with a few addons which are listed below. ### `misra.py` -[`misra.py`](https://github.com/danmar/cppcheck/blob/main/addons/misra.py) is used to verify compliance with MISRA C 2012, a proprietary set of guidelines to avoid questionable code, developed for embedded systems. +[`misra.py`](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/misra.py) is used to verify compliance with MISRA C 2012, a proprietary set of guidelines to avoid questionable code, developed for embedded systems. The `misra.py` script does not provide rule texts, those should be downloaded from [MISRA](https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/tools). @@ -1067,7 +1067,7 @@ Misra checkers in open source Cppcheck only cover MISRA rules partially and for ### `namingng.py` -[`namingng.py`](https://github.com/danmar/cppcheck/blob/main/addons/namingng.py) allows you to configure and check naming conventions. +[`namingng.py`](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/namingng.py) allows you to configure and check naming conventions. You need to have a configuration file that defines your naming conventions. By default the filename `namingng.config.json` is used but there is an option so you can use any filename you want. @@ -1093,11 +1093,11 @@ Example configuration of naming conventions: ### `threadsafety.py` -[`threadsafety.py`](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py) analyses Cppcheck dump files to locate thread safety issues like static local objects used by multiple threads. +[`threadsafety.py`](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/threadsafety.py) analyses Cppcheck dump files to locate thread safety issues like static local objects used by multiple threads. ### `y2038.py` -[`y2038.py`](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py) checks source code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. +[`y2038.py`](https://github.com/cppcheck-opensource/cppcheck/blob/main/addons/y2038.py) checks source code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. ## Running addons diff --git a/readme.md b/readme.md index 7bacadd3456..25db9d2513e 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ |release-windows|OSS-Fuzz|Coverity Scan Build Status|include-what-you-use|License| |:--:|:--:|:--:|:--:|:--:| -|[![release-windows](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml/badge.svg?branch=main)](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml)|[![OSS-Fuzz](https://oss-fuzz-build-logs.storage.googleapis.com/badges/cppcheck.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:cppcheck)|[![Coverity Scan Build Status](https://img.shields.io/coverity/scan/512.svg)](https://scan.coverity.com/projects/512)|[![include-what-you-use](https://github.com/danmar/cppcheck/actions/workflows/iwyu.yml/badge.svg?branch=main)](https://github.com/danmar/cppcheck/actions/workflows/iwyu.yml)|[![License](https://img.shields.io/badge/license-GPL3.0-blue.svg)](https://opensource.org/licenses/GPL-3.0)| +|[![release-windows](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/release-windows.yml/badge.svg?branch=main)](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/release-windows.yml)|[![OSS-Fuzz](https://oss-fuzz-build-logs.storage.googleapis.com/badges/cppcheck.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:cppcheck)|[![Coverity Scan Build Status](https://img.shields.io/coverity/scan/512.svg)](https://scan.coverity.com/projects/512)|[![include-what-you-use](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/iwyu.yml/badge.svg?branch=main)](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/iwyu.yml)|[![License](https://img.shields.io/badge/license-GPL3.0-blue.svg)](https://opensource.org/licenses/GPL-3.0)| ## About the name @@ -263,7 +263,7 @@ Besides building yourself on the platform of your choice there are also several Official packages are maintained by the Cppcheck team. * (Windows) An official Windows installer is available via the official Cppcheck SourceForge page: . -* (Windows) Official builds of the current development versions are available via the [release-windows](https://github.com/danmar/cppcheck/actions/workflows/release-windows.yml) workflow. They are built nightly for the `main` branch and for each commit for release branches. As these are development versions please refrain from using these in production environments! +* (Windows) Official builds of the current development versions are available via the [release-windows](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/release-windows.yml) workflow. They are built nightly for the `main` branch and for each commit for release branches. As these are development versions please refrain from using these in production environments! * A portable package (i.e. does not require installation) is available as the `portable` artifact. This is still a work-in-progress - see for details. * An installer is available via the `installer` artifact. * (Multi-Platform) A premium version with additional features provided by the original author of Cppcheck is available for purchase via . @@ -274,7 +274,7 @@ Third-party packages are ***not*** maintained by the Cppcheck team but their res *Note:* The following list is purely informational and listed in no particular order. -*Note:* Please always try to obtain the package from the primary official source of your operating system/distro first and make sure you are getting the latest released/tagged version (see ). Some packages might not carry the latest patch version though. +*Note:* Please always try to obtain the package from the primary official source of your operating system/distro first and make sure you are getting the latest released/tagged version (see ). Some packages might not carry the latest patch version though. *Note:* Some issues might be related to additional patches carried by the builds in these packages or by the packaging itself. Please try to verify the issue with an official build before reporting it upstream. Otherwise you might need toreport it to the respective maintainer of the package. diff --git a/readmeja.md b/readmeja.md index 6d9dae60c95..7299d61745c 100644 --- a/readmeja.md +++ b/readmeja.md @@ -2,7 +2,7 @@ | Linux ビルド状態 | Windows ビルド状態 | Coverity Scan Build 状態 | |:--:|:--:|:--:| -| [![Linux ビルド状態](https://img.shields.io/travis/danmar/cppcheck/master.svg?label=Linux%20build)](https://travis-ci.org/danmar/cppcheck) | [![Windows ビルド状態](https://img.shields.io/appveyor/ci/danmar/cppcheck/master.svg?label=Windows%20build)](https://ci.appveyor.com/project/danmar/cppcheck/branch/master) | [![Coverity Scan Build 状態](https://img.shields.io/coverity/scan/512.svg)](https://scan.coverity.com/projects/512) | +| [![Linux ビルド状態](https://img.shields.io/travis/cppcheck-opensource/cppcheck/master.svg?label=Linux%20build)](https://travis-ci.org/cppcheck-opensource/cppcheck) | [![Windows ビルド状態](https://img.shields.io/appveyor/ci/cppcheck-opensource/cppcheck/master.svg?label=Windows%20build)](https://ci.appveyor.com/project/cppcheck-opensource/cppcheck/branch/master) | [![Coverity Scan Build 状態](https://img.shields.io/coverity/scan/512.svg)](https://scan.coverity.com/projects/512) | ## 名前について diff --git a/releasenotes.txt b/releasenotes.txt index 38a9e1a41ae..d2ff9c94044 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -23,5 +23,5 @@ Infrastructure & dependencies: Other: - Make it possible to specify the regular expression engine using the `engine` element in a rule XML. - Added CLI option `--exitcode-suppress` to specify an error ID which should not result in a non-zero exitcode. -- +- Moved source code from https://github.com/danmar/cppcheck to https://github.com/cppcheck-opensource/cppcheck - diff --git a/tools/bisect/bisect.sh b/tools/bisect/bisect.sh index cf0d4cd5b96..067cd9606aa 100644 --- a/tools/bisect/bisect.sh +++ b/tools/bisect/bisect.sh @@ -26,7 +26,7 @@ mkdir -p "$bisect_dir" || exit 1 cd "$bisect_dir" || exit 1 if [ ! -d 'cppcheck' ]; then - git clone https://github.com/danmar/cppcheck.git || exit 1 + git clone https://github.com/cppcheck-opensource/cppcheck.git || exit 1 fi bisect_repo_dir="$bisect_dir/cppcheck" diff --git a/tools/donate_cpu_lib.py b/tools/donate_cpu_lib.py index 44d3157bc40..c292d2b9a13 100644 --- a/tools/donate_cpu_lib.py +++ b/tools/donate_cpu_lib.py @@ -16,12 +16,12 @@ # Version scheme (MAJOR.MINOR.PATCH) should orientate on "Semantic Versioning" https://semver.org/ # Every change in this script should result in increasing the version number accordingly (exceptions may be cosmetic # changes) -CLIENT_VERSION = "1.3.70" +CLIENT_VERSION = "1.4.0" # Timeout for analysis with Cppcheck in seconds CPPCHECK_TIMEOUT = 30 * 60 -CPPCHECK_REPO_URL = "https://github.com/danmar/cppcheck.git" +CPPCHECK_REPO_URL = "https://github.com/cppcheck-opensource/cppcheck.git" # Return code that is used to mark a timed out analysis RETURN_CODE_TIMEOUT = -999 @@ -133,7 +133,7 @@ def checkout_cppcheck_version(repo_path, version, cppcheck_path): hash_old = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'], cwd=cppcheck_path).strip() print('Pulling {}'.format(version)) - # --rebase is a workaround for a dropped commit - see https://github.com/danmar/cppcheck/pull/6904 + # --rebase is a workaround for a dropped commit - see https://github.com/cppcheck-opensource/cppcheck/pull/6904 # TODO: drop the commit in question # TOD: remove --rebase subprocess.check_call(['git', 'pull', '--rebase'], cwd=cppcheck_path) From d4c522245b27e0d59f6531e25cfe9880fc8826fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 25 Apr 2026 23:37:27 +0200 Subject: [PATCH 036/493] Fix #14690 (ci: update cppcheck premium version in CI) (#8492) --- .github/workflows/cppcheck-premium.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cppcheck-premium.yml b/.github/workflows/cppcheck-premium.yml index 5cb63ca4d5e..ed0f2a1bcd5 100644 --- a/.github/workflows/cppcheck-premium.yml +++ b/.github/workflows/cppcheck-premium.yml @@ -33,7 +33,7 @@ jobs: run: | premium_version=${{ inputs.premium_version }} if [ -z $premium_version ]; then - premium_version=25.8.3 + premium_version=26.3.0 #wget https://files.cppchecksolutions.com/devdrop/cppcheckpremium-$premium_version-amd64.tar.gz -O cppcheckpremium.tar.gz wget https://files.cppchecksolutions.com/$premium_version/ubuntu-24.04/cppcheckpremium-$premium_version-amd64.tar.gz -O cppcheckpremium.tar.gz else From 02a7c33b789bef2c4596731e15d990ba70bebe81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 26 Apr 2026 02:50:48 +0200 Subject: [PATCH 037/493] valueflow.cpp: pass `ProgramMemory` by reference to `valueFlowForLoop2()` (#8488) --- lib/valueflow.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 0f1c8a20ce7..6db9ba6d1e3 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5158,9 +5158,9 @@ struct SymbolicConditionHandler : SimpleConditionHandler { }; static bool valueFlowForLoop2(const Token *tok, - ProgramMemory *memory1, - ProgramMemory *memory2, - ProgramMemory *memoryAfter, + ProgramMemory &memory1, + ProgramMemory &memory2, + ProgramMemory &memoryAfter, const Settings& settings) { // for ( firstExpression ; secondExpression ; thirdExpression ) @@ -5203,13 +5203,10 @@ static bool valueFlowForLoop2(const Token *tok, } // TODO: add bailout message - if (memory1) - memory1->swap(startMemory); + memory1.swap(startMemory); if (!error) { - if (memory2) - memory2->swap(endMemory); - if (memoryAfter) - memoryAfter->swap(programMemory); + memory2.swap(endMemory); + memoryAfter.swap(programMemory); } return true; @@ -5384,7 +5381,7 @@ static void valueFlowForLoop(const TokenList &tokenlist, const SymbolDatabase& s valueFlowForLoopSimplifyAfter(tok, varid, afterValue, tokenlist, errorLogger, settings); } else { ProgramMemory mem1, mem2, memAfter; - if (valueFlowForLoop2(tok, &mem1, &mem2, &memAfter, settings)) { + if (valueFlowForLoop2(tok, mem1, mem2, memAfter, settings)) { for (const auto& p : mem1) { if (!p.second.isIntValue()) continue; From 6e6f628cebd0c8e7cf0fb9c3120909df4974921f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 26 Apr 2026 02:54:29 +0200 Subject: [PATCH 038/493] fixed #14626 - `execinfo.h` detection in `Makefile` did not work (#8401) --- .github/workflows/CI-unixish.yml | 6 ++++++ Makefile | 8 +++++++- tools/dmake/dmake.cpp | 9 +++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index cf555a8ecc6..3251a6b5adb 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -679,6 +679,12 @@ jobs: test -z "$(nm processexecutor.o)" # TODO: test NO_* defines + - name: Test execinfo.h detection + run: | + make clean + make cli/stacktrace.o | grep HAVE_EXECINFO_H=1 + test -n "$(nm cli/stacktrace.o)" + - name: Test testrunner inclusion/exclusion run: | ! ./testrunner -d TestUtils | grep -v TestUtils > /dev/null diff --git a/Makefile b/Makefile index cd7a56377e2..02735d36ee8 100644 --- a/Makefile +++ b/Makefile @@ -155,7 +155,13 @@ else ifneq ($(HAVE_RULES),) $(error invalid HAVE_RULES value '$(HAVE_RULES)') endif -HAVE_EXECINFO_H=$(shell echo "\#include " | $(CXX) -c -xc - 2> /dev/null && echo "1" || echo "0") +# older make versions do not support # in $(shell) and newer ones handle the escape sequence literally +REQUIRE_ESCAPE=$(shell echo "\#define DEF" | $(CXX) -c -xc - 2> /dev/null && echo "1" || echo "0") +ifeq ($(REQUIRE_ESCAPE),1) + HAVE_EXECINFO_H=$(shell echo "\#include " | $(CXX) -c -xc - 2> /dev/null && echo "1" || echo "0") +else + HAVE_EXECINFO_H=$(shell echo "#include " | $(CXX) -c -xc - 2> /dev/null && echo "1" || echo "0") +endif override CPPFLAGS += -DHAVE_EXECINFO_H=$(HAVE_EXECINFO_H) override CXXFLAGS += $(CXXOPTS) diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index 82754f1df11..80f3aa35b83 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -771,8 +771,13 @@ int main(int argc, char **argv) << " $(error invalid HAVE_RULES value '$(HAVE_RULES)')\n" << "endif\n\n"; - // the # needs to be escaped on older make versions - fout << "HAVE_EXECINFO_H=$(shell echo \"\\#include \" | $(CXX) -c -xc - 2> /dev/null && echo \"1\" || echo \"0\")\n" + fout << "# older make versions do not support # in $(shell) and newer ones handle the escape sequence literally\n" + << "REQUIRE_ESCAPE=$(shell echo \"\\#define DEF\" | $(CXX) -c -xc - 2> /dev/null && echo \"1\" || echo \"0\")\n" + << "ifeq ($(REQUIRE_ESCAPE),1)\n" + << " HAVE_EXECINFO_H=$(shell echo \"\\#include \" | $(CXX) -c -xc - 2> /dev/null && echo \"1\" || echo \"0\")\n" + << "else\n" + << " HAVE_EXECINFO_H=$(shell echo \"#include \" | $(CXX) -c -xc - 2> /dev/null && echo \"1\" || echo \"0\")\n" + << "endif\n" << "override CPPFLAGS += -DHAVE_EXECINFO_H=$(HAVE_EXECINFO_H)\n\n"; fout << "override CXXFLAGS += $(CXXOPTS)\n"; From f59b0c99f0bda35e8737ef974b91bc1149f1826f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 26 Apr 2026 02:55:50 +0200 Subject: [PATCH 039/493] refs #14599 - added `OneShotTimer` / moved some `ShowTime` logic out of `Timer` / added more `--showtime` tests (#8435) --- cli/cppcheckexecutor.cpp | 8 +-- lib/cppcheck.cpp | 8 +-- lib/timer.cpp | 42 ++++++++------ lib/timer.h | 23 ++++---- test/cli/other_test.py | 116 ++++++++++++++++++++++++++++++++------- test/cli/testutils.py | 17 ++++++ 6 files changed, 157 insertions(+), 57 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 69f3e842785..680f7387c70 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -267,8 +267,9 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) return EXIT_SUCCESS; } - TimerResults overallTimerResults; - Timer realTimeClock("Overall time", settings.showtime, &overallTimerResults, Timer::Type::OVERALL); + std::unique_ptr overallTimer; + if (settings.showtime == ShowTime::SUMMARY || settings.showtime == ShowTime::TOP5_SUMMARY) + overallTimer.reset(new OneShotTimer("Overall time", settings.showtime)); settings.loadSummaries(); @@ -277,9 +278,6 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) const int ret = check_wrapper(settings, supprs); - realTimeClock.stop(); - overallTimerResults.showResults(settings.showtime, false, true); - return ret; } diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 0a8e721936b..db2b2e5091a 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -923,8 +923,9 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str if (Settings::terminated()) return mLogger->exitcode(); - TimerResults checkTimeResults; - Timer fileTotalTimer{"Check time: " + file.spath(), mSettings.showtime, &checkTimeResults, Timer::Type::FILE}; + std::unique_ptr checkTimeTimer; + if (mSettings.showtime == ShowTime::FILE || mSettings.showtime == ShowTime::FILE_TOTAL || mSettings.showtime == ShowTime::TOP5_FILE) + checkTimeTimer.reset(new OneShotTimer("Check time: " + file.spath(), mSettings.showtime)); if (!mSettings.quiet) { std::string fixedpath = Path::toNativeSeparators(file.spath()); @@ -1296,9 +1297,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str if (mTimerResults && (mSettings.showtime == ShowTime::FILE || mSettings.showtime == ShowTime::TOP5_FILE)) mTimerResults->showResults(mSettings.showtime); - fileTotalTimer.stop(); - checkTimeResults.showResults(mSettings.showtime, false, true); - return mLogger->exitcode(); } diff --git a/lib/timer.cpp b/lib/timer.cpp index 5a18953767a..495b114fd98 100644 --- a/lib/timer.cpp +++ b/lib/timer.cpp @@ -38,7 +38,7 @@ namespace { // TODO: this does not include any file context when SHOWTIME_FILE thus rendering it useless - should we include the logging with the progress logging? // that could also get rid of the broader locking -void TimerResults::showResults(ShowTime mode, bool metrics, bool format) const +void TimerResults::showResults(ShowTime mode, bool metrics) const { if (mode == ShowTime::NONE) return; @@ -60,11 +60,7 @@ void TimerResults::showResults(ShowTime mode, bool metrics, bool format) const const double sec = iter->second.getSeconds().count(); const double secAverage = sec / static_cast(iter->second.mNumberOfResults); if ((mode != ShowTime::TOP5_FILE && mode != ShowTime::TOP5_SUMMARY) || (ordinal<=5)) { - std::cout << iter->first << ": "; - if (format) - std::cout << TimerResultsData::durationToString(iter->second.mDuration); - else - std::cout << sec << "s"; + std::cout << iter->first << ": " << sec << "s"; if (metrics) std::cout << " (avg. " << secAverage << "s - " << iter->second.mNumberOfResults << " result(s))"; std::cout << std::endl; @@ -87,10 +83,9 @@ void TimerResults::reset() mResults.clear(); } -Timer::Timer(std::string str, ShowTime showtimeMode, TimerResultsIntf* timerResults, Type type) +Timer::Timer(std::string str, ShowTime showtimeMode, TimerResultsIntf* timerResults) : mName(std::move(str)) , mMode(showtimeMode) - , mType(type) , mStart(Clock::now()) , mResults(timerResults) {} @@ -104,14 +99,6 @@ void Timer::stop() { if (mMode == ShowTime::NONE) return; - if (mType == Type::OVERALL && mMode != ShowTime::TOP5_SUMMARY && mMode != ShowTime::SUMMARY) { - mMode = ShowTime::NONE; - return; - } - if (mType == Type::FILE && mMode != ShowTime::TOP5_FILE && mMode != ShowTime::FILE && mMode != ShowTime::FILE_TOTAL) { - mMode = ShowTime::NONE; - return; - } if (mStart != TimePoint{}) { if (!mResults) { assert(false); @@ -124,7 +111,7 @@ void Timer::stop() mMode = ShowTime::NONE; // prevent multiple stops } -std::string TimerResultsData::durationToString(std::chrono::milliseconds duration) +static std::string durationToString(std::chrono::milliseconds duration) { // Extract hours auto hours = std::chrono::duration_cast(duration); @@ -148,3 +135,24 @@ std::string TimerResultsData::durationToString(std::chrono::milliseconds duratio secondsStr.resize(pos + 4); // keep three decimal return (ellapsedTime + secondsStr + "s"); } + +OneShotTimer::OneShotTimer(std::string name, ShowTime showtime) +{ + if (showtime == ShowTime::NONE) + return; + + class MyResults : public TimerResultsIntf + { + private: + void addResults(const std::string &name, std::chrono::milliseconds duration) override + { + std::lock_guard l(stdCoutLock); + + // TODO: do not use std::cout directly + std::cout << name << ": " << durationToString(duration) << std::endl; + } + }; + + mResults.reset(new MyResults); + mTimer.reset(new Timer(std::move(name), showtime, mResults.get())); +} diff --git a/lib/timer.h b/lib/timer.h index e0c4ee2d45f..e6c6833ad54 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -52,15 +53,13 @@ struct TimerResultsData { std::chrono::duration getSeconds() const { return std::chrono::duration_cast>(mDuration); } - - static std::string durationToString(std::chrono::milliseconds duration); }; class CPPCHECKLIB WARN_UNUSED TimerResults : public TimerResultsIntf { public: TimerResults() = default; - void showResults(ShowTime mode, bool metrics = true, bool format = false) const; + void showResults(ShowTime mode, bool metrics = true) const; void addResults(const std::string& str, std::chrono::milliseconds duration) override; void reset(); @@ -75,13 +74,7 @@ class CPPCHECKLIB Timer { using Clock = std::chrono::high_resolution_clock; using TimePoint = std::chrono::time_point; - enum class Type : std::uint8_t { - FILE, - OVERALL, - OTHER - }; - - Timer(std::string str, ShowTime showtimeMode, TimerResultsIntf* timerResults = nullptr, Type type = Type::OTHER); + Timer(std::string str, ShowTime showtimeMode, TimerResultsIntf* timerResults = nullptr); ~Timer(); Timer(const Timer&) = delete; @@ -98,10 +91,18 @@ class CPPCHECKLIB Timer { private: const std::string mName; ShowTime mMode{}; - Type mType{}; TimePoint mStart; TimerResultsIntf* mResults{}; }; +class CPPCHECKLIB OneShotTimer +{ +public: + OneShotTimer(std::string name, ShowTime showtime); +private: + std::unique_ptr mResults; + std::unique_ptr mTimer; +}; + //--------------------------------------------------------------------------- #endif // timerH diff --git a/test/cli/other_test.py b/test/cli/other_test.py index d10cb541e5b..9735c94482b 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -9,7 +9,7 @@ import subprocess import shutil -from testutils import cppcheck, assert_cppcheck, cppcheck_ex, __lookup_cppcheck_exe +from testutils import cppcheck, assert_cppcheck, cppcheck_ex, __lookup_cppcheck_exe, create_compile_commands from xml.etree import ElementTree @@ -956,10 +956,9 @@ def test_unused_function_include(tmpdir): # TODO: test with clang-tidy # TODO: test with --addon -# TODO: test with FileSettings # TODO: test with multiple files -def __test_showtime(tmp_path, showtime, exp_res, exp_last, extra_args=None): - test_file = tmp_path / 'test.cpp' +def __test_showtime(tmp_path, showtime, exp_res, exp_last, use_compdb, extra_args=None): + test_file = tmp_path / 'test.cpp' # the use of C++ is intentional with open(test_file, 'wt') as f: f.write( """ @@ -972,10 +971,17 @@ def __test_showtime(tmp_path, showtime, exp_res, exp_last, extra_args=None): args = [ f'--showtime={showtime}', '--quiet', - '--inline-suppr', - str(test_file) + '--inline-suppr' ] + if use_compdb: + compdb_file = tmp_path / 'compile_commands.json' + create_compile_commands(compdb_file, [test_file]) + + args.append(f'--project={compdb_file}') + else: + args.append(str(test_file)) + if extra_args: args += extra_args @@ -994,50 +1000,122 @@ def __test_showtime(tmp_path, showtime, exp_res, exp_last, extra_args=None): assert stderr == '' +def __test_showtime_top5_file(tmp_path, use_compdb): + __test_showtime(tmp_path, 'top5_file', 5, 'Check time: ', use_compdb) + + def test_showtime_top5_file(tmp_path): - __test_showtime(tmp_path, 'top5_file', 5, 'Check time: ') + __test_showtime_top5_file(tmp_path, False) + + +def test_showtime_top5_file_compdb(tmp_path): + __test_showtime_top5_file(tmp_path, True) + + +# TODO: remove extra args when --executor=process works +def __test_showtime_top5_summary(tmp_path, use_compdb): + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb, ['-j1']) -# TODO: remove extra args when --executor=process works works def test_showtime_top5_summary(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', ['-j1']) + __test_showtime_top5_summary(tmp_path, False) + +def test_showtime_top5_summary_compdb(tmp_path): + __test_showtime_top5_summary(tmp_path, True) -# TODO: remove when --executor=process works works + +# TODO: remove when --executor=process works def test_showtime_top5_summary_j_thread(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', ['-j2', '--executor=thread']) + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', False, ['-j2', '--executor=thread']) + + +# TODO: remove when --executor=process works +def test_showtime_top5_summary_compdb_j_thread(tmp_path): + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', True, ['-j2', '--executor=thread']) # TODO: remove override when fixed @pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") @pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 def test_showtime_top5_summary_j_process(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', ['-j2', '--executor=process']) + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', False, ['-j2', '--executor=process']) + + +# TODO: remove override when fixed +@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") +@pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 +def test_showtime_top5_summary_compdb_j_process(tmp_path): + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', True, ['-j2', '--executor=process']) + + +def __test_showtime_file(tmp_path, use_compdb): + exp_res = 79 + # project analysis does not call Preprocessor::getConfig() + if use_compdb: + exp_res -= 1 + __test_showtime(tmp_path, 'file', exp_res, 'Check time: ', use_compdb) def test_showtime_file(tmp_path): - __test_showtime(tmp_path, 'file', 79, 'Check time: ') + __test_showtime_file(tmp_path, False) + + +def test_showtime_file_compdb(tmp_path): + __test_showtime_file(tmp_path, True) + + +# TODO: remove extra args when --executor=process works +def __test_showtime_summary(tmp_path, use_compdb): + exp_res = 79 + # project analysis does not call Preprocessor::getConfig() + if use_compdb: + exp_res -= 1 + __test_showtime(tmp_path, 'summary', exp_res, 'Overall time: ', use_compdb, ['-j1']) -# TODO: remove extra args when --executor=process works works def test_showtime_summary(tmp_path): - __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', ['-j1']) + __test_showtime_summary(tmp_path, False,) + +def test_showtime_summary_compdb(tmp_path): + __test_showtime_summary(tmp_path, True) -# TODO: remove when --executor=process works works + +# TODO: remove when --executor=process works def test_showtime_summary_j_thread(tmp_path): - __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', ['-j2', '--executor=thread']) + __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', False, ['-j2', '--executor=thread']) + + +# TODO: remove when --executor=process works +def test_showtime_summary_compdb_j_thread(tmp_path): + __test_showtime(tmp_path, 'summary', 78, 'Overall time: ', True, ['-j2', '--executor=thread']) # TODO: remove override when fixed @pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") @pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 def test_showtime_summary_j_process(tmp_path): - __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', ['-j2', '--executor=process']) + __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', False, ['-j2', '--executor=process']) + + +# TODO: remove override when fixed +@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") +@pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 +def test_showtime_summary_compdb_j_process(tmp_path): + __test_showtime(tmp_path, 'summary', 78, 'Overall time: ', True, ['-j2', '--executor=process']) + + +def __test_showtime_file_total(tmp_path, use_compdb): + __test_showtime(tmp_path, 'file-total', 0, 'Check time: ', use_compdb) def test_showtime_file_total(tmp_path): - __test_showtime(tmp_path, 'file-total', 0, 'Check time: ') + __test_showtime_file_total(tmp_path, False) + + +def test_showtime_file_total_compdb(tmp_path): + __test_showtime_file_total(tmp_path, True) def test_showtime_unique(tmp_path): diff --git a/test/cli/testutils.py b/test/cli/testutils.py index f352af49f15..2140c42205b 100644 --- a/test/cli/testutils.py +++ b/test/cli/testutils.py @@ -5,6 +5,7 @@ import subprocess import time import tempfile +import json # Create Cppcheck project file import sys @@ -45,6 +46,22 @@ def create_gui_project_file(project_file, root_path=None, import_project=None, p f.write(cppcheck_xml) +def create_compile_commands(compdb_file, files): + compdb = [] + # TODO: bail out on empty list + for f in files: + compdb.append( + { + "file": str(f), + "directory": os.path.dirname(f), + "command": "gcc -c {}".format(os.path.basename(f)) + } + ) + compdb_j = json.dumps(compdb) + with open(compdb_file, 'wt') as f: + f.write(compdb_j) + + def __lookup_cppcheck_exe(): # path the script is located in script_path = os.path.dirname(os.path.realpath(__file__)) From c5e0a3dd71d0f2fbe72482fd73cdf6d1b537d46b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 26 Apr 2026 10:25:58 +0200 Subject: [PATCH 040/493] refs #10543 - config.h: removed platform checks in favor of `HAVE_EXECINFO_H` / added `__has_include()` as fallback (#8489) --- lib/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config.h b/lib/config.h index 960c2c91aa4..c88c431288c 100644 --- a/lib/config.h +++ b/lib/config.h @@ -203,7 +203,7 @@ #if HAVE_EXECINFO_H #define USE_UNIX_BACKTRACE_SUPPORT #endif -#elif defined(__GNUC__) && !defined(__APPLE__) && !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__SVR4) && !defined(__QNX__) && !defined(_AIX) +#elif __has_include() #define USE_UNIX_BACKTRACE_SUPPORT #endif #endif From 0294253bc08389cf4dc5fb5d58aa31eb3734d3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 26 Apr 2026 10:28:02 +0200 Subject: [PATCH 041/493] utils.h: reject unexpected preceding characters in `strToInt()` (#8490) --- lib/utils.h | 28 +++++++++++++--- test/testcmdlineparser.cpp | 34 ++++++++++---------- test/testerrorlogger.cpp | 4 +-- test/testsuppressions.cpp | 12 +++---- test/testutils.cpp | 66 ++++++++++++++++++++++++++++++-------- 5 files changed, 101 insertions(+), 43 deletions(-) diff --git a/lib/utils.h b/lib/utils.h index 14f5382a8bf..3f9c4ab949f 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -220,7 +220,7 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr) tmp = std::stoll(str, &idx); if (idx != str.size()) { if (err) - *err = "not an integer"; + *err = "not an integer (pos)"; return false; } } catch (const std::out_of_range&) { @@ -229,7 +229,7 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr) return false; } catch (const std::invalid_argument &) { if (err) - *err = "not an integer"; + *err = "not an integer (invalid_argument)"; return false; } if (str.front() == '-' && std::numeric_limits::min() == 0) { @@ -237,6 +237,16 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr) *err = "needs to be positive"; return false; } + if (str.front() != '+' && str.front() != '-' && isdigit(str.front()) == 0) { + if (err) + *err = "not an integer"; + return false; + } + if (str.size() > 1 && str.front() == '0') { + if (err) + *err = "not an integer"; + return false; + } if (tmp < std::numeric_limits::min() || tmp > std::numeric_limits::max()) { if (err) *err = "out of range (limits)"; @@ -255,7 +265,7 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr) tmp = std::stoull(str, &idx); if (idx != str.size()) { if (err) - *err = "not an integer"; + *err = "not an integer (pos)"; return false; } } catch (const std::out_of_range&) { @@ -264,7 +274,7 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr) return false; } catch (const std::invalid_argument &) { if (err) - *err = "not an integer"; + *err = "not an integer (invalid_argument)"; return false; } if (str.front() == '-') { @@ -272,6 +282,16 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr) *err = "needs to be positive"; return false; } + if (str.front() != '+' && isdigit(str.front()) == 0) { + if (err) + *err = "not an integer"; + return false; + } + if (str.size() > 1 && str.front() == '0') { + if (err) + *err = "not an integer"; + return false; + } if (tmp > std::numeric_limits::max()) { if (err) *err = "out of range (limits)"; diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 71dd068b39e..06ee30837d6 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -1236,7 +1236,7 @@ class TestCmdlineParser : public TestFixture { const char * const argv[] = {"cppcheck", "--error-exitcode=", "file.cpp"}; // Fails since exit code not given ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--error-exitcode=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--error-exitcode=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void errorExitcodeStr() { @@ -1244,7 +1244,7 @@ class TestCmdlineParser : public TestFixture { const char * const argv[] = {"cppcheck", "--error-exitcode=foo", "file.cpp"}; // Fails since invalid exit code ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--error-exitcode=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--error-exitcode=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void exitcodeSuppressionsOld() { @@ -1395,7 +1395,7 @@ class TestCmdlineParser : public TestFixture { const char * const argv[] = {"cppcheck", "-j", "file.cpp"}; // Fails since -j is missing thread count ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '-j' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '-j' is not valid - not an integer (invalid_argument).\n", logger->str()); } void jobsInvalid() { @@ -1403,7 +1403,7 @@ class TestCmdlineParser : public TestFixture { const char * const argv[] = {"cppcheck", "-j", "e", "file.cpp"}; // Fails since invalid count given for -j ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '-j' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '-j' is not valid - not an integer (invalid_argument).\n", logger->str()); } void jobsNoJobs() { @@ -1433,7 +1433,7 @@ class TestCmdlineParser : public TestFixture { const char * const argv[] = {"cppcheck", "--max-configs=", "file.cpp"}; // Fails since --max-configs= is missing limit ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--max-configs=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--max-configs=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void maxConfigsInvalid() { @@ -1441,7 +1441,7 @@ class TestCmdlineParser : public TestFixture { const char * const argv[] = {"cppcheck", "--max-configs=e", "file.cpp"}; // Fails since invalid count given for --max-configs= ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--max-configs=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--max-configs=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void maxConfigsTooSmall() { @@ -1672,7 +1672,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--report-progress=", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--report-progress=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--report-progress=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void reportProgress3() { @@ -2172,7 +2172,7 @@ class TestCmdlineParser : public TestFixture { const char * const argv[] = {"cppcheck", "--xml", "--xml-version=a", "file.cpp"}; // FAils since unknown XML format version ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--xml-version=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--xml-version=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void doc() { @@ -2395,7 +2395,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--valueflow-max-iterations=seven"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--valueflow-max-iterations=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--valueflow-max-iterations=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void valueFlowMaxIterationsInvalid3() { @@ -2423,7 +2423,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--checks-max-time=one", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--checks-max-time=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--checks-max-time=' is not valid - not an integer (invalid_argument).\n", logger->str()); } #ifdef HAS_THREADING_MODEL_FORK @@ -2445,7 +2445,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "-l", "one", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '-l' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '-l' is not valid - not an integer (invalid_argument).\n", logger->str()); } #else void loadAverageNotSupported() { @@ -2482,7 +2482,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--max-ctu-depth=one", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--max-ctu-depth=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--max-ctu-depth=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void performanceValueflowMaxTime() { @@ -2496,7 +2496,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--performance-valueflow-max-time=one", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--performance-valueflow-max-time=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--performance-valueflow-max-time=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void performanceValueFlowMaxIfCount() { @@ -2510,7 +2510,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--performance-valueflow-max-if-count=one", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--performance-valueflow-max-if-count=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--performance-valueflow-max-if-count=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void templateMaxTime() { @@ -2524,7 +2524,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--template-max-time=one", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--template-max-time=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--template-max-time=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void templateMaxTimeInvalid2() { @@ -2545,7 +2545,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--typedef-max-time=one", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--typedef-max-time=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--typedef-max-time=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void typedefMaxTimeInvalid2() { @@ -3235,7 +3235,7 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--max-template-recursion=", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--max-template-recursion=' is not valid - not an integer.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--max-template-recursion=' is not valid - not an integer (invalid_argument).\n", logger->str()); } void emitDuplicates() { diff --git a/test/testerrorlogger.cpp b/test/testerrorlogger.cpp index 812ea500299..23b3233995c 100644 --- a/test/testerrorlogger.cpp +++ b/test/testerrorlogger.cpp @@ -599,7 +599,7 @@ class TestErrorLogger : public TestFixture { "0 " "0 "; ErrorMessage msg; - ASSERT_THROW_INTERNAL_EQUALS(msg.deserialize(str), INTERNAL, "Internal Error: Deserialization of error message failed - invalid CWE ID - not an integer"); + ASSERT_THROW_INTERNAL_EQUALS(msg.deserialize(str), INTERNAL, "Internal Error: Deserialization of error message failed - invalid CWE ID - not an integer (invalid_argument)"); } { // invalid hash @@ -615,7 +615,7 @@ class TestErrorLogger : public TestFixture { "0 " "0 "; ErrorMessage msg; - ASSERT_THROW_INTERNAL_EQUALS(msg.deserialize(str), INTERNAL, "Internal Error: Deserialization of error message failed - invalid hash - not an integer"); + ASSERT_THROW_INTERNAL_EQUALS(msg.deserialize(str), INTERNAL, "Internal Error: Deserialization of error message failed - invalid hash - not an integer (invalid_argument)"); } { // out-of-range CWE ID diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 3233a5918c7..49d46149c90 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -188,12 +188,12 @@ class TestSuppressions : public TestFixture { ASSERT_THROW_EQUALS(SuppressionList::parseLine("id::1"), std::runtime_error, "filename is missing"); // missing/invalid line - ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer)"); - ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:\n"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer)"); - ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:\n1"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer)"); - ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:#1"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer)"); // TODO: looks like a valid filename - ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c://1"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer)"); - ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:zero"), std::runtime_error, "invalid line number (converting 'zero' to integer failed - not an integer)"); + ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer (invalid_argument))"); + ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:\n"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer (invalid_argument))"); + ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:\n1"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer (invalid_argument))"); + ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:#1"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer (invalid_argument))"); // TODO: looks like a valid filename + ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c://1"), std::runtime_error, "invalid line number (converting '' to integer failed - not an integer (invalid_argument))"); + ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:zero"), std::runtime_error, "invalid line number (converting 'zero' to integer failed - not an integer (invalid_argument))"); // invalid extras ASSERT_THROW_EQUALS(SuppressionList::parseLine("id:1.c:1\n"), std::runtime_error, "unexpected extra ''"); diff --git a/test/testutils.cpp b/test/testutils.cpp index 85da8c6c595..8e91108c3f4 100644 --- a/test/testutils.cpp +++ b/test/testutils.cpp @@ -223,19 +223,57 @@ class TestUtils : public TestFixture { void strToInt() { ASSERT_EQUALS(1, ::strToInt("1")); + ASSERT_EQUALS(1, ::strToInt("+1")); ASSERT_EQUALS(-1, ::strToInt("-1")); ASSERT_EQUALS(1, ::strToInt("1")); - ASSERT_THROW_EQUALS(::strToInt(""), std::runtime_error, "converting '' to integer failed - not an integer"); - ASSERT_THROW_EQUALS(::strToInt(""), std::runtime_error, "converting '' to integer failed - not an integer"); - ASSERT_THROW_EQUALS(::strToInt(" "), std::runtime_error, "converting ' ' to integer failed - not an integer"); - ASSERT_THROW_EQUALS(::strToInt(" "), std::runtime_error, "converting ' ' to integer failed - not an integer"); + ASSERT_EQUALS(1, ::strToInt("+1")); + ASSERT_EQUALS(0, ::strToInt("0")); + ASSERT_EQUALS(0, ::strToInt("+0")); + ASSERT_EQUALS(0, ::strToInt("-0")); + ASSERT_EQUALS(0, ::strToInt("0")); + ASSERT_EQUALS(0, ::strToInt("+0")); + ASSERT_THROW_EQUALS(::strToInt(""), std::runtime_error, "converting '' to integer failed - not an integer (invalid_argument)"); + ASSERT_THROW_EQUALS(::strToInt(""), std::runtime_error, "converting '' to integer failed - not an integer (invalid_argument)"); + ASSERT_THROW_EQUALS(::strToInt(" "), std::runtime_error, "converting ' ' to integer failed - not an integer (invalid_argument)"); + ASSERT_THROW_EQUALS(::strToInt(" "), std::runtime_error, "converting ' ' to integer failed - not an integer (invalid_argument)"); ASSERT_THROW_EQUALS(::strToInt("-1"), std::runtime_error, "converting '-1' to integer failed - needs to be positive"); - ASSERT_THROW_EQUALS(::strToInt("1ms"), std::runtime_error, "converting '1ms' to integer failed - not an integer"); - ASSERT_THROW_EQUALS(::strToInt("1.0"), std::runtime_error, "converting '1.0' to integer failed - not an integer"); - ASSERT_THROW_EQUALS(::strToInt("one"), std::runtime_error, "converting 'one' to integer failed - not an integer"); - ASSERT_THROW_EQUALS(::strToInt("1ms"), std::runtime_error, "converting '1ms' to integer failed - not an integer"); - ASSERT_THROW_EQUALS(::strToInt("1.0"), std::runtime_error, "converting '1.0' to integer failed - not an integer"); - ASSERT_THROW_EQUALS(::strToInt("one"), std::runtime_error, "converting 'one' to integer failed - not an integer"); + ASSERT_THROW_EQUALS(::strToInt("-0"), std::runtime_error, "converting '-0' to integer failed - needs to be positive"); + ASSERT_THROW_EQUALS(::strToInt("-1"), std::runtime_error, "converting '-1' to integer failed - needs to be positive"); + ASSERT_THROW_EQUALS(::strToInt("-0"), std::runtime_error, "converting '-0' to integer failed - needs to be positive"); + ASSERT_THROW_EQUALS(::strToInt("1ms"), std::runtime_error, "converting '1ms' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1.0"), std::runtime_error, "converting '1.0' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("+1.0"), std::runtime_error, "converting '+1.0' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("-1.0"), std::runtime_error, "converting '-1.0' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1U"), std::runtime_error, "converting '1U' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1L"), std::runtime_error, "converting '1L' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1Z"), std::runtime_error, "converting '1Z' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("01"), std::runtime_error, "converting '01' to integer failed - not an integer"); + ASSERT_THROW_EQUALS(::strToInt("0x1"), std::runtime_error, "converting '0x1' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("0b1"), std::runtime_error, "converting '0b1' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("one"), std::runtime_error, "converting 'one' to integer failed - not an integer (invalid_argument)"); + ASSERT_THROW_EQUALS(::strToInt(" 1"), std::runtime_error, "converting ' 1' to integer failed - not an integer"); + ASSERT_THROW_EQUALS(::strToInt("\t1"), std::runtime_error, "converting '\t1' to integer failed - not an integer"); + ASSERT_THROW_EQUALS(::strToInt("1 "), std::runtime_error, "converting '1 ' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1\t"), std::runtime_error, "converting '1\t' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("+ 1"), std::runtime_error, "converting '+ 1' to integer failed - not an integer (invalid_argument)"); + ASSERT_THROW_EQUALS(::strToInt("O1"), std::runtime_error, "converting 'O1' to integer failed - not an integer (invalid_argument)"); + ASSERT_THROW_EQUALS(::strToInt("1ms"), std::runtime_error, "converting '1ms' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1.0"), std::runtime_error, "converting '1.0' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("+1.0"), std::runtime_error, "converting '+1.0' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("-1.0"), std::runtime_error, "converting '-1.0' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1U"), std::runtime_error, "converting '1U' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1L"), std::runtime_error, "converting '1L' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1Z"), std::runtime_error, "converting '1Z' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("01"), std::runtime_error, "converting '01' to integer failed - not an integer"); + ASSERT_THROW_EQUALS(::strToInt("0x1"), std::runtime_error, "converting '0x1' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("0b1"), std::runtime_error, "converting '0b1' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("one"), std::runtime_error, "converting 'one' to integer failed - not an integer (invalid_argument)"); + ASSERT_THROW_EQUALS(::strToInt(" 1"), std::runtime_error, "converting ' 1' to integer failed - not an integer"); + ASSERT_THROW_EQUALS(::strToInt("\t1"), std::runtime_error, "converting '\t1' to integer failed - not an integer"); + ASSERT_THROW_EQUALS(::strToInt("1 "), std::runtime_error, "converting '1 ' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("1\t"), std::runtime_error, "converting '1\t' to integer failed - not an integer (pos)"); + ASSERT_THROW_EQUALS(::strToInt("- 1"), std::runtime_error, "converting '- 1' to integer failed - not an integer (invalid_argument)"); + ASSERT_THROW_EQUALS(::strToInt("O1"), std::runtime_error, "converting 'O1' to integer failed - not an integer (invalid_argument)"); ASSERT_THROW_EQUALS(::strToInt(std::to_string(static_cast(std::numeric_limits::max()) + 1)), std::runtime_error, "converting '2147483648' to integer failed - out of range (limits)"); ASSERT_THROW_EQUALS(::strToInt(std::to_string(static_cast(std::numeric_limits::min()) - 1)), std::runtime_error, "converting '-2147483649' to integer failed - out of range (limits)"); ASSERT_THROW_EQUALS(::strToInt(std::to_string(static_cast(std::numeric_limits::max()) + 1)), std::runtime_error, "converting '128' to integer failed - out of range (limits)"); @@ -311,25 +349,25 @@ class TestUtils : public TestFixture { long tmp; std::string err; ASSERT(!::strToInt("1ms", tmp, &err)); - ASSERT_EQUALS("not an integer", err); + ASSERT_EQUALS("not an integer (pos)", err); } { long tmp; std::string err; ASSERT(!::strToInt("1.0", tmp, &err)); - ASSERT_EQUALS("not an integer", err); + ASSERT_EQUALS("not an integer (pos)", err); } { long tmp; std::string err; ASSERT(!::strToInt("one", tmp, &err)); - ASSERT_EQUALS("not an integer", err); + ASSERT_EQUALS("not an integer (invalid_argument)", err); } { std::size_t tmp; std::string err; ASSERT(!::strToInt("1ms", tmp, &err)); - ASSERT_EQUALS("not an integer", err); + ASSERT_EQUALS("not an integer (pos)", err); } { long tmp; From a374143aa25c215ed7f71c9fa6affe50d4853f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 26 Apr 2026 10:29:20 +0200 Subject: [PATCH 042/493] fixed #14618 - added more metrics to timer summary / small `TimerResultsData` refactoring (#8458) --- lib/timer.cpp | 16 +++++++++------- lib/timer.h | 17 ++++++++++++----- test/options.cpp | 4 +--- test/testtimer.cpp | 2 +- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/timer.cpp b/lib/timer.cpp index 495b114fd98..f4025fb3427 100644 --- a/lib/timer.cpp +++ b/lib/timer.cpp @@ -57,24 +57,26 @@ void TimerResults::showResults(ShowTime mode, bool metrics) const size_t ordinal = 1; // maybe it would be nice to have an ordinal in output later! for (auto iter=data.cbegin(); iter!=data.cend(); ++iter) { - const double sec = iter->second.getSeconds().count(); - const double secAverage = sec / static_cast(iter->second.mNumberOfResults); if ((mode != ShowTime::TOP5_FILE && mode != ShowTime::TOP5_SUMMARY) || (ordinal<=5)) { + const double sec = iter->second.getSeconds().count(); std::cout << iter->first << ": " << sec << "s"; - if (metrics) - std::cout << " (avg. " << secAverage << "s - " << iter->second.mNumberOfResults << " result(s))"; + if (metrics) { + const double secAverage = sec / static_cast(iter->second.mResults.size()); + const double secMin = asSeconds(*std::min_element(iter->second.mResults.cbegin(), iter->second.mResults.cend())).count(); + const double secMax = asSeconds(*std::max_element(iter->second.mResults.cbegin(), iter->second.mResults.cend())).count(); + std::cout << " (avg. " << secAverage << "s / min " << secMin << "s / max " << secMax << "s - " << iter->second.mResults.size() << " result(s))"; + } std::cout << std::endl; } ++ordinal; } } -void TimerResults::addResults(const std::string& str, std::chrono::milliseconds duration) +void TimerResults::addResults(const std::string& name, std::chrono::milliseconds duration) { std::lock_guard l(mResultsSync); - mResults[str].mDuration += duration; - mResults[str].mNumberOfResults++; + mResults[name].mResults.push_back(duration); } void TimerResults::reset() diff --git a/lib/timer.h b/lib/timer.h index e6c6833ad54..5611bc5304b 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -27,8 +27,10 @@ #include #include #include +#include #include #include +#include enum class ShowTime : std::uint8_t { NONE, @@ -43,15 +45,20 @@ class CPPCHECKLIB TimerResultsIntf { public: virtual ~TimerResultsIntf() = default; - virtual void addResults(const std::string& timerName, std::chrono::milliseconds duation) = 0; + virtual void addResults(const std::string& name, std::chrono::milliseconds duration) = 0; + + static std::chrono::duration asSeconds(std::chrono::milliseconds ms) { + return std::chrono::duration_cast>(ms); + } }; struct TimerResultsData { - std::chrono::milliseconds mDuration; - long mNumberOfResults{}; + std::vector mResults; std::chrono::duration getSeconds() const { - return std::chrono::duration_cast>(mDuration); + return std::accumulate(mResults.cbegin(), mResults.cend(), std::chrono::duration{}, [](std::chrono::duration secs, std::chrono::milliseconds duration) { + return secs + TimerResultsIntf::asSeconds(duration); + }); } }; @@ -60,7 +67,7 @@ class CPPCHECKLIB WARN_UNUSED TimerResults : public TimerResultsIntf { TimerResults() = default; void showResults(ShowTime mode, bool metrics = true) const; - void addResults(const std::string& str, std::chrono::milliseconds duration) override; + void addResults(const std::string& name, std::chrono::milliseconds duration) override; void reset(); diff --git a/test/options.cpp b/test/options.cpp index bdb4f553ac8..9db2bce8563 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -59,10 +59,8 @@ options::options(int argc, const char* const argv[]) options::~options() { // TODO: allow more than 5 results to be shown - // TODO: provide higher resolution in output - // TODO: disable the metrics if (mTimerResults) - mTimerResults->showResults(ShowTime::TOP5_FILE); + mTimerResults->showResults(ShowTime::TOP5_FILE, false); } bool options::quiet() const diff --git a/test/testtimer.cpp b/test/testtimer.cpp index c8d468b1afb..3f160c0c2b7 100644 --- a/test/testtimer.cpp +++ b/test/testtimer.cpp @@ -33,7 +33,7 @@ class TestTimer : public TestFixture { void result() const { TimerResultsData t1; - t1.mDuration = std::chrono::milliseconds{1234}; + t1.mResults.emplace_back(1234); ASSERT(t1.getSeconds().count() > 1.233 && t1.getSeconds().count() < 1.235); // TODO : more tests From 6fa5b6b943186c808dfddd13d8677a3015262e9e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 26 Apr 2026 10:57:53 +0200 Subject: [PATCH 043/493] Refs #4412: using namespace std; not simplified (constructor) (#8477) Co-authored-by: chrchr-github --- lib/tokenize.cpp | 14 ++++++++++---- test/testtokenize.cpp | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index e173aabc30d..4cce2a71434 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10344,6 +10344,13 @@ static bool isStdSmartPointer(const Token* tok, const Settings& settings) return ptr && startsWith(ptr->name, "std::"); } +static bool isLibraryType(const Token* tok, const Settings& settings) +{ + return settings.library.hasAnyTypeCheck("std::" + tok->str()) || + settings.library.podtype("std::" + tok->str()) || + isStdContainerOrIterator(tok, settings); +} + // Add std:: in front of std classes, when using namespace std; was given void Tokenizer::simplifyNamespaceStd() { @@ -10371,14 +10378,13 @@ void Tokenizer::simplifyNamespaceStd() if (start != tok && start->isName() && !start->isKeyword() && (!start->previous() || Token::Match(start->previous(), "[;{}]"))) userFunctions.insert(tok->str()); } - if (userFunctions.find(tok->str()) == userFunctions.end() && mSettings.library.matchArguments(tok, "std::" + tok->str())) + if ((userFunctions.find(tok->str()) == userFunctions.end() && mSettings.library.matchArguments(tok, "std::" + tok->str())) || + (tok->tokAt(-1)->isKeyword() && isLibraryType(tok, mSettings))) insert = true; } else if (Token::simpleMatch(tok->next(), "<") && (isStdContainerOrIterator(tok, mSettings) || isStdSmartPointer(tok, mSettings))) insert = true; - else if (mSettings.library.hasAnyTypeCheck("std::" + tok->str()) || - mSettings.library.podtype("std::" + tok->str()) || - isStdContainerOrIterator(tok, mSettings)) + else if (isLibraryType(tok, mSettings)) insert = true; else if (Token::simpleMatch(tok, "aligned_storage")) insert = true; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 0798983c079..9b816a357b7 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -5288,12 +5288,7 @@ class TestTokenizer : public TestFixture { "if ( ! p ) {\n" "throw std :: runtime_error ( \"abc\" ) ; }\n" "}"; - TODO_ASSERT_EQUALS(expected, - "void f ( const std :: unique_ptr < int > & p ) {\n" - "if ( ! p ) {\n" - "throw runtime_error ( \"abc\" ) ; }\n" - "}", - tokenizeAndStringify(code)); + ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } { @@ -5315,6 +5310,17 @@ class TestTokenizer : public TestFixture { "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } + + { + const char code[] = "using namespace std;\n" + "string_view f() { return string(); }\n" + "void move() {}\n" + "void string() {}\n"; + expected = "std :: string_view f ( ) { return std :: string ( ) ; }\n" + "void move ( ) { }\n" + "void string ( ) { }"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code)); + } } void microsoftMemory() { From aec1a7f17bad28a5b0c4cc93a041f745a5ea7b6c Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 26 Apr 2026 21:05:24 +0200 Subject: [PATCH 044/493] Fix #6492 valueflow: for loop condition not used for conditional analysis (#8472) To be merged after #8471. Ignoring the debug messages since the line numbers were flaky. --------- Co-authored-by: chrchr-github --- lib/valueflow.cpp | 32 +++++++++++++++++++------------- test/testnullpointer.cpp | 7 +++++++ test/testsimplifytokens.cpp | 1 + 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 6db9ba6d1e3..614d568ea80 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4961,6 +4961,24 @@ static void valueFlowCondition(const ValuePtr& handler, handler->afterCondition(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions); } +static const Token* getConditionVariable(const Token* tok) +{ + if (tok->str() == "!") + return tok->astOperand1(); + + if (const Token* parent = tok->astParent()) { + if (Token::Match(parent, "%oror%|&&|?") || + Token::Match(parent->previous(), "if|while (") || + (parent->str() == ";" && astIsLHS(tok) && Token::simpleMatch(parent->astParent(), ";"))) { // for loop condition + if (Token::simpleMatch(tok, "=")) + return tok->astOperand1(); + if (!Token::Match(tok, "%comp%|%assign%")) + return tok; + } + } + return nullptr; +} + struct SimpleConditionHandler : ConditionHandler { std::vector parse(const Token* tok, const Settings& /*settings*/) const override { @@ -4979,19 +4997,7 @@ struct SimpleConditionHandler : ConditionHandler { if (!conds.empty()) return conds; - const Token* vartok = nullptr; - - if (tok->str() == "!") { - vartok = tok->astOperand1(); - - } else if (tok->astParent() && (Token::Match(tok->astParent(), "%oror%|&&|?") || - Token::Match(tok->astParent()->previous(), "if|while ("))) { - if (Token::simpleMatch(tok, "=")) - vartok = tok->astOperand1(); - else if (!Token::Match(tok, "%comp%|%assign%")) - vartok = tok; - } - + const Token* vartok = getConditionVariable(tok); if (!vartok) return {}; Condition cond; diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 83a19c40805..967cd0d2315 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -3723,6 +3723,13 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:19]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n" "[test.cpp:8:9] -> [test.cpp:7:18]: (warning) Either the condition 's' is redundant or there is possible null pointer dereference: s. [nullPointerRedundantCheck]\n", errout_str()); + + check("struct S { int a; };\n" // #6492 + "void h(const S* s) {\n" + " for (int i = s->a; s; ++i) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:24] -> [test.cpp:3:18]: (warning) Either the condition 's' is redundant or there is possible null pointer dereference: s. [nullPointerRedundantCheck]\n", + errout_str()); } void nullpointerDeadCode() { diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 4e227bfca17..88d1a4b2725 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2207,6 +2207,7 @@ class TestSimplifyTokens : public TestFixture { "for ( i = 0 ; ( i < sz ) && ( sz > 3 ) ; ++ i ) { }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, dinit(TokenizeAndStringifyOptions, $.cpp = false))); + ignore_errout(); } void simplifyKnownVariables49() { // #3691 From 6dc5c7645f8c893bf2963c14d876dc2f3e6ff498 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 27 Apr 2026 10:16:42 +0200 Subject: [PATCH 045/493] Fix #14546 FN uninitMemberVar (in-class initializers but no constructor) (#8274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: chrchr-github Co-authored-by: Daniel Marjamäki --- lib/checkclass.cpp | 218 ++++++++++++++++++++++++-------------- lib/checkclass.h | 6 +- lib/pathmatch.h | 4 +- lib/tokenize.h | 8 +- releasenotes.txt | 1 + test/testconstructors.cpp | 13 +++ 6 files changed, 161 insertions(+), 89 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index ebdb434bb24..69cf8e70533 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -116,6 +116,90 @@ CheckClass::CheckClass(const Tokenizer *tokenizer, const Settings *settings, Err mSymbolDatabase(tokenizer?tokenizer->getSymbolDatabase():nullptr) {} +bool CheckClass::isInitialized(const CheckClass::Usage& usage, FunctionType funcType) const +{ + const Variable& var = *usage.var; + + if (usage.assign || usage.init || var.isStatic()) + return true; + + if (!var.nameToken() || var.nameToken()->isAnonymous()) + return true; + + if (var.valueType() && var.valueType()->pointer == 0 && var.type() && var.type()->needInitialization == Type::NeedInitialization::False && var.type()->derivedFrom.empty()) + return true; + + if (var.isConst() && funcType == FunctionType::eOperatorEqual) // We can't set const members in assignment operator + return true; + + // Check if this is a class constructor + if (!var.isPointer() && !var.isPointerArray() && var.isClass() && funcType == FunctionType::eConstructor) { + // Unknown type so assume it is initialized + if (!var.type()) { + if (var.isStlType() && var.valueType() && var.valueType()->containerTypeToken) { + if (var.valueType()->type == ValueType::Type::ITERATOR) + { + // needs initialization + } + else if (var.getTypeName() == "std::array") { + const Token* ctt = var.valueType()->containerTypeToken; + if (!ctt->isStandardType() && + (!ctt->type() || ctt->type()->needInitialization != Type::NeedInitialization::True) && + !mSettings->library.podtype(ctt->str())) // TODO: handle complex type expression + return true; + } + else + return true; + } + else + return true; + } + + // Known type that doesn't need initialization or + // known type that has member variables of an unknown type + else if (var.type()->needInitialization != Type::NeedInitialization::True) + return true; + } + + // Check if type can't be copied + if (!var.isPointer() && !var.isPointerArray() && var.typeScope()) { + if (funcType == FunctionType::eMoveConstructor) { + if (canNotMove(var.typeScope())) + return true; + } + else { + if (canNotCopy(var.typeScope())) + return true; + } + } + return false; +} + +void CheckClass::handleUnionMembers(std::vector& usageList) +{ + // Assign 1 union member => assign all union members + for (const Usage& usage : usageList) { + const Variable& var = *usage.var; + if (!usage.assign && !usage.init) + continue; + const Scope* varScope1 = var.nameToken()->scope(); + while (varScope1->type == ScopeType::eStruct) + varScope1 = varScope1->nestedIn; + if (varScope1->type == ScopeType::eUnion) { + for (Usage& usage2 : usageList) { + const Variable& var2 = *usage2.var; + if (usage2.assign || usage2.init || var2.isStatic()) + continue; + const Scope* varScope2 = var2.nameToken()->scope(); + while (varScope2->type == ScopeType::eStruct) + varScope2 = varScope2->nestedIn; + if (varScope1 == varScope2) + usage2.assign = true; + } + } + } +} + //--------------------------------------------------------------------------- // ClassCheck: Check that all class constructors are ok. //--------------------------------------------------------------------------- @@ -145,6 +229,7 @@ void CheckClass::constructors() }); // There are no constructors. + std::set diagVars; if (scope->numConstructors == 0 && printStyle && !usedInUnion) { // If there is a private variable, there should be a constructor.. int needInit = 0, haveInit = 0; @@ -163,8 +248,10 @@ void CheckClass::constructors() if (haveInit == 0) noConstructorError(scope->classDef, scope->className, scope->classDef->str() == "struct"); else - for (const Variable* uv : uninitVars) + for (const Variable* uv : uninitVars) { uninitVarError(uv->typeStartToken(), uv->scope()->className, uv->name()); + diagVars.emplace(uv); + } } } @@ -201,85 +288,15 @@ void CheckClass::constructors() std::list callstack; initializeVarList(func, callstack, scope, usageList); - // Assign 1 union member => assign all union members - for (const Usage &usage : usageList) { - const Variable& var = *usage.var; - if (!usage.assign && !usage.init) - continue; - const Scope* varScope1 = var.nameToken()->scope(); - while (varScope1->type == ScopeType::eStruct) - varScope1 = varScope1->nestedIn; - if (varScope1->type == ScopeType::eUnion) { - for (Usage &usage2 : usageList) { - const Variable& var2 = *usage2.var; - if (usage2.assign || usage2.init || var2.isStatic()) - continue; - const Scope* varScope2 = var2.nameToken()->scope(); - while (varScope2->type == ScopeType::eStruct) - varScope2 = varScope2->nestedIn; - if (varScope1 == varScope2) - usage2.assign = true; - } - } - } + handleUnionMembers(usageList); // Check if any variables are uninitialized for (const Usage &usage : usageList) { - const Variable& var = *usage.var; - - if (usage.assign || usage.init || var.isStatic()) - continue; - - if (!var.nameToken() || var.nameToken()->isAnonymous()) - continue; - - if (var.valueType() && var.valueType()->pointer == 0 && var.type() && var.type()->needInitialization == Type::NeedInitialization::False && var.type()->derivedFrom.empty()) - continue; - - if (var.isConst() && func.isOperator()) // We can't set const members in assignment operator + if (isInitialized(usage, func.type)) continue; - // Check if this is a class constructor - if (!var.isPointer() && !var.isPointerArray() && var.isClass() && func.type == FunctionType::eConstructor) { - // Unknown type so assume it is initialized - if (!var.type()) { - if (var.isStlType() && var.valueType() && var.valueType()->containerTypeToken) { - if (var.valueType()->type == ValueType::Type::ITERATOR) - { - // needs initialization - } - else if (var.getTypeName() == "std::array") { - const Token* ctt = var.valueType()->containerTypeToken; - if (!ctt->isStandardType() && - (!ctt->type() || ctt->type()->needInitialization != Type::NeedInitialization::True) && - !mSettings->library.podtype(ctt->str())) // TODO: handle complex type expression - continue; - } - else - continue; - } - else - continue; - } - - // Known type that doesn't need initialization or - // known type that has member variables of an unknown type - else if (var.type()->needInitialization != Type::NeedInitialization::True) - continue; - } - - // Check if type can't be copied - if (!var.isPointer() && !var.isPointerArray() && var.typeScope()) { - if (func.type == FunctionType::eMoveConstructor) { - if (canNotMove(var.typeScope())) - continue; - } else { - if (canNotCopy(var.typeScope())) - continue; - } - } - // Is there missing member copy in copy/move constructor or assignment operator? + const Variable& var = *usage.var; bool missingCopy = false; // Don't warn about unknown types in copy constructors since we @@ -326,6 +343,38 @@ void CheckClass::constructors() } } } + + if (scope->numConstructors == 0) { + + // Mark all variables not used + clearAllVar(usageList); + + // Variables with default initializers + bool hasAnyDefaultInit = false; + for (Usage& usage : usageList) { + const Variable& var = *usage.var; + + // check for C++11 initializer + if (var.hasDefault()) { + usage.init = true; + hasAnyDefaultInit = true; + } + } + if (!hasAnyDefaultInit) + continue; + + handleUnionMembers(usageList); + + // Check if any variables are uninitialized + for (const Usage& usage : usageList) { + if (isInitialized(usage, FunctionType::eConstructor)) + continue; + + const Variable& var = *usage.var; + if (diagVars.count(&var) == 0) + uninitVarError(scope->bodyStart, false, FunctionType::eConstructor, var.scope()->className, var.name(), false, false, true); + } + } } } @@ -1118,17 +1167,22 @@ void CheckClass::noExplicitConstructorError(const Token *tok, const std::string reportError(tok, Severity::style, "noExplicitConstructor", "$symbol:" + classname + '\n' + message + '\n' + verbose, CWE398, Certainty::normal); } -void CheckClass::uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive) +void CheckClass::uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor) { - std::string ctor; - if (functionType == FunctionType::eCopyConstructor) - ctor = "copy "; - else if (functionType == FunctionType::eMoveConstructor) - ctor = "move "; - std::string message("Member variable '$symbol' is not initialized in the " + ctor + "constructor."); + std::string message("Member variable '$symbol' "); + if (noCtor) + message += "has no initializer."; + else { + message += "is not initialized in the "; + if (functionType == FunctionType::eCopyConstructor) + message += "copy "; + else if (functionType == FunctionType::eMoveConstructor) + message += "move "; + message += "constructor."; + } if (derived) message += " Maybe it should be initialized directly in the class " + classname + "?"; - std::string id = std::string("uninit") + (derived ? "Derived" : "") + "MemberVar" + (isprivate ? "Private" : ""); + std::string id = std::string("uninit") + (derived ? "Derived" : "") + "MemberVar" + (isprivate ? "Private" : "") + (noCtor ? "NoCtor" : ""); const std::string verbose {message + " Member variables of native types, pointers, or references are left uninitialized when the class is instantiated. That may cause bugs or undefined behavior."}; reportError(tok, Severity::warning, id, "$symbol:" + classname + "::" + varname + '\n' + message + '\n' + verbose, CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal); } diff --git a/lib/checkclass.h b/lib/checkclass.h index 6cdea8d581c..2fb1862dad1 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -155,7 +155,7 @@ class CPPCHECKLIB CheckClass : public Check { void noCopyConstructorError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive); void noOperatorEqError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive); void noDestructorError(const Scope *scope, bool isdefault, const Token *alloc); - void uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive); + void uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor = false); void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname); void missingMemberCopyError(const Token *tok, FunctionType functionType, const std::string& classname, const std::string& varname); void operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive); @@ -254,6 +254,10 @@ class CPPCHECKLIB CheckClass : public Check { bool init{}; }; + static void handleUnionMembers(std::vector& usageList); + + bool isInitialized(const Usage& usage, FunctionType funcType) const; + static bool isBaseClassMutableMemberFunc(const Token *tok, const Scope *scope); /** diff --git a/lib/pathmatch.h b/lib/pathmatch.h index 33d9a64ec90..72fc89b7faa 100644 --- a/lib/pathmatch.h +++ b/lib/pathmatch.h @@ -274,9 +274,9 @@ class PathMatch::PathIterator { /* Position struct */ struct Pos { /* String pointer */ - const char *p; + const char *p{}; /* Raw characters left */ - std::size_t l; + std::size_t l{}; /* Buffered character */ int c {EOF}; }; diff --git a/lib/tokenize.h b/lib/tokenize.h index 16cd88fa30e..f7f6ddbecae 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -700,12 +700,12 @@ class CPPCHECKLIB Tokenizer { std::string name; std::string originalName; std::string filename; - int lineNumber; - int column; + int lineNumber{}; + int column{}; int tagLine{-1}; int tagColumn{-1}; - bool used; - bool isFunctionPointer; + bool used{}; + bool isFunctionPointer{}; std::vector typedefInfoTokens; }; std::vector mTypedefInfo; diff --git a/releasenotes.txt b/releasenotes.txt index d2ff9c94044..ec8c6032da9 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -7,6 +7,7 @@ Major bug fixes & crashes: New checks: - MISRA C 2012 rule 10.3 now warns on assigning integer literals 0 and 1 to bool in C99 and later while preserving the existing C89 behavior. - funcArgNamesDifferentUnnamed warns on function declarations/definitions where a parameter in either location is unnamed +- uninitMemberVarNoCtor warns on user-defined types where some but not all members requiring initialization have in-class initializers. C/C++ support: - diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 54af2d0a1c3..61916e1d0bb 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -92,6 +92,7 @@ class TestConstructors : public TestFixture { TEST_CASE(noConstructor13); // #9998 TEST_CASE(noConstructor14); // #10770 TEST_CASE(noConstructor15); // #5499 + TEST_CASE(noConstructor16); TEST_CASE(forwardDeclaration); // ticket #4290/#3190 @@ -758,6 +759,18 @@ class TestConstructors : public TestFixture { ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'C::i2' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } + void noConstructor16() { + check("struct S {\n" // #14546 + " int a = 0, b;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:1:10]: (warning) Member variable 'S::b' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" + " int a, b;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + // ticket #4290 "False Positive: style (noConstructor): The class 'foo' does not have a constructor." // ticket #3190 "SymbolDatabase: Parse of sub class constructor fails" void forwardDeclaration() { From ddbe12ec8329f9415d21a03c1abfadbe345a9ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 27 Apr 2026 11:11:57 +0200 Subject: [PATCH 046/493] Fix #14695 (triage: handle https urls also) (#8495) --- tools/triage/mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/triage/mainwindow.cpp b/tools/triage/mainwindow.cpp index 564d6e1bcf2..c8989601efd 100644 --- a/tools/triage/mainwindow.cpp +++ b/tools/triage/mainwindow.cpp @@ -137,7 +137,7 @@ void MainWindow::load(QTextStream &textStream) QString line = textStream.readLine(); if (line.isNull()) break; - if (line.startsWith("ftp://") || (line.startsWith(DACA2_PACKAGES) && line.endsWith(".tar.xz"))) { + if (line.startsWith("ftp://") || line.startsWith("https://") || (line.startsWith(DACA2_PACKAGES) && line.endsWith(".tar.xz"))) { local = line.startsWith(DACA2_PACKAGES) && line.endsWith(".tar.xz"); url = line; if (!errorMessage.isEmpty()) @@ -293,7 +293,7 @@ void MainWindow::showResult(QListWidgetItem *item) { ui->statusBar->clearMessage(); const bool local = item->text().startsWith(DACA2_PACKAGES); - if (!item->text().startsWith("ftp://") && !local) + if (!item->text().startsWith("ftp://") && !item->text().startsWith("https://") && !local) return; const QStringList lines = item->text().split("\n"); if (lines.size() < 2) From c9f142e5770ec9280cbceab465a3b672027ebf74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Mon, 27 Apr 2026 11:55:17 +0200 Subject: [PATCH 047/493] readme.md: added a note about the repository move [skip ci] (#8501) --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 25db9d2513e..512a1ec1110 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,7 @@ # **Cppcheck** +NOTE: This repository was recently moved from https://github.com/danmar/cppcheck to https://github.com/cppcheck-opensource/cppcheck. Please make sure to update all your references to it accordingly. + |release-windows|OSS-Fuzz|Coverity Scan Build Status|include-what-you-use|License| |:--:|:--:|:--:|:--:|:--:| |[![release-windows](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/release-windows.yml/badge.svg?branch=main)](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/release-windows.yml)|[![OSS-Fuzz](https://oss-fuzz-build-logs.storage.googleapis.com/badges/cppcheck.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:cppcheck)|[![Coverity Scan Build Status](https://img.shields.io/coverity/scan/512.svg)](https://scan.coverity.com/projects/512)|[![include-what-you-use](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/iwyu.yml/badge.svg?branch=main)](https://github.com/cppcheck-opensource/cppcheck/actions/workflows/iwyu.yml)|[![License](https://img.shields.io/badge/license-GPL3.0-blue.svg)](https://opensource.org/licenses/GPL-3.0)| From a3faaa7e103fb195ace7c86bb3095dd4b2b60fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 27 Apr 2026 12:22:57 +0200 Subject: [PATCH 048/493] Fix #14520: false positive: passedByValue on declaration with const (#8460) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Oliver Stöneberg --- lib/checkother.cpp | 15 +++++++++++++++ test/testother.cpp | 11 +++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 9cd5dba4469..ab1d1fec37b 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1591,6 +1591,21 @@ void CheckOther::checkPassByReference() if (var->isArray() && (!var->isStlType() || Token::simpleMatch(var->nameToken()->next(), "["))) continue; + if (var->isArgument()) { + const Token *tok = var->typeStartToken(); + for (; tok; tok = tok->next()) { + if (Token::simpleMatch(tok, "(")) { + tok = tok->link(); + continue; + } + if (Token::simpleMatch(tok, ")")) + break; + } + + if (Token::simpleMatch(tok, ") ;")) + continue; + } + const bool isConst = var->isConst(); if (isConst) { passedByValueError(var, inconclusive, isRangeBasedFor); diff --git a/test/testother.cpp b/test/testother.cpp index 54676cc6814..e11a08f49de 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2911,6 +2911,9 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); check("struct X { int a[5]; }; void f(const X v);"); + ASSERT_EQUALS("", errout_str()); + + check("struct X { int a[5]; }; void f(const X v) { (void) v; }"); ASSERT_EQUALS("[test.cpp:1:40]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); check("extern \"C\" { struct X { int a[5]; }; void f(const X v); }"); @@ -4109,6 +4112,14 @@ class TestOther : public TestFixture { " if (*pp) {}\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("class C {\n" + "public:\n" + " explicit C(const std::string s);\n" + "private:\n" + " std::string _s;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); } void constParameterCallback() { From b9513d3f14d64d62b0a44659eb4debbd443a2b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 27 Apr 2026 12:26:06 +0200 Subject: [PATCH 049/493] Fix #14487: FP duplicateBranch with empty macro (#8481) My reasoning here is that a single semicolon most likely is a result of an empty macro expansion. I can't think of a case where one would put a single semicolon where it would make sense to warn. --- lib/checkother.cpp | 2 +- test/testother.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index ab1d1fec37b..4628dd0d774 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2692,7 +2692,7 @@ void CheckOther::checkDuplicateBranch() const std::string branch2 = tokElse->stringifyList(scope.bodyEnd->linkAt(2)); // check for duplicates - if (branch1 == branch2) { + if (branch1 == branch2 && branch1 != ";") { duplicateBranchError(scope.classDef, scope.bodyEnd->next(), ErrorPath{}); continue; } diff --git a/test/testother.cpp b/test/testother.cpp index e11a08f49de..0b645a87ff0 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -7316,6 +7316,15 @@ class TestOther : public TestFixture { " }\n" "}"); ASSERT_EQUALS("", errout_str()); + + check("void f(int i) {\n" + " if (1 == i) {\n" + " ;\n" + " } else {\n" + " ;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void duplicateBranch6() { From 34486df78318da429a21445ab4b6561dfcef4848 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 27 Apr 2026 17:11:19 +0200 Subject: [PATCH 050/493] Fix #14693 False positive: null pointer, std::string && val = {} (#8499) --- lib/tokenlist.cpp | 2 +- test/testsymboldatabase.cpp | 5 +++++ test/testvalueflow.cpp | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 3df17141f24..e525bdd7609 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -446,7 +446,7 @@ static Token* skipDecl(Token* tok, std::vector* inner = nullptr) if (!Token::Match(tok->previous(), "( %name%")) return tok; Token *vartok = tok; - while (Token::Match(vartok, "%name%|*|&|::|<")) { + while (Token::Match(vartok, "%name%|*|&|&&|::|<")) { if (vartok->str() == "<") { if (vartok->link()) vartok = vartok->link(); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 8348e0cd44b..6efda65c11b 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -587,6 +587,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(valueType3); TEST_CASE(valueTypeThis); TEST_CASE(valueTypeChar); + TEST_CASE(valueTypeRValueReference); TEST_CASE(variadic1); // #7453 TEST_CASE(variadic2); // #7649 @@ -10175,6 +10176,10 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS("char", typeOf("char buf[10]; buf[0] = 'x';", "[ 0 ]", true, &s)); } + void valueTypeRValueReference() { + TODO_ASSERT_EQUALS("", "bool", typeOf("void f(std::string&& s = {})", "&&")); + } + void variadic1() { // #7453 { GET_SYMBOL_DB("CBase* create(const char *c1, ...);\n" diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index d8a5b533bf3..ff5d18b3175 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5277,6 +5277,12 @@ class TestValueFlow : public TestFixture { " continuous_src_time(std::complex f, double st = 0.0, double et = infinity) {}\n" "};"; (void)testValueOfX(code, 2U, 2); // Don't crash (#6494) + + code = "struct S {\n" // #14693 + " int i;\n" + " explicit S(std::string&& s = {}) : i(0) {}\n" + "};"; + ASSERT_EQUALS(false, testKnownValueOfTok(code, "{ } )", 0)); } bool isNotKnownValues(const char code[], const char str[]) { From 10a0cbb0404cb20127e51541279eb09101fc496a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 28 Apr 2026 09:06:27 +0200 Subject: [PATCH 051/493] Fix #14703 False positive: buffer out of bounds, memcpy, array of pointer (#8504) Co-authored-by: chrchr-github --- lib/symboldatabase.cpp | 7 ++++++- test/testbufferoverrun.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 9b42b799405..5905597c8c1 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2503,7 +2503,12 @@ bool Variable::isMember() const { bool Variable::isPointerArray() const { - return isArray() && nameToken() && nameToken()->previous() && (nameToken()->strAt(-1) == "*"); + if (!isArray()) + return false; + const Token* tok = nameToken() ? nameToken()->previous() : nullptr; + while (Token::Match(tok, "const|volatile")) + tok = tok->previous(); + return Token::simpleMatch(tok, "*"); } bool Variable::isUnsigned() const diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 7118a7ae906..35e2cca6667 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -226,6 +226,7 @@ class TestBufferOverrun : public TestFixture { TEST_CASE(buffer_overrun_34); //#11035 TEST_CASE(buffer_overrun_35); //#2304 TEST_CASE(buffer_overrun_36); + TEST_CASE(buffer_overrun_37); TEST_CASE(buffer_overrun_errorpath); TEST_CASE(buffer_overrun_bailoutIfSwitch); // ticket #2378 : bailoutIfSwitch TEST_CASE(buffer_overrun_function_array_argument); @@ -3497,6 +3498,15 @@ class TestBufferOverrun : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void buffer_overrun_37() { // #14703 + check("void f() {\n" + " const char *dst[256];\n" + " static const char * const src[] = {\"a\", \"b\", \"c\"};\n" + " memcpy(dst, src, sizeof(src));\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void buffer_overrun_errorpath() { setMultiline(); Settings s = settings0; From 189653164fe9c7f5c0f0e89d9e7fc71d00c1cdc7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 28 Apr 2026 11:50:31 +0200 Subject: [PATCH 052/493] Add test for #10948 (#8506) --- test/cfg/std.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/cfg/std.c b/test/cfg/std.c index e8dcec1be6c..928d52bf116 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -287,6 +287,13 @@ char* nullPointer_fgets(char *buffer, int n, FILE *stream) return fgets(buffer, n, stream); } +void nullPointer_fseek(void) { // #10948 + FILE *p = fopen("foo", "r"); + // cppcheck-suppress nullPointerOutOfResources + fseek(p, 1, SEEK_SET); + fclose(p); +} + void memleak_aligned_alloc(void) { // cppcheck-suppress [unusedAllocatedMemory, unreadVariable, constVariablePointer] From ba0b3a61f84ed0d1bdcddb6ccbd1bd998fdbb10d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 28 Apr 2026 21:48:09 +0200 Subject: [PATCH 053/493] Fix #14696 FP passedByValueCallback, constParameterCallback for constructor (#8497) --- lib/symboldatabase.cpp | 2 +- test/testother.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 5905597c8c1..e6593c737cc 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1203,7 +1203,7 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass) tok->function(function); - if (tok->strAt(1) != "(") + if (!function->isConstructor() && tok->strAt(1) != "(") const_cast(function)->functionPointerUsage = tok; } } diff --git a/test/testother.cpp b/test/testother.cpp index 0b645a87ff0..42f83a14ca2 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4161,6 +4161,16 @@ class TestOther : public TestFixture { " S s2{ cb };\n" "}\n"); ASSERT_EQUALS("[test.cpp:6:11] -> [test.cpp:2:21]: (performance) Function parameter 's' should be passed by const reference. However it seems that 'cb' is a callback function. [passedByValueCallback]\n", errout_str()); + + check("struct S {\n" // #14696 + " explicit S(std::string s = {}) {}\n" + "};\n" + "struct T {\n" + " explicit T(std::string* s = {}) {}\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:2:28]: (performance) Function parameter 's' should be passed by const reference. [passedByValue]\n" + "[test.cpp:5:29]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n", + errout_str()); } void constPointer() { From 978a82e0a46b8f2d87d1c38e6fb1a2b263c93660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 29 Apr 2026 00:41:01 +0200 Subject: [PATCH 054/493] refs #14599 - moved `ShowTime` logic out of timer-related code (#8493) --- Makefile | 4 ++-- cli/cmdlineparser.cpp | 13 +++++------ cli/cppcheckexecutor.cpp | 25 +++++++++++++-------- lib/cppcheck.cpp | 25 ++++++++++++--------- lib/settings.h | 10 ++++++++- lib/timer.cpp | 43 ++++++++++++++---------------------- lib/timer.h | 23 ++++++------------- lib/tokenize.cpp | 22 ++++++++---------- lib/valueflow.cpp | 2 +- test/fixture.cpp | 8 ++----- test/options.cpp | 3 +-- test/testcmdlineparser.cpp | 13 +++++------ test/testprocessexecutor.cpp | 10 ++++----- test/testsingleexecutor.cpp | 10 ++++----- test/testthreadexecutor.cpp | 10 ++++----- 15 files changed, 104 insertions(+), 117 deletions(-) diff --git a/Makefile b/Makefile index 02735d36ee8..69ad5a02544 100644 --- a/Makefile +++ b/Makefile @@ -695,7 +695,7 @@ $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathli frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_FE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ frontend/frontend.cpp -cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h lib/xml.h +cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h @@ -776,7 +776,7 @@ test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 552af42ab71..2069c89579c 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -36,7 +36,6 @@ #include "settings.h" #include "standards.h" #include "suppressions.h" -#include "timer.h" #include "utils.h" #include "frontend.h" @@ -1430,17 +1429,17 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a else if (std::strncmp(argv[i], "--showtime=", 11) == 0) { const std::string showtimeMode = argv[i] + 11; if (showtimeMode == "file") - mSettings.showtime = ShowTime::FILE; + mSettings.showtime = Settings::ShowTime::FILE; else if (showtimeMode == "file-total") - mSettings.showtime = ShowTime::FILE_TOTAL; + mSettings.showtime = Settings::ShowTime::FILE_TOTAL; else if (showtimeMode == "summary") - mSettings.showtime = ShowTime::SUMMARY; + mSettings.showtime = Settings::ShowTime::SUMMARY; else if (showtimeMode == "top5_file") - mSettings.showtime = ShowTime::TOP5_FILE; + mSettings.showtime = Settings::ShowTime::TOP5_FILE; else if (showtimeMode == "top5_summary") - mSettings.showtime = ShowTime::TOP5_SUMMARY; + mSettings.showtime = Settings::ShowTime::TOP5_SUMMARY; else if (showtimeMode == "none") - mSettings.showtime = ShowTime::NONE; + mSettings.showtime = Settings::ShowTime::NONE; else if (showtimeMode.empty()) { mLogger.printError("no mode provided for --showtime"); return Result::Fail; diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 680f7387c70..5fb4d89855d 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -268,8 +269,8 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) } std::unique_ptr overallTimer; - if (settings.showtime == ShowTime::SUMMARY || settings.showtime == ShowTime::TOP5_SUMMARY) - overallTimer.reset(new OneShotTimer("Overall time", settings.showtime)); + if (settings.showtime == Settings::ShowTime::SUMMARY || settings.showtime == Settings::ShowTime::TOP5_SUMMARY) + overallTimer.reset(new OneShotTimer("Overall time")); settings.loadSummaries(); @@ -420,7 +421,9 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& supprs) const { StdLogger stdLogger(settings); - TimerResults timerResults; + std::unique_ptr timerResults; + if (settings.showtime != Settings::ShowTime::NONE) + timerResults.reset(new TimerResults); if (settings.reportProgress >= 0) stdLogger.resetLatestProgressOutputTime(); @@ -441,31 +444,35 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup if (!settings.checkersReportFilename.empty()) std::remove(settings.checkersReportFilename.c_str()); - CppCheck cppcheck(settings, supprs, stdLogger, &timerResults, true, executeCommand); + CppCheck cppcheck(settings, supprs, stdLogger, timerResults.get(), true, executeCommand); unsigned int returnValue = 0; if (settings.useSingleJob()) { // Single process - SingleExecutor executor(cppcheck, mFiles, mFileSettings, settings, supprs, stdLogger, &timerResults); + SingleExecutor executor(cppcheck, mFiles, mFileSettings, settings, supprs, stdLogger, timerResults.get()); returnValue = executor.check(); } else { #if defined(HAS_THREADING_MODEL_THREAD) if (settings.executor == Settings::ExecutorType::Thread) { - ThreadExecutor executor(mFiles, mFileSettings, settings, supprs, stdLogger, &timerResults, CppCheckExecutor::executeCommand); + ThreadExecutor executor(mFiles, mFileSettings, settings, supprs, stdLogger, timerResults.get(), CppCheckExecutor::executeCommand); returnValue = executor.check(); } #endif #if defined(HAS_THREADING_MODEL_FORK) if (settings.executor == Settings::ExecutorType::Process) { - ProcessExecutor executor(mFiles, mFileSettings, settings, supprs, stdLogger, &timerResults, CppCheckExecutor::executeCommand); + ProcessExecutor executor(mFiles, mFileSettings, settings, supprs, stdLogger, timerResults.get(), CppCheckExecutor::executeCommand); returnValue = executor.check(); } #endif } // TODO: show time *after* the whole program analysis - if (settings.showtime == ShowTime::SUMMARY || settings.showtime == ShowTime::TOP5_SUMMARY) - timerResults.showResults(settings.showtime); + if (timerResults) { + if (settings.showtime == Settings::ShowTime::SUMMARY) + timerResults->showResults(); + else if (settings.showtime == Settings::ShowTime::TOP5_SUMMARY) + timerResults->showResults(5); + } // TODO: is this run again instead of using previously cached results? returnValue |= cppcheck.analyseWholeProgram(settings.buildDir, mFiles, mFileSettings, stdLogger.getCtuInfo()); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index db2b2e5091a..3ef1e7c83e3 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -924,8 +924,8 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str return mLogger->exitcode(); std::unique_ptr checkTimeTimer; - if (mSettings.showtime == ShowTime::FILE || mSettings.showtime == ShowTime::FILE_TOTAL || mSettings.showtime == ShowTime::TOP5_FILE) - checkTimeTimer.reset(new OneShotTimer("Check time: " + file.spath(), mSettings.showtime)); + if (mSettings.showtime == Settings::ShowTime::FILE || mSettings.showtime == Settings::ShowTime::FILE_TOTAL || mSettings.showtime == Settings::ShowTime::TOP5_FILE) + checkTimeTimer.reset(new OneShotTimer("Check time: " + file.spath())); if (!mSettings.quiet) { std::string fixedpath = Path::toNativeSeparators(file.spath()); @@ -1045,7 +1045,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str // Get configurations.. std::set configurations; if (maxConfigs > 1) { - Timer::run("Preprocessor::getConfigs", mSettings.showtime, mTimerResults, [&]() { + Timer::run("Preprocessor::getConfigs", mTimerResults, [&]() { configurations = preprocessor.getConfigs(); }); } else { @@ -1130,7 +1130,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str if (mSettings.preprocessOnly) { std::string codeWithoutCfg; - Timer::run("Preprocessor::getcode", mSettings.showtime, mTimerResults, [&]() { + Timer::run("Preprocessor::getcode", mTimerResults, [&]() { codeWithoutCfg = preprocessor.getcode(currentConfig, files, true); }); @@ -1154,7 +1154,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str { bool skipCfg = false; // Create tokens, skip rest of iteration if failed - Timer::run("Tokenizer::createTokens", mSettings.showtime, mTimerResults, [&]() { + Timer::run("Tokenizer::createTokens", mTimerResults, [&]() { simplecpp::OutputList outputList_cfg; simplecpp::TokenList tokensP = preprocessor.preprocess(currentConfig, files, outputList_cfg); const simplecpp::Output* o = preprocessor.handleErrors(outputList_cfg); @@ -1180,8 +1180,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str Tokenizer tokenizer(std::move(tokenlist), mErrorLogger); try { - if (mSettings.showtime != ShowTime::NONE) - tokenizer.setTimerResults(mTimerResults); + tokenizer.setTimerResults(mTimerResults); tokenizer.setDirectives(directives); // TODO: how to avoid repeated copies? // locations macros @@ -1294,8 +1293,12 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str // TODO: clear earlier? mLogger->clear(); - if (mTimerResults && (mSettings.showtime == ShowTime::FILE || mSettings.showtime == ShowTime::TOP5_FILE)) - mTimerResults->showResults(mSettings.showtime); + if (mTimerResults) { + if (mSettings.showtime == Settings::ShowTime::FILE) + mTimerResults->showResults(); + else if (mSettings.showtime == Settings::ShowTime::TOP5_FILE) + mTimerResults->showResults(5); + } return mLogger->exitcode(); } @@ -1354,7 +1357,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation return; } - Timer::run(check->name() + "::runChecks", mSettings.showtime, mTimerResults, [&]() { + Timer::run(check->name() + "::runChecks", mTimerResults, [&]() { check->runChecks(tokenizer, &mErrorLogger); }); } @@ -1489,7 +1492,7 @@ void CppCheck::executeAddons(const std::string& dumpFile, const FileWithDetails& { if (!dumpFile.empty()) { std::vector f{dumpFile}; - Timer::run("CppCheck::executeAddons", mSettings.showtime, mTimerResults, [&]() { + Timer::run("CppCheck::executeAddons", mTimerResults, [&]() { executeAddons(f, file.spath()); }); } diff --git a/lib/settings.h b/lib/settings.h index 85da57c4458..b7b23675aae 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -53,7 +53,6 @@ class Regex; #endif struct Suppressions; -enum class ShowTime : std::uint8_t; namespace ValueFlow { class Value; } @@ -442,6 +441,15 @@ class CPPCHECKLIB WARN_UNUSED Settings { SimpleEnableGroup certainty; SimpleEnableGroup checks; + enum class ShowTime : std::uint8_t { + NONE, + FILE, + FILE_TOTAL, + SUMMARY, + TOP5_SUMMARY, + TOP5_FILE + }; + /** @brief show timing information (--showtime=file|summary|top5) */ ShowTime showtime{}; diff --git a/lib/timer.cpp b/lib/timer.cpp index f4025fb3427..5c0735ad609 100644 --- a/lib/timer.cpp +++ b/lib/timer.cpp @@ -19,8 +19,6 @@ #include "timer.h" #include -#include -#include #include #include #include @@ -38,12 +36,9 @@ namespace { // TODO: this does not include any file context when SHOWTIME_FILE thus rendering it useless - should we include the logging with the progress logging? // that could also get rid of the broader locking -void TimerResults::showResults(ShowTime mode, bool metrics) const +void TimerResults::showResults(size_t max_results, bool metrics) const { - if (mode == ShowTime::NONE) - return; std::vector data; - { std::lock_guard l(mResultsSync); @@ -57,7 +52,7 @@ void TimerResults::showResults(ShowTime mode, bool metrics) const size_t ordinal = 1; // maybe it would be nice to have an ordinal in output later! for (auto iter=data.cbegin(); iter!=data.cend(); ++iter) { - if ((mode != ShowTime::TOP5_FILE && mode != ShowTime::TOP5_SUMMARY) || (ordinal<=5)) { + if (ordinal <= max_results) { const double sec = iter->second.getSeconds().count(); std::cout << iter->first << ": " << sec << "s"; if (metrics) { @@ -85,12 +80,14 @@ void TimerResults::reset() mResults.clear(); } -Timer::Timer(std::string str, ShowTime showtimeMode, TimerResultsIntf* timerResults) +Timer::Timer(std::string str, TimerResultsIntf* timerResults) : mName(std::move(str)) - , mMode(showtimeMode) - , mStart(Clock::now()) , mResults(timerResults) -{} +{ + if (!mResults) + return; + mStart = Clock::now(); +} Timer::~Timer() { @@ -99,18 +96,13 @@ Timer::~Timer() void Timer::stop() { - if (mMode == ShowTime::NONE) + if (mStart == TimePoint{}) return; - if (mStart != TimePoint{}) { - if (!mResults) { - assert(false); - } - else { - auto diff = std::chrono::duration_cast(Clock::now() - mStart); - mResults->addResults(mName, diff); - } - } - mMode = ShowTime::NONE; // prevent multiple stops + + const auto diff = std::chrono::duration_cast(Clock::now() - mStart); + mResults->addResults(mName, diff); + + mStart = TimePoint{}; // prevent multiple stops } static std::string durationToString(std::chrono::milliseconds duration) @@ -138,11 +130,8 @@ static std::string durationToString(std::chrono::milliseconds duration) return (ellapsedTime + secondsStr + "s"); } -OneShotTimer::OneShotTimer(std::string name, ShowTime showtime) +OneShotTimer::OneShotTimer(std::string name) { - if (showtime == ShowTime::NONE) - return; - class MyResults : public TimerResultsIntf { private: @@ -156,5 +145,5 @@ OneShotTimer::OneShotTimer(std::string name, ShowTime showtime) }; mResults.reset(new MyResults); - mTimer.reset(new Timer(std::move(name), showtime, mResults.get())); + mTimer.reset(new Timer(std::move(name), mResults.get())); } diff --git a/lib/timer.h b/lib/timer.h index 5611bc5304b..4858d4b15ba 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -23,7 +23,8 @@ #include "config.h" #include -#include +#include +#include #include #include #include @@ -32,15 +33,6 @@ #include #include -enum class ShowTime : std::uint8_t { - NONE, - FILE, - FILE_TOTAL, - SUMMARY, - TOP5_SUMMARY, - TOP5_FILE -}; - class CPPCHECKLIB TimerResultsIntf { public: virtual ~TimerResultsIntf() = default; @@ -66,7 +58,7 @@ class CPPCHECKLIB WARN_UNUSED TimerResults : public TimerResultsIntf { public: TimerResults() = default; - void showResults(ShowTime mode, bool metrics = true) const; + void showResults(size_t max_results = std::numeric_limits::max(), bool metrics = true) const; void addResults(const std::string& name, std::chrono::milliseconds duration) override; void reset(); @@ -81,7 +73,7 @@ class CPPCHECKLIB Timer { using Clock = std::chrono::high_resolution_clock; using TimePoint = std::chrono::time_point; - Timer(std::string str, ShowTime showtimeMode, TimerResultsIntf* timerResults = nullptr); + explicit Timer(std::string str, TimerResultsIntf* timerResults = nullptr); ~Timer(); Timer(const Timer&) = delete; @@ -90,14 +82,13 @@ class CPPCHECKLIB Timer { void stop(); template - static void run(std::string str, ShowTime showtimeMode, TimerResultsIntf* timerResults, const TFunc& f) { - Timer t(std::move(str), showtimeMode, timerResults); + static void run(std::string str, TimerResultsIntf* timerResults, const TFunc& f) { + Timer t(std::move(str), timerResults); f(); } private: const std::string mName; - ShowTime mMode{}; TimePoint mStart; TimerResultsIntf* mResults{}; }; @@ -105,7 +96,7 @@ class CPPCHECKLIB Timer { class CPPCHECKLIB OneShotTimer { public: - OneShotTimer(std::string name, ShowTime showtime); + explicit OneShotTimer(std::string name); private: std::unique_ptr mResults; std::unique_ptr mTimer; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 4cce2a71434..bda68e34fb0 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3508,7 +3508,7 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration, int fileIndex) mConfiguration = configuration; if (mTimerResults) { - Timer t("Tokenizer::simplifyTokens1::simplifyTokenList1", mSettings.showtime, mTimerResults); + Timer t("Tokenizer::simplifyTokens1::simplifyTokenList1", mTimerResults); if (!simplifyTokenList1(list.getFiles().front().c_str())) return false; } else { @@ -3516,18 +3516,16 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration, int fileIndex) return false; } - const ShowTime showTime = mTimerResults ? mSettings.showtime : ShowTime::NONE; - - Timer::run("Tokenizer::simplifyTokens1::createAst", showTime, mTimerResults, [&]() { + Timer::run("Tokenizer::simplifyTokens1::createAst", mTimerResults, [&]() { list.createAst(); list.validateAst(mSettings.debugnormal); }); - Timer::run("Tokenizer::simplifyTokens1::createSymbolDatabase", showTime, mTimerResults, [&]() { + Timer::run("Tokenizer::simplifyTokens1::createSymbolDatabase", mTimerResults, [&]() { createSymbolDatabase(); }); - Timer::run("Tokenizer::simplifyTokens1::setValueType", showTime, mTimerResults, [&]() { + Timer::run("Tokenizer::simplifyTokens1::setValueType", mTimerResults, [&]() { mSymbolDatabase->setValueTypeInTokenList(false); mSymbolDatabase->setValueTypeInTokenList(true); }); @@ -3542,7 +3540,7 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration, int fileIndex) const bool doValueFlow = !disableValueflowEnv || (std::strcmp(disableValueflowEnv, "1") != 0); if (doValueFlow) { - Timer::run("Tokenizer::simplifyTokens1::ValueFlow", showTime, mTimerResults, [&]() { + Timer::run("Tokenizer::simplifyTokens1::ValueFlow", mTimerResults, [&]() { ValueFlow::setValues(list, *mSymbolDatabase, mErrorLogger, mSettings, mTimerResults); }); @@ -5753,10 +5751,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) validate(); - const ShowTime showTime = mTimerResults ? mSettings.showtime : ShowTime::NONE; - // Bail out if code is garbage - Timer::run("Tokenizer::simplifyTokens1::simplifyTokenList1::findGarbageCode", showTime, mTimerResults, [&]() { + Timer::run("Tokenizer::simplifyTokens1::simplifyTokenList1::findGarbageCode", mTimerResults, [&]() { findGarbageCode(); }); @@ -5893,7 +5889,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) simplifyTypedefLHS(); // typedef.. - Timer::run("Tokenizer::simplifyTokens1::simplifyTokenList1::simplifyTypedef", showTime, mTimerResults, [&]() { + Timer::run("Tokenizer::simplifyTokens1::simplifyTokenList1::simplifyTypedef", mTimerResults, [&]() { simplifyTypedef(); }); @@ -5987,7 +5983,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) simplifyTypeIntrinsics(); // Handle templates.. - Timer::run("Tokenizer::simplifyTokens1::simplifyTokenList1::simplifyTemplates", showTime, mTimerResults, [&]() { + Timer::run("Tokenizer::simplifyTokens1::simplifyTokenList1::simplifyTemplates", mTimerResults, [&]() { simplifyTemplates(); }); @@ -6014,7 +6010,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) validate(); // #6772 "segmentation fault (invalid code) in Tokenizer::setVarId" - Timer::run("Tokenizer::simplifyTokens1::simplifyTokenList1::setVarId", showTime, mTimerResults, [&](){ + Timer::run("Tokenizer::simplifyTokens1::simplifyTokenList1::setVarId", mTimerResults, [&](){ setVarId(); }); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 614d568ea80..21825f055d7 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7272,7 +7272,7 @@ struct ValueFlowPassRunner { name += ' '; name += std::to_string(it); } - Timer t(name, state.settings.showtime, timerResults); + Timer t(name, timerResults); pass->run(state); } else { pass->run(state); diff --git a/test/fixture.cpp b/test/fixture.cpp index cdc826d083a..de42837a56e 100644 --- a/test/fixture.cpp +++ b/test/fixture.cpp @@ -116,7 +116,7 @@ bool TestFixture::prepareTest(const char testname[]) std::cout << fullTestName << std::endl; } if (timer_results) - mTimer.reset(new Timer(fullTestName, ShowTime::TOP5_SUMMARY, timer_results)); + mTimer.reset(new Timer(fullTestName, timer_results)); return !dry_run; } @@ -423,11 +423,7 @@ std::size_t TestFixture::runTests(const options& args) const auto f = [&](){ fixture = test->create(); }; - // TODO: Timer::run() needs proper handling if no results should be collected - if (args.timer_results()) - Timer::run(test->classname + " - create", ShowTime::TOP5_SUMMARY, args.timer_results(), f); - else - f(); + Timer::run(test->classname + " - create", args.timer_results(), f); fixture->processOptions(args); fixture->run(tests); } diff --git a/test/options.cpp b/test/options.cpp index 9db2bce8563..54527b26ecd 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -58,9 +58,8 @@ options::options(int argc, const char* const argv[]) options::~options() { - // TODO: allow more than 5 results to be shown if (mTimerResults) - mTimerResults->showResults(ShowTime::TOP5_FILE, false); + mTimerResults->showResults(10, false); } bool options::quiet() const diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 06ee30837d6..e5d231d47ed 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -31,7 +31,6 @@ #include "settings.h" #include "standards.h" #include "suppressions.h" -#include "timer.h" #include "utils.h" #include @@ -2193,21 +2192,21 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--showtime=summary", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); - ASSERT(settings->showtime == ShowTime::SUMMARY); + ASSERT_EQUALS_ENUM(Settings::ShowTime::SUMMARY, settings->showtime); } void showtimeFile() { REDIRECT; const char * const argv[] = {"cppcheck", "--showtime=file", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); - ASSERT(settings->showtime == ShowTime::FILE); + ASSERT_EQUALS_ENUM(Settings::ShowTime::FILE, settings->showtime); } void showtimeFileTotal() { REDIRECT; const char * const argv[] = {"cppcheck", "--showtime=file-total", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); - ASSERT(settings->showtime == ShowTime::FILE_TOTAL); + ASSERT_EQUALS_ENUM(Settings::ShowTime::FILE_TOTAL, settings->showtime); } void showtimeTop5() { @@ -2221,21 +2220,21 @@ class TestCmdlineParser : public TestFixture { REDIRECT; const char * const argv[] = {"cppcheck", "--showtime=top5_file", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); - ASSERT(settings->showtime == ShowTime::TOP5_FILE); + ASSERT_EQUALS_ENUM(Settings::ShowTime::TOP5_FILE, settings->showtime); } void showtimeTop5Summary() { REDIRECT; const char * const argv[] = {"cppcheck", "--showtime=top5_summary", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); - ASSERT(settings->showtime == ShowTime::TOP5_SUMMARY); + ASSERT_EQUALS_ENUM(Settings::ShowTime::TOP5_SUMMARY, settings->showtime); } void showtimeNone() { REDIRECT; const char * const argv[] = {"cppcheck", "--showtime=none", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); - ASSERT(settings->showtime == ShowTime::NONE); + ASSERT_EQUALS_ENUM(Settings::ShowTime::NONE, settings->showtime); } void showtimeEmpty() { diff --git a/test/testprocessexecutor.cpp b/test/testprocessexecutor.cpp index 10562088f56..5a379166039 100644 --- a/test/testprocessexecutor.cpp +++ b/test/testprocessexecutor.cpp @@ -64,7 +64,7 @@ class TestProcessExecutorBase : public TestFixture { struct CheckOptions { bool quiet = true; - ShowTime showtime = ShowTime::NONE; + Settings::ShowTime showtime = Settings::ShowTime::NONE; const char* plistOutput = nullptr; std::vector filesList; }; @@ -177,7 +177,7 @@ class TestProcessExecutorBase : public TestFixture { "void f()\n" "{\n" " (void)(*((int*)0));\n" - "}", dinit(CheckOptions, $.showtime = ShowTime::SUMMARY)); + "}", dinit(CheckOptions, $.showtime = Settings::ShowTime::SUMMARY)); // we are not interested in the results - so just consume them ignore_errout(); } @@ -246,7 +246,7 @@ class TestProcessExecutorBase : public TestFixture { check(2, 2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::TOP5_FILE)); + $.showtime = Settings::ShowTime::TOP5_FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; // for each file: top5 results + check time TODO_ASSERT_EQUALS(static_cast(5 + 1) * 2, 0, cppcheck::count_all_of(output_s, '\n')); @@ -257,7 +257,7 @@ class TestProcessExecutorBase : public TestFixture { check(2, 2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::FILE)); + $.showtime = Settings::ShowTime::FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; TODO_ASSERT_EQUALS(2, 0, cppcheck::count_all_of(output_s, "Overall time:")); } @@ -267,7 +267,7 @@ class TestProcessExecutorBase : public TestFixture { check(2, 2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::FILE_TOTAL)); + $.showtime = Settings::ShowTime::FILE_TOTAL)); const std::string output_s = GET_REDIRECT_OUTPUT; TODO_ASSERT(output_s.find("Check time: " + fprefix() + "_1.c: ") != std::string::npos); TODO_ASSERT(output_s.find("Check time: " + fprefix() + "_2.c: ") != std::string::npos); diff --git a/test/testsingleexecutor.cpp b/test/testsingleexecutor.cpp index 8351bb7c331..57343c58525 100644 --- a/test/testsingleexecutor.cpp +++ b/test/testsingleexecutor.cpp @@ -61,7 +61,7 @@ class TestSingleExecutorBase : public TestFixture { struct CheckOptions { bool quiet = true; - ShowTime showtime = ShowTime::NONE; + Settings::ShowTime showtime = Settings::ShowTime::NONE; const char* plistOutput = nullptr; std::vector filesList; }; @@ -165,7 +165,7 @@ class TestSingleExecutorBase : public TestFixture { "void f()\n" "{\n" " (void)(*((int*)0));\n" - "}", dinit(CheckOptions, $.showtime = ShowTime::SUMMARY)); + "}", dinit(CheckOptions, $.showtime = Settings::ShowTime::SUMMARY)); // we are not interested in the results - so just consume them ignore_errout(); } @@ -239,7 +239,7 @@ class TestSingleExecutorBase : public TestFixture { check(2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::TOP5_FILE)); + $.showtime = Settings::ShowTime::TOP5_FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; // for each file: top5 results + check time ASSERT_EQUALS((5 + 1) * 2LL, cppcheck::count_all_of(output_s, '\n')); @@ -250,7 +250,7 @@ class TestSingleExecutorBase : public TestFixture { check(2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::FILE)); + $.showtime = Settings::ShowTime::FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; ASSERT_EQUALS(0, cppcheck::count_all_of(output_s, "Overall time:")); } @@ -260,7 +260,7 @@ class TestSingleExecutorBase : public TestFixture { check(2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::FILE_TOTAL)); + $.showtime = Settings::ShowTime::FILE_TOTAL)); const std::string output_s = GET_REDIRECT_OUTPUT; ASSERT(output_s.find("Check time: " + fprefix() + "_" + zpad3(1) + ".c: ") != std::string::npos); ASSERT(output_s.find("Check time: " + fprefix() + "_" + zpad3(2) + ".c: ") != std::string::npos); diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp index 36c3e69f8e8..8da83aa1b8f 100644 --- a/test/testthreadexecutor.cpp +++ b/test/testthreadexecutor.cpp @@ -64,7 +64,7 @@ class TestThreadExecutorBase : public TestFixture { struct CheckOptions { bool quiet = true; - ShowTime showtime = ShowTime::NONE; + Settings::ShowTime showtime = Settings::ShowTime::NONE; const char* plistOutput = nullptr; std::vector filesList; }; @@ -178,7 +178,7 @@ class TestThreadExecutorBase : public TestFixture { "void f()\n" "{\n" " (void)(*((int*)0));\n" - "}", dinit(CheckOptions, $.showtime = ShowTime::SUMMARY)); + "}", dinit(CheckOptions, $.showtime = Settings::ShowTime::SUMMARY)); // we are not interested in the results - so just consume them ignore_errout(); } @@ -247,7 +247,7 @@ class TestThreadExecutorBase : public TestFixture { check(2, 2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::TOP5_FILE)); + $.showtime = Settings::ShowTime::TOP5_FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; // for each file: top5 results + check time ASSERT_EQUALS((5 + 1) * 2LL, cppcheck::count_all_of(output_s, '\n')); @@ -258,7 +258,7 @@ class TestThreadExecutorBase : public TestFixture { check(2, 2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::FILE)); + $.showtime = Settings::ShowTime::FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; ASSERT_EQUALS(0, cppcheck::count_all_of(output_s, "Overall time:")); } @@ -268,7 +268,7 @@ class TestThreadExecutorBase : public TestFixture { check(2, 2, 0, "int main() {}", dinit(CheckOptions, - $.showtime = ShowTime::FILE_TOTAL)); + $.showtime = Settings::ShowTime::FILE_TOTAL)); const std::string output_s = GET_REDIRECT_OUTPUT; ASSERT(output_s.find("Check time: " + fprefix() + "_1.c: ") != std::string::npos); ASSERT(output_s.find("Check time: " + fprefix() + "_2.c: ") != std::string::npos); From 20b45eea31d487e8a086c2c1922b559844f01c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 29 Apr 2026 00:41:44 +0200 Subject: [PATCH 055/493] pass `Library` instead of `Settings` (#8500) --- lib/astutils.cpp | 4 ++-- lib/astutils.h | 2 +- lib/symboldatabase.cpp | 2 +- lib/tokenize.cpp | 22 +++++++++++----------- lib/valueflow.cpp | 18 +++++++++--------- lib/vf_settokenvalue.cpp | 12 ++++++------ 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 37360519474..fa2c9c3890b 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -320,12 +320,12 @@ Library::Container::Yield astContainerYield(const Token* tok, const Library& lib return ftokCont.second->getYield(ftokCont.first->str()); } -Library::Container::Yield astFunctionYield(const Token* tok, const Settings& settings, const Token** ftok) +Library::Container::Yield astFunctionYield(const Token* tok, const Library& library, const Token** ftok) { if (!tok) return Library::Container::Yield::NO_YIELD; - const auto* function = settings.library.getFunction(tok); + const auto* function = library.getFunction(tok); if (!function) return Library::Container::Yield::NO_YIELD; diff --git a/lib/astutils.h b/lib/astutils.h index 5b6b878f3ae..617e01f0415 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -166,7 +166,7 @@ bool astIsContainerString(const Token* tok); Library::Container::Action astContainerAction(const Token* tok, const Library& library, const Token** ftok = nullptr); Library::Container::Yield astContainerYield(const Token* tok, const Library& library, const Token** ftok = nullptr); -Library::Container::Yield astFunctionYield(const Token* tok, const Settings& settings, const Token** ftok = nullptr); +Library::Container::Yield astFunctionYield(const Token* tok, const Library& library, const Token** ftok = nullptr); /** Is given token a range-declaration in a range-based for loop */ bool astIsRangeBasedForDecl(const Token* tok); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index e6593c737cc..5eeaafb7dd0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -8053,7 +8053,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to continue; } - const auto yield = astFunctionYield(tok->previous(), mSettings); + const auto yield = astFunctionYield(tok->previous(), mSettings.library); if (yield == Library::Container::Yield::START_ITERATOR || yield == Library::Container::Yield::END_ITERATOR || yield == Library::Container::Yield::ITERATOR) { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index bda68e34fb0..1acf1b1f6c4 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10328,23 +10328,23 @@ void Tokenizer::simplifyBitfields() } } -static bool isStdContainerOrIterator(const Token* tok, const Settings& settings) +static bool isStdContainerOrIterator(const Token* tok, const Library& library) { - const Library::Container* ctr = settings.library.detectContainerOrIterator(tok, nullptr, /*withoutStd*/ true); + const Library::Container* ctr = library.detectContainerOrIterator(tok, nullptr, /*withoutStd*/ true); return ctr && startsWith(ctr->startPattern, "std ::"); } -static bool isStdSmartPointer(const Token* tok, const Settings& settings) +static bool isStdSmartPointer(const Token* tok, const Library& library) { - const Library::SmartPointer* ptr = settings.library.detectSmartPointer(tok, /*withoutStd*/ true); + const Library::SmartPointer* ptr = library.detectSmartPointer(tok, /*withoutStd*/ true); return ptr && startsWith(ptr->name, "std::"); } -static bool isLibraryType(const Token* tok, const Settings& settings) +static bool isLibraryType(const Token* tok, const Library& library) { - return settings.library.hasAnyTypeCheck("std::" + tok->str()) || - settings.library.podtype("std::" + tok->str()) || - isStdContainerOrIterator(tok, settings); + return library.hasAnyTypeCheck("std::" + tok->str()) || + library.podtype("std::" + tok->str()) || + isStdContainerOrIterator(tok, library); } // Add std:: in front of std classes, when using namespace std; was given @@ -10375,12 +10375,12 @@ void Tokenizer::simplifyNamespaceStd() userFunctions.insert(tok->str()); } if ((userFunctions.find(tok->str()) == userFunctions.end() && mSettings.library.matchArguments(tok, "std::" + tok->str())) || - (tok->tokAt(-1)->isKeyword() && isLibraryType(tok, mSettings))) + (tok->tokAt(-1)->isKeyword() && isLibraryType(tok, mSettings.library))) insert = true; } else if (Token::simpleMatch(tok->next(), "<") && - (isStdContainerOrIterator(tok, mSettings) || isStdSmartPointer(tok, mSettings))) + (isStdContainerOrIterator(tok, mSettings.library) || isStdSmartPointer(tok, mSettings.library))) insert = true; - else if (isLibraryType(tok, mSettings)) + else if (isLibraryType(tok, mSettings.library)) insert = true; else if (Token::simpleMatch(tok, "aligned_storage")) insert = true; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 21825f055d7..06e5fbf2d97 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -365,7 +365,7 @@ const Token *ValueFlow::parseCompareInt(const Token *tok, ValueFlow::Value &true }); } -static bool isEscapeScope(const Token* tok, const Settings& settings, bool unknown = false) +static bool isEscapeScope(const Token* tok, const Library& library, bool unknown = false) { if (!Token::simpleMatch(tok, "{")) return false; @@ -374,7 +374,7 @@ static bool isEscapeScope(const Token* tok, const Settings& settings, bool unkno if (termTok && termTok->scope() == tok->scope()) return true; std::string unknownFunction; - if (settings.library.isScopeNoReturn(tok->link(), &unknownFunction)) + if (library.isScopeNoReturn(tok->link(), &unknownFunction)) return unknownFunction.empty() || unknown; return false; } @@ -3044,7 +3044,7 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co // Skip if its a free function that doesnt yield an iterator to the container if (Token::Match(parent->previous(), "%name% (") && !contains({Library::Container::Yield::START_ITERATOR, Library::Container::Yield::END_ITERATOR}, - astFunctionYield(parent->previous(), settings))) + astFunctionYield(parent->previous(), settings.library))) continue; ValueFlow::Value master; @@ -3056,7 +3056,7 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co master.lifetimeKind = ValueFlow::Value::LifetimeKind::Iterator; } else if (astIsIterator(parent) && Token::Match(parent->previous(), "%name% (") && contains({Library::Container::Yield::START_ITERATOR, Library::Container::Yield::END_ITERATOR}, - astFunctionYield(parent->previous(), settings))) { + astFunctionYield(parent->previous(), settings.library))) { master.errorPath.emplace_back(parent, "Iterator to container is created here."); master.lifetimeKind = ValueFlow::Value::LifetimeKind::Iterator; } else if ((astIsPointer(parent->tokAt(2)) && @@ -3479,7 +3479,7 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist, } // Check if the block terminates early - if (isEscapeScope(blockTok, settings)) { + if (isEscapeScope(blockTok, settings.library)) { const Scope* scope2 = scope; // If escaping a loop then only use the loop scope if (isBreakOrContinueScope(blockTok->link())) { @@ -6339,9 +6339,9 @@ static void valueFlowSmartPointer(TokenList &tokenlist, ErrorLogger & errorLogge } } -static Library::Container::Yield findIteratorYield(Token* tok, const Token*& ftok, const Settings& settings) +static Library::Container::Yield findIteratorYield(Token* tok, const Token*& ftok, const Library& library) { - auto yield = astContainerYield(tok, settings.library, &ftok); + auto yield = astContainerYield(tok, library, &ftok); if (ftok) return yield; @@ -6349,7 +6349,7 @@ static Library::Container::Yield findIteratorYield(Token* tok, const Token*& fto return yield; // begin/end free functions - return astFunctionYield(tok->astParent()->previous(), settings, &ftok); + return astFunctionYield(tok->astParent()->previous(), library, &ftok); } static void valueFlowIterators(TokenList& tokenlist, const Settings& settings) @@ -6362,7 +6362,7 @@ static void valueFlowIterators(TokenList& tokenlist, const Settings& settings) if (!astIsContainer(tok)) continue; const Token* ftok = nullptr; - const Library::Container::Yield yield = findIteratorYield(tok, ftok, settings); + const Library::Container::Yield yield = findIteratorYield(tok, ftok, settings.library); if (!ftok) continue; if (yield == Library::Container::Yield::START_ITERATOR) { diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index 602d87e159d..c5fe519b720 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -47,7 +47,7 @@ namespace ValueFlow { - static Library::Container::Yield getContainerYield(Token* tok, const Settings& settings, Token*& parent) + static Library::Container::Yield getContainerYield(Token* tok, const Library& library, Token*& parent) { if (Token::Match(tok, ". %name% (") && tok->astParent() == tok->tokAt(2) && tok->astOperand1() && tok->astOperand1()->valueType()) { @@ -57,7 +57,7 @@ namespace ValueFlow } if (Token::Match(tok->previous(), "%name% (")) { parent = tok; - if (const Library::Function* f = settings.library.getFunction(tok->previous())) { + if (const Library::Function* f = library.getFunction(tok->previous())) { return f->containerYield; } } @@ -95,7 +95,7 @@ namespace ValueFlow return v; } - static const Token *getCastTypeStartToken(const Token *parent, const Settings& settings) + static const Token *getCastTypeStartToken(const Token *parent, const Library& library) { // TODO: This might be a generic utility function? if (!Token::Match(parent, "{|(")) @@ -114,7 +114,7 @@ namespace ValueFlow ftok = ftok->next(); while (Token::Match(ftok, "%name% ::")) ftok = ftok->tokAt(2); - if (settings.library.isNotLibraryFunction(ftok)) + if (library.isNotLibraryFunction(ftok)) return parent->next(); } if (parent->astOperand2() && Token::Match(parent->astOperand1(), "const_cast|dynamic_cast|reinterpret_cast|static_cast <")) @@ -301,7 +301,7 @@ namespace ValueFlow } } Token* next = nullptr; - const Library::Container::Yield yields = getContainerYield(parent, settings, next); + const Library::Container::Yield yields = getContainerYield(parent, settings.library, next); if (yields == Library::Container::Yield::SIZE) { value.valueType = Value::ValueType::INT; setTokenValue(next, std::move(value), settings); @@ -371,7 +371,7 @@ namespace ValueFlow } // cast.. - if (const Token *castType = getCastTypeStartToken(parent, settings)) { + if (const Token *castType = getCastTypeStartToken(parent, settings.library)) { if (contains({Value::ValueType::INT, Value::ValueType::SYMBOLIC}, value.valueType) && Token::simpleMatch(parent->astOperand1(), "dynamic_cast")) return; From 1f41e56c3d7b42aa25ca811727f9be733a8ffc0a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 29 Apr 2026 08:22:28 +0200 Subject: [PATCH 056/493] Fix #14701 Bad AST for rvalue references in parameter lists (#8505) --- lib/tokenlist.cpp | 2 +- test/testtokenize.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index e525bdd7609..5f48baea018 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1623,7 +1623,7 @@ static Token * createAstAtToken(Token *tok) if (Token::Match(tok, "%type%") && !Token::Match(tok, "return|throw|if|while|new|delete")) { bool isStandardTypeOrQualifier = false; Token* type = tok; - while (Token::Match(type, "%type%|*|&|<")) { + while (Token::Match(type, "%type%|*|&|&&|<")) { if (type->isName() && (type->isStandardType() || Token::Match(type, "const|mutable|static|volatile"))) isStandardTypeOrQualifier = true; if (type->str() == "<") { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 9b816a357b7..7b2bee0d80e 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -7527,6 +7527,7 @@ class TestTokenizer : public TestFixture { void astfuncdecl() { ASSERT_EQUALS("", testAst("bool operator==(const S& a, const S& b);", AstStyle::Simple, ListSimplification::Full)); ASSERT_EQUALS("", testAst("::int32_t f();")); + ASSERT_EQUALS("", testAst("void f(int&& var);")); } void astarrayinit() { // #11738 From 294503058a5d8fd33e1e514284ff6577d1ab0a69 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 29 Apr 2026 08:23:19 +0200 Subject: [PATCH 057/493] Fix #14706 FP Memleak struct member when struct is passed to function (#8509) Co-authored-by: chrchr-github --- lib/checkmemoryleak.cpp | 2 +- test/testmemleak.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 7ce49292ffd..82973958847 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -787,7 +787,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable* const vari bool deallocated = false; const Token* const end = tok->linkAt(1); for (const Token* tok2 = tok; tok2 != end; tok2 = tok2->next()) { - if (Token::Match(tok2, "[(,] &| %varid% [,)]", structid)) { + if (Token::Match(tok2, "%varid%", structid)) { /** @todo check if the function deallocates the memory */ deallocated = true; break; diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 08ea1530f90..3b7777f4f87 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -1684,6 +1684,7 @@ class TestMemleakStructMember : public TestFixture { TEST_CASE(function3); // #3024: kernel list TEST_CASE(function4); // #3038: Deallocating in function TEST_CASE(function5); // #10381, #10382, #10158 + TEST_CASE(function6); // Handle if-else TEST_CASE(ifelse); @@ -2082,6 +2083,17 @@ class TestMemleakStructMember : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void function6() { + check("struct S { int* p; };\n" // #14706 + "void g(void*);\n" + "void f() {\n" + " S* s = new S();\n" + " s->p = new int();\n" + " g((void*)s);\n" + "}"); + ASSERT_EQUALS("", errout_str()); + } + void ifelse() { check("static void foo()\n" "{\n" From e47d7b5dc7ba1240742ed3dba197babee8fbdebf Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 29 Apr 2026 08:24:18 +0200 Subject: [PATCH 058/493] Fix #14702 FP functionConst (iterating over *this) (#8507) --- lib/checkclass.cpp | 2 +- test/testclass.cpp | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 69cf8e70533..9fc9bdc7863 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2567,7 +2567,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member return false; if (Token::Match(tok1->previous(), "( this . * %var% )")) // call using ptr to member function TODO: check constness return false; - if (Token::simpleMatch(tok1->astParent(), "*") && tok1->astParent()->astParent() && tok1->astParent()->astParent()->isIncDecOp()) + if (Token::simpleMatch(tok1->astParent(), "*")) return false; } diff --git a/test/testclass.cpp b/test/testclass.cpp index 62cf32cfba5..2cecdfe80f6 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -6974,13 +6974,28 @@ class TestClass : public TestFixture { } void const101() { - checkConst("struct error {\n" + checkConst("struct error {\n" // #14450 " error() = default;\n" "};\n" "struct S : U {\n" " int f() { return this->error(); }\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + checkConst("struct S {\n" // #14702 + " int i;\n" + " void f() {\n" + " S& r = *this;\n" + " r.i = 0;\n" + " }\n" + "};\n" + "struct T : std::array {\n" + " void g() {\n" + " for (int& r : *this)\n" + " r = 0;\n" + " }\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); } void const_handleDefaultParameters() { From ba55280e9622aa578cf3c2fecce8c9096ae66936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 29 Apr 2026 10:05:37 +0200 Subject: [PATCH 059/493] small `TimerResults` cleanup / improved `TestTimer` (#8498) --- Makefile | 2 +- lib/timer.cpp | 36 ++++++++++++++++++++++------------- lib/timer.h | 19 ++----------------- test/testtimer.cpp | 47 +++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 69ad5a02544..b82b924e1d9 100644 --- a/Makefile +++ b/Makefile @@ -917,7 +917,7 @@ test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp -test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h +test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h diff --git a/lib/timer.cpp b/lib/timer.cpp index 5c0735ad609..275acc06078 100644 --- a/lib/timer.cpp +++ b/lib/timer.cpp @@ -20,16 +20,11 @@ #include #include +#include #include #include namespace { - using dataElementType = std::pair; - bool more_second_sec(const dataElementType& lhs, const dataElementType& rhs) - { - return lhs.second.getSeconds() > rhs.second.getSeconds(); - } - // TODO: remove and print through (synchronized) ErrorLogger instead std::mutex stdCoutLock; } @@ -38,6 +33,8 @@ namespace { // that could also get rid of the broader locking void TimerResults::showResults(size_t max_results, bool metrics) const { + using dataElementType = std::pair>; + std::vector data; { std::lock_guard l(mResultsSync); @@ -45,7 +42,20 @@ void TimerResults::showResults(size_t max_results, bool metrics) const data.reserve(mResults.size()); data.insert(data.begin(), mResults.cbegin(), mResults.cend()); } - std::sort(data.begin(), data.end(), more_second_sec); + + const auto asSeconds = [](std::chrono::milliseconds ms) -> std::chrono::duration { + return std::chrono::duration_cast>(ms); + }; + + const auto getSeconds = [&asSeconds](const std::vector& results) -> std::chrono::duration { + return std::accumulate(results.cbegin(), results.cend(), std::chrono::duration{}, [&asSeconds](std::chrono::duration secs, std::chrono::milliseconds duration) { + return secs + asSeconds(duration); + }); + }; + + std::sort(data.begin(), data.end(), [&getSeconds](const dataElementType& lhs, const dataElementType& rhs) -> bool { + return getSeconds(lhs.second) > getSeconds(rhs.second); + }); // lock the whole logging operation to avoid multiple threads printing their results at the same time std::lock_guard l(stdCoutLock); @@ -53,13 +63,13 @@ void TimerResults::showResults(size_t max_results, bool metrics) const size_t ordinal = 1; // maybe it would be nice to have an ordinal in output later! for (auto iter=data.cbegin(); iter!=data.cend(); ++iter) { if (ordinal <= max_results) { - const double sec = iter->second.getSeconds().count(); + const double sec = getSeconds(iter->second).count(); std::cout << iter->first << ": " << sec << "s"; if (metrics) { - const double secAverage = sec / static_cast(iter->second.mResults.size()); - const double secMin = asSeconds(*std::min_element(iter->second.mResults.cbegin(), iter->second.mResults.cend())).count(); - const double secMax = asSeconds(*std::max_element(iter->second.mResults.cbegin(), iter->second.mResults.cend())).count(); - std::cout << " (avg. " << secAverage << "s / min " << secMin << "s / max " << secMax << "s - " << iter->second.mResults.size() << " result(s))"; + const double secAverage = sec / static_cast(iter->second.size()); + const double secMin = asSeconds(*std::min_element(iter->second.cbegin(), iter->second.cend())).count(); + const double secMax = asSeconds(*std::max_element(iter->second.cbegin(), iter->second.cend())).count(); + std::cout << " (avg. " << secAverage << "s / min " << secMin << "s / max " << secMax << "s - " << iter->second.size() << " result(s))"; } std::cout << std::endl; } @@ -71,7 +81,7 @@ void TimerResults::addResults(const std::string& name, std::chrono::milliseconds { std::lock_guard l(mResultsSync); - mResults[name].mResults.push_back(duration); + mResults[name].push_back(duration); } void TimerResults::reset() diff --git a/lib/timer.h b/lib/timer.h index 4858d4b15ba..58ec8de08cc 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -38,20 +37,6 @@ class CPPCHECKLIB TimerResultsIntf { virtual ~TimerResultsIntf() = default; virtual void addResults(const std::string& name, std::chrono::milliseconds duration) = 0; - - static std::chrono::duration asSeconds(std::chrono::milliseconds ms) { - return std::chrono::duration_cast>(ms); - } -}; - -struct TimerResultsData { - std::vector mResults; - - std::chrono::duration getSeconds() const { - return std::accumulate(mResults.cbegin(), mResults.cend(), std::chrono::duration{}, [](std::chrono::duration secs, std::chrono::milliseconds duration) { - return secs + TimerResultsIntf::asSeconds(duration); - }); - } }; class CPPCHECKLIB WARN_UNUSED TimerResults : public TimerResultsIntf { @@ -63,8 +48,8 @@ class CPPCHECKLIB WARN_UNUSED TimerResults : public TimerResultsIntf { void reset(); -private: - std::map mResults; +protected: + std::map> mResults; mutable std::mutex mResultsSync; }; diff --git a/test/testtimer.cpp b/test/testtimer.cpp index 3f160c0c2b7..179f87deba4 100644 --- a/test/testtimer.cpp +++ b/test/testtimer.cpp @@ -17,26 +17,63 @@ */ #include "fixture.h" +#include "redirect.h" #include "timer.h" #include +#include class TestTimer : public TestFixture { public: TestTimer() : TestFixture("TestTimer") {} private: + class TimerResultsTest : public TimerResults + { + public: + std::map> getResults() const { + std::lock_guard l(mResultsSync); + return mResults; + } + }; void run() override { TEST_CASE(result); } - void result() const { - TimerResultsData t1; - t1.mResults.emplace_back(1234); - ASSERT(t1.getSeconds().count() > 1.233 && t1.getSeconds().count() < 1.235); + void result() { + REDIRECT; - // TODO : more tests + TimerResultsTest t1; + t1.addResults("call1", std::chrono::milliseconds{1230}); + t1.addResults("call2", std::chrono::milliseconds{1234}); + t1.addResults("call1", std::chrono::milliseconds{1235}); + t1.addResults("call1", std::chrono::milliseconds{1239}); + + const auto results = t1.getResults(); + ASSERT_EQUALS(2, results.size()); + + auto it = results.find("call1"); + ASSERT(it != results.cend()); + ASSERT_EQUALS(3, it->second.size()); + ASSERT_EQUALS(1230, it->second[0].count()); + ASSERT_EQUALS(1235, it->second[1].count()); + ASSERT_EQUALS(1239, it->second[2].count()); + + it = results.find("call2"); + ASSERT(it != results.cend()); + ASSERT_EQUALS(1, it->second.size()); + ASSERT_EQUALS(1234, it->second[0].count()); + + t1.showResults(); + ASSERT_EQUALS("call1: 3.704s (avg. 1.23467s / min 1.23s / max 1.239s - 3 result(s))\n" + "call2: 1.234s (avg. 1.234s / min 1.234s / max 1.234s - 1 result(s))\n", GET_REDIRECT_OUTPUT); + + t1.showResults(1); + ASSERT_EQUALS("call1: 3.704s (avg. 1.23467s / min 1.23s / max 1.239s - 3 result(s))\n", GET_REDIRECT_OUTPUT); + + t1.showResults(1, false); + ASSERT_EQUALS("call1: 3.704s\n", GET_REDIRECT_OUTPUT); } }; From 96827311afbb7f44e2e46aaa303be75a2aafc760 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 29 Apr 2026 11:09:09 +0200 Subject: [PATCH 060/493] Fix #14700 FN constParameterPointer with usage in ternary (#8503) --- lib/checkother.cpp | 4 ++++ test/testother.cpp | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 4628dd0d774..1584038f135 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1947,6 +1947,10 @@ void CheckOther::checkConstPointer() continue; if (mSettings->library.isFunctionConst(parent->astOperand2())) continue; + if (parent->astOperand2()->varId()) { + if (gparent->str() == "?" && astIsLHS(parent)) + continue; + } } } if (hasIncDecPlus) { diff --git a/test/testother.cpp b/test/testother.cpp index 42f83a14ca2..3f726831656 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4817,6 +4817,12 @@ class TestOther : public TestFixture { " return bar = 0;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S { int x; };\n" // #14700 + "int f(S* s) {\n" + " return s->x ? 1 : 0;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:10]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n", errout_str()); } void constArray() { From 7edc29e65bbd9096701477edb86674dc25265437 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 29 Apr 2026 12:23:12 +0200 Subject: [PATCH 061/493] Fix #14692 False positive: uninitialized variable, libcurl.cfg configuration (#8502) --- cfg/libcurl.cfg | 2 +- test/cfg/libcurl.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cfg/libcurl.cfg b/cfg/libcurl.cfg index 381fbb237d7..949b6de0282 100644 --- a/cfg/libcurl.cfg +++ b/cfg/libcurl.cfg @@ -167,7 +167,7 @@ - + diff --git a/test/cfg/libcurl.c b/test/cfg/libcurl.c index 07fd26b031f..c47f2c68c34 100644 --- a/test/cfg/libcurl.c +++ b/test/cfg/libcurl.c @@ -12,6 +12,15 @@ #include #include +struct S_WriteHeader { + int x; +}; + +size_t cb_WriteHeader(void * /*ptr*/, size_t size, size_t nmemb, void *p) { + struct S_WriteHeader *s = (struct S_WriteHeader *)p; + return s->x ? size * nmemb : 0; +} + void validCode() { CURL *curl = curl_easy_init(); @@ -19,6 +28,9 @@ void validCode() CURLcode res; // cppcheck-suppress valueFlowBailoutIncompleteVar curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, cb_WriteHeader); + struct S_WriteHeader s; + curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &s); // #14692 res = curl_easy_perform(curl); if (res != CURLE_OK) { printf("error"); From ad117758df524f0efffc002291d04b3d8adae1f3 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 29 Apr 2026 15:32:42 +0200 Subject: [PATCH 062/493] Fix CI failure in libcurl.c (#8515) Detected after https://github.com/cppcheck-opensource/cppcheck/pull/8503 --- test/cfg/libcurl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cfg/libcurl.c b/test/cfg/libcurl.c index c47f2c68c34..f5faadbd0d1 100644 --- a/test/cfg/libcurl.c +++ b/test/cfg/libcurl.c @@ -17,6 +17,7 @@ struct S_WriteHeader { }; size_t cb_WriteHeader(void * /*ptr*/, size_t size, size_t nmemb, void *p) { + // cppcheck-suppress constVariablePointer struct S_WriteHeader *s = (struct S_WriteHeader *)p; return s->x ? size * nmemb : 0; } From d161c5f94340f359475f034986c320ad96ef4497 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 29 Apr 2026 17:56:47 +0200 Subject: [PATCH 063/493] Fix #14710 False positive: func arg names different when using VLAs (#8510) --- lib/checkother.cpp | 4 ++-- test/testother.cpp | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 1584038f135..fd23e113509 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4048,8 +4048,8 @@ void CheckOther::checkFuncArgNamesDifferent() decl = decl->nextArgument(); break; } - // skip over template - if (decl->link() && decl->str() == "<") + // skip over templates and arrays + if (decl->link() && decl->str() != "(") decl = decl->link(); else if (decl->varId()) declarations[j] = decl; diff --git a/test/testother.cpp b/test/testother.cpp index 3f726831656..c23e8c64155 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -12936,6 +12936,10 @@ class TestOther : public TestFixture { "[test.cpp:9:20] -> [test.cpp:14:22]: (warning) Function 'func2' argument order different: declaration 'a, b, c' definition 'c, b, a' [funcArgOrderDifferent]\n" "[test.cpp:10:20] -> [test.cpp:15:22]: (warning) Function 'func3' argument order different: declaration 'a, b, c' definition 'c, b, a' [funcArgOrderDifferent]\n" "[test.cpp:11:16] -> [test.cpp:16:22]: (warning) Function 'func4' argument order different: declaration ', b, c' definition 'c, b, a' [funcArgOrderDifferent]\n", errout_str()); + + check("void f(int N, const int a[N], const int b[N]);\n" // #14710 + "void f(int N, const int a[N], const int b[N]) {}\n"); + ASSERT_EQUALS("", errout_str()); } // #7846 - Syntax error when using C++11 braced-initializer in default argument From 89da2d116e7e7f5de903bb1b826c198b807ae168 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 29 Apr 2026 18:49:37 +0200 Subject: [PATCH 064/493] Fix #14711 FP identicalInnerCondition, return expression is not condition (#8514) --- lib/checkcondition.cpp | 2 +- test/testcondition.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index f4aed747de9..a8a4281b58b 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -741,7 +741,7 @@ void CheckCondition::multiCondition2() // Condition.. const Token *cond2 = tok->str() == "if" ? condStartToken->astOperand2() : condStartToken->astOperand1(); - const bool isReturnVar = (tok->str() == "return" && (!Token::Match(cond2, "%cop%") || (cond2 && cond2->isUnaryOp("!")))); + const bool isReturnVar = (tok->str() == "return" && (!Token::Match(cond2, "%cop%") || cond2->isUnaryOp("!") || cond2->isUnaryOp("*"))); ErrorPath errorPath; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index afbcf14ca6d..a9e55268253 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -2836,6 +2836,13 @@ class TestCondition : public TestFixture { " }\n" "}\n"); ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:4:13]: (warning) Identical inner 'if' condition is always true. [identicalInnerCondition]\n", errout_str()); + + check("int f(const int *q, const int *s) {\n" // #14711 + " if (*q && *s)\n" + " return *q;\n" + " return 0;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void identicalConditionAfterEarlyExit() { From 1aec3cc863f24110c724eafa77d6a337353dab9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 29 Apr 2026 20:18:12 +0200 Subject: [PATCH 065/493] added early exit in `Settings::isPremiumEnabled()` (#8513) --- lib/settings.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/settings.cpp b/lib/settings.cpp index 0708a37516b..bdbbb1040ba 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -737,6 +737,8 @@ static const std::set misracpp2023Checkers{ bool Settings::isPremiumEnabled(const char id[]) const { + if (premiumArgs.empty()) + return false; if (premiumArgs.find("autosar") != std::string::npos && autosarCheckers.count(id)) return true; if (premiumArgs.find("cert-c-") != std::string::npos && certCCheckers.count(id)) From 9f576351b627e71d140f3ca1e26fcaceb4f68b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 30 Apr 2026 09:29:32 +0200 Subject: [PATCH 066/493] TestNullPointer: avoid unnecessary `Settings` creations (#8511) --- test/testnullpointer.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 967cd0d2315..04d2f61fc0c 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -37,6 +37,7 @@ class TestNullPointer : public TestFixture { private: const Settings settings = settingsBuilder().library("std.cfg").severity(Severity::warning).build(); + const Settings settings_i = settingsBuilder(settings).certainty(Certainty::inconclusive).build(); void run() override { mNewTemplate = true; @@ -183,13 +184,12 @@ class TestNullPointer : public TestFixture { { bool inconclusive = false; bool cpp = true; - Standards::cstd_t cstd = Standards::CLatest; }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { - const Settings settings1 = settingsBuilder(settings).certainty(Certainty::inconclusive, options.inconclusive).c(options.cstd).build(); + const Settings& settings1 = options.inconclusive ? settings_i : settings; // Tokenize.. SimpleTokenizer tokenizer(settings1, *this, options.cpp); @@ -199,6 +199,16 @@ class TestNullPointer : public TestFixture { runChecks(tokenizer, this); } + template + void check_(const char* file, int line, const char (&code)[size], bool cpp, const Settings& s) { + // Tokenize.. + SimpleTokenizer tokenizer(s, *this, cpp); + ASSERT_LOC(tokenizer.tokenize(code), file, line); + + // Check for null pointer dereferences.. + runChecks(tokenizer, this); + } + #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) template void checkP_(const char* file, int line, const char (&code)[size]) { @@ -1338,7 +1348,8 @@ class TestNullPointer : public TestFixture { check(code); // C++ file => nullptr means NULL ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: i [nullPointer]\n", errout_str()); - check(code, dinit(CheckOptions, $.cpp = false, $.cstd = Standards::C17)); // C17 file => nullptr does not mean NULL + const Settings s = settingsBuilder(settings).c(Standards::C17).build(); + check(code, false, s); // C17 file => nullptr does not mean NULL ASSERT_EQUALS("", errout_str()); check(code, dinit(CheckOptions, $.cpp = false)); From c3df66541df059f6d119d5add967fbcf120e2fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 30 Apr 2026 09:29:46 +0200 Subject: [PATCH 067/493] testrunner: only provide `TimerResults` in executor tests when desired (#8512) --- test/testprocessexecutor.cpp | 6 ++++-- test/testsingleexecutor.cpp | 8 +++++--- test/testthreadexecutor.cpp | 6 ++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/test/testprocessexecutor.cpp b/test/testprocessexecutor.cpp index 5a379166039..87b03d915f8 100644 --- a/test/testprocessexecutor.cpp +++ b/test/testprocessexecutor.cpp @@ -104,7 +104,9 @@ class TestProcessExecutorBase : public TestFixture { s.plistOutput = opt.plistOutput; s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; Suppressions supprs; - TimerResults timerResults; + std::unique_ptr timerResults; + if (s.showtime != Settings::ShowTime::NONE) + timerResults.reset(new TimerResults); // NOLINTNEXTLINE(performance-unnecessary-value-param) auto executeFn = [](std::string,std::vector,std::string,std::string&){ @@ -120,7 +122,7 @@ class TestProcessExecutorBase : public TestFixture { if (useFS) filelist.clear(); - ProcessExecutor executor(filelist, fileSettings, s, supprs, *this, &timerResults, executeFn); + ProcessExecutor executor(filelist, fileSettings, s, supprs, *this, timerResults.get(), executeFn); ASSERT_EQUALS(result, executor.check()); } #endif // HAS_THREADING_MODEL_FORK diff --git a/test/testsingleexecutor.cpp b/test/testsingleexecutor.cpp index 57343c58525..d3f42868a4d 100644 --- a/test/testsingleexecutor.cpp +++ b/test/testsingleexecutor.cpp @@ -97,10 +97,12 @@ class TestSingleExecutorBase : public TestFixture { s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; // TODO: remove when we only longer rely on toString() in unique message handling? Suppressions supprs; - TimerResults timerResults; + std::unique_ptr timerResults; + if (s.showtime != Settings::ShowTime::NONE) + timerResults.reset(new TimerResults); // NOLINTNEXTLINE(performance-unnecessary-value-param) - CppCheck cppcheck(s, supprs, *this, &timerResults, true, [](std::string,std::vector,std::string,std::string&){ + CppCheck cppcheck(s, supprs, *this, timerResults.get(), true, [](std::string,std::vector,std::string,std::string&){ return EXIT_SUCCESS; }); @@ -113,7 +115,7 @@ class TestSingleExecutorBase : public TestFixture { if (useFS) filelist.clear(); - SingleExecutor executor(cppcheck, filelist, fileSettings, s, supprs, *this, &timerResults); + SingleExecutor executor(cppcheck, filelist, fileSettings, s, supprs, *this, timerResults.get()); ASSERT_EQUALS(result, executor.check()); } diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp index 8da83aa1b8f..ddd65c316b2 100644 --- a/test/testthreadexecutor.cpp +++ b/test/testthreadexecutor.cpp @@ -105,7 +105,9 @@ class TestThreadExecutorBase : public TestFixture { s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; // TODO: remove when we only longer rely on toString() in unique message handling? Suppressions supprs; - TimerResults timerResults; + std::unique_ptr timerResults; + if (s.showtime != Settings::ShowTime::NONE) + timerResults.reset(new TimerResults); // NOLINTNEXTLINE(performance-unnecessary-value-param) auto executeFn = [](std::string,std::vector,std::string,std::string&){ @@ -121,7 +123,7 @@ class TestThreadExecutorBase : public TestFixture { if (useFS) filelist.clear(); - ThreadExecutor executor(filelist, fileSettings, s, supprs, *this, &timerResults, executeFn); + ThreadExecutor executor(filelist, fileSettings, s, supprs, *this, timerResults.get(), executeFn); ASSERT_EQUALS(result, executor.check()); } #endif // HAS_THREADING_MODEL_THREAD From 93052167fdc0c2f8f764fa7b70430c777b51482b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 30 Apr 2026 09:52:46 +0200 Subject: [PATCH 068/493] Fix #901 Improve out-of-bounds check to detect error with sprintf() (#8473) Co-authored-by: chrchr-github --- Makefile | 2 +- lib/checkbufferoverrun.cpp | 9 +++++---- lib/valueflow.cpp | 6 +++--- lib/vf_analyzers.cpp | 2 +- lib/vf_common.cpp | 6 ++++-- lib/vf_common.h | 2 +- oss-fuzz/Makefile | 2 +- test/testbufferoverrun.cpp | 35 +++++++++++++++++++++++++++++++++++ 8 files changed, 51 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index b82b924e1d9..bb006c36fea 100644 --- a/Makefile +++ b/Makefile @@ -515,7 +515,7 @@ $(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h li $(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp $(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index a8f7efeabd6..642e40bce76 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -36,6 +36,7 @@ #include "utils.h" #include "valueflow.h" #include "vfvalue.h" +#include "vf_common.h" #include #include @@ -83,7 +84,7 @@ static const Token* getRealBufferTok(const Token* tok) { return (op->valueType() && op->valueType()->pointer) ? op : tok; } -static int getMinFormatStringOutputLength(const std::vector ¶meters, nonneg int formatStringArgNr) +static int getMinFormatStringOutputLength(const std::vector ¶meters, nonneg int formatStringArgNr, const Settings& settings) { if (formatStringArgNr <= 0 || formatStringArgNr > parameters.size()) return 0; @@ -138,8 +139,8 @@ static int getMinFormatStringOutputLength(const std::vector ¶m break; case 's': parameterLength = 0; - if (inputArgNr < parameters.size() && parameters[inputArgNr]->tokType() == Token::eString) - parameterLength = Token::getStrLength(parameters[inputArgNr]); + if (inputArgNr < parameters.size()) + parameterLength = ValueFlow::valueFlowGetStrLength(parameters[inputArgNr], settings); handleNextParameter = true; break; @@ -602,7 +603,7 @@ static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::Mi switch (minsize.type) { case Library::ArgumentChecks::MinSize::Type::STRLEN: if (settings.library.isargformatstr(ftok, minsize.arg)) { - return getMinFormatStringOutputLength(args, minsize.arg) < bufferSize; + return getMinFormatStringOutputLength(args, minsize.arg, settings) < bufferSize; } else if (arg) { const Token *strtoken = arg->getValueTokenMaxStrLength(); if (strtoken) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 06e5fbf2d97..e22a93845a8 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6801,17 +6801,17 @@ static void valueFlowContainerSize(const TokenList& tokenlist, } else if (tok->str() == "+=" && astIsContainer(tok->astOperand1())) { const Token* containerTok = tok->astOperand1(); const Token* valueTok = tok->astOperand2(); - const MathLib::bigint size = ValueFlow::valueFlowGetStrLength(valueTok); + const MathLib::bigint size = ValueFlow::valueFlowGetStrLength(valueTok, settings); forwardMinimumContainerSize(size, tok, containerTok); } else if (tok->str() == "=" && Token::simpleMatch(tok->astOperand2(), "+") && astIsContainerString(tok)) { const Token* tok2 = tok->astOperand2(); MathLib::bigint size = 0; while (Token::simpleMatch(tok2, "+") && tok2->astOperand2()) { - size += ValueFlow::valueFlowGetStrLength(tok2->astOperand2()); + size += ValueFlow::valueFlowGetStrLength(tok2->astOperand2(), settings); tok2 = tok2->astOperand1(); } - size += ValueFlow::valueFlowGetStrLength(tok2); + size += ValueFlow::valueFlowGetStrLength(tok2, settings); forwardMinimumContainerSize(size, tok, tok->astOperand1()); } } diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 24b1fea3274..45d5e7c9547 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -1547,7 +1547,7 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer { case Library::Container::Action::APPEND: { std::vector args = getArguments(tok->astParent()->tokAt(2)); if (args.size() == 1) // TODO: handle overloads - n = ValueFlow::valueFlowGetStrLength(tok->astParent()->tokAt(3)); + n = ValueFlow::valueFlowGetStrLength(tok->astParent()->tokAt(3), settings); if (n == 0) // TODO: handle known empty append val->setPossible(); break; diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index d6c6088b34b..261972cba63 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -389,7 +389,7 @@ namespace ValueFlow v.debugPath.emplace_back(tok, std::move(s)); } - MathLib::bigint valueFlowGetStrLength(const Token* tok) + MathLib::bigint valueFlowGetStrLength(const Token* tok, const Settings& settings) { if (tok->tokType() == Token::eString) return Token::getStrLength(tok); @@ -399,8 +399,10 @@ namespace ValueFlow return v->intvalue; if (const Value* v = tok->getKnownValue(Value::ValueType::TOK)) { if (v->tokvalue != tok) - return valueFlowGetStrLength(v->tokvalue); + return valueFlowGetStrLength(v->tokvalue, settings); } + if (const Token* cont = settings.library.getContainerFromYield(tok, Library::Container::Yield::BUFFER_NT)) + return valueFlowGetStrLength(cont, settings); return 0; } } diff --git a/lib/vf_common.h b/lib/vf_common.h index 3ed36e6c47f..64e394b2979 100644 --- a/lib/vf_common.h +++ b/lib/vf_common.h @@ -53,7 +53,7 @@ namespace ValueFlow const Token* tok, SourceLocation local = SourceLocation::current()); - MathLib::bigint valueFlowGetStrLength(const Token* tok); + MathLib::bigint valueFlowGetStrLength(const Token* tok, const Settings& settings); } #endif // vfCommonH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 1dfa482ae95..b2a42dba2a7 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -185,7 +185,7 @@ $(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/addoninf $(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp $(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 35e2cca6667..8a7c1d311b0 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -4620,6 +4620,41 @@ class TestBufferOverrun : public TestFixture { " mysprintf(a, \"abcd\");\n" "}", settings); ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" // #901 + " const char b[] = \"b\";\n" + " char a[1];\n" + " sprintf(a, \"%s\", b);\n" + "}\n" + "void g() {\n" + " const char* b = \"b\";\n" + " char a[1];\n" + " sprintf(a, \"%s\", b);\n" + "}\n" + "void h() {\n" + " const std::string b = \"b\";\n" + " char a[1];\n" + " sprintf(a, \"%s\", b.c_str());\n" + "}\n" + "void i() {\n" + " const char b[] = \"b\";\n" + " char a[2];\n" + " sprintf(a, \"%s\", b);\n" + "}\n" + "void j() {\n" + " const char* b = \"b\";\n" + " char a[2];\n" + " sprintf(a, \"%s\", b);\n" + "}\n" + "void k() {\n" + " const std::string b = \"b\";\n" + " char a[2];\n" + " sprintf(a, \"%s\", b.c_str());\n" + "}\n", settings0); + ASSERT_EQUALS("[test.cpp:4:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n" + "[test.cpp:9:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n" + "[test.cpp:14:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n", + errout_str()); } void minsize_mul() { From cf2edfd6503c1b80c408622d026e4510efb029fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Devansh=20Varshney=20=28=E0=A4=A6=E0=A5=87=E0=A4=B5?= =?UTF-8?q?=E0=A4=BE=E0=A4=82=E0=A4=B6=20=E0=A4=B5=E0=A4=BE=E0=A4=B0?= =?UTF-8?q?=E0=A5=8D=E0=A4=B7=E0=A5=8D=E0=A4=A3=E0=A5=87=E0=A4=AF=29?= Date: Thu, 30 Apr 2026 22:25:15 +0530 Subject: [PATCH 069/493] AUTHORS: varshneydevansh (#8519) Added My name `Devansh Varshney` in the Authors file. --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index d9c8a8c78fb..40391c83d7d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -105,6 +105,7 @@ Debrard Sebastien Deepak Gupta Degen's Regens dencat +Devansh Varshney Diego de las Heras Dirk Jagdmann Dirk Mueller From 63cb6308b90da5b878f41d134cddf60a0ee190b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Thu, 30 Apr 2026 20:04:59 +0200 Subject: [PATCH 070/493] tools: Rename -p to --max-packages and fix skipped package counter (#8518) -p was unclear and was in the mutually exclusive group with --packages-path, preventing combined use. This commit renames to -n/--max-packages and move it outside the exclusive group so a package limit can be specified alongside a packages path. Also, this commit fixes incrementing packages_processed when a package was skipped due to a download failure or missing source files. Signed-off-by: Francois Berder --- tools/test-my-pr.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/test-my-pr.py b/tools/test-my-pr.py index e0ed773afef..0a630c57c90 100755 --- a/tools/test-my-pr.py +++ b/tools/test-my-pr.py @@ -124,8 +124,8 @@ def getpackages(): parser = argparse.ArgumentParser(description='Run this script from your branch with proposed Cppcheck patch to verify your patch against current main. It will compare output of testing bunch of opensource packages') parser.add_argument('-j', default=1, type=int, help='Concurency execution threads') + parser.add_argument('-n', '--max-packages', default=256, type=int, help='Maximum number of packages to test') package_group = parser.add_mutually_exclusive_group() - package_group.add_argument('-p', default=256, type=int, help='Count of packages to check') package_group.add_argument('--packages', nargs='+', help='Check specific packages and then stop.') package_group.add_argument('--packages-path', default=None, type=str, help='Check packages in path.') parser.add_argument('-o', default='my_check_diff.log', help='Filename of result inside a working path dir') @@ -146,6 +146,8 @@ def getpackages(): args.packages = getpackages() random.shuffle(args.packages) + packages_to_process = min(args.max_packages, len(args.packages)) + print('\n'.join(args.packages[:20])) if not lib.check_requirements(): @@ -212,8 +214,11 @@ def getpackages(): crashes = [] timeouts = [] - while packages_processed < args.p and args.packages: + while packages_processed < packages_to_process and args.packages: package = args.packages.pop() + packages_processed += 1 + print('Processing package {} of {}'.format(packages_processed, packages_to_process)) + if package.startswith('ftp://') or package.startswith('https://'): tgz = lib.download_package(work_path, package, None) @@ -298,9 +303,6 @@ def getpackages(): format_float(time_your), format_float(time_your, time_main), package_width=package_width, timing_width=timing_width)) - packages_processed += 1 - print(str(packages_processed) + ' of ' + str(args.p) + ' packages processed\n') - with open(result_file, 'a') as myfile: myfile.write('\n\ncrashes\n') myfile.write('\n'.join(crashes)) From 0fda84ef7fdc2e183b4b7a923c15d6a49379f86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 1 May 2026 02:32:52 +0200 Subject: [PATCH 071/493] test/cli/other_test.py: added more `--showtime` tests (#8517) --- test/cli/more-projects_test.py | 2 +- test/cli/other_test.py | 129 +++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 41 deletions(-) diff --git a/test/cli/more-projects_test.py b/test/cli/more-projects_test.py index 73d738d9cfb..504a2b14431 100644 --- a/test/cli/more-projects_test.py +++ b/test/cli/more-projects_test.py @@ -258,7 +258,7 @@ def test_project_std(tmpdir): -@pytest.mark.skip() # clang-tidy is not available in all cases +@pytest.mark.skip() # clang-tidy is not available in all cases - TODO: enable conditionally def test_clang_tidy(tmpdir): test_file = os.path.join(tmpdir, 'test.cpp') with open(test_file, 'wt') as f: diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 9735c94482b..fa87948b028 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -13,6 +13,14 @@ from xml.etree import ElementTree +try: + # TODO: handle exitcode? + subprocess.call(['clang-tidy', '--version']) + __has_clang_tidy = True +except OSError: + __has_clang_tidy = False + + def __remove_verbose_log(l : list): l.remove('Defines:') l.remove('Undefines:') @@ -954,10 +962,8 @@ def test_unused_function_include(tmpdir): __test_unused_function_include(tmpdir, []) -# TODO: test with clang-tidy -# TODO: test with --addon # TODO: test with multiple files -def __test_showtime(tmp_path, showtime, exp_res, exp_last, use_compdb, extra_args=None): +def __test_showtime(tmp_path, showtime, exp_res, exp_last, use_compdb=False, use_addons=False, use_clang_tidy=False, extra_args=None): test_file = tmp_path / 'test.cpp' # the use of C++ is intentional with open(test_file, 'wt') as f: f.write( @@ -974,6 +980,17 @@ def __test_showtime(tmp_path, showtime, exp_res, exp_last, use_compdb, extra_arg '--inline-suppr' ] + if use_addons: + args += ['--addon=misra', '--addon=misc'] + + if use_clang_tidy: + args += ['--clang-tidy'] + args += ['--suppress=clang-tidy-misc-use-internal-linkage'] + args += ['--suppress=clang-tidy-google-readability-casting'] + args += ['--suppress=clang-tidy-modernize-avoid-c-style-cast'] + args += ['--suppress=clang-tidy-hicpp-use-nullptr'] + args += ['--suppress=clang-tidy-modernize-use-nullptr'] + if use_compdb: compdb_file = tmp_path / 'compile_commands.json' create_compile_commands(compdb_file, [test_file]) @@ -991,6 +1008,9 @@ def __test_showtime(tmp_path, showtime, exp_res, exp_last, use_compdb, extra_arg exp_len = exp_res if 'cppcheck internal API usage' in stdout: exp_len += 1 + if use_addons: + exp_len += 1 # TODO: should have individual entries for each addon and whole program analysis + # TODO: add entry for clang-tidy analysis exp_len += 1 # last line assert len(lines) == exp_len for i in range(1, exp_res): @@ -1000,118 +1020,154 @@ def __test_showtime(tmp_path, showtime, exp_res, exp_last, use_compdb, extra_arg assert stderr == '' -def __test_showtime_top5_file(tmp_path, use_compdb): - __test_showtime(tmp_path, 'top5_file', 5, 'Check time: ', use_compdb) +def __test_showtime_top5_file(tmp_path, use_compdb=False): + __test_showtime(tmp_path, 'top5_file', 5, 'Check time: ', use_compdb=use_compdb) def test_showtime_top5_file(tmp_path): - __test_showtime_top5_file(tmp_path, False) + __test_showtime_top5_file(tmp_path) def test_showtime_top5_file_compdb(tmp_path): - __test_showtime_top5_file(tmp_path, True) + __test_showtime_top5_file(tmp_path, use_compdb=True) # TODO: remove extra args when --executor=process works -def __test_showtime_top5_summary(tmp_path, use_compdb): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb, ['-j1']) +def __test_showtime_top5_summary(tmp_path, use_compdb=False): + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb=use_compdb, extra_args=['-j1']) def test_showtime_top5_summary(tmp_path): - __test_showtime_top5_summary(tmp_path, False) + __test_showtime_top5_summary(tmp_path) def test_showtime_top5_summary_compdb(tmp_path): - __test_showtime_top5_summary(tmp_path, True) + __test_showtime_top5_summary(tmp_path, use_compdb=True) # TODO: remove when --executor=process works def test_showtime_top5_summary_j_thread(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', False, ['-j2', '--executor=thread']) + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', extra_args=['-j2', '--executor=thread']) # TODO: remove when --executor=process works def test_showtime_top5_summary_compdb_j_thread(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', True, ['-j2', '--executor=thread']) + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb=True, extra_args=['-j2', '--executor=thread']) # TODO: remove override when fixed @pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") @pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 def test_showtime_top5_summary_j_process(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', False, ['-j2', '--executor=process']) + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', extra_args=['-j2', '--executor=process']) # TODO: remove override when fixed @pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") @pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 def test_showtime_top5_summary_compdb_j_process(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', True, ['-j2', '--executor=process']) + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb=True, extra_args=['-j2', '--executor=process']) -def __test_showtime_file(tmp_path, use_compdb): +def __test_showtime_file(tmp_path, use_compdb=False, use_addons=False, use_clang_tidy=False): exp_res = 79 # project analysis does not call Preprocessor::getConfig() if use_compdb: exp_res -= 1 - __test_showtime(tmp_path, 'file', exp_res, 'Check time: ', use_compdb) + __test_showtime(tmp_path, 'file', exp_res, 'Check time: ', use_compdb=use_compdb, use_addons=use_addons, use_clang_tidy=use_clang_tidy) def test_showtime_file(tmp_path): - __test_showtime_file(tmp_path, False) + __test_showtime_file(tmp_path) def test_showtime_file_compdb(tmp_path): - __test_showtime_file(tmp_path, True) + __test_showtime_file(tmp_path, use_compdb=True) + + +def test_showtime_file_addon(tmp_path): + __test_showtime_file(tmp_path, use_addons=True) + + +def test_showtime_file_addon_compdb(tmp_path): + __test_showtime_file(tmp_path, use_addons=True, use_compdb=True) + + +@pytest.mark.skipif(not __has_clang_tidy, reason='clang-tidy is not available') +def test_showtime_file_clang_tidy(tmp_path): + __test_showtime_file(tmp_path, use_clang_tidy=True) + + +@pytest.mark.skipif(not __has_clang_tidy, reason='clang-tidy is not available') +def test_showtime_file_clang_tidy_compdb(tmp_path): + __test_showtime_file(tmp_path, use_clang_tidy=True, use_compdb=True) # TODO: remove extra args when --executor=process works -def __test_showtime_summary(tmp_path, use_compdb): +def __test_showtime_summary(tmp_path, use_compdb=False, use_addons=False, use_clang_tidy=False): exp_res = 79 # project analysis does not call Preprocessor::getConfig() if use_compdb: exp_res -= 1 - __test_showtime(tmp_path, 'summary', exp_res, 'Overall time: ', use_compdb, ['-j1']) + __test_showtime(tmp_path, 'summary', exp_res, 'Overall time: ', use_compdb=use_compdb, use_addons=use_addons, use_clang_tidy=use_clang_tidy, extra_args=['-j1']) def test_showtime_summary(tmp_path): - __test_showtime_summary(tmp_path, False,) + __test_showtime_summary(tmp_path) def test_showtime_summary_compdb(tmp_path): - __test_showtime_summary(tmp_path, True) + __test_showtime_summary(tmp_path, use_compdb=True) + + +def test_showtime_summary_addon(tmp_path): + __test_showtime_summary(tmp_path, use_addons=True) + + +def test_showtime_summary_addon_compdb(tmp_path): + __test_showtime_summary(tmp_path, use_addons=True, use_compdb=True) + + +@pytest.mark.skipif(not __has_clang_tidy, reason='clang-tidy is not available') +def test_showtime_summary_clang_tidy(tmp_path): + __test_showtime_summary(tmp_path, use_clang_tidy=True) + + +@pytest.mark.skipif(not __has_clang_tidy, reason='clang-tidy is not available') +def test_showtime_summary_clang_tidy_compdb(tmp_path): + __test_showtime_summary(tmp_path, use_clang_tidy=True, use_compdb=True) # TODO: remove when --executor=process works def test_showtime_summary_j_thread(tmp_path): - __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', False, ['-j2', '--executor=thread']) + __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', extra_args=['-j2', '--executor=thread']) # TODO: remove when --executor=process works def test_showtime_summary_compdb_j_thread(tmp_path): - __test_showtime(tmp_path, 'summary', 78, 'Overall time: ', True, ['-j2', '--executor=thread']) + __test_showtime(tmp_path, 'summary', 78, 'Overall time: ', use_compdb=True, extra_args=['-j2', '--executor=thread']) # TODO: remove override when fixed @pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") @pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 def test_showtime_summary_j_process(tmp_path): - __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', False, ['-j2', '--executor=process']) + __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', extra_args=['-j2', '--executor=process']) # TODO: remove override when fixed @pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") @pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 def test_showtime_summary_compdb_j_process(tmp_path): - __test_showtime(tmp_path, 'summary', 78, 'Overall time: ', True, ['-j2', '--executor=process']) + __test_showtime(tmp_path, 'summary', 78, 'Overall time: ', use_compdb=True, extra_args=['-j2', '--executor=process']) -def __test_showtime_file_total(tmp_path, use_compdb): - __test_showtime(tmp_path, 'file-total', 0, 'Check time: ', use_compdb) +def __test_showtime_file_total(tmp_path, use_compdb=False): + __test_showtime(tmp_path, 'file-total', 0, 'Check time: ', use_compdb=use_compdb) def test_showtime_file_total(tmp_path): - __test_showtime_file_total(tmp_path, False) + __test_showtime_file_total(tmp_path) def test_showtime_file_total_compdb(tmp_path): @@ -3423,13 +3479,6 @@ def test_check_unused_templates_func(tmp_path): # #13714 assert stdout.splitlines() == [] assert stderr.splitlines() == [] # no error since the unused templates are not being checked -try: - # TODO: handle exitcode? - subprocess.call(['clang-tidy', '--version']) - has_clang_tidy = True -except OSError: - has_clang_tidy = False - def __test_clang_tidy(tmpdir, use_compdb): test_file = os.path.join(tmpdir, 'test.cpp') with open(test_file, 'wt') as f: @@ -3460,18 +3509,18 @@ def __test_clang_tidy(tmpdir, use_compdb): ] -@pytest.mark.skipif(not has_clang_tidy, reason='clang-tidy is not available') +@pytest.mark.skipif(not __has_clang_tidy, reason='clang-tidy is not available') @pytest.mark.xfail(strict=True) # TODO: clang-tidy is only invoked with FileSettings - see #12053 def test_clang_tidy(tmpdir): # #12053 __test_clang_tidy(tmpdir, False) -@pytest.mark.skipif(not has_clang_tidy, reason='clang-tidy is not available') +@pytest.mark.skipif(not __has_clang_tidy, reason='clang-tidy is not available') def test_clang_tidy_project(tmpdir): __test_clang_tidy(tmpdir, True) -@pytest.mark.skipif(not has_clang_tidy, reason='clang-tidy is not available') +@pytest.mark.skipif(not __has_clang_tidy, reason='clang-tidy is not available') def test_clang_tidy_error_exit(tmp_path): # #13828 / #13829 test_file = tmp_path / 'test.cpp' with open(test_file, 'wt') as f: From e5c4a734d8e86ef9dd2f0ab8e4aaf92d0c8bcd19 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 1 May 2026 11:10:43 +0200 Subject: [PATCH 072/493] Fix #14715 FP invalidFunctionArgStr, buffer is nul-terminated in every path (#8516) --- lib/checkfunctions.cpp | 2 +- test/testfunctions.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index f6799d199e7..7611ea7eee4 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -153,7 +153,7 @@ void CheckFunctions::invalidFunctionUsage() // Is non-null terminated local variable of type char (e.g. char buf[] = {'x'};) ? if (variable && variable->isLocal() && valueType && (valueType->type == ValueType::Type::CHAR || valueType->type == ValueType::Type::WCHAR_T) - && !isVariablesChanged(variable->declEndToken(), functionToken, 0 /*indirect*/, { variable }, *mSettings)) { + && !isVariablesChanged(variable->declEndToken(), functionToken, valueType->pointer, { variable }, *mSettings)) { const Token* varTok = variable->declEndToken(); MathLib::bigint count = -1; // Find out explicitly set count, e.g.: char buf[3] = {...}. Variable 'count' is set to 3 then. if (varTok && Token::simpleMatch(varTok->astOperand1(), "[")) diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index c3fe10afe39..8bbd3d92c6b 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -761,6 +761,13 @@ class TestFunctions : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); + check("char* f() {\n" // #14715 + " char a[3] = { 'a', 'b', 'c' };\n" + " *a = 0;\n" + " return strdup(a);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + check("size_t f() { wchar_t x = L'x'; return wcslen(&x); }"); ASSERT_EQUALS("[test.cpp:1:46]: (error) Invalid wcslen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); From b60118dd7a5546d1b1aefa017d23d4904c1b86a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Mon, 4 May 2026 14:50:45 +0200 Subject: [PATCH 073/493] Fix #14689 (html report: Fix missing severity and classification bars) (#8456) Fixes a bug introduced in #7994. --- htmlreport/cppcheck-htmlreport | 8 ++++---- test/tools/htmlreport/test_htmlreport.py | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/htmlreport/cppcheck-htmlreport b/htmlreport/cppcheck-htmlreport index 5044443a0a9..fb263c73d12 100755 --- a/htmlreport/cppcheck-htmlreport +++ b/htmlreport/cppcheck-htmlreport @@ -278,7 +278,7 @@ HTML_HEAD = """ updateFileRows(); } - + function toggleClassification(cb) { cb.parentElement.classList.toggle("unchecked", !cb.checked); var elements = document.querySelectorAll(".class_" + cb.id); @@ -289,7 +289,7 @@ HTML_HEAD = """ updateFileRows(); } - + function toggleTool(cb) { cb.parentElement.classList.toggle("unchecked", !cb.checked); @@ -469,9 +469,9 @@ def filter_button(enabled_filters, id, function): def filter_bar(enabled): severity_bar = ''.join([filter_button(enabled, severity, 'toggleSeverity') for severity in ['error', 'warning', 'portability', 'performance', 'style', 'information']]) + '\n | ' classification_bar = ''.join([filter_button(enabled, _class, 'toggleClassification') for _class in ['Mandatory', 'Required', 'Advisory', 'Document', 'Disapplied', 'L1','L2','L3','']]) + '\n | ' - if "checked/>" not in severity_bar: + if "checked>" not in severity_bar: severity_bar = '' - if "checked/>" not in classification_bar: + if "checked>" not in classification_bar: classification_bar = '' return ''.join([ '
\n' diff --git a/test/tools/htmlreport/test_htmlreport.py b/test/tools/htmlreport/test_htmlreport.py index 6f8713f4f55..f84fd279fb3 100755 --- a/test/tools/htmlreport/test_htmlreport.py +++ b/test/tools/htmlreport/test_htmlreport.py @@ -107,6 +107,13 @@ def testAddTimestamp(self): output_directory.cleanup() + def testSeverityFilterBar(self): + with runCheck( + xml_filename=os.path.join(TEST_TOOLS_DIR, 'example.xml'), + ) as (report, output_directory): + self.assertIn('onclick="toggleSeverity(this)"', report) + output_directory.cleanup() + @contextlib.contextmanager def runCheck(source_filename=None, xml_version='1', xml_filename=None, checkers_filename=None): From 519958a32ae6b14f123c323d810878e49c31fb94 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 4 May 2026 15:03:10 +0200 Subject: [PATCH 074/493] Fix #14709 FP memleak using IS_NULL() macro (#8522) --- lib/astutils.cpp | 2 ++ test/testleakautovar.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index fa2c9c3890b..c745d0cf9f2 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -400,6 +400,8 @@ const Token * astIsVariableComparison(const Token *tok, const std::string &comp, } while (ret && ret->str() == ".") ret = ret->astOperand2(); + while (ret && ret->isCast()) + ret = ret->astOperand2() ? ret->astOperand2() : ret->astOperand1(); if (ret && ret->str() == "=" && ret->astOperand1() && ret->astOperand1()->varId()) ret = ret->astOperand1(); else if (ret && ret->varId() == 0U) diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 300db8d9855..b038270dcb7 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -154,6 +154,7 @@ class TestLeakAutoVar : public TestFixture { TEST_CASE(ifelse27); TEST_CASE(ifelse28); // #11038 TEST_CASE(ifelse29); + TEST_CASE(ifelse30); // switch TEST_CASE(switch1); @@ -2390,6 +2391,22 @@ class TestLeakAutoVar : public TestFixture { ASSERT_EQUALS("", errout_str()); // don't crash } + void ifelse30() { + check("void f(void** pp) {\n" // #14709 + " void* p = malloc(8);\n" + " if ((void*)p == 0)\n" + " return;\n" + " *pp = p;\n" + "}\n" + "void g(void** pp) {\n" + " void* p = malloc(8);\n" + " if (static_cast(p) == 0)\n" + " return;\n" + " *pp = p;\n" + "}\n", dinit(CheckOptions, $.cpp = true)); + ASSERT_EQUALS("", errout_str()); + } + void switch1() { check("void f() {\n" " char *p = 0;\n" From 5d48a7c8ebd374181ce2cfbd32af4dd6228299bd Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 5 May 2026 11:30:25 +0200 Subject: [PATCH 075/493] Fix #14718 memleakOnRealloc false positive (#8524) --- lib/checkmemoryleak.cpp | 5 +++- test/testmemleak.cpp | 55 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 82973958847..1a6ef787eb6 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -477,8 +477,11 @@ void CheckMemoryLeakInFunction::checkReallocUsage() // Check that another copy of the pointer wasn't saved earlier in the function if (Token::findmatch(scope->bodyStart, "%name% = %varid% ;", tok, tok->varId()) || - Token::findmatch(scope->bodyStart, "[{};] %varid% = *| %var% .| %var%| [;=]", tok, tok->varId())) + Token::findmatch(scope->bodyStart, "[{};] %varid% = *| %var%", tok, tok->varId())) continue; + if (const Token* storeTok = Token::findmatch(scope->bodyStart, "[{};] %varid% = %name% (", tok, tok->varId())) + if (storeTok->tokAt(3) != reallocTok && !mSettings->library.getAllocFuncInfo(storeTok->tokAt(3))) + continue; // Check if the argument is known to be null, which means it is not a memory leak if (arg->hasKnownIntValue() && arg->getKnownIntValue() == 0) { diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 3b7777f4f87..1ed88120886 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -150,6 +150,7 @@ class TestMemleakInFunction : public TestFixture { TEST_CASE(realloc22); TEST_CASE(realloc23); TEST_CASE(realloc24); // #9228 + TEST_CASE(realloc25); } void realloc1() { @@ -418,6 +419,60 @@ class TestMemleakInFunction : public TestFixture { "}"); ASSERT_EQUALS("", errout_str()); } + + void realloc25() { + check("struct T {\n" + " char* ptr;\n" + " size_t len;\n" + "};\n" + "struct S {\n" + " struct T t;\n" + "};\n" + "void f(struct S* s, size_t len) {\n" + " char* p = s->t.ptr;\n" + " p = realloc(p, len);\n" + " if (p) {\n" + " s->t.ptr = p;\n" + " s->t.len = len;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct T {\n" + " char* ptr;\n" + " size_t len;\n" + "};\n" + "struct S {\n" + " struct T t[1];\n" + "};\n" + "void f(struct S* s, size_t len) {\n" + " char* p = s->t[0].ptr;\n" + " p = realloc(p, len);\n" + " if (p) {\n" + " s->t[0].ptr = p;\n" + " s->t[0].len = len;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct T {\n" // #14718 + " char* ptr;\n" + " size_t len;\n" + "};\n" + "struct S {\n" + " struct T t;\n" + "};\n" + "char* get(struct T t) { return t.ptr; };\n" + "void f(struct S* s, size_t len) {\n" + " char* p = get(s->t);\n" + " p = realloc(p, len);\n" + " if (p) {\n" + " s->t.ptr = p;\n" + " s->t.len = len;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } }; REGISTER_TEST(TestMemleakInFunction) From f01120ba32cea5ad76d4cece6a8561dc55e9723c Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 5 May 2026 11:35:05 +0200 Subject: [PATCH 076/493] #14719 FP uninitdata for new array with initializer (#8528) Co-authored-by: chrchr-github --- lib/checkuninitvar.cpp | 14 +++++++++----- test/testuninitvar.cpp | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 3d1a0ecccc5..2e749c6b71e 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -784,12 +784,16 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var // standard or enum type: check if new initializes the allocated memory if (var.typeStartToken()->isStandardType() || var.typeStartToken()->isEnumType()) { // scalar new with initialization - if (Token::Match(tok->next(), "= new %type% (")) - return true; - // array new - if (Token::Match(tok->next(), "= new %type% [") && Token::simpleMatch(tok->linkAt(4), "] (")) - return true; + if (Token::Match(tok->next(), "= new ::|%type%")) { + const Token* initTok = tok->tokAt(4); + while (Token::Match(initTok, "::|%type%")) + initTok = initTok->next(); + if (Token::simpleMatch(initTok, "[")) + initTok = initTok->link()->next(); + if (Token::Match(initTok, "[({]")) + return true; + } } continue; diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 960fee4ee87..e22c4009f5d 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -2181,6 +2181,26 @@ class TestUninitVar : public TestFixture { " return s;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + checkUninitVar("int f() {\n" // #14719 + " int* p = new int[]{ 1, 2 };\n" + " int i = p[0] + p[1];\n" + " delete[] p;\n" + " return i;\n" + "}\n" + "int g() {\n" + " int* p = new std::int32_t[]{ 1, 2 };\n" + " int i = p[0] + p[1];\n" + " delete[] p;\n" + " return i;\n" + "}\n" + "int h() {\n" + " int* p = new ::std::int32_t[]{ 1, 2 };\n" + " int i = p[0] + p[1];\n" + " delete[] p;\n" + " return i;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } // class / struct.. From 4ff8d437132b8741e4e8a9100d16c8cd5c82e4bf Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 5 May 2026 12:35:13 +0200 Subject: [PATCH 077/493] Fix #14720 FP assertWithSideEffect (const function call QDir::exists() in assert) (#8526) Co-authored-by: chrchr-github --- cfg/qt.cfg | 2 ++ test/cfg/qt.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/cfg/qt.cfg b/cfg/qt.cfg index 5371e598568..66f6e78b3b6 100644 --- a/cfg/qt.cfg +++ b/cfg/qt.cfg @@ -2428,6 +2428,7 @@ false + @@ -2440,6 +2441,7 @@ false + diff --git a/test/cfg/qt.cpp b/test/cfg/qt.cpp index 70e6ac0310a..4ff0a476959 100644 --- a/test/cfg/qt.cpp +++ b/test/cfg/qt.cpp @@ -76,6 +76,11 @@ void ignoredReturnValue_QDir(const QString& dirname) dir.entryList(); } +void assertWithSideEffect_QDir_exists(const char *path) { // #14720 + QDir dir(path); + assert(dir.exists()); + (void)dir; +} void unusedVariable_QTransform() { From 28dfa41e1da2d32095c18da650e144ae9b30e9ee Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 5 May 2026 12:37:18 +0200 Subject: [PATCH 078/493] Fix #14724 FP: overlapping inner condition, function call (#8527) Co-authored-by: chrchr-github --- lib/checkcondition.cpp | 2 +- test/testcondition.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index a8a4281b58b..1b761ce4802 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -684,7 +684,7 @@ void CheckCondition::multiCondition2() if (!nonlocal && var) { if (!(var->isLocal() || var->isArgument())) nonlocal = true; - else if ((var->isPointer() || var->isReference()) && !Token::Match(cond->astParent(), "%oror%|&&|!")) + else if ((var->isPointer() || var->isReference() || var->isArray()) && !Token::Match(cond->astParent(), "%oror%|&&|!")) // TODO: if var is pointer check what it points at nonlocal = true; } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index a9e55268253..9737217add3 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -2843,6 +2843,15 @@ class TestCondition : public TestFixture { " return 0;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f(int x, int y) {\n" + " int a[] = { x, y };\n" + " if (a[0] == 1) {\n" + " if (a[0] == 1) {}\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:3:14] -> [test.cpp:4:18]: (warning) Identical inner 'if' condition is always true. [identicalInnerCondition]\n", + errout_str()); } void identicalConditionAfterEarlyExit() { @@ -3029,6 +3038,15 @@ class TestCondition : public TestFixture { " }\n" "}"); ASSERT_EQUALS("", errout_str()); + + check("void g(int[]);\n" // #14724 + "void f(int a[]) {\n" + " if (a[0] == 1) {\n" + " g(a);\n" + " if (a[0] == 1) {}\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout_str()); } void overlappingInnerCondition() { From efae8c0fd239105649f846619949ef21aea9d11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 5 May 2026 14:08:54 +0200 Subject: [PATCH 079/493] refs #4452 - transfer timer results in `ProcessExecutor` (#8521) --- cli/processexecutor.cpp | 38 +++++++++++++++++++++++++++-- lib/timer.h | 5 ++++ test/cli/other_test.py | 54 ++--------------------------------------- test/testtimer.cpp | 12 +-------- 4 files changed, 44 insertions(+), 65 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index 11f920db13c..cc6c7baf214 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -78,7 +78,7 @@ ProcessExecutor::ProcessExecutor(const std::list &files, const namespace { class PipeWriter : public ErrorLogger { public: - enum PipeSignal : std::uint8_t {REPORT_OUT='1',REPORT_ERROR='2',REPORT_SUPPR_INLINE='3',REPORT_SUPPR='4',CHILD_END='5',REPORT_METRIC='6'}; + enum PipeSignal : std::uint8_t {REPORT_OUT='1',REPORT_ERROR='2',REPORT_SUPPR_INLINE='3',REPORT_SUPPR='4',CHILD_END='5',REPORT_METRIC='6',REPORT_TIMER='7'}; explicit PipeWriter(int pipe) : mWpipe(pipe) {} @@ -104,6 +104,18 @@ namespace { writeToPipe(REPORT_METRIC, metric); } + void writeTimer(const TimerResults* timerResults) const { + if (!timerResults) + return; + + for (const auto& entry : timerResults->getResults()) + { + for (const auto& d : entry.second) { + writeToPipe(REPORT_TIMER, entry.first + ";" + std::to_string(d.count())); + } + } + } + void writeEnd(const std::string& str) const { writeToPipe(CHILD_END, str); } @@ -188,7 +200,8 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str type != PipeWriter::REPORT_SUPPR_INLINE && type != PipeWriter::REPORT_SUPPR && type != PipeWriter::CHILD_END && - type != PipeWriter::REPORT_METRIC) { + type != PipeWriter::REPORT_METRIC && + type != PipeWriter::REPORT_TIMER) { std::cerr << "#### ThreadExecutor::handleRead(" << filename << ") invalid type " << int(type) << std::endl; std::exit(EXIT_FAILURE); } @@ -272,6 +285,20 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str res = false; } else if (type == PipeWriter::REPORT_METRIC) { mErrorLogger.reportMetric(buf); + } else if (type == PipeWriter::REPORT_TIMER) { + if (!mTimerResults) { + // TODO: make this non-fatal + std::cerr << "#### ThreadExecutor::handleRead(" << filename << ") received timer results when no timer is enabled" << std::endl; + std::exit(EXIT_FAILURE); + } + const auto parts = splitString(buf, ';'); + if (parts.size() < 2) + { + // TODO: make this non-fatal + std::cerr << "#### ThreadExecutor::handleRead(" << filename << ") adding of timer result failed - insufficient data" << std::endl; + std::exit(EXIT_FAILURE); + } + mTimerResults->addResults(parts[0], std::chrono::milliseconds{strToInt(parts[1])}); } return res; @@ -346,6 +373,11 @@ unsigned int ProcessExecutor::check() #endif close(pipes[0]); + // reset so we do not have the data which has already been transferred back + if (mTimerResults) + mTimerResults->reset(); + // TODO: how to "reset" mSuppressions? + PipeWriter pipewriter(pipes[1]); CppCheck fileChecker(mSettings, mSuppressions, pipewriter, mTimerResults, false, mExecuteCommand); unsigned int resultOfCheck = 0; @@ -359,6 +391,8 @@ unsigned int ProcessExecutor::check() pipewriter.writeSuppr(mSuppressions.nomsg); + pipewriter.writeTimer(mTimerResults); + pipewriter.writeEnd(std::to_string(resultOfCheck)); std::exit(EXIT_SUCCESS); } diff --git a/lib/timer.h b/lib/timer.h index 58ec8de08cc..1ee7fde52f9 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -48,6 +48,11 @@ class CPPCHECKLIB WARN_UNUSED TimerResults : public TimerResultsIntf { void reset(); + std::map> getResults() const { + std::lock_guard l(mResultsSync); + return mResults; + } + protected: std::map> mResults; mutable std::mutex mResultsSync; diff --git a/test/cli/other_test.py b/test/cli/other_test.py index fa87948b028..4aaddc3572d 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -1032,9 +1032,8 @@ def test_showtime_top5_file_compdb(tmp_path): __test_showtime_top5_file(tmp_path, use_compdb=True) -# TODO: remove extra args when --executor=process works def __test_showtime_top5_summary(tmp_path, use_compdb=False): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb=use_compdb, extra_args=['-j1']) + __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb=use_compdb) def test_showtime_top5_summary(tmp_path): @@ -1045,30 +1044,6 @@ def test_showtime_top5_summary_compdb(tmp_path): __test_showtime_top5_summary(tmp_path, use_compdb=True) -# TODO: remove when --executor=process works -def test_showtime_top5_summary_j_thread(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', extra_args=['-j2', '--executor=thread']) - - -# TODO: remove when --executor=process works -def test_showtime_top5_summary_compdb_j_thread(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb=True, extra_args=['-j2', '--executor=thread']) - - -# TODO: remove override when fixed -@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") -@pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 -def test_showtime_top5_summary_j_process(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', extra_args=['-j2', '--executor=process']) - - -# TODO: remove override when fixed -@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") -@pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 -def test_showtime_top5_summary_compdb_j_process(tmp_path): - __test_showtime(tmp_path, 'top5_summary', 5, 'Overall time: ', use_compdb=True, extra_args=['-j2', '--executor=process']) - - def __test_showtime_file(tmp_path, use_compdb=False, use_addons=False, use_clang_tidy=False): exp_res = 79 # project analysis does not call Preprocessor::getConfig() @@ -1103,13 +1078,12 @@ def test_showtime_file_clang_tidy_compdb(tmp_path): __test_showtime_file(tmp_path, use_clang_tidy=True, use_compdb=True) -# TODO: remove extra args when --executor=process works def __test_showtime_summary(tmp_path, use_compdb=False, use_addons=False, use_clang_tidy=False): exp_res = 79 # project analysis does not call Preprocessor::getConfig() if use_compdb: exp_res -= 1 - __test_showtime(tmp_path, 'summary', exp_res, 'Overall time: ', use_compdb=use_compdb, use_addons=use_addons, use_clang_tidy=use_clang_tidy, extra_args=['-j1']) + __test_showtime(tmp_path, 'summary', exp_res, 'Overall time: ', use_compdb=use_compdb, use_addons=use_addons, use_clang_tidy=use_clang_tidy) def test_showtime_summary(tmp_path): @@ -1138,30 +1112,6 @@ def test_showtime_summary_clang_tidy_compdb(tmp_path): __test_showtime_summary(tmp_path, use_clang_tidy=True, use_compdb=True) -# TODO: remove when --executor=process works -def test_showtime_summary_j_thread(tmp_path): - __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', extra_args=['-j2', '--executor=thread']) - - -# TODO: remove when --executor=process works -def test_showtime_summary_compdb_j_thread(tmp_path): - __test_showtime(tmp_path, 'summary', 78, 'Overall time: ', use_compdb=True, extra_args=['-j2', '--executor=thread']) - - -# TODO: remove override when fixed -@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") -@pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 -def test_showtime_summary_j_process(tmp_path): - __test_showtime(tmp_path, 'summary', 79, 'Overall time: ', extra_args=['-j2', '--executor=process']) - - -# TODO: remove override when fixed -@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") -@pytest.mark.xfail(strict=True) # TODO: need to transfer the timer results to parent process - see #4452 -def test_showtime_summary_compdb_j_process(tmp_path): - __test_showtime(tmp_path, 'summary', 78, 'Overall time: ', use_compdb=True, extra_args=['-j2', '--executor=process']) - - def __test_showtime_file_total(tmp_path, use_compdb=False): __test_showtime(tmp_path, 'file-total', 0, 'Check time: ', use_compdb=use_compdb) diff --git a/test/testtimer.cpp b/test/testtimer.cpp index 179f87deba4..4d5c1c2700c 100644 --- a/test/testtimer.cpp +++ b/test/testtimer.cpp @@ -21,22 +21,12 @@ #include "timer.h" #include -#include class TestTimer : public TestFixture { public: TestTimer() : TestFixture("TestTimer") {} private: - class TimerResultsTest : public TimerResults - { - public: - std::map> getResults() const { - std::lock_guard l(mResultsSync); - return mResults; - } - }; - void run() override { TEST_CASE(result); } @@ -44,7 +34,7 @@ class TestTimer : public TestFixture { void result() { REDIRECT; - TimerResultsTest t1; + TimerResults t1; t1.addResults("call1", std::chrono::milliseconds{1230}); t1.addResults("call2", std::chrono::milliseconds{1234}); t1.addResults("call1", std::chrono::milliseconds{1235}); From 6278f6b039dd0cdc05be6b03a7743ab7fa642e31 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 5 May 2026 15:01:04 +0200 Subject: [PATCH 080/493] Fix #14721 FP container considered empty after insertion (*m)[1] = 42; (#8529) --- lib/valueflow.cpp | 2 ++ test/testvalueflow.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e22a93845a8..3819bfc4b41 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6221,6 +6221,8 @@ bool ValueFlow::isContainerSizeChanged(const Token* tok, int indirect, const Set return true; if (astIsLHS(tok) && Token::simpleMatch(tok->astParent(), "[")) return tok->valueType()->container->stdAssociativeLike; + if (Token::simpleMatch(tok->astParent(), "*") && indirect > 0) + return isContainerSizeChanged(tok->astParent(), indirect - 1, settings, depth + 1); const Library::Container::Action action = astContainerAction(tok, settings.library); switch (action) { case Library::Container::Action::RESIZE: diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index ff5d18b3175..51bb78aa40a 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -7486,6 +7486,16 @@ class TestValueFlow : public TestFixture { " if (s.empty()) {}\n" "}"; ASSERT(!isKnownContainerSizeValue(tokenValues(code, "s ."), 0).empty()); + + code = "void g(std::map* p) {\n" // #14721 + " (*p)[1] = 2;\n" + "}\n" + "void f() {\n" + " std::map m;\n" + " g(&m);\n" + " if (m.empty()) {}\n" + "}\n"; + ASSERT(!isKnownContainerSizeValue(tokenValues(code, "m ."), 0).empty()); } void valueFlowContainerElement() From ce9227ff922e5a71ff0b24a5d91844efdd59ac1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 6 May 2026 11:33:30 +0200 Subject: [PATCH 081/493] fixed #14726 - removed explicit usage of Visual Studio CMake generators from CI (#8532) --- .github/workflows/CI-windows.yml | 6 +++--- .github/workflows/release-windows.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml index 6fa92373a7c..71d72025cf9 100644 --- a/.github/workflows/CI-windows.yml +++ b/.github/workflows/CI-windows.yml @@ -92,7 +92,7 @@ jobs: - name: Run CMake run: | - cmake -S . -B build.cxxstd -Werror=dev -G "Visual Studio 17 2022" -A x64 -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake -S . -B build.cxxstd -Werror=dev -A x64 -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! - name: Build run: | @@ -133,12 +133,12 @@ jobs: - name: Run CMake (without GUI) run: | :: TODO: enable DHAVE_RULES? - cmake-${{ env.CMAKE_VERSION_FULL }}-windows-x86_64\bin\cmake.exe -S . -B cmake.output -G "Visual Studio 17 2022" -A x64 -DHAVE_RULES=Off -DBUILD_TESTING=On + cmake-${{ env.CMAKE_VERSION_FULL }}-windows-x86_64\bin\cmake.exe -S . -B cmake.output -A x64 -DHAVE_RULES=Off -DBUILD_TESTING=On - name: Run CMake (with GUI) run: | :: TODO: enable DHAVE_RULES? - cmake-${{ env.CMAKE_VERSION_FULL }}-windows-x86_64\bin\cmake.exe -S . -B cmake.output.gui -G "Visual Studio 17 2022" -A x64 -DHAVE_RULES=Off -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On + cmake-${{ env.CMAKE_VERSION_FULL }}-windows-x86_64\bin\cmake.exe -S . -B cmake.output.gui -A x64 -DHAVE_RULES=Off -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On build: strategy: diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index 3b5036ff29e..bacf32c8eaf 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -55,7 +55,7 @@ jobs: 7z x pcre-%PCRE_VERSION%.zip || exit /b !errorlevel! cd pcre-%PCRE_VERSION% || exit /b !errorlevel! git apply --ignore-space-change ..\externals\pcre.patch || exit /b !errorlevel! - cmake . -G "Visual Studio 17 2022" -A x64 -DPCRE_BUILD_PCRECPP=OFF -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake . -A x64 -DPCRE_BUILD_PCRECPP=OFF -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! msbuild -m PCRE.sln -p:Configuration=Release -p:Platform=x64 || exit /b !errorlevel! copy pcre.h ..\externals || exit /b !errorlevel! copy Release\pcre.lib ..\externals\pcre64.lib || exit /b !errorlevel! From 747e25796f7d1a133c813850d44d63fe42204cda Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 6 May 2026 14:14:20 +0200 Subject: [PATCH 082/493] Fix #14716 FP oppositeInnerCondition, x.size() < y.size() does not mean that x must be empty (#8533) --- lib/astutils.cpp | 2 +- test/testcondition.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index c745d0cf9f2..94dc6fc5afa 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1816,7 +1816,7 @@ static bool isZeroBoundCond(const Token * const cond, bool reverse) const Token* op = reverse ? cond->astOperand1() : cond->astOperand2(); if (!op->hasKnownIntValue()) - return false; + return true; // Assume unsigned const bool isZero = op->getKnownIntValue() == 0; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 9737217add3..fae9c8fce13 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -2682,6 +2682,12 @@ class TestCondition : public TestFixture { check("void f1(const std::string &s) { if(s.empty()) if(42 < s.size()) {}}"); ASSERT_EQUALS("[test.cpp:1:43] -> [test.cpp:1:53]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); + check("void f(const std::string& s, int n) {\n" // #14716 + " if (s.size() < n)\n" + " if (s.empty()) {}\n" + "}"); + ASSERT_EQUALS("", errout_str()); + // TODO: These are identical condition since size cannot be negative check("void f1(const std::string &s) { if(s.size() <= 0) if(s.empty()) {}}"); ASSERT_EQUALS("", errout_str()); From 6c73feb07da029c947952b4b3971f2547882e697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 7 May 2026 00:23:19 +0200 Subject: [PATCH 083/493] added CLI option `--debug-ipc` to log `ProcessExecutor` IPC communication (#8530) --- cli/cmdlineparser.cpp | 3 +++ cli/processexecutor.cpp | 11 +++++++++-- lib/check.cpp | 1 + lib/settings.h | 3 +++ test/cli/other_test.py | 26 +++++++++++++++++++++++++- test/testcmdlineparser.cpp | 8 ++++++++ 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 2069c89579c..865580f049d 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -631,6 +631,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a else if (std::strcmp(argv[i], "--debug-ignore") == 0) mSettings.debugignore = true; + else if (std::strcmp(argv[i], "--debug-ipc") == 0) + mSettings.debugipc = true; + // Show --debug output after the first simplifications else if (std::strcmp(argv[i], "--debug") == 0 || std::strcmp(argv[i], "--debug-normal") == 0) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index cc6c7baf214..f7c04301ac5 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -80,7 +80,7 @@ namespace { public: enum PipeSignal : std::uint8_t {REPORT_OUT='1',REPORT_ERROR='2',REPORT_SUPPR_INLINE='3',REPORT_SUPPR='4',CHILD_END='5',REPORT_METRIC='6',REPORT_TIMER='7'}; - explicit PipeWriter(int pipe) : mWpipe(pipe) {} + explicit PipeWriter(int pipe, bool debug) : mWpipe(pipe), mDebug(debug) {} void reportOut(const std::string &outmsg, Color c) override { writeToPipe(REPORT_OUT, static_cast(c) + outmsg); @@ -153,6 +153,9 @@ namespace { void writeToPipe(PipeSignal type, const std::string &data) const { + if (mDebug) + std::cout << "writeToPipe - " << static_cast(type) << " - " << data << std::endl; + { const auto t = static_cast(type); writeToPipeInternal(type, &t, 1); @@ -169,6 +172,7 @@ namespace { } const int mWpipe; + const bool mDebug; }; } @@ -235,6 +239,9 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str } while (bytes_to_read != 0); } + if (mSettings.debugipc) + std::cout << "handleRead - " << type << " - " << buf << std::endl; + bool res = true; if (type == PipeWriter::REPORT_OUT) { // the first character is the color @@ -378,7 +385,7 @@ unsigned int ProcessExecutor::check() mTimerResults->reset(); // TODO: how to "reset" mSuppressions? - PipeWriter pipewriter(pipes[1]); + PipeWriter pipewriter(pipes[1], mSettings.debugipc); CppCheck fileChecker(mSettings, mSuppressions, pipewriter, mTimerResults, false, mExecuteCommand); unsigned int resultOfCheck = 0; diff --git a/lib/check.cpp b/lib/check.cpp index 58b8dbfe0e1..1d0cfe61792 100644 --- a/lib/check.cpp +++ b/lib/check.cpp @@ -130,6 +130,7 @@ ErrorPath Check::getErrorPath(const Token* errtok, const ValueFlow::Value* value void Check::logChecker(const char id[]) { + // TODO: only issue when we would actually use it later on reportError(nullptr, Severity::internal, "logChecker", id); } diff --git a/lib/settings.h b/lib/settings.h index b7b23675aae..8e0881562ed 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -202,6 +202,9 @@ class CPPCHECKLIB WARN_UNUSED Settings { /** @brief Is --debug-ignore given? */ bool debugignore{}; + /** @brief Is --debug-ipc given? */ + bool debugipc{}; + /** @brief Internal: Is --debug-lookup or --debug-lookup=all given? */ bool debuglookup{}; diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 4aaddc3572d..72f0a7a00bd 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4633,4 +4633,28 @@ def test_dui_include_absolute_missing(tmp_path): # #14675 assert stdout == '' assert stderr.splitlines() == [ f"{test_file}:0:0: error: Can not open include file '/share/include/missing.h' that is explicitly included. [missingIncludeExplicit]" - ] \ No newline at end of file + ] + + +@pytest.mark.xfail(strict=True) # TODO: should not report logChecker when not required +@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") +def test_ipc_log_checker(tmp_path): + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() {}') + + args = [ + '-q', + '--debug-ipc', + '-j2', + '--executor=process', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + assert stdout.splitlines() == [ + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0' + ] + assert stderr.splitlines() == [] \ No newline at end of file diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index e5d231d47ed..250faaf8d1f 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -498,6 +498,7 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(noSafety); TEST_CASE(noSafetyOverride); TEST_CASE(debugAnalyzerinfo); + TEST_CASE(debugIpc); TEST_CASE(ignorepaths1); TEST_CASE(ignorepaths2); @@ -3479,6 +3480,13 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS(true, settings->debugainfo); } + void debugIpc() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--debug-ipc", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); + ASSERT_EQUALS(true, settings->debugipc); + } + void ignorepaths1() { REDIRECT; const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"}; From 2807d6e069eed46ec92819a0eadd76bc85b6ef89 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 7 May 2026 08:22:38 +0200 Subject: [PATCH 084/493] Fix #14708 FP uninitialized variable reported for array decay to pointer in initializer list (#8531) --- lib/checkuninitvar.cpp | 2 -- test/testuninitvar.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 2e749c6b71e..9ff66c055ef 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1262,8 +1262,6 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, const Library& const Token *parent = valueExpr->astParent(); while (Token::simpleMatch(parent, ",")) parent = parent->astParent(); - if (Token::simpleMatch(parent, "{")) - return valueExpr; const int use = isFunctionParUsage(valueExpr, library, pointer, alloc, indirect); return (use>0) ? valueExpr : nullptr; } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index e22c4009f5d..1366b350223 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -7935,6 +7935,12 @@ class TestUninitVar : public TestFixture { " (*fp[0])();\n" "}"); ASSERT_EQUALS("", errout_str()); + + checkUninitVar("void f() {\n" // #14708 + " int a[1], b[1];\n" + " int* c[2]{ a, b };\n" + "}"); + ASSERT_EQUALS("", errout_str()); } void isVariableUsageDerefValueflow() From a5a7dd7776b7a53476c2acb1576217b76f0342d3 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 7 May 2026 08:23:50 +0200 Subject: [PATCH 085/493] Fix #7959 invalidPrintfArgType_uint false positive (#8534) --- lib/checkio.cpp | 5 +++-- test/testio.cpp | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 0e1d0395146..8b3c835caf3 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -1539,9 +1539,10 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings &settings, if (element && isStdVectorOrString()) { // isStdVectorOrString sets type token if true element = false; // not really an array element } else if (variableInfo->isEnumType()) { - if (variableInfo->type() && variableInfo->type()->classScope && variableInfo->type()->classScope->enumType) + const bool hasEnumType = variableInfo->type() && variableInfo->type()->classScope && variableInfo->type()->classScope->enumType; + if (hasEnumType && variableInfo->type()->classScope->enumType->isStandardType()) typeToken = variableInfo->type()->classScope->enumType; - else { + else if (!hasEnumType) { tempToken = new Token(tok1); tempToken->str("int"); typeToken = tempToken; diff --git a/test/testio.cpp b/test/testio.cpp index ec6a87a1e16..02180f12376 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -3371,6 +3371,20 @@ class TestIO : public TestFixture { "}"); ASSERT_EQUALS("", errout_str()); + check("enum E : uint8_t { E0 }; \n" // #7959 + "void f(E e) {\n" + " printf(\"%hhu\", e);\n" + "}"); + ASSERT_EQUALS("", errout_str()); + + check("enum E : uint8_t { E0 }; \n" + "void f(E e) {\n" + " printf(\"%lu\", e);\n" + "}"); + TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'uint8_t'.\n", + "", + errout_str()); + check("void f() {\n" " printf(\"%lu\", sizeof(char));\n" "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); From 0045a090ad4d90d5d8c2a966daf12788ea2d02e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 7 May 2026 22:35:33 +0200 Subject: [PATCH 086/493] Fixed #14735 (dumpfile: Value::intvalue with negative value for unsigned expression) (#8540) --- lib/token.cpp | 2 +- test/testsymboldatabase.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/token.cpp b/lib/token.cpp index b11e12bf0a7..d1e76ebdd67 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1816,7 +1816,7 @@ void Token::printValueFlow(const std::vector& files, bool xml, std: outs += " valueType() && tok->valueType()->sign == ValueType::UNSIGNED) { + if (tok->valueType() && tok->valueType()->sign == ValueType::UNSIGNED && value.toString() != "!<=-1") { outs += "intvalue=\""; outs += MathLib::toString(static_cast(value.intvalue)); outs += '\"'; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 6efda65c11b..e981c8ea546 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -632,6 +632,8 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(stdintFunction); TEST_CASE(userDefinedLiteral); + + TEST_CASE(dumpValueNegative); // #14735 - dumping negative impossible value for unsigned expression } void array() { @@ -11444,6 +11446,18 @@ class TestSymbolDatabase : public TestFixture { ASSERT(!x->varId()); ASSERT(!x->variable()); } + + void dumpValueNegative() { // #14735 + GET_SYMBOL_DB("void f(unsigned int x) { a = x; }"); + const Token* x = Token::findsimplematch(tokenizer.tokens(), "x ;"); + ASSERT(x != nullptr); + std::ostringstream out; + x->printValueFlow({"test.cpp"}, true, out); + const std::string dump = out.str(); + const std::string expected = ""; + // dump should contain expected string, otherwise print the dump string + ASSERT_EQUALS(expected, dump.find(expected) == std::string::npos ? dump : expected); + } }; REGISTER_TEST(TestSymbolDatabase) From b1a98cf87b09c843c61e2c468203597d623888b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 8 May 2026 01:40:47 +0200 Subject: [PATCH 087/493] fixed #14732 - fixed potential crash with incomplete preprocessor directive (#8539) --- lib/preprocessor.cpp | 4 +++ ...h-41fefbc326c326d02c9e1fe315280ddd326e8a5b | 1 + test/testpreprocessor.cpp | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 test/cli/fuzz-crash/crash-41fefbc326c326d02c9e1fe315280ddd326e8a5b diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 273d8df6123..3b69c31085d 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -469,6 +469,8 @@ static std::string readcondition(const simplecpp::Token *iftok, const std::setstr() == "==" || cond->str() == "<=" || cond->str() == ">=") { + if (!cond->next) + break; if (cond->next->number) { const simplecpp::Token *dtok = cond->previous; if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end()) @@ -477,6 +479,8 @@ static std::string readcondition(const simplecpp::Token *iftok, const std::setop == '<' || cond->op == '>') { + if (!cond->next) + break; if (cond->next->number) { const simplecpp::Token *dtok = cond->previous; if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end()) { diff --git a/test/cli/fuzz-crash/crash-41fefbc326c326d02c9e1fe315280ddd326e8a5b b/test/cli/fuzz-crash/crash-41fefbc326c326d02c9e1fe315280ddd326e8a5b new file mode 100644 index 00000000000..b090d2bf345 --- /dev/null +++ b/test/cli/fuzz-crash/crash-41fefbc326c326d02c9e1fe315280ddd326e8a5b @@ -0,0 +1 @@ +#if< \ No newline at end of file diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index d072ebbf2e3..6846d49ff30 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -343,6 +343,8 @@ class TestPreprocessor : public TestFixture { TEST_CASE(getConfigsAndCodeIssue14317); TEST_CASE(getConfigsMostGeneralConfigIssue14317); + TEST_CASE(getConfigsInvalid); // #14732 + TEST_CASE(if_sizeof); TEST_CASE(invalid_ifs); // #5909 @@ -2715,6 +2717,33 @@ class TestPreprocessor : public TestFixture { ASSERT_EQUALS("\nX\nY=Y\nZ\n", getConfigsStr(filedata)); } + void getConfigsInvalid() { // #14732 + { + const char filedata[] = "#if<"; + ASSERT_EQUALS("\n", getConfigsStr(filedata)); + } + { + const char filedata[] = "#if>"; + ASSERT_EQUALS("\n", getConfigsStr(filedata)); + } + { + const char filedata[] = "#if=="; + ASSERT_EQUALS("\n", getConfigsStr(filedata)); + } + { + const char filedata[] = "#if<="; + ASSERT_EQUALS("\n", getConfigsStr(filedata)); + } + { + const char filedata[] = "#if>="; + ASSERT_EQUALS("\n", getConfigsStr(filedata)); + } + { + const char filedata[] = "#if!"; + ASSERT_EQUALS("\n", getConfigsStr(filedata)); + } + } + void if_sizeof() { // #4071 const char code[] = "#if sizeof(unsigned short) == 2\n" "Fred & Wilma\n" From 504d1d2a1c3964f575815150e4c0d3df7cd03106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 8 May 2026 01:41:59 +0200 Subject: [PATCH 088/493] only issue `logChecker` messages when necessary (#8535) --- cli/cppcheckexecutor.cpp | 8 ++++---- cli/processexecutor.cpp | 2 +- lib/check.cpp | 4 ++-- lib/settings.cpp | 15 +++++++++++++++ lib/settings.h | 2 ++ test/cli/other_test.py | 4 ++-- 6 files changed, 26 insertions(+), 9 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 5fb4d89855d..72a20315272 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -501,6 +501,7 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup void StdLogger::writeCheckersReport(const Suppressions& supprs) { + // TODO: only necessary when we actually issue a checkers report? if (!mCheckersFile.empty()) { std::ofstream fout(mCheckersFile); @@ -510,15 +511,14 @@ void StdLogger::writeCheckersReport(const Suppressions& supprs) } } - const bool summary = mSettings.safety || mSettings.severity.isEnabled(Severity::information); - const bool xmlReport = mSettings.outputFormat == Settings::OutputFormat::xml && mSettings.xml_version == 3; - const bool textReport = !mSettings.checkersReportFilename.empty(); + bool summary, xmlReport, textReport; - if (!summary && !xmlReport && !textReport) + if (!mSettings.collectLogCheckers(&summary, &xmlReport, &textReport)) return; CheckersReport checkersReport(mSettings, mActiveCheckers); + // TODO: include in summary boolean const auto& suppressions = supprs.nomsg.getSuppressions(); const bool summarySuppressed = std::any_of(suppressions.cbegin(), suppressions.cend(), [](const SuppressionList::Suppression& s) { return s.errorId == "checkersReport"; diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index f7c04301ac5..e430f6ccbf2 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -154,7 +154,7 @@ namespace { void writeToPipe(PipeSignal type, const std::string &data) const { if (mDebug) - std::cout << "writeToPipe - " << static_cast(type) << " - " << data << std::endl; + std::cout << "writeToPipe - " << static_cast(type) << " - " << data << std::endl; { const auto t = static_cast(type); diff --git a/lib/check.cpp b/lib/check.cpp index 1d0cfe61792..812c8b02fcd 100644 --- a/lib/check.cpp +++ b/lib/check.cpp @@ -130,7 +130,7 @@ ErrorPath Check::getErrorPath(const Token* errtok, const ValueFlow::Value* value void Check::logChecker(const char id[]) { - // TODO: only issue when we would actually use it later on - reportError(nullptr, Severity::internal, "logChecker", id); + if (!mSettings->buildDir.empty() || mSettings->collectLogCheckers()) + reportError(nullptr, Severity::internal, "logChecker", id); } diff --git a/lib/settings.cpp b/lib/settings.cpp index bdbbb1040ba..080946e07bc 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -770,3 +770,18 @@ bool Settings::unusedFunctionOnly() const char* unusedFunctionOnly = std::getenv("UNUSEDFUNCTION_ONLY"); return unusedFunctionOnly && (std::strcmp(unusedFunctionOnly, "1") == 0); } + +bool Settings::collectLogCheckers(bool* summary, bool* xmlReport, bool* textReport) const +{ + const bool s = safety || severity.isEnabled(Severity::information); + if (summary) + *summary = s; + const bool x = outputFormat == Settings::OutputFormat::xml && xml_version == 3; + if (xmlReport) + *xmlReport = x; + const bool t = !checkersReportFilename.empty(); + if (textReport) + *textReport = t; + + return s || x || t; +} diff --git a/lib/settings.h b/lib/settings.h index 8e0881562ed..6c12c509701 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -596,6 +596,8 @@ class CPPCHECKLIB WARN_UNUSED Settings { static bool unusedFunctionOnly(); + bool collectLogCheckers(bool* summary = nullptr, bool* xmlReport = nullptr, bool* textReport = nullptr) const; + private: static std::string parseEnabled(const std::string &str, std::tuple, SimpleEnableGroup> &groups); std::string applyEnabled(const std::string &str, bool enable); diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 72f0a7a00bd..baee758be5c 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4636,9 +4636,8 @@ def test_dui_include_absolute_missing(tmp_path): # #14675 ] -@pytest.mark.xfail(strict=True) # TODO: should not report logChecker when not required @pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") -def test_ipc_log_checker(tmp_path): +def test_ipc(tmp_path): test_file = tmp_path / 'test.c' with open(test_file, "w") as f: f.write('void f() {}') @@ -4648,6 +4647,7 @@ def test_ipc_log_checker(tmp_path): '--debug-ipc', '-j2', '--executor=process', + '--no-cppcheck-build-dir', str(test_file) ] From 17947fd455a721a7ad94d0aeb2f24a139aa4af64 Mon Sep 17 00:00:00 2001 From: Wija <50847546+wjakobsson@users.noreply.github.com> Date: Fri, 8 May 2026 12:42:17 +0200 Subject: [PATCH 089/493] Fix #14739 Improve bad CERT INT parameter handling (#8542) --- cli/cmdlineparser.cpp | 5 +++++ test/testcmdlineparser.cpp | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 865580f049d..43361c6e5bc 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -1151,6 +1151,11 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a mLogger.printError("invalid --premium option '" + (p2.empty() ? p : p2) + "'."); return Result::Fail; } + if (p2 == "cert-c-int-precision") { + int tmp; + if (!parseNumberArg(argv[i], 31, tmp, true)) + return Result::Fail; + } mSettings.premiumArgs += "--" + p; if (isCodingStandard) { // All checkers related to the coding standard should be enabled. The coding standards diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 250faaf8d1f..135b7c782be 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -1621,6 +1621,14 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS("--cert-c-int-precision=12", settings->premiumArgs); } + void premiumOptionsCertCIntPrecisionInvalid() { + REDIRECT; + asPremium(); + const char * const argv[] = {"cppcheck", "--premium-cert-c-int-precision=abc", "file.c"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); + ASSERT_EQUALS("cppcheck: error: argument to '--premium-cert-c-int-precision=' is not valid - not an integer (invalid_argument).\n", logger->str()); + } + void premiumOptionsLicenseFile() { REDIRECT; asPremium(); From eccb7271942f630b65d24d0402bf7d74bea39e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 8 May 2026 15:26:59 +0200 Subject: [PATCH 090/493] Fix #14737 (GUI: Remove handling of Cppcheck Premium LOC license) (#8543) --- gui/mainwindow.cpp | 24 ------------------------ gui/projectfile.cpp | 9 --------- gui/projectfile.h | 11 ----------- gui/projectfile.ui | 19 ------------------- gui/projectfiledialog.cpp | 4 ---- lib/importproject.h | 1 - 6 files changed, 68 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index ff2b63d3a75..a08d1eb738e 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -1863,30 +1863,6 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis QFileInfo inf(projectFile->getFilename()); const QString& rootpath = projectFile->getRootPath(); - if (isCppcheckPremium() && !projectFile->getLicenseFile().isEmpty()) { - if (rootpath.isEmpty() || rootpath == ".") - QDir::setCurrent(inf.absolutePath()); - else if (QDir(rootpath).isAbsolute()) - QDir::setCurrent(rootpath); - else - QDir::setCurrent(inf.absolutePath() + "/" + rootpath); - - QString licenseFile = projectFile->getLicenseFile(); - if (!QFileInfo(licenseFile).isAbsolute() && !rootpath.isEmpty()) - licenseFile = inf.absolutePath() + "/" + licenseFile; - -#ifdef Q_OS_WIN - const QString premiumaddon = QCoreApplication::applicationDirPath() + "/premiumaddon.exe"; -#else - const QString premiumaddon = QCoreApplication::applicationDirPath() + "/premiumaddon"; -#endif - const std::vector args{"--check-loc-license", licenseFile.toStdString()}; - std::string output; - CheckThread::executeCommand(premiumaddon.toStdString(), args, "", output); - std::ofstream fout(inf.absolutePath().toStdString() + "/cppcheck-premium-loc"); - fout << output; - } - QDir::setCurrent(inf.absolutePath()); mThread->setAddonsAndTools(projectFile->getAddonsAndTools()); diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index a77c1a0fc94..9144f5a6117 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -88,7 +88,6 @@ void ProjectFile::clear() mBughunting = false; mCertIntPrecision = 0; mCodingStandards.clear(); - mPremiumLicenseFile.clear(); } bool ProjectFile::read(const QString &filename) @@ -233,8 +232,6 @@ bool ProjectFile::read(const QString &filename) readStringList(mCodingStandards, xmlReader, CppcheckXml::CodingStandardElementName); if (xmlReader.name() == QString(CppcheckXml::CertIntPrecisionElementName)) mCertIntPrecision = readInt(xmlReader, 0); - if (xmlReader.name() == QString(CppcheckXml::LicenseFileElementName)) - mPremiumLicenseFile = readString(xmlReader); if (xmlReader.name() == QString(CppcheckXml::ProjectNameElementName)) mProjectName = readString(xmlReader); @@ -1053,12 +1050,6 @@ bool ProjectFile::write(const QString &filename) xmlWriter.writeEndElement(); } - if (!mPremiumLicenseFile.isEmpty()) { - xmlWriter.writeStartElement(CppcheckXml::LicenseFileElementName); - xmlWriter.writeCharacters(mPremiumLicenseFile); - xmlWriter.writeEndElement(); - } - xmlWriter.writeEndDocument(); file.close(); return true; diff --git a/gui/projectfile.h b/gui/projectfile.h index 0dd68b58453..5a5e0ccb89b 100644 --- a/gui/projectfile.h +++ b/gui/projectfile.h @@ -404,14 +404,6 @@ class ProjectFile : public QObject { return mCertIntPrecision; } - /** Cppcheck Premium: License file */ - void setLicenseFile(const QString& licenseFile) { - mPremiumLicenseFile = licenseFile; - } - const QString& getLicenseFile() const { - return mPremiumLicenseFile; - } - /** * @brief Write project file (to disk). * @param filename Filename to use. @@ -653,9 +645,6 @@ class ProjectFile : public QObject { */ QStringList mCodingStandards; - /** @brief Cppcheck Premium: license file */ - QString mPremiumLicenseFile; - /** @brief Project name, used when generating compliance report */ QString mProjectName; diff --git a/gui/projectfile.ui b/gui/projectfile.ui index 5543e67910c..84a1d6e40ec 100644 --- a/gui/projectfile.ui +++ b/gui/projectfile.ui @@ -629,25 +629,6 @@ - - - - Premium License - - - - - - - - - Browse... - - - - - - diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index 82fc0aac7c4..4e75696484b 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -139,8 +139,6 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, bool premium, QWi setWindowTitle(title); loadSettings(); - mUI->premiumLicense->setVisible(false); - QStringList libs; // Search the std.cfg first since other libraries could depend on it QString stdLibraryFilename; @@ -464,7 +462,6 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile) mUI->mToolClangTidy->setEnabled(false); } mUI->mEditTags->setText(projectFile->getTags().join(';')); - mUI->mEditLicenseFile->setText(projectFile->getLicenseFile()); updatePathsAndDefines(); } @@ -552,7 +549,6 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const projectFile->setBughunting(mUI->mBughunting->isChecked()); projectFile->setClangAnalyzer(mUI->mToolClangAnalyzer->isChecked()); projectFile->setClangTidy(mUI->mToolClangTidy->isChecked()); - projectFile->setLicenseFile(mUI->mEditLicenseFile->text()); projectFile->setTags(mUI->mEditTags->text().split(";", Qt::SkipEmptyParts)); } diff --git a/lib/importproject.h b/lib/importproject.h index fb724b5b454..608af552408 100644 --- a/lib/importproject.h +++ b/lib/importproject.h @@ -198,7 +198,6 @@ namespace CppcheckXml { static constexpr char CodingStandardsElementName[] = "coding-standards"; static constexpr char CodingStandardElementName[] = "coding-standard"; static constexpr char CertIntPrecisionElementName[] = "cert-c-int-precision"; - static constexpr char LicenseFileElementName[] = "license-file"; static constexpr char ProjectNameElementName[] = "project-name"; } From 00d23ca0f3ace1ad1b1af05634014e920edc3551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sat, 9 May 2026 10:08:27 +0200 Subject: [PATCH 091/493] ProcessExecutor: do not modify mutable objects from parent in forked process (#8541) --- cli/processexecutor.cpp | 18 +++++--- test/cli/other_test.py | 92 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 6 deletions(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index e430f6ccbf2..a410f58d5ea 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -342,6 +342,12 @@ unsigned int ProcessExecutor::check() return v + p.size(); }); + // pass unmodified suppressions to forked process so we only transfer back the actual changes done by the fork + // and do not see the changes which have already been transferred back + Suppressions supprs; + supprs.nomsg.addSuppressions(mSuppressions.nomsg.getSuppressions()); + supprs.nofail.addSuppressions(mSuppressions.nofail.getSuppressions()); + std::list rpipes; std::map childFile; std::map pipeFile; @@ -380,13 +386,13 @@ unsigned int ProcessExecutor::check() #endif close(pipes[0]); - // reset so we do not have the data which has already been transferred back + // create a separate result object so we do not get the results which have already been transferred back + std::unique_ptr timerResults; if (mTimerResults) - mTimerResults->reset(); - // TODO: how to "reset" mSuppressions? + timerResults.reset(new TimerResults); PipeWriter pipewriter(pipes[1], mSettings.debugipc); - CppCheck fileChecker(mSettings, mSuppressions, pipewriter, mTimerResults, false, mExecuteCommand); + CppCheck fileChecker(mSettings, supprs, pipewriter, timerResults.get(), false, mExecuteCommand); unsigned int resultOfCheck = 0; if (iFileSettings != mFileSettings.end()) { @@ -396,9 +402,9 @@ unsigned int ProcessExecutor::check() resultOfCheck = fileChecker.check(*iFile); } - pipewriter.writeSuppr(mSuppressions.nomsg); + pipewriter.writeSuppr(supprs.nomsg); - pipewriter.writeTimer(mTimerResults); + pipewriter.writeTimer(timerResults.get()); pipewriter.writeEnd(std::to_string(resultOfCheck)); std::exit(EXIT_SUCCESS); diff --git a/test/cli/other_test.py b/test/cli/other_test.py index baee758be5c..243f600b5a6 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4657,4 +4657,96 @@ def test_ipc(tmp_path): 'writeToPipe - 5 - 0', 'handleRead - 5 - 0' ] + assert stderr.splitlines() == [] + + +@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") +def test_ipc_suppressions(tmp_path): + test1_file = tmp_path / 'test1.c' + with open(test1_file, "w") as f: + f.write('void f() {}') + + test2_file = tmp_path / 'test2.c' + with open(test2_file, "w") as f: + f.write('void f() {}') + + test3_file = tmp_path / 'test3.c' + with open(test3_file, "w") as f: + f.write('void f() {}') + + args = [ + '-q', + '--debug-ipc', + '-j2', + '--executor=process', + '--no-cppcheck-build-dir', + '--suppress=id0:test1.c', + str(tmp_path) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + # sort the lines since the order is not fixed + stdout_exp = [ + 'writeToPipe - 4 - id0:test1.c;0;1;0;', + 'handleRead - 4 - id0:test1.c;0;1;0;', + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0', + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0', + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0' + ] + stdout_exp.sort() + stdout_lines = stdout.splitlines() + stdout_lines.sort() + assert stdout_lines == stdout_exp + assert stderr.splitlines() == [] + + +@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") +def test_ipc_inline_suppressions(tmp_path): + test1_file = tmp_path / 'test1.c' + with open(test1_file, "w") as f: + f.write('void f() {} // cppcheck-suppress id1') + + test2_file = tmp_path / 'test2.c' + with open(test2_file, "w") as f: + f.write('void f() {} // cppcheck-suppress id2') + + test3_file = tmp_path / 'test3.c' + with open(test3_file, "w") as f: + f.write('void f() {} // cppcheck-suppress id3') + + args = [ + '-q', + '--debug-ipc', + '-j2', + '--executor=process', + '--no-cppcheck-build-dir', + '--inline-suppr', + str(tmp_path) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + # sort the lines since the order is not fixed + stdout_exp = [ + f'writeToPipe - 3 - id1:{test1_file}:1;13;1;0;', + f'handleRead - 3 - id1:{test1_file}:1;13;1;0;', + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0', + f'writeToPipe - 3 - id2:{test2_file}:1;13;1;0;', + f'handleRead - 3 - id2:{test2_file}:1;13;1;0;', + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0', + f'writeToPipe - 3 - id3:{test3_file}:1;13;1;0;', + f'handleRead - 3 - id3:{test3_file}:1;13;1;0;', + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0' + ] + stdout_exp.sort() + stdout_lines = stdout.splitlines() + stdout_lines.sort() + assert stdout_lines == stdout_exp assert stderr.splitlines() == [] \ No newline at end of file From 95a7f7c22d66d464475be45ab1de88e9e919bf0b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 9 May 2026 11:02:00 +0200 Subject: [PATCH 092/493] Fix #14734 FP invalidFunctionArg with ternary expression (#8538) Co-authored-by: chrchr-github --- lib/programmemory.cpp | 25 +++++++++++-------------- test/cfg/std.cpp | 14 ++++++++------ test/testvalueflow.cpp | 9 +++++++++ 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index eb0b290ac6c..3dca55e5117 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -632,10 +632,6 @@ static MathLib::bigint asInt(const ValueFlow::Value& value) return value.isFloatValue() ? static_cast(value.floatValue) : value.intvalue; } -static std::string removeAssign(const std::string& assign) { - return std::string{assign.cbegin(), assign.cend() - 1}; -} - namespace { struct assign { template @@ -651,22 +647,23 @@ static bool isIntegralValue(const ValueFlow::Value& value) return value.isIntValue() || value.isIteratorValue() || value.isSymbolicValue(); } -static ValueFlow::Value evaluate(const std::string& op, const ValueFlow::Value& lhs, const ValueFlow::Value& rhs) +static ValueFlow::Value evaluate(const Token* op, const ValueFlow::Value& lhs, const ValueFlow::Value& rhs, bool removeAssign = false) { + const std::string opStr = removeAssign ? op->str().substr(0, op->str().size() - 1) : op->str(); ValueFlow::Value result; if (lhs.isImpossible() && rhs.isImpossible()) return ValueFlow::Value::unknown(); if (lhs.isImpossible() || rhs.isImpossible()) { // noninvertible - if (contains({"%", "/", "&", "|"}, op)) + if (contains({"%", "/", "&", "|"}, opStr)) return ValueFlow::Value::unknown(); result.setImpossible(); } if (isNumericValue(lhs) && isNumericValue(rhs)) { if (lhs.isFloatValue() || rhs.isFloatValue()) { - result.valueType = ValueFlow::Value::ValueType::FLOAT; + result.valueType = op->isArithmeticalOp() ? ValueFlow::Value::ValueType::FLOAT : ValueFlow::Value::ValueType::INT; bool error = false; - result.floatValue = calculate(op, asFloat(lhs), asFloat(rhs), &error); + result.floatValue = calculate(opStr, asFloat(lhs), asFloat(rhs), &error); if (error) return ValueFlow::Value::unknown(); return result; @@ -678,12 +675,12 @@ static ValueFlow::Value evaluate(const std::string& op, const ValueFlow::Value& // If not the same type then one must be int if (lhs.valueType != rhs.valueType && !lhs.isIntValue() && !rhs.isIntValue()) return ValueFlow::Value::unknown(); - const bool compareOp = contains({"==", "!=", "<", ">", ">=", "<="}, op); + const bool compareOp = op->isComparisonOp(); // Comparison must be the same type if (compareOp && lhs.valueType != rhs.valueType) return ValueFlow::Value::unknown(); // Only add, subtract, and compare for non-integers - if (!compareOp && !contains({"+", "-"}, op) && !lhs.isIntValue() && !rhs.isIntValue()) + if (!compareOp && !contains({"+", "-"}, opStr) && !lhs.isIntValue() && !rhs.isIntValue()) return ValueFlow::Value::unknown(); // Both can't be iterators for non-compare if (!compareOp && lhs.isIteratorValue() && rhs.isIteratorValue()) @@ -701,10 +698,10 @@ static ValueFlow::Value evaluate(const std::string& op, const ValueFlow::Value& result.valueType = ValueFlow::Value::ValueType::INT; } bool error = false; - result.intvalue = calculate(op, lhs.intvalue, rhs.intvalue, &error); + result.intvalue = calculate(opStr, lhs.intvalue, rhs.intvalue, &error); if (error) return ValueFlow::Value::unknown(); - if (result.isImpossible() && op == "!=") { + if (result.isImpossible() && opStr == "!=") { if (isTrue(result)) { result.intvalue = 1; } else if (isFalse(result)) { @@ -1501,7 +1498,7 @@ namespace { if (!pm->hasValue(expr->astOperand1()->exprId())) return unknown(); ValueFlow::Value& lhs = pm->at(expr->astOperand1()->exprId()); - rhs = evaluate(removeAssign(expr->str()), lhs, rhs); + rhs = evaluate(expr, lhs, rhs, /*removeAssign*/ true); if (lhs.isIntValue()) ValueFlow::Value::visitValue(rhs, std::bind(assign{}, std::ref(lhs.intvalue), std::placeholders::_1)); else if (lhs.isFloatValue()) @@ -1565,7 +1562,7 @@ namespace { ValueFlow::Value rhs = execute(expr->astOperand2()); if (rhs.isUninitValue()) return unknown(); - ValueFlow::Value r = evaluate(expr->str(), lhs, rhs); + ValueFlow::Value r = evaluate(expr, lhs, rhs); if (expr->isComparisonOp() && (r.isUninitValue() || r.isImpossible())) { if (rhs.isIntValue() && !expr->astOperand1()->values().empty()) { std::vector result = infer(makeIntegralInferModel(), diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index abe952de075..0344b98455c 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -1058,7 +1058,7 @@ void returnValue_std_isgreater(void) { // cppcheck-suppress knownConditionTrueFalse if (std::isgreater(4,2) == 0) {} - // @todo support floats + // cppcheck-suppress knownConditionTrueFalse if (std::isgreater(4.0f,2.0f) == 0) {} } @@ -1066,7 +1066,7 @@ void returnValue_std_isgreaterequal(void) { // cppcheck-suppress knownConditionTrueFalse if (std::isgreaterequal(4,2) == 0) {} - // @todo support floats + // cppcheck-suppress knownConditionTrueFalse if (std::isgreaterequal(4.0f,2.0f) == 0) {} } @@ -1074,7 +1074,7 @@ void returnValue_std_isless(void) { // cppcheck-suppress knownConditionTrueFalse if (std::isless(4,2) == 0) {} - // @todo support floats + // cppcheck-suppress knownConditionTrueFalse if (std::isless(4.0f,2.0f) == 0) {} } @@ -1082,7 +1082,7 @@ void returnValue_std_islessequal(void) { // cppcheck-suppress knownConditionTrueFalse if (std::islessequal(4,2) == 0) {} - // @todo support floats + // cppcheck-suppress knownConditionTrueFalse if (std::islessequal(4.0f,2.0f) == 0) {} } @@ -1093,8 +1093,10 @@ void returnValue_std_islessgreater(void) // cppcheck-suppress knownConditionTrueFalse if (std::islessgreater(2,4) == 0) {} - if (std::islessgreater(4.0f,2.0f) == 0) {} // @todo support floats - if (std::islessgreater(2.0f,4.0f) == 0) {} // @todo support floats + // cppcheck-suppress knownConditionTrueFalse + if (std::islessgreater(4.0f,2.0f) == 0) {} + // cppcheck-suppress knownConditionTrueFalse + if (std::islessgreater(2.0f,4.0f) == 0) {} } void bufferAccessOutOfBounds(void) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 51bb78aa40a..dc5345ab3e3 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -4119,6 +4119,15 @@ class TestValueFlow : public TestFixture { "}\n"; ASSERT_EQUALS(true, testValueOfX(code, 4U, 0)); ASSERT_EQUALS(false, testValueOfXImpossible(code, 4U, 0)); + + code = "double f(double d, bool b) {\n" // #14734 + " double s = 0.0;\n" + " if (b)\n" + " s += d;\n" + " return s > 0.0 ? s : 0.0;\n" + "}\n"; + auto values = tokenValues(code, "s :", ValueFlow::Value::ValueType::FLOAT); + ASSERT_EQUALS(0, values.size()); } void valueFlowForwardLambda() { From 761e9c893fb17c570a80e9704b35547640f1c78f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 9 May 2026 11:04:11 +0200 Subject: [PATCH 093/493] Fix #14733 FP functionStatic for brace initialization + typedef (#8537) --- lib/tokenize.cpp | 2 +- test/testvarid.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1acf1b1f6c4..70a38a30eb9 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4970,7 +4970,7 @@ void Tokenizer::setVarIdPass1() decl = false; } else if (cpp && Token::Match(prev2, "%type% {") && Token::simpleMatch(tok2->link(), "} ;")) { // C++11 initialization style if (tok2->link() != tok2->next() && // add value-initialized variable T x{}; - (Token::Match(prev2, "do|try|else") || Token::Match(prev2->tokAt(-2), "struct|class|:"))) + (Token::Match(prev2, "do|try|else") || Token::simpleMatch(prev2->tokAt(-2), ":"))) continue; } else decl = false; diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 64b7b6664be..73eaa3f97eb 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -3066,6 +3066,11 @@ class TestVarID : public TestFixture { " int j{i};\n" " }\n" "};")); + + ASSERT_EQUALS("1: struct Sx { int i@1 ; } ;\n" // #14733 + "2: struct Sx sx@2 { 0 } ;\n", + tokenize("struct Sx { int i; };\n" + "struct Sx sx{ 0 }; \n")); } void varid_inheritedMembers() { From 2d6f23e4c5539e69ce63f2d16c9ac9d0e94acdf0 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 9 May 2026 13:05:01 +0200 Subject: [PATCH 094/493] Fix #14728 FP ctunullpointer with std::optional (#8536) --- lib/checknullpointer.cpp | 2 ++ test/testnullpointer.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 02c5cd8c812..beb9d5d77a3 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -187,6 +187,8 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Set // declaration of function pointer if (tok->variable() && tok->variable()->nameToken() == tok) return false; + if ((tok->valueType() && tok->valueType()->pointer == 0) && !astIsIterator(tok) && !astIsSmartPointer(tok)) + return false; if (!addressOf) return true; } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 04d2f61fc0c..c025d7462d4 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -4830,6 +4830,15 @@ class TestNullPointer : public TestFixture { "[test.cpp:5:20]: note: Assignment 'f=fopen(notexist,t)', assigned value is 0\n" "[test.cpp:6:8]: note: Calling function foo, 1st argument is null\n" "[test.cpp:2:13]: note: Dereferencing argument f that is null\n", errout_str()); + + ctu("void g(std::optional& o) {\n" // #14728 + " *o = 1;\n" + "}\n" + "void f() {\n" + " std::optional x = 0;\n" + " g(x);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } }; From ff799b5365cfd151c07cdcec703f12bb8cb7ef7e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 May 2026 12:28:46 +0200 Subject: [PATCH 095/493] Fix #14740 Hang: createAst, daca package lomiri-location-service (#8551) --- lib/tokenlist.cpp | 2 ++ test/testgarbage.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 5f48baea018..74c0bae258f 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -740,6 +740,8 @@ static void compileBinOp(Token *&tok, AST_state& state, void (*f)(Token *&tok, A binop->astOperand1(state.op.top()); state.op.pop(); } + if (!state.op.empty() && state.op.top() == binop) + throw InternalError(tok, "Syntax Error: Infinite loop when creating AST.", InternalError::AST); state.op.push(binop); } diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 68715b78ae8..44f163a53c1 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -1343,6 +1343,8 @@ class TestGarbage : public TestFixture { "{ return return { | { - name3 1 enum != >= 1 >= ++ { name6 | ; ++}}}}}}}"), UNKNOWN_MACRO); ASSERT_THROW_INTERNAL(checkCode("else return % name5 name2 - =name1 return enum | { - name3 1 enum != >= 1 >= ++ { { || " "{ return return { | { - name3 1 enum != >= 1 >= ++ { { || ; ++}}}}}}}}"), UNKNOWN_MACRO); + + ASSERT_THROW_INTERNAL(checkCode("f(*p, requires(x));"), AST); // #14740 } void templateSimplifierCrashes() { From 18f180855a26d33a841e97a2175903649b4ef9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= Date: Tue, 12 May 2026 14:02:53 +0000 Subject: [PATCH 096/493] gtk.cfg: g_application_get_default is transfer none (#8545) See https://docs.gtk.org/gio/type_func.Application.get_default.html --- cfg/gtk.cfg | 7 ++++++- test/cfg/gtk.c | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index 9b89a069903..c4ab8972155 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -807,7 +807,6 @@ g_app_info_get_default_for_uri_scheme g_application_new g_application_get_dbus_connection - g_application_get_default g_buffered_input_stream_new g_buffered_output_stream_new g_cancellable_new @@ -926,6 +925,12 @@ g_file_attribute_matcher_ref g_file_attribute_matcher_unref + + + false + + + true diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c index 3e4e5b1cb06..bcee84c8264 100644 --- a/test/cfg/gtk.c +++ b/test/cfg/gtk.c @@ -82,6 +82,10 @@ void validCode(int argInt, GHashTableIter * hash_table_iter, GHashTable * hash_t // cppcheck-suppress valueFlowBailout // TODO: caused by ? printf("%s", str); g_free(str); + + // transfer none functions: return value should not be unreffed + const GApplication *app = g_application_get_default(); + printf("%p\n", app); } void g_malloc_test() From 7c7ed58951839b24119bad7a6c6aba5c5eb28d43 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 May 2026 21:02:20 +0200 Subject: [PATCH 097/493] Fix #12320 FP knownConditionTrueFalse with if chain (#8547) --- lib/programmemory.h | 2 +- test/testcondition.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/programmemory.h b/lib/programmemory.h index bb68a9404d4..95effc70874 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -102,7 +102,7 @@ struct ExprIdToken { }; struct CPPCHECKLIB ProgramMemory { - using Map = std::unordered_map; + using Map = std::map; ProgramMemory() : mValues(new Map()) {} diff --git a/test/testcondition.cpp b/test/testcondition.cpp index fae9c8fce13..f0764dd2bd6 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -5174,6 +5174,15 @@ class TestCondition : public TestFixture { TODO_ASSERT_EQUALS("", "[test.cpp:11:14]: (style) Condition 'p->i==o' is always true [knownConditionTrueFalse]\n", errout_str()); + + check("void f(int x) {\n" // #12320 + " int a = 0, b = 0, c = 0;\n" + " a = x;\n" + " if (a) b = x;\n" + " if (b) c = x;\n" + " if (c) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void alwaysTrueInfer() { From eed1daf5eb82d8f5482ad55f644d12c5d066113a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 May 2026 21:12:46 +0200 Subject: [PATCH 098/493] Fix #9761 FP constParameter on parameter assigned to boost::optional (#8548) Co-authored-by: chrchr-github --- lib/astutils.cpp | 2 ++ lib/checkother.cpp | 10 +++++++--- test/testother.cpp | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 94dc6fc5afa..56a9489d00e 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3114,6 +3114,8 @@ static const Token* findExpressionChangedImpl(const Token* expr, if (vt->type == ValueType::ITERATOR) ++indirect; } + if (indirect == 0 && tok2->astParent() && tok2->astParent()->isUnaryOp("*")) + ++indirect; for (int i = 0; i <= indirect; ++i) { if (isExpressionChangedAt(tok, tok2, i, global, settings, depth)) return true; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index fd23e113509..7a1e1fea774 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1769,9 +1769,13 @@ void CheckOther::checkConstVariable() //Is it the right side of an initialization of a non-const reference bool usedInAssignment = false; for (const Token* tok = var->nameToken(); tok != scope->bodyEnd && tok != nullptr; tok = tok->next()) { - if (Token::Match(tok, "& %var% = %varid%", var->declarationId())) { - const Variable* refvar = tok->next()->variable(); - if (refvar && !refvar->isConst() && refvar->nameToken() == tok->next()) { + if (Token::Match(tok, "%name% = %varid%", var->declarationId())) { + const Variable* refvar = tok->variable(); + if (tok->strAt(-1) == "&" && refvar && !refvar->isConst() && refvar->nameToken() == tok) { + usedInAssignment = true; + break; + } + if (!tok->valueType() || tok->valueType()->type == ValueType::Type::RECORD) { usedInAssignment = true; break; } diff --git a/test/testother.cpp b/test/testother.cpp index c23e8c64155..a768abb647e 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4120,6 +4120,27 @@ class TestOther : public TestFixture { " std::string _s;\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + check("void f(int& r) {\n" // #9761 + " o1 = r;\n" + "}\n" + "boost::optional o2;\n" + "void g(int& r) {\n" + " o2 = r;\n" + "}\n" + "struct T {\n" + " int* p;\n" + " T& operator=(int& rhs) { p = &rhs; return *this; }\n" + "};\n" + "void h(T& t, int& r) {\n" + " t = r;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("void f(std::optional& o) {\n" + " *o = 1;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void constParameterCallback() { From ae2816b13bac96925a78cb6e6e130aa67f90ec35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 14 May 2026 15:38:20 +0200 Subject: [PATCH 099/493] Fix #14471: Improve check: shadowVariable for function argument (#8303) --- .selfcheck_suppressions | 2 ++ gui/mainwindow.cpp | 20 ++++++------ gui/mainwindow.h | 18 +++++------ lib/checkcondition.cpp | 4 +-- lib/checkcondition.h | 2 +- lib/checkother.cpp | 62 ++++++++++++++++++++++++------------ lib/checkother.h | 2 +- lib/checkunusedfunctions.cpp | 8 ++--- lib/checkunusedfunctions.h | 2 +- lib/filesettings.h | 4 +-- lib/preprocessor.cpp | 36 ++++++++++----------- lib/preprocessor.h | 4 +-- lib/programmemory.cpp | 4 +-- lib/programmemory.h | 2 +- lib/regex.cpp | 6 ++-- lib/symboldatabase.cpp | 12 +++---- lib/symboldatabase.h | 4 +-- lib/token.cpp | 58 ++++++++++++++++----------------- lib/token.h | 22 ++++++------- lib/tokenlist.cpp | 8 ++--- lib/tokenlist.h | 6 ++-- lib/vf_analyzers.cpp | 4 +-- test/cfg/qt.cpp | 2 ++ test/testother.cpp | 34 +++++++++++++++++--- tools/triage/mainwindow.cpp | 6 ++-- tools/triage/mainwindow.h | 2 +- 26 files changed, 191 insertions(+), 143 deletions(-) diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index 5dbce0afc79..1687753c268 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -78,3 +78,5 @@ knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp useStlAlgorithm:externals/simplecpp/simplecpp.cpp funcArgNamesDifferentUnnamed:externals/simplecpp/simplecpp.h missingMemberCopy:externals/simplecpp/simplecpp.h +shadowFunction:externals/simplecpp/simplecpp.cpp +shadowFunction:externals/simplecpp/simplecpp.h diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index a08d1eb738e..ce1b3ef1508 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -562,7 +562,7 @@ void MainWindow::saveSettings() const mUI->mResults->saveSettings(mSettings); } -void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, const bool checkConfiguration) +void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bool checkConfig) { Settings checkSettings; auto supprs = std::make_shared(); @@ -606,8 +606,8 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons mUI->mResults->setCheckDirectory(checkPath); checkSettings.force = false; - checkSettings.checkLibrary = checkLibrary; - checkSettings.checkConfiguration = checkConfiguration; + checkSettings.checkLibrary = checkLib; + checkSettings.checkConfiguration = checkConfig; if (mProjectFile) qDebug() << "Checking project file" << mProjectFile->getFilename(); @@ -634,7 +634,7 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons mUI->mResults->setCheckSettings(checkSettings); } -void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrary, const bool checkConfiguration) +void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, const bool checkConfig) { if (files.isEmpty()) return; @@ -675,7 +675,7 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrar // TODO: lock UI here? mUI->mResults->checkingStarted(fdetails.size()); mThread->setFiles(std::move(fdetails)); - if (mProjectFile && !checkConfiguration) + if (mProjectFile && !checkConfig) mThread->setAddonsAndTools(mProjectFile->getAddonsAndTools()); mThread->setSuppressions(mProjectFile ? mProjectFile->getCheckingSuppressions() : QList()); QDir inf(mCurrentDirectory); @@ -685,8 +685,8 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrar checkLockDownUI(); // lock UI while checking mUI->mResults->setCheckDirectory(checkPath); - checkSettings.checkLibrary = checkLibrary; - checkSettings.checkConfiguration = checkConfiguration; + checkSettings.checkLibrary = checkLib; + checkSettings.checkConfiguration = checkConfig; if (mProjectFile) qDebug() << "Checking project file" << mProjectFile->getFilename(); @@ -1856,7 +1856,7 @@ bool MainWindow::loadLastResults() return true; } -void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringList& recheckFiles, const bool checkLibrary, const bool checkConfiguration) +void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringList& recheckFiles, const bool checkLib, const bool checkConfig) { Settings::terminate(false); @@ -1961,7 +1961,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis msg.exec(); return; } - doAnalyzeProject(p, checkLibrary, checkConfiguration); // TODO: avoid copy + doAnalyzeProject(p, checkLib, checkConfig); // TODO: avoid copy return; } @@ -1974,7 +1974,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis if (paths.isEmpty()) { paths << mCurrentDirectory; } - doAnalyzeFiles(paths, checkLibrary, checkConfiguration); + doAnalyzeFiles(paths, checkLib, checkConfig); } void MainWindow::newProjectFile() diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 3015a708836..febd3a41d4c 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -267,10 +267,10 @@ private slots: * @brief Analyze the project. * @param projectFile Pointer to the project to analyze. * @param recheckFiles files to recheck, empty => check all files - * @param checkLibrary Flag to indicate if the library should be checked. - * @param checkConfiguration Flag to indicate if the configuration should be checked. + * @param checkLib Flag to indicate if the library should be checked. + * @param checkConfig Flag to indicate if the configuration should be checked. */ - void analyzeProject(const ProjectFile *projectFile, const QStringList& recheckFiles, bool checkLibrary = false, bool checkConfiguration = false); + void analyzeProject(const ProjectFile *projectFile, const QStringList& recheckFiles, bool checkLib = false, bool checkConfig = false); /** * @brief Set current language @@ -306,19 +306,19 @@ private slots: /** * @brief Analyze project * @param p imported project - * @param checkLibrary Flag to indicate if library should be checked - * @param checkConfiguration Flag to indicate if the configuration should be checked. + * @param checkLib Flag to indicate if library should be checked + * @param checkConfig Flag to indicate if the configuration should be checked. */ - void doAnalyzeProject(ImportProject p, bool checkLibrary = false, bool checkConfiguration = false); + void doAnalyzeProject(ImportProject p, bool checkLib = false, bool checkConfig = false); /** * @brief Analyze all files specified in parameter files * * @param files List of files and/or directories to analyze - * @param checkLibrary Flag to indicate if library should be checked - * @param checkConfiguration Flag to indicate if the configuration should be checked. + * @param checkLib Flag to indicate if library should be checked + * @param checkConfig Flag to indicate if the configuration should be checked. */ - void doAnalyzeFiles(const QStringList &files, bool checkLibrary = false, bool checkConfiguration = false); + void doAnalyzeFiles(const QStringList &files, bool checkLib = false, bool checkConfig = false); /** * @brief Get our default cppcheck settings and read project file. diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 1b761ce4802..d0913963cca 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -2085,10 +2085,10 @@ void CheckCondition::checkCompareValueOutOfTypeRange() } } -void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, MathLib::bigint value, bool result) +void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparisonTok, const std::string &type, MathLib::bigint value, bool result) { reportError( - comparison, + comparisonTok, Severity::style, "compareValueOutOfTypeRangeError", "Comparing expression of type '" + type + "' against value " + MathLib::toString(value) + ". Condition is always " + bool_to_string(result) + ".", diff --git a/lib/checkcondition.h b/lib/checkcondition.h index 2c010cd7c5a..2ea20158b11 100644 --- a/lib/checkcondition.h +++ b/lib/checkcondition.h @@ -156,7 +156,7 @@ class CPPCHECKLIB CheckCondition : public Check { void assignmentInCondition(const Token *eq); void checkCompareValueOutOfTypeRange(); - void compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, MathLib::bigint value, bool result); + void compareValueOutOfTypeRangeError(const Token *comparisonTok, const std::string &type, MathLib::bigint value, bool result); void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 7a1e1fea774..fb75d80fca7 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4168,18 +4168,21 @@ void CheckOther::checkShadowVariables() const Scope *functionScope = &scope; while (functionScope && functionScope->type != ScopeType::eFunction && functionScope->type != ScopeType::eLambda) functionScope = functionScope->nestedIn; - for (const Variable &var : scope.varlist) { - if (var.nameToken() && var.nameToken()->isExpandedMacro()) // #8903 - continue; + const auto checkVar = [&](const Variable &var) { + if (!var.nameToken()) + return; + + if (var.nameToken()->isExpandedMacro()) // #8903 + return; - if (functionScope && functionScope->type == ScopeType::eFunction && functionScope->function) { + if (!var.isArgument() && functionScope && functionScope->type == ScopeType::eFunction && functionScope->function) { const auto & argList = functionScope->function->argumentList; auto it = std::find_if(argList.cbegin(), argList.cend(), [&](const Variable& arg) { return arg.nameToken() && var.name() == arg.name(); }); if (it != argList.end()) { - shadowError(var.nameToken(), it->nameToken(), "argument"); - continue; + shadowError(var.nameToken(), "local variable", it->nameToken(), "argument"); + return; } } @@ -4187,27 +4190,43 @@ void CheckOther::checkShadowVariables() if (!shadowed) shadowed = findShadowed(scope.functionOf, var, var.nameToken()->linenr()); if (!shadowed) - continue; + return; if (scope.type == ScopeType::eFunction && scope.className == var.name()) - continue; + return; if (functionScope->functionOf && functionScope->functionOf->isClassOrStructOrUnion() && functionScope->function && (functionScope->function->isStatic() || functionScope->function->isFriend()) && shadowed->variable() && !shadowed->variable()->isLocal()) - continue; - shadowError(var.nameToken(), shadowed, (shadowed->varId() != 0) ? "variable" : "function"); - } + return; + if (var.scope() && var.scope()->function && var.scope()->function->isConstructor()) { + if (shadowed->variable() && shadowed->variable()->isMember()) + return; + if (shadowed->function() && shadowed->function()->nestedIn && + shadowed->function()->nestedIn->isClassOrStruct()) + return; + } + shadowError(var.nameToken(), var.isArgument() ? "argument" : "local variable", + shadowed, (shadowed->varId() != 0) ? + (shadowed->variable()->isMember() ? "member" : "variable") : "function"); + }; + for (const Variable &var : scope.varlist) + checkVar(var); + if (functionScope && functionScope->type == ScopeType::eFunction && functionScope->function) + for (const Variable &arg: functionScope->function->argumentList) + checkVar(arg); } } -void CheckOther::shadowError(const Token *var, const Token *shadowed, const std::string& type) +void CheckOther::shadowError(const Token *shadows, const std::string &shadowsType, + const Token *shadowed, const std::string &shadowedType) { ErrorPath errorPath; - errorPath.emplace_back(shadowed, "Shadowed declaration"); - errorPath.emplace_back(var, "Shadow variable"); - const std::string &varname = var ? var->str() : type; - const std::string Type = char(std::toupper(type[0])) + type.substr(1); - const std::string id = "shadow" + Type; - const std::string message = "$symbol:" + varname + "\nLocal variable \'$symbol\' shadows outer " + type; + errorPath.emplace_back(shadowed, "Shadowed " + shadowedType); + errorPath.emplace_back(shadows, "Shadow " + shadowsType); + const std::string &varname = shadows ? shadows->str() : shadowsType; + const std::string ShadowsType = char(std::toupper(shadowsType[0])) + shadowsType.substr(1); + const std::string ShadowedType = char(std::toupper(shadowedType[0])) + shadowedType.substr(1); + const std::string id = "shadow" + ShadowedType; + const std::string message = "$symbol:" + varname + "\n" + ShadowsType + " \'$symbol\' shadows outer " + shadowedType; reportError(std::move(errorPath), Severity::style, id.c_str(), message, CWE398, Certainty::normal); } @@ -4889,9 +4908,10 @@ void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *sett c.accessMovedError(nullptr, "v", nullptr, false); c.funcArgNamesDifferent("function", 1, nullptr, nullptr); c.redundantBitwiseOperationInSwitchError(nullptr, "varname"); - c.shadowError(nullptr, nullptr, "variable"); - c.shadowError(nullptr, nullptr, "function"); - c.shadowError(nullptr, nullptr, "argument"); + c.shadowError(nullptr, "local variable", nullptr, "variable"); + c.shadowError(nullptr, "local variable", nullptr, "argument"); + c.shadowError(nullptr, "local variable", nullptr, "function"); + c.shadowError(nullptr, "local variable", nullptr, "member"); c.knownArgumentError(nullptr, nullptr, nullptr, "x", false); c.knownPointerToBoolError(nullptr, nullptr); c.comparePointersError(nullptr, nullptr, nullptr); diff --git a/lib/checkother.h b/lib/checkother.h index 28ee25cfa76..f779141f499 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -258,7 +258,7 @@ class CPPCHECKLIB CheckOther : public Check { void accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive); void funcArgNamesDifferent(const std::string & functionName, nonneg int index, const Token* declaration, const Token* definition); void funcArgOrderDifferent(const std::string & functionName, const Token * declaration, const Token * definition, const std::vector & declarations, const std::vector & definitions); - void shadowError(const Token *var, const Token *shadowed, const std::string& type); + void shadowError(const Token *shadows, const std::string &shadowsType, const Token *shadowed, const std::string &shadowedType); void knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value, const std::string &varexpr, bool isVariableExpressionHidden); void knownPointerToBoolError(const Token* tok, const ValueFlow::Value* value); void comparePointersError(const Token *tok, const ValueFlow::Value *v1, const ValueFlow::Value *v2); diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index fa086cca1f1..5965de1aada 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -505,9 +505,9 @@ void CheckUnusedFunctions::analyseWholeProgram(const Settings &settings, ErrorLo } } -void CheckUnusedFunctions::updateFunctionData(const CheckUnusedFunctions& check) +void CheckUnusedFunctions::updateFunctionData(const CheckUnusedFunctions& checkUnusedFunctions) { - for (const auto& entry : check.mFunctions) + for (const auto& entry : checkUnusedFunctions.mFunctions) { FunctionUsage &usage = mFunctions[entry.first]; if (!usage.lineNumber) { @@ -521,6 +521,6 @@ void CheckUnusedFunctions::updateFunctionData(const CheckUnusedFunctions& check) usage.usedOtherFile |= entry.second.usedOtherFile; usage.usedSameFile |= entry.second.usedSameFile; } - mFunctionDecl.insert(mFunctionDecl.cend(), check.mFunctionDecl.cbegin(), check.mFunctionDecl.cend()); - mFunctionCalls.insert(check.mFunctionCalls.cbegin(), check.mFunctionCalls.cend()); + mFunctionDecl.insert(mFunctionDecl.cend(), checkUnusedFunctions.mFunctionDecl.cbegin(), checkUnusedFunctions.mFunctionDecl.cend()); + mFunctionCalls.insert(checkUnusedFunctions.mFunctionCalls.cbegin(), checkUnusedFunctions.mFunctionCalls.cend()); } diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 6f10e3446eb..20e1788cf64 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -58,7 +58,7 @@ class CPPCHECKLIB CheckUnusedFunctions { // Return true if an error is reported. bool check(const Settings& settings, ErrorLogger& errorLogger) const; - void updateFunctionData(const CheckUnusedFunctions& check); + void updateFunctionData(const CheckUnusedFunctions& checkUnusedFunctions); private: static void unusedFunctionError(ErrorLogger& errorLogger, diff --git a/lib/filesettings.h b/lib/filesettings.h index e9f883d5a87..183e38708fd 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -91,9 +91,9 @@ class FileWithDetails return mFsFileId; } - void setFsFileId(std::size_t fsFileId) + void setFsFileId(std::size_t id) { - mFsFileId = fsFileId; + mFsFileId = id; } private: std::string mPath; diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 3b69c31085d..4246da39c83 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -516,14 +516,14 @@ static std::string readcondition(const simplecpp::Token *iftok, const std::set &configs, const std::strin return ret; } -static bool isUndefined(const std::string &cfg, const std::set &undefined) +static bool isUndefined(const std::string &cfgStr, const std::set &undefined) { - for (std::string::size_type pos1 = 0U; pos1 < cfg.size();) { - const std::string::size_type pos2 = cfg.find(';',pos1); - const std::string def = (pos2 == std::string::npos) ? cfg.substr(pos1) : cfg.substr(pos1, pos2 - pos1); + for (std::string::size_type pos1 = 0U; pos1 < cfgStr.size();) { + const std::string::size_type pos2 = cfgStr.find(';',pos1); + const std::string def = (pos2 == std::string::npos) ? cfgStr.substr(pos1) : cfgStr.substr(pos1, pos2 - pos1); const std::string::size_type eq = def.find('='); if (eq == std::string::npos && undefined.find(def) != undefined.end()) @@ -801,11 +801,11 @@ std::set Preprocessor::getConfigs() const return ret; } -static void splitcfg(const std::string &cfg, std::list &defines, const std::string &defaultValue) +static void splitcfg(const std::string &cfgStr, std::list &defines, const std::string &defaultValue) { - for (std::string::size_type defineStartPos = 0U; defineStartPos < cfg.size();) { - const std::string::size_type defineEndPos = cfg.find(';', defineStartPos); - std::string def = (defineEndPos == std::string::npos) ? cfg.substr(defineStartPos) : cfg.substr(defineStartPos, defineEndPos - defineStartPos); + for (std::string::size_type defineStartPos = 0U; defineStartPos < cfgStr.size();) { + const std::string::size_type defineEndPos = cfgStr.find(';', defineStartPos); + std::string def = (defineEndPos == std::string::npos) ? cfgStr.substr(defineStartPos) : cfgStr.substr(defineStartPos, defineEndPos - defineStartPos); if (!defaultValue.empty() && def.find('=') == std::string::npos) def += '=' + defaultValue; defines.push_back(std::move(def)); @@ -815,14 +815,14 @@ static void splitcfg(const std::string &cfg, std::list &defines, co } } -static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cfg, Standards::Language lang) +static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cfgStr, Standards::Language lang) { // TODO: make it possible to specify platform-dependent sizes simplecpp::DUI dui; splitcfg(mSettings.userDefines, dui.defines, "1"); - if (!cfg.empty()) - splitcfg(cfg, dui.defines, ""); + if (!cfgStr.empty()) + splitcfg(cfgStr, dui.defines, ""); for (const std::string &def : mSettings.library.defines()) { const std::string::size_type pos = def.find_first_of(" ("); @@ -903,9 +903,9 @@ void Preprocessor::setPlatformInfo() mTokens.sizeOfType["long double *"] = mSettings.platform.sizeof_pointer; } -simplecpp::TokenList Preprocessor::preprocess(const std::string &cfg, std::vector &files, simplecpp::OutputList& outputList) +simplecpp::TokenList Preprocessor::preprocess(const std::string &cfgStr, std::vector &files, simplecpp::OutputList& outputList) { - const simplecpp::DUI dui = createDUI(mSettings, cfg, mLang); + const simplecpp::DUI dui = createDUI(mSettings, cfgStr, mLang); std::list macroUsage; std::list ifCond; @@ -919,10 +919,10 @@ simplecpp::TokenList Preprocessor::preprocess(const std::string &cfg, std::vecto return tokens2; } -std::string Preprocessor::getcode(const std::string &cfg, std::vector &files, const bool writeLocations) +std::string Preprocessor::getcode(const std::string &cfgStr, std::vector &files, const bool writeLocations) { simplecpp::OutputList outputList; - simplecpp::TokenList tokens2 = preprocess(cfg, files, outputList); + simplecpp::TokenList tokens2 = preprocess(cfgStr, files, outputList); handleErrors(outputList); unsigned int prevfile = 0; unsigned int line = 1; diff --git a/lib/preprocessor.h b/lib/preprocessor.h index a211341691f..9daabbf6ca8 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -118,9 +118,9 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { void setPlatformInfo(); - simplecpp::TokenList preprocess(const std::string &cfg, std::vector &files, simplecpp::OutputList& outputList); + simplecpp::TokenList preprocess(const std::string &cfgStr, std::vector &files, simplecpp::OutputList& outputList); - std::string getcode(const std::string &cfg, std::vector &files, bool writeLocations); + std::string getcode(const std::string &cfgStr, std::vector &files, bool writeLocations); /** * Calculate HASH. Using toolinfo, tokens1, filedata. diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 3dca55e5117..92952152ca5 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -150,11 +150,11 @@ bool ProgramMemory::getContainerEmptyValue(nonneg int exprid, MathLib::bigint& r return false; } -void ProgramMemory::setContainerSizeValue(const Token* expr, MathLib::bigint value, bool isEqual) +void ProgramMemory::setContainerSizeValue(const Token* expr, MathLib::bigint value, bool equal) { ValueFlow::Value v(value); v.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; - if (!isEqual) + if (!equal) v.valueKind = ValueFlow::Value::ValueKind::Impossible; setValue(expr, v); } diff --git a/lib/programmemory.h b/lib/programmemory.h index 95effc70874..21350d86d36 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -116,7 +116,7 @@ struct CPPCHECKLIB ProgramMemory { bool getContainerSizeValue(nonneg int exprid, MathLib::bigint& result) const; bool getContainerEmptyValue(nonneg int exprid, MathLib::bigint& result) const; - void setContainerSizeValue(const Token* expr, MathLib::bigint value, bool isEqual = true); + void setContainerSizeValue(const Token* expr, MathLib::bigint value, bool equal = true); void setUnknown(const Token* expr); diff --git a/lib/regex.cpp b/lib/regex.cpp index bee8acb2a2a..0c8b0c9f188 100644 --- a/lib/regex.cpp +++ b/lib/regex.cpp @@ -177,7 +177,7 @@ namespace { } std::string compile(); - std::string match(const std::string& str, const MatchFn& match) const override; + std::string match(const std::string& str, const MatchFn& matchFn) const override; private: std::string mPattern; @@ -219,7 +219,7 @@ namespace { return ""; } - std::string PcreRegex::match(const std::string& str, const MatchFn& match) const + std::string PcreRegex::match(const std::string& str, const MatchFn& matchFn) const { if (!mRe) return "regular expression has not been compiled yet"; @@ -236,7 +236,7 @@ namespace { const auto pos1 = static_cast(ovector[0]); const auto pos2 = static_cast(ovector[1]); - match(pos1, pos2); + matchFn(pos1, pos2); // jump to the end of the match for the next pcre_exec pos = static_cast(pos2); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 5eeaafb7dd0..38018372eb0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2370,9 +2370,9 @@ void SymbolDatabase::validate() const validateVariables(); } -void SymbolDatabase::clangSetVariables(const std::vector &variableList) +void SymbolDatabase::clangSetVariables(const std::vector &vars) { - mVariableList = variableList; + mVariableList = vars; } void SymbolDatabase::debugSymbolDatabase() const @@ -2641,16 +2641,16 @@ void Variable::evaluate(const Settings& settings) } } -void Variable::setValueType(const ValueType &valueType) +void Variable::setValueType(const ValueType &vt) { - if (valueType.type == ValueType::Type::UNKNOWN_TYPE) { + if (vt.type == ValueType::Type::UNKNOWN_TYPE) { const Token *declType = Token::findsimplematch(mTypeStartToken, "decltype (", mTypeEndToken); if (declType && !declType->next()->valueType()) return; } - const auto* vt = new ValueType(valueType); + const auto* tmp = new ValueType(vt); delete mValueType; - mValueType = vt; + mValueType = tmp; if ((mValueType->pointer > 0) && (!isArray() || Token::Match(mNameToken->previous(), "( * %name% )"))) setFlag(fIsPointer, true); setFlag(fIsConst, mValueType->constness & (1U << mValueType->pointer)); diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 1ba1aeb0b13..a4a07fd2083 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -651,7 +651,7 @@ class CPPCHECKLIB Variable { return mValueType; } - void setValueType(const ValueType &valueType); + void setValueType(const ValueType &vt); AccessControl accessControl() const { return mAccess; @@ -1424,7 +1424,7 @@ class CPPCHECKLIB SymbolDatabase { /** Set array dimensions when valueflow analysis is completed */ void setArrayDimensionsUsingValueFlow(); - void clangSetVariables(const std::vector &variableList); + void clangSetVariables(const std::vector &vars); void createSymbolDatabaseExprIds(); /* returns the opening { if tok points to enum */ diff --git a/lib/token.cpp b/lib/token.cpp index d1e76ebdd67..539141c0b0f 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -211,9 +211,9 @@ static const std::unordered_set stdTypes = { "bool" , "unsigned" }; -bool Token::isStandardType(const std::string& str) +bool Token::isStandardType(const std::string& s) { - return stdTypes.find(str) != stdTypes.end(); + return stdTypes.find(s) != stdTypes.end(); } void Token::update_property_isStandardType() @@ -637,31 +637,31 @@ bool Token::simpleMatch(const Token *tok, const char pattern[], size_t pattern_l return true; } -bool Token::firstWordEquals(const char *str, const char *word) +bool Token::firstWordEquals(const char *s, const char *word) { for (;;) { - if (*str != *word) - return (*str == ' ' && *word == 0); - if (*str == 0) + if (*s != *word) + return (*s == ' ' && *word == 0); + if (*s == 0) break; - ++str; + ++s; ++word; } return true; } -const char *Token::chrInFirstWord(const char *str, char c) +const char *Token::chrInFirstWord(const char *s, char c) { for (;;) { - if (*str == ' ' || *str == 0) + if (*s == ' ' || *s == 0) return nullptr; - if (*str == c) - return str; + if (*s == c) + return s; - ++str; + ++s; } } @@ -1014,41 +1014,41 @@ Token *Token::findsimplematch(Token * const startTok, const char pattern[], size } template )> -static T *findmatchImpl(T * const startTok, const char pattern[], const nonneg int varId) +static T *findmatchImpl(T * const startTok, const char pattern[], const nonneg int varid) { for (T* tok = startTok; tok; tok = tok->next()) { - if (Token::Match(tok, pattern, varId)) + if (Token::Match(tok, pattern, varid)) return tok; } return nullptr; } -const Token *Token::findmatch(const Token * const startTok, const char pattern[], const nonneg int varId) +const Token *Token::findmatch(const Token * const startTok, const char pattern[], const nonneg int varid) { - return findmatchImpl(startTok, pattern, varId); + return findmatchImpl(startTok, pattern, varid); } -Token *Token::findmatch(Token * const startTok, const char pattern[], const nonneg int varId) { - return findmatchImpl(startTok, pattern, varId); +Token *Token::findmatch(Token * const startTok, const char pattern[], const nonneg int varid) { + return findmatchImpl(startTok, pattern, varid); } template )> -static T *findmatchImpl(T * const startTok, const char pattern[], const Token * const end, const nonneg int varId) +static T *findmatchImpl(T * const startTok, const char pattern[], const Token * const end, const nonneg int varid) { for (T* tok = startTok; tok && tok != end; tok = tok->next()) { - if (Token::Match(tok, pattern, varId)) + if (Token::Match(tok, pattern, varid)) return tok; } return nullptr; } -const Token *Token::findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId) +const Token *Token::findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varid) { - return findmatchImpl(startTok, pattern, end, varId); + return findmatchImpl(startTok, pattern, end, varid); } -Token *Token::findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId) { - return findmatchImpl(startTok, pattern, end, varId); +Token *Token::findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varid) { + return findmatchImpl(startTok, pattern, end, varid); } void Token::function(const Function *f) @@ -2661,26 +2661,26 @@ Token::Impl::~Impl() } } -void Token::Impl::setCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint value) +void Token::Impl::setCppcheckAttribute(CppcheckAttributesType attrType, MathLib::bigint value) { CppcheckAttributes *attr = mCppcheckAttributes; - while (attr && attr->type != type) + while (attr && attr->type != attrType) attr = attr->next; if (attr) attr->value = value; else { attr = new CppcheckAttributes; - attr->type = type; + attr->type = attrType; attr->value = value; attr->next = mCppcheckAttributes; mCppcheckAttributes = attr; } } -bool Token::Impl::getCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint &value) const +bool Token::Impl::getCppcheckAttribute(CppcheckAttributesType attrType, MathLib::bigint &value) const { const CppcheckAttributes *attr = mCppcheckAttributes; - while (attr && attr->type != type) + while (attr && attr->type != attrType) attr = attr->next; if (attr) value = attr->value; diff --git a/lib/token.h b/lib/token.h index 733887207ad..ca945fcab22 100644 --- a/lib/token.h +++ b/lib/token.h @@ -174,8 +174,8 @@ class CPPCHECKLIB Token { std::int8_t mMutableExpr{-1}; - void setCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint value); - bool getCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint &value) const; + void setCppcheckAttribute(CppcheckAttributesType attrType, MathLib::bigint value); + bool getCppcheckAttribute(CppcheckAttributesType attrType, MathLib::bigint &value) const; Impl() = default; ~Impl(); @@ -872,8 +872,8 @@ class CPPCHECKLIB Token { } static const Token *findsimplematch(const Token * startTok, const char pattern[], size_t pattern_len, const Token * end); - static const Token *findmatch(const Token * startTok, const char pattern[], nonneg int varId = 0); - static const Token *findmatch(const Token * startTok, const char pattern[], const Token * end, nonneg int varId = 0); + static const Token *findmatch(const Token * startTok, const char pattern[], nonneg int varid = 0); + static const Token *findmatch(const Token * startTok, const char pattern[], const Token * end, nonneg int varid = 0); template static Token *findsimplematch(Token * const startTok, const char (&pattern)[count]) { @@ -886,8 +886,8 @@ class CPPCHECKLIB Token { } static Token *findsimplematch(Token * startTok, const char pattern[], size_t pattern_len, const Token * end); - static Token *findmatch(Token * startTok, const char pattern[], nonneg int varId = 0); - static Token *findmatch(Token * startTok, const char pattern[], const Token * end, nonneg int varId = 0); + static Token *findmatch(Token * startTok, const char pattern[], nonneg int varid = 0); + static Token *findmatch(Token * startTok, const char pattern[], const Token * end, nonneg int varid = 0); private: template )> @@ -1267,7 +1267,7 @@ class CPPCHECKLIB Token { static std::string typeStr(const Token* tok); - static bool isStandardType(const std::string& str); + static bool isStandardType(const std::string& s); /** * @return a pointer to the Enumerator associated with this token. @@ -1439,17 +1439,17 @@ class CPPCHECKLIB Token { /** * Works almost like strcmp() except returns only true or false and - * if str has empty space ' ' character, that character is handled + * if s has empty space ' ' character, that character is handled * as if it were '\\0' */ - static bool firstWordEquals(const char *str, const char *word); + static bool firstWordEquals(const char *s, const char *word); /** * Works almost like strchr() except - * if str has empty space ' ' character, that character is handled + * if s has empty space ' ' character, that character is handled * as if it were '\\0' */ - static const char *chrInFirstWord(const char *str, char c); + static const char *chrInFirstWord(const char *s, char c); RET_NONNULL Token* insertToken(const std::string& tokenStr, bool prepend); RET_NONNULL Token* insertToken(const std::string& tokenStr, const std::string& originalNameStr, bool prepend); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 74c0bae258f..f155a75014a 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -2309,7 +2309,7 @@ bool TokenList::isCPP() const return mLang == Standards::Language::CPP; } -const Token * TokenList::isFunctionHead(const Token *tok, const std::string &endsWith) +const Token * TokenList::isFunctionHead(const Token *tok, const std::string &suffix) { if (!tok) return nullptr; @@ -2322,11 +2322,11 @@ const Token * TokenList::isFunctionHead(const Token *tok, const std::string &end if (Token::Match(tok, ") ;|{|[")) { tok = tok->next(); while (tok && tok->str() == "[" && tok->link()) { - if (endsWith.find(tok->str()) != std::string::npos) + if (suffix.find(tok->str()) != std::string::npos) return tok; tok = tok->link()->next(); } - return (tok && endsWith.find(tok->str()) != std::string::npos) ? tok : nullptr; + return (tok && suffix.find(tok->str()) != std::string::npos) ? tok : nullptr; } if (tok->isCpp() && tok->str() == ")") { tok = tok->next(); @@ -2361,7 +2361,7 @@ const Token * TokenList::isFunctionHead(const Token *tok, const std::string &end } if (tok && tok->str() == ":" && !Token::Match(tok->next(), "%name%|::")) return nullptr; - return (tok && endsWith.find(tok->str()) != std::string::npos) ? tok : nullptr; + return (tok && suffix.find(tok->str()) != std::string::npos) ? tok : nullptr; } return nullptr; } diff --git a/lib/tokenlist.h b/lib/tokenlist.h index ae61fff6de4..f5b652f3506 100644 --- a/lib/tokenlist.h +++ b/lib/tokenlist.h @@ -206,10 +206,10 @@ class CPPCHECKLIB TokenList { /** * is token pointing at function head? * @param tok A '(' or ')' token in a possible function head - * @param endsWith string after function head - * @return token matching with endsWith if syntax seems to be a function head else nullptr + * @param suffix string after function head + * @return token matching with suffix if syntax seems to be a function head else nullptr */ - static const Token * isFunctionHead(const Token *tok, const std::string &endsWith); + static const Token * isFunctionHead(const Token *tok, const std::string &suffix); const Settings& getSettings() const { return mSettings; diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 45d5e7c9547..a50a3b1d4a4 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -673,12 +673,12 @@ struct ValueFlowAnalyzer : Analyzer { } template - std::vector evaluateInt(const Token* tok, F getProgramMemory) const + std::vector evaluateInt(const Token* tok, F getProgramMemoryFunc) const { if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) return {v->intvalue}; std::vector result; - ProgramMemory pm = getProgramMemory(); + ProgramMemory pm = getProgramMemoryFunc(); if (Token::Match(tok, "&&|%oror%")) { if (conditionIsTrue(tok, pm, getSettings())) result.push_back(1); diff --git a/test/cfg/qt.cpp b/test/cfg/qt.cpp index 4ff0a476959..78827d3583c 100644 --- a/test/cfg/qt.cpp +++ b/test/cfg/qt.cpp @@ -728,6 +728,7 @@ namespace { private: int m_value; }; + // cppcheck-suppress shadowFunction void Counter1::setValue(int value) { if (value != m_value) { m_value = value; @@ -751,6 +752,7 @@ namespace { private: int m_value; }; + // cppcheck-suppress shadowFunction void Counter2::setValue(int value) { if (value != m_value) { m_value = value; diff --git a/test/testother.cpp b/test/testother.cpp index a768abb647e..c5a94a673fe 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -6574,9 +6574,9 @@ class TestOther : public TestFixture { check("class Foo {\n" " int var;\n" - " void func(int var);\n" + " Foo(int var);\n" "};\n" - "void Foo::func(int var) {\n" + "Foo::Foo(int var) {\n" " this->var = var;\n" "}"); ASSERT_EQUALS("", errout_str()); @@ -13035,14 +13035,14 @@ class TestOther : public TestFixture { " int i{};\n" " void f() { int i; }\n" "};\n"); - ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:20]: (style) Local variable 'i' shadows outer variable [shadowVariable]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:20]: (style) Local variable 'i' shadows outer member [shadowMember]\n", errout_str()); check("struct S {\n" " int i{};\n" " std::vector v;\n" " void f() const { for (const int& i : v) {} }\n" "};\n"); - ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:38]: (style) Local variable 'i' shadows outer variable [shadowVariable]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:38]: (style) Local variable 'i' shadows outer member [shadowMember]\n", errout_str()); check("struct S {\n" // #10405 " F* f{};\n" @@ -13052,7 +13052,7 @@ class TestOther : public TestFixture { "void S::f() const {\n" " for (const F& f : fl) {}\n" "};\n"); - ASSERT_EQUALS("[test.cpp:2:8] -> [test.cpp:7:19]: (style) Local variable 'f' shadows outer variable [shadowVariable]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:8] -> [test.cpp:7:19]: (style) Local variable 'f' shadows outer member [shadowMember]\n", errout_str()); check("extern int a;\n" "int a;\n" @@ -13074,6 +13074,30 @@ class TestOther : public TestFixture { " friend int f() { int i = 5; return i; }\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + check("int x;\n" + "void f(int x) {}\n"); + ASSERT_EQUALS("[test.cpp:1:5] -> [test.cpp:2:12]: (style) Argument 'x' shadows outer variable [shadowVariable]\n", errout_str()); + + check("void x() {}\n" + "void f(int x) {}\n"); + ASSERT_EQUALS("[test.cpp:1:6] -> [test.cpp:2:12]: (style) Argument 'x' shadows outer function [shadowFunction]\n", errout_str()); + + check("struct S { int v; void func(int v); };\n" + "void S::func(int v) { this->v = v; }\n"); + ASSERT_EQUALS("[test.cpp:1:16] -> [test.cpp:2:18]: (style) Argument 'v' shadows outer member [shadowMember]\n", errout_str()); + + check("struct S { int v; void func(void); };\n" + "void S::func() { int v = 0; }\n"); + ASSERT_EQUALS("[test.cpp:1:16] -> [test.cpp:2:22]: (style) Local variable 'v' shadows outer member [shadowMember]\n", errout_str()); + + check("struct S { int v; explicit S(int v); };\n" + "S::S(int v) : v(v) {}\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S { int v(); explicit S(int v); };\n" + "S::S(int v) : v(v) {}\n"); + ASSERT_EQUALS("", errout_str()); } void knownArgument() { diff --git a/tools/triage/mainwindow.cpp b/tools/triage/mainwindow.cpp index c8989601efd..e8a15f87f3b 100644 --- a/tools/triage/mainwindow.cpp +++ b/tools/triage/mainwindow.cpp @@ -181,12 +181,12 @@ void MainWindow::refreshResults() filter(ui->version->currentText()); } -void MainWindow::filter(const QString& filter) +void MainWindow::filter(const QString& filterStr) { QStringList allErrors; for (const QString &errorItem : mAllErrors) { - if (filter.isEmpty()) { + if (filterStr.isEmpty()) { allErrors << errorItem; continue; } @@ -195,7 +195,7 @@ void MainWindow::filter(const QString& filter) if (lines.size() < 2) continue; - if (lines[1].startsWith(filter)) + if (lines[1].startsWith(filterStr)) allErrors << errorItem; } diff --git a/tools/triage/mainwindow.h b/tools/triage/mainwindow.h index 999740fb59d..38afcaf9553 100644 --- a/tools/triage/mainwindow.h +++ b/tools/triage/mainwindow.h @@ -46,7 +46,7 @@ class MainWindow : public QMainWindow { public slots: void loadFile(); void loadFromClipboard(); - void filter(const QString& filter); + void filter(const QString& filterStr); void showResult(QListWidgetItem *item); void refreshResults(); void fileTreeFilter(const QString &str); From 7bfa45875c78dcd32560466fb181ec7394e876ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 14 May 2026 15:44:10 +0200 Subject: [PATCH 100/493] Fix #14474: Bad varid for global variable matching function pointer argument (#8467) --- addons/misra.py | 3 +-- lib/tokenize.cpp | 7 ++++++- test/testvarid.cpp | 10 ++++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/addons/misra.py b/addons/misra.py index 43b92b51fb0..933ef4c2025 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -803,8 +803,7 @@ def get_function_pointer_type(tok): ret += '(' tok = tok.next.next while tok and (tok.str not in '()'): - if tok.varId is None: - ret += ' ' + tok.str + ret += ' ' + tok.str tok = tok.next if (tok is None) or tok.str != ')': return None diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 70a38a30eb9..6f9cf90a852 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1025,7 +1025,12 @@ namespace { } bool Tokenizer::isFunctionPointer(const Token* tok) { - return Token::Match(tok, "%name% ) ("); + if (!Token::Match(tok, "%name%")) + return false; + tok = tok->next(); + while (Token::Match(tok, "[")) + tok = tok->link()->next(); + return Token::simpleMatch(tok, ") ("); } static bool matchCurrentType(const Token* tok, std::map& types) diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 73eaa3f97eb..57b4bf1744a 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -1328,7 +1328,7 @@ class TestVarID : public TestFixture { ASSERT_EQUALS(expected2, tokenize(code2)); const char code3[] = "extern void (*arr[10])(uint32_t some);\n"; - const char expected3[] = "1: extern void ( * arr@1 [ 10 ] ) ( uint32_t some@2 ) ;\n"; + const char expected3[] = "1: extern void ( * arr@1 [ 10 ] ) ( uint32_t ) ;\n"; ASSERT_EQUALS(expected3, tokenize(code3)); const char code4[] = "_Static_assert(sizeof((struct S){0}.i) == 4);\n"; // #12729 @@ -3545,9 +3545,15 @@ class TestVarID : public TestFixture { "}\n"; ASSERT_EQUALS("1: void f ( ) {\n" "2: int * p@1 ;\n" - "3: void ( * a@2 [ 1 ] ) ( int * p ) = { 0 } ;\n" + "3: void ( * a@2 [ 1 ] ) ( int * ) = { 0 } ;\n" "4: }\n", tokenize(code4)); + + const char code5[] = "int *p;\n" + "void (*a[1])(int* p) = { 0 } ;\n"; + ASSERT_EQUALS("1: int * p@1 ;\n" + "2: void ( * a@2 [ 1 ] ) ( int * ) = { 0 } ;\n" + , tokenize(code5)); } void varid_alignas() { From 7a7c28ca45422f17fecb199059494afa95e69de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 14 May 2026 15:45:19 +0200 Subject: [PATCH 101/493] Fix #14729: False positive: uninitdata reported for ternary operator that does not dereference buffer (#8550) --- lib/checkuninitvar.cpp | 2 +- test/testuninitvar.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 9ff66c055ef..a7a4d8b1bf3 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -383,7 +383,7 @@ static bool isVariableUsed(const Token *tok, const Variable& var) return isVariableUsed(tok->astOperand1(),var) || isVariableUsed(tok->astOperand2(),var); if (tok->varId() != var.declarationId()) return false; - if (!var.isArray()) + if (!var.isArray() && !var.isPointer()) return true; const Token *parent = tok->astParent(); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 1366b350223..db499dabf72 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -80,7 +80,8 @@ class TestUninitVar : public TestFixture { TEST_CASE(uninitvar_unconditionalTry); TEST_CASE(uninitvar_funcptr); // #6404 TEST_CASE(uninitvar_operator); // #6680 - TEST_CASE(uninitvar_ternaryexpression); // #4683 + TEST_CASE(uninitvar_ternaryexpression1); // #4683 + TEST_CASE(uninitvar_ternaryexpression2); // #14729 TEST_CASE(uninitvar_pointertoarray); TEST_CASE(uninitvar_cpp11ArrayInit); // #7010 TEST_CASE(uninitvar_rangeBasedFor); // #7078 @@ -5447,7 +5448,7 @@ class TestUninitVar : public TestFixture { ASSERT_EQUALS("", errout_str()); } - void uninitvar_ternaryexpression() { // #4683 + void uninitvar_ternaryexpression1() { // #4683 checkUninitVar("struct B { int asd; };\n" "int f() {\n" " int a=0;\n" @@ -5461,6 +5462,14 @@ class TestUninitVar : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void uninitvar_ternaryexpression2() { // #14729 + checkUninitVar("void f(bool b, int i) {\n" + " int *p = (int*) malloc(4);\n" + " int *q = b ? p : &i;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void uninitvar_rangeBasedFor() { checkUninitVar("void function(Entry& entry) {\n" // #7078 " for (auto* expr : entry.exprs) {\n" From 887439a23e3db6b3095b53c6b5ccaebe9ab98441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 15 May 2026 16:12:54 +0200 Subject: [PATCH 102/493] Fix #14717 (FP: same exprId for different expressions leads to wrong redundantAssignment) (#8520) --- lib/symboldatabase.cpp | 37 ++++++++++++++++++++++--------------- test/testvarid.cpp | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 38018372eb0..dda3e9b1e0b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1611,6 +1611,26 @@ static std::string getIncompleteNameID(const Token* tok) } namespace { + int getExprIdForOperand(const Token* tok) { + if (!tok) + return 0; + + int otherExprId = 0; + + // Look through all referenced tokens. + // If two exprIds are found and one matches tok->exprId(), return the other. + // Otherwise, default to returning tok->exprId(). + for (const auto& ref: followAllReferences(tok)) { + const int refExprId = ref.token->exprId(); + if (refExprId != 0 && refExprId != tok->exprId()) { + if (otherExprId != 0 && otherExprId != refExprId) + return tok->exprId(); + otherExprId = refExprId; + } + } + return otherExprId != 0 ? otherExprId : tok->exprId(); + } + struct ExprIdKey { std::string parentOp; nonneg int operand1; @@ -1645,8 +1665,8 @@ namespace { ExprIdKey key; key.parentOp = tok->astParent()->str(); - key.operand1 = op1 ? op1->exprId() : 0; - key.operand2 = op2 ? op2->exprId() : 0; + key.operand1 = getExprIdForOperand(op1); + key.operand2 = getExprIdForOperand(op2); if (tok->astParent()->isCast() && tok->astParent()->str() == "(") { const Token* typeStartToken; @@ -1665,19 +1685,6 @@ namespace { key.parentOp += type; } - for (const auto& ref: followAllReferences(op1)) { - if (ref.token->exprId() != 0) { // cppcheck-suppress useStlAlgorithm - key.operand1 = ref.token->exprId(); - break; - } - } - for (const auto& ref: followAllReferences(op2)) { - if (ref.token->exprId() != 0) { // cppcheck-suppress useStlAlgorithm - key.operand2 = ref.token->exprId(); - break; - } - } - if (key.operand1 > key.operand2 && key.operand2 && Token::Match(tok->astParent(), "%or%|%oror%|+|*|&|&&|^|==|!=")) { // In C++ the order of operands of + might matter diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 57b4bf1744a..941b5812678 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -262,6 +262,7 @@ class TestVarID : public TestFixture { TEST_CASE(exprid12); TEST_CASE(exprid13); TEST_CASE(exprid14); + TEST_CASE(exprid15); TEST_CASE(structuredBindings); } @@ -4529,6 +4530,24 @@ class TestVarID : public TestFixture { ASSERT_EQUALS(exp, tokenize(code, s)); // don't crash } + void exprid15() + { + // #14717 + const char code[] = "#define MAX(a, b) (((a) > (b)) ? (a) : (b))\n" + "\n" + "void f(char *d) {\n" + " const char *p = &d[0];\n" + " int a = 1 / MAX(1, p[0]);\n" + " a = 1 / MAX(1, p[1]);\n" + "}\n"; + const char exp[] = "3: void f ( char * d ) {\n" + "4: const char * p@2 ; p@2 =@UNIQUE &@UNIQUE d@1 [@UNIQUE 0 ] ;\n" + "5: int a@3 ; a@3 =@UNIQUE 1 /@UNIQUE $( $( 1 $>@UNIQUE $( p@2 [@9 0 ] $) $) $?@UNIQUE $( 1 $) $:@UNIQUE $( p@2 [@9 0 ] $) $) ;\n" + "6: a@3 =@UNIQUE 1 /@UNIQUE $( $( 1 $>@UNIQUE $( p@2 [@15 1 ] $) $) $?@UNIQUE $( 1 $) $:@UNIQUE $( p@2 [@15 1 ] $) $) ;\n" + "7: }\n"; + ASSERT_EQUALS(exp, tokenizeExpr(code)); + } + void structuredBindings() { const char code[] = "int foo() { auto [x,y] = xy(); return x+y; }"; ASSERT_EQUALS("1: int foo ( ) { auto [ x@1 , y@2 ] = xy ( ) ; return x@1 + y@2 ; }\n", From a03cf24ee0295037ce4d19f98e548f3e4814ac34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 15 May 2026 16:39:46 +0200 Subject: [PATCH 103/493] small `Check::instances()` usage cleanup (#8559) - consistently use range loops - fixed `shadowFunction` selfcheck warnings - return a const reference --- cli/cmdlineparser.cpp | 6 +++--- lib/check.cpp | 11 ++++++++--- lib/check.h | 7 +++++-- lib/cppcheck.cpp | 28 ++++++++++++---------------- test/testcheck.cpp | 9 +++++---- test/testgarbage.cpp | 4 ++-- 6 files changed, 35 insertions(+), 30 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 43361c6e5bc..2ebef4ba3c9 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -359,9 +359,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a if (std::strcmp(argv[i], "--doc") == 0) { std::ostringstream doc; // Get documentation.. - for (const Check * it : Check::instances()) { - const std::string& name(it->name()); - const std::string info(it->classInfo()); + for (const Check * const c : Check::instances()) { + const std::string& name(c->name()); + const std::string info(c->classInfo()); if (!name.empty() && !info.empty()) doc << "## " << name << " ##\n" << info << "\n"; diff --git a/lib/check.cpp b/lib/check.cpp index 812c8b02fcd..f639ba226bd 100644 --- a/lib/check.cpp +++ b/lib/check.cpp @@ -50,9 +50,9 @@ Check::Check(const std::string &aname) return i->name() > aname; }); if (it == instances().end()) - instances().push_back(this); + instances_internal().push_back(this); else - instances().insert(it, this); + instances_internal().insert(it, this); } void Check::writeToErrorList(const ErrorMessage &errmsg) @@ -88,7 +88,7 @@ bool Check::wrongData(const Token *tok, const char *str) return true; } -std::list &Check::instances() +std::list &Check::instances_internal() { #ifdef __SVR4 // Under Solaris, destructors are called in wrong order which causes a segmentation fault. @@ -101,6 +101,11 @@ std::list &Check::instances() #endif } +const std::list &Check::instances() +{ + return instances_internal(); +} + std::string Check::getMessageId(const ValueFlow::Value &value, const char id[]) { if (value.condition != nullptr) diff --git a/lib/check.h b/lib/check.h index 4e3c5b9a4e3..8c3e42a69de 100644 --- a/lib/check.h +++ b/lib/check.h @@ -66,17 +66,20 @@ class CPPCHECKLIB Check { Check(std::string aname, const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger), mName(std::move(aname)) {} +private: + static std::list &instances_internal(); + public: virtual ~Check() { if (!mTokenizer) - instances().remove(this); + instances_internal().remove(this); } Check(const Check &) = delete; Check& operator=(const Check &) = delete; /** List of registered check classes. This is used by Cppcheck to run checks and generate documentation */ - static std::list &instances(); + static const std::list &instances(); /** run checks, the token list is not simplified */ virtual void runChecks(const Tokenizer &, ErrorLogger *) = 0; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 3ef1e7c83e3..652bd4f5bef 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1338,8 +1338,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation const std::time_t maxTime = mSettings.checksMaxTime > 0 ? std::time(nullptr) + mSettings.checksMaxTime : 0; // call all "runChecks" in all registered Check classes - // cppcheck-suppress shadowFunction - TODO: fix this - for (Check *check : Check::instances()) { + for (Check * const c : Check::instances()) { if (Settings::terminated()) return; @@ -1357,8 +1356,8 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation return; } - Timer::run(check->name() + "::runChecks", mTimerResults, [&]() { - check->runChecks(tokenizer, &mErrorLogger); + Timer::run(c->name() + "::runChecks", mTimerResults, [&]() { + c->runChecks(tokenizer, &mErrorLogger); }); } } @@ -1388,11 +1387,10 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation } if (!doUnusedFunctionOnly) { - // cppcheck-suppress shadowFunction - TODO: fix this - for (const Check *check : Check::instances()) { - if (Check::FileInfo * const fi = check->getFileInfo(tokenizer, mSettings, currentConfig)) { + for (const Check * const c : Check::instances()) { + if (Check::FileInfo * const fi = c->getFileInfo(tokenizer, mSettings, currentConfig)) { if (analyzerInformation) - analyzerInformation->setFileInfo(check->name(), fi->toString()); + analyzerInformation->setFileInfo(c->name(), fi->toString()); if (mSettings.useSingleJob()) mFileInfo.push_back(fi); else @@ -1714,8 +1712,8 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) s.addEnabled("all"); // call all "getErrorMessages" in all registered Check classes - for (auto it = Check::instances().cbegin(); it != Check::instances().cend(); ++it) - (*it)->getErrorMessages(&errorlogger, &s); + for (const Check * const c : Check::instances()) + c->getErrorMessages(&errorlogger, &s); CheckUnusedFunctions::getErrorMessages(errorlogger); Preprocessor::getErrorMessages(errorlogger, s); @@ -1832,9 +1830,8 @@ bool CppCheck::analyseWholeProgram() } } - // cppcheck-suppress shadowFunction - TODO: fix this - for (Check *check : Check::instances()) - errors |= check->analyseWholeProgram(ctu, mFileInfo, mSettings, mErrorLogger); // TODO: ctu + for (Check * const c : Check::instances()) + errors |= c->analyseWholeProgram(ctu, mFileInfo, mSettings, mErrorLogger); // TODO: ctu } if (mUnusedFunctionsCheck) @@ -1881,9 +1878,8 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st } else { // Analyse the tokens - // cppcheck-suppress shadowFunction - TODO: fix this - for (Check *check : Check::instances()) - check->analyseWholeProgram(ctuFileInfo, fileInfoList, mSettings, mErrorLogger); + for (Check * const c : Check::instances()) + c->analyseWholeProgram(ctuFileInfo, fileInfoList, mSettings, mErrorLogger); } for (Check::FileInfo *fi : fileInfoList) diff --git a/test/testcheck.cpp b/test/testcheck.cpp index 8ea4cef38d8..b07c7e0db0c 100644 --- a/test/testcheck.cpp +++ b/test/testcheck.cpp @@ -33,18 +33,19 @@ class TestCheck : public TestFixture { } void instancesSorted() const { - for (auto i = Check::instances().cbegin(); i != Check::instances().cend(); ++i) { + const auto& checks = Check::instances(); + for (auto i = checks.cbegin(); i != checks.cend(); ++i) { auto j = i; ++j; - if (j != Check::instances().cend()) { + if (j != checks.cend()) { ASSERT_EQUALS(true, (*i)->name() < (*j)->name()); } } } void classInfoFormat() const { - for (auto i = Check::instances().cbegin(); i != Check::instances().cend(); ++i) { - const std::string info = (*i)->classInfo(); + for (const Check * const c : Check::instances()) { + const std::string info = c->classInfo(); if (!info.empty()) { ASSERT('\n' != info[0]); // No \n in the beginning ASSERT('\n' == info.back()); // \n at end diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 44f163a53c1..38baa798fed 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -285,8 +285,8 @@ class TestGarbage : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // call all "runChecks" in all registered Check classes - for (auto it = Check::instances().cbegin(); it != Check::instances().cend(); ++it) { - (*it)->runChecks(tokenizer, this); + for (Check * const c : Check::instances()) { + c->runChecks(tokenizer, this); } return tokenizer.tokens()->stringifyList(false, false, false, true, false, nullptr, nullptr); From 40f6f6ad90c987ca6ffcd72881128acab9ed8997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= Date: Fri, 15 May 2026 16:15:20 +0000 Subject: [PATCH 104/493] gtk.cfg: Add some defines (#8558) --- cfg/gtk.cfg | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index c4ab8972155..b561aad91b2 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -10,10 +10,24 @@ + + + + + + + + + + + + + + @@ -234,6 +248,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + g_thread_new g_thread_try_new @@ -22972,6 +23066,10 @@ + + + + From 5d69c9fc2e0e7dd8c58a23aa5357d42275778c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 15 May 2026 18:18:17 +0200 Subject: [PATCH 105/493] AUTHORS: Add Tamaranch [skip ci] (#8560) --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 40391c83d7d..04cff0891a9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -141,6 +141,7 @@ Frank Winklmeier Frank Zingsheim Frederik Schwarzer fu7mu4 +Gaël Bonithon Galimov Albert Garrett Bodily Gary Leutheuser From dc0a43793e6364c032ca8490ee36442d187ab20c Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 15 May 2026 19:16:22 +0200 Subject: [PATCH 106/493] Fix #14707 Clarify: uninitMemberVarNoCtor variable (#8556) Co-authored-by: chrchr-github --- lib/checkclass.cpp | 2 +- test/testconstructors.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 9fc9bdc7863..dd96b4dc43c 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -372,7 +372,7 @@ void CheckClass::constructors() const Variable& var = *usage.var; if (diagVars.count(&var) == 0) - uninitVarError(scope->bodyStart, false, FunctionType::eConstructor, var.scope()->className, var.name(), false, false, true); + uninitVarError(var.nameToken(), false, FunctionType::eConstructor, var.scope()->className, var.name(), false, false, true); } } } diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 61916e1d0bb..7fb5889c88a 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -763,7 +763,7 @@ class TestConstructors : public TestFixture { check("struct S {\n" // #14546 " int a = 0, b;\n" "};\n"); - ASSERT_EQUALS("[test.cpp:1:10]: (warning) Member variable 'S::b' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:16]: (warning) Member variable 'S::b' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); check("struct S {\n" " int a, b;\n" From e277aba41ca11ba815df7403c81537612ac40e71 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 15 May 2026 19:17:47 +0200 Subject: [PATCH 107/493] Fix #14453 FP constParameterPointer with strchr() (#8554) --- cfg/std.cfg | 10 +++++----- test/cfg/std.c | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index e282dd99995..ec5fbb72548 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -4411,7 +4411,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + @@ -4444,7 +4444,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + @@ -4861,7 +4861,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -5044,7 +5044,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -5433,7 +5433,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + diff --git a/test/cfg/std.c b/test/cfg/std.c index 928d52bf116..997f8204f73 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -3519,6 +3519,13 @@ void invalidFunctionArg_strchr(const char *cs, int c) (void)strchr(cs, 256); } +void constParameterPointer_strchr(char *str) // #14453 +{ + char *sep = strchr(str, ':'); + if (sep) + *sep = '\0'; +} + void invalidFunctionArg_log10(float f, double d, const long double ld) { // cppcheck-suppress invalidFunctionArg From 7a9174637689297090c056150adab06f90a85ea7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 15 May 2026 22:45:04 +0200 Subject: [PATCH 108/493] Fix #14714, #14748 FN constParameterPointer (array member, dereference in ternary) (#8553) Co-authored-by: chrchr-github --- lib/checkother.cpp | 4 +++- test/testother.cpp | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index fb75d80fca7..0c4ce7d63cf 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1941,7 +1941,9 @@ void CheckOther::checkConstPointer() continue; if (deref != NONE) { const Token* gparent = parent->astParent(); - while (Token::simpleMatch(gparent, "[") && parent != gparent->astOperand2() && parent->str() == gparent->str()) + while (Token::simpleMatch(gparent, "[") && parent != gparent->astOperand2()) + gparent = gparent->astParent(); + while (Token::Match(gparent, "[?:]")) gparent = gparent->astParent(); if (deref == MEMBER) { if (!gparent) diff --git a/test/testother.cpp b/test/testother.cpp index c5a94a673fe..cfdcffe05d3 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4844,6 +4844,26 @@ class TestOther : public TestFixture { " return s->x ? 1 : 0;\n" "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n", errout_str()); + + check("struct S { int a[1][1]; };\n" // #14714 + "int f(S* s) {\n" + " return s->a[0][0] ? 1 : 0;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:10]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n", errout_str()); + + check("int f(int *p, int *q) {\n" // #14748 + " return p ? *p : *q;\n" + "}\n" + "void g(int *p, int *q) {\n" + " int& r = p ? *p : *q;\n" + " r = 0;\n" + "}\n" + "void h(int *p, int *q) {\n" + " i(p ? *p : *q);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:1:12]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n" + "[test.cpp:1:20]: (style) Parameter 'q' can be declared as pointer to const [constParameterPointer]\n", + errout_str()); } void constArray() { From f7f054932c7245d1f9c2a18c68396311ae97a836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sat, 16 May 2026 16:01:44 +0200 Subject: [PATCH 109/493] refs #14498 - do not create global static instances of the checks (#8555) --- Makefile | 160 ++++++++++++++++++----------------- cli/cmdlineparser.cpp | 3 +- lib/check.cpp | 43 +--------- lib/check.h | 10 +-- lib/check64bit.cpp | 5 -- lib/checkassert.cpp | 5 -- lib/checkautovariables.cpp | 6 -- lib/checkbool.cpp | 5 -- lib/checkbufferoverrun.cpp | 7 -- lib/checkclass.cpp | 5 -- lib/checkcondition.cpp | 5 -- lib/checkexceptionsafety.cpp | 5 -- lib/checkfunctions.cpp | 6 -- lib/checkinternal.cpp | 6 -- lib/checkinternal.h | 5 ++ lib/checkio.cpp | 5 -- lib/checkleakautovar.cpp | 5 -- lib/checkmemoryleak.cpp | 8 -- lib/checknullpointer.cpp | 5 -- lib/checkother.cpp | 5 -- lib/checkpostfixoperator.cpp | 6 -- lib/checks.cpp | 123 +++++++++++++++++++++++++++ lib/checks.h | 34 ++++++++ lib/checksizeof.cpp | 5 -- lib/checkstl.cpp | 5 -- lib/checkstring.cpp | 5 -- lib/checktype.cpp | 5 -- lib/checkuninitvar.cpp | 5 -- lib/checkunusedvar.cpp | 5 -- lib/checkvaarg.cpp | 8 -- lib/cppcheck.cpp | 13 +-- lib/cppcheck.vcxproj | 2 + oss-fuzz/Makefile | 6 +- test/fixture.h | 3 +- test/testcheck.cpp | 15 +--- test/testgarbage.cpp | 3 +- 36 files changed, 271 insertions(+), 276 deletions(-) create mode 100644 lib/checks.cpp create mode 100644 lib/checks.h diff --git a/Makefile b/Makefile index bb006c36fea..932a1ad302b 100644 --- a/Makefile +++ b/Makefile @@ -228,6 +228,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/checknullpointer.o \ $(libcppdir)/checkother.o \ $(libcppdir)/checkpostfixoperator.o \ + $(libcppdir)/checks.o \ $(libcppdir)/checksizeof.o \ $(libcppdir)/checkstl.o \ $(libcppdir)/checkstring.o \ @@ -560,6 +561,9 @@ $(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib $(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp +$(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/standards.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp + $(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp @@ -590,7 +594,7 @@ $(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h l $(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h +$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp $(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h @@ -695,7 +699,7 @@ $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathli frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_FE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ frontend/frontend.cpp -cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h +cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h @@ -728,238 +732,238 @@ cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h +test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp -test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/main.cpp test/options.o: test/options.cpp lib/config.h lib/timer.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp -test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp -test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp -test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp -test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp -test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp -test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp -test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp -test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp -test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheckersreport.cpp -test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp -test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp -test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp -test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp -test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp -test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h +test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp -test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp -test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexecutor.cpp -test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp -test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp -test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp -test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp -test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp -test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h +test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp -test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp -test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkinternal.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp -test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkio.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp -test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkleakautovar.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp -test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp -test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp -test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkmemoryleak.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp -test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/checks.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp -test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp -test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp -test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp -test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpathmatch.cpp -test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp -test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp -test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp -test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp -test/testprogrammemory.o: test/testprogrammemory.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testprogrammemory.o: test/testprogrammemory.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprogrammemory.cpp -test/testregex.o: test/testregex.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testregex.o: test/testregex.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testregex.cpp -test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsarifreport.cpp -test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp -test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytemplate.cpp -test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytokens.cpp -test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytypedef.cpp -test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifyusing.cpp -test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp -test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp -test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp -test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp -test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsummaries.cpp -test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp -test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp -test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp -test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h +test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp -test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtoken.cpp -test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenize.cpp -test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenlist.cpp -test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp -test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp -test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp -test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp -test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp -test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp -test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp -test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp -test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp -test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvfvalue.cpp externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 2ebef4ba3c9..27cfe08d871 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -20,6 +20,7 @@ #include "addoninfo.h" #include "check.h" +#include "checks.h" #include "checkers.h" #include "color.h" #include "config.h" @@ -359,7 +360,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a if (std::strcmp(argv[i], "--doc") == 0) { std::ostringstream doc; // Get documentation.. - for (const Check * const c : Check::instances()) { + for (const Check * const c : CheckInstances::get()) { const std::string& name(c->name()); const std::string info(c->classInfo()); if (!name.empty() && !info.empty()) diff --git a/lib/check.cpp b/lib/check.cpp index f639ba226bd..4033378e927 100644 --- a/lib/check.cpp +++ b/lib/check.cpp @@ -26,34 +26,15 @@ #include "tokenize.h" #include "vfvalue.h" -#include #include #include -#include #include //--------------------------------------------------------------------------- -Check::Check(const std::string &aname) - : mName(aname) -{ - { - const auto it = std::find_if(instances().begin(), instances().end(), [&](const Check *i) { - return i->name() == aname; - }); - if (it != instances().end()) - throw std::runtime_error("'" + aname + "' instance already exists"); - } - - // make sure the instances are sorted - const auto it = std::find_if(instances().begin(), instances().end(), [&](const Check* i) { - return i->name() > aname; - }); - if (it == instances().end()) - instances_internal().push_back(this); - else - instances_internal().insert(it, this); -} +Check::Check(std::string aname) + : mName(std::move(aname)) +{} void Check::writeToErrorList(const ErrorMessage &errmsg) { @@ -88,24 +69,6 @@ bool Check::wrongData(const Token *tok, const char *str) return true; } -std::list &Check::instances_internal() -{ -#ifdef __SVR4 - // Under Solaris, destructors are called in wrong order which causes a segmentation fault. - // This fix ensures pointer remains valid and reachable until program terminates. - static std::list *_instances= new std::list; - return *_instances; -#else - static std::list _instances; - return _instances; -#endif -} - -const std::list &Check::instances() -{ - return instances_internal(); -} - std::string Check::getMessageId(const ValueFlow::Value &value, const char id[]) { if (value.condition != nullptr) diff --git a/lib/check.h b/lib/check.h index 8c3e42a69de..9a50e64baa1 100644 --- a/lib/check.h +++ b/lib/check.h @@ -59,7 +59,7 @@ class Tokenizer; class CPPCHECKLIB Check { public: /** This constructor is used when registering the CheckClass */ - explicit Check(const std::string &aname); + explicit Check(std::string aname); protected: /** This constructor is used when running checks. */ @@ -70,17 +70,11 @@ class CPPCHECKLIB Check { static std::list &instances_internal(); public: - virtual ~Check() { - if (!mTokenizer) - instances_internal().remove(this); - } + virtual ~Check() = default; Check(const Check &) = delete; Check& operator=(const Check &) = delete; - /** List of registered check classes. This is used by Cppcheck to run checks and generate documentation */ - static const std::list &instances(); - /** run checks, the token list is not simplified */ virtual void runChecks(const Tokenizer &, ErrorLogger *) = 0; diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index d203eb5f279..b33ab5bdbcb 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -36,11 +36,6 @@ // CWE ids used static const CWE CWE758(758U); // Reliance on Undefined, Unspecified, or Implementation-Defined Behavior -// Register this check class (by creating a static instance of it) -namespace { - Check64BitPortability instance; -} - static bool is32BitIntegerReturn(const Function* func, const Settings* settings) { if (settings->platform.sizeof_pointer != 8) diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index 3ab55967ede..ce2d7c62169 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -39,11 +39,6 @@ // CWE ids used static const CWE CWE398(398U); // Indicator of Poor Code Quality -// Register this check class (by creating a static instance of it) -namespace { - CheckAssert instance; -} - void CheckAssert::assertWithSideEffects() { if (!mSettings->severity.isEnabled(Severity::warning)) diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index e778f3d5959..fdc5deceefa 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -39,12 +39,6 @@ //--------------------------------------------------------------------------- - -// Register this check class into cppcheck by creating a static instance of it.. -namespace { - CheckAutoVariables instance; -} - static const CWE CWE398(398U); // Indicator of Poor Code Quality static const CWE CWE562(562U); // Return of Stack Variable Address static const CWE CWE590(590U); // Free of Memory not on the Heap diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index 93e501416aa..c9a66876317 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -32,11 +32,6 @@ #include //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckBool instance; -} - static const CWE CWE398(398U); // Indicator of Poor Code Quality static const CWE CWE571(571U); // Expression is Always True static const CWE CWE587(587U); // Assignment of a Fixed Address to a Pointer diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 642e40bce76..3ba41882316 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -50,13 +50,6 @@ //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckBufferOverrun instance; -} - -//--------------------------------------------------------------------------- - // CWE ids used: static const CWE CWE131(131U); // Incorrect Calculation of Buffer Size static const CWE CWE170(170U); // Improper Null Termination diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index dd96b4dc43c..9c0ad424112 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -43,11 +43,6 @@ //--------------------------------------------------------------------------- -// Register CheckClass.. -namespace { - CheckClass instance; -} - static const CWE CWE398(398U); // Indicator of Poor Code Quality static const CWE CWE404(404U); // Improper Resource Shutdown or Release static const CWE CWE665(665U); // Improper Initialization diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index d0913963cca..cec3293ad27 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -52,11 +52,6 @@ static const CWE CWE571(571U); // Expression is Always True //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckCondition instance; -} - bool CheckCondition::diag(const Token* tok, bool insert) { if (!tok) diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index 34303cc0f4a..6da5281e80a 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -34,11 +34,6 @@ //--------------------------------------------------------------------------- -// Register CheckExceptionSafety.. -namespace { - CheckExceptionSafety instance; -} - static const CWE CWE398(398U); // Indicator of Poor Code Quality static const CWE CWE703(703U); // Improper Check or Handling of Exceptional Conditions static const CWE CWE480(480U); // Use of Incorrect Operator diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 7611ea7eee4..733b868814e 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -44,12 +44,6 @@ //--------------------------------------------------------------------------- - -// Register this check class (by creating a static instance of it) -namespace { - CheckFunctions instance; -} - static const CWE CWE252(252U); // Unchecked Return Value static const CWE CWE477(477U); // Use of Obsolete Functions static const CWE CWE758(758U); // Reliance on Undefined, Unspecified, or Implementation-Defined Behavior diff --git a/lib/checkinternal.cpp b/lib/checkinternal.cpp index f289044b102..ed39b4db96a 100644 --- a/lib/checkinternal.cpp +++ b/lib/checkinternal.cpp @@ -31,12 +31,6 @@ #include #include -// Register this check class (by creating a static instance of it). -// Disabled in release builds -namespace { - CheckInternal instance; -} - void CheckInternal::checkTokenMatchPatterns() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); diff --git a/lib/checkinternal.h b/lib/checkinternal.h index 1fc97bcb247..d62d9698b8d 100644 --- a/lib/checkinternal.h +++ b/lib/checkinternal.h @@ -22,6 +22,8 @@ #define checkinternalH //--------------------------------------------------------------------------- +#ifdef CHECK_INTERNAL + #include "check.h" #include "config.h" @@ -93,4 +95,7 @@ class CPPCHECKLIB CheckInternal : public Check { }; /// @} //--------------------------------------------------------------------------- + +#endif // CHECK_INTERNAL + #endif // checkinternalH diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 8b3c835caf3..32bedf8024f 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -45,11 +45,6 @@ //--------------------------------------------------------------------------- -// Register CheckIO.. -namespace { - CheckIO instance; -} - // CVE ID used: static const CWE CWE119(119U); // Improper Restriction of Operations within the Bounds of a Memory Buffer static const CWE CWE398(398U); // Indicator of Poor Code Quality diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 803ea9967a3..1c9a7283161 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -45,11 +45,6 @@ //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckLeakAutoVar instance; -} - static const CWE CWE672(672U); static const CWE CWE415(415U); diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 1a6ef787eb6..b2f97693cd6 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -37,14 +37,6 @@ //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckMemoryLeakInFunction instance1; - CheckMemoryLeakInClass instance2; - CheckMemoryLeakStructMember instance3; - CheckMemoryLeakNoVar instance4; -} - // CWE ID used: static const CWE CWE398(398U); // Indicator of Poor Code Quality static const CWE CWE401(401U); // Improper Release of Memory Before Removing Last Reference ('Memory Leak') diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index beb9d5d77a3..5bd602488b4 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -47,11 +47,6 @@ static const CWE CWE_NULL_POINTER_DEREFERENCE(476U); static const CWE CWE_INCORRECT_CALCULATION(682U); -// Register this check class (by creating a static instance of it) -namespace { - CheckNullPointer instance; -} - //--------------------------------------------------------------------------- static bool checkNullpointerFunctionCallPlausibility(const Function* func, unsigned int arg) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 0c4ce7d63cf..b454c4410cf 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -49,11 +49,6 @@ //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckOther instance; -} - static const CWE CWE128(128U); // Wrap-around Error static const CWE CWE131(131U); // Incorrect Calculation of Buffer Size static const CWE CWE197(197U); // Numeric Truncation Error diff --git a/lib/checkpostfixoperator.cpp b/lib/checkpostfixoperator.cpp index c6c9ccba77b..d771177b2d2 100644 --- a/lib/checkpostfixoperator.cpp +++ b/lib/checkpostfixoperator.cpp @@ -34,12 +34,6 @@ //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckPostfixOperator instance; -} - - // CWE ids used static const CWE CWE398(398U); // Indicator of Poor Code Quality diff --git a/lib/checks.cpp b/lib/checks.cpp new file mode 100644 index 00000000000..169832c2745 --- /dev/null +++ b/lib/checks.cpp @@ -0,0 +1,123 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2026 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "checks.h" + +#include "check64bit.h" +#include "checkassert.h" +#include "checkautovariables.h" +#include "checkbool.h" +#include "checkbufferoverrun.h" +#include "checkclass.h" +#include "checkcondition.h" +#include "checkexceptionsafety.h" +#include "checkfunctions.h" +#include "checkinternal.h" +#include "checkio.h" +#include "checkleakautovar.h" +#include "checkmemoryleak.h" +#include "checknullpointer.h" +#include "checkother.h" +#include "checkpostfixoperator.h" +#include "checksizeof.h" +#include "checkstl.h" +#include "checkstring.h" +#include "checktype.h" +#include "checkuninitvar.h" +#include "checkunusedvar.h" +#include "checkvaarg.h" + +class CheckInstancesImpl +{ +private: +/* *INDENT-OFF* */ +#define UPI(c) std::unique_ptr m##c{new c} +/* *INDENT-ON* */ + UPI(Check64BitPortability); + UPI(CheckAssert); + UPI(CheckAutoVariables); + UPI(CheckBool); + UPI(CheckBufferOverrun); + UPI(CheckClass); + UPI(CheckCondition); + UPI(CheckExceptionSafety); + UPI(CheckFunctions); +#ifdef CHECK_INTERNAL + UPI(CheckInternal); +#endif + UPI(CheckIO); + UPI(CheckLeakAutoVar); + UPI(CheckMemoryLeakInFunction); + UPI(CheckMemoryLeakInClass); + UPI(CheckMemoryLeakStructMember); + UPI(CheckMemoryLeakNoVar); + UPI(CheckNullPointer); + UPI(CheckOther); + UPI(CheckPostfixOperator); + UPI(CheckSizeof); + UPI(CheckStl); + UPI(CheckString); + UPI(CheckType); + UPI(CheckUninitVar); + UPI(CheckUnusedVar); + UPI(CheckVaarg); +#undef UPI + +public: + const std::list& get() const + { + static std::list s_checks{ + mCheck64BitPortability.get(), + mCheckAssert.get(), + mCheckAutoVariables.get(), + mCheckBool.get(), + mCheckBufferOverrun.get(), + mCheckClass.get(), + mCheckCondition.get(), + mCheckExceptionSafety.get(), + mCheckFunctions.get(), + #ifdef CHECK_INTERNAL + mCheckInternal.get(), + #endif + mCheckIO.get(), + mCheckLeakAutoVar.get(), + mCheckMemoryLeakInFunction.get(), + mCheckMemoryLeakInClass.get(), + mCheckMemoryLeakStructMember.get(), + mCheckMemoryLeakNoVar.get(), + mCheckNullPointer.get(), + mCheckOther.get(), + mCheckPostfixOperator.get(), + mCheckSizeof.get(), + mCheckStl.get(), + mCheckString.get(), + mCheckType.get(), + mCheckUninitVar.get(), + mCheckUnusedVar.get(), + mCheckVaarg.get() + }; + + return s_checks; + } +}; + +const std::list& CheckInstances::get() +{ + static const CheckInstancesImpl s_impl; + return s_impl.get(); +} diff --git a/lib/checks.h b/lib/checks.h new file mode 100644 index 00000000000..ec4a78c2008 --- /dev/null +++ b/lib/checks.h @@ -0,0 +1,34 @@ +/* -*- C++ -*- + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2026 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef checksH +#define checksH + +#include "config.h" + +#include + +class Check; + +namespace CheckInstances +{ + /** List of registered check classes. This is used by Cppcheck to run checks and generate documentation */ + CPPCHECKLIB const std::list& get(); +}; + +#endif // checksH diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index f7c0d44d399..134cca92b7f 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -34,11 +34,6 @@ //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckSizeof instance; -} - // CWE IDs used: static const CWE CWE467(467U); // Use of sizeof() on a Pointer Type static const CWE CWE682(682U); // Incorrect Calculation diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index faa6f25911d..b1543f4af37 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -46,11 +46,6 @@ #include #include -// Register this check class (by creating a static instance of it) -namespace { - CheckStl instance; -} - // CWE IDs used: static const CWE CWE398(398U); // Indicator of Poor Code Quality static const CWE CWE597(597U); // Use of Wrong Operator in String Comparison diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 64b575df72d..580597bb10d 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -36,11 +36,6 @@ //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckString instance; -} - // CWE ids used: static const CWE CWE570(570U); // Expression is Always False static const CWE CWE571(571U); // Expression is Always True diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 3f42bf075ef..eb222fbe6f5 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -44,11 +44,6 @@ //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckType instance; -} - //--------------------------------------------------------------------------- // Checking for shift by too many bits //--------------------------------------------------------------------------- diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index a7a4d8b1bf3..b88debda6f8 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -50,11 +50,6 @@ // CWE ids used: static const CWE CWE_USE_OF_UNINITIALIZED_VARIABLE(457U); -// Register this check class (by creating a static instance of it) -namespace { - CheckUninitVar instance; -} - //--------------------------------------------------------------------------- // get ast parent, skip possible address-of and casts diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 6dd98de078e..9531237a208 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -40,11 +40,6 @@ #include //--------------------------------------------------------------------------- -// Register this check class (by creating a static instance of it) -namespace { - CheckUnusedVar instance; -} - static const CWE CWE563(563U); // Assignment to Variable without Use ('Unused Variable') static const CWE CWE665(665U); // Improper Initialization diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index 8151957a7d7..e6efc8f5ed9 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -30,14 +30,6 @@ #include #include -//--------------------------------------------------------------------------- - -// Register this check class (by creating a static instance of it) -namespace { - CheckVaarg instance; -} - - //--------------------------------------------------------------------------- // Ensure that correct parameter is passed to va_start() //--------------------------------------------------------------------------- diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 652bd4f5bef..f39e64a938f 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -21,6 +21,7 @@ #include "addoninfo.h" #include "analyzerinfo.h" #include "check.h" +#include "checks.h" #include "checkunusedfunctions.h" #include "clangimport.h" #include "color.h" @@ -1338,7 +1339,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation const std::time_t maxTime = mSettings.checksMaxTime > 0 ? std::time(nullptr) + mSettings.checksMaxTime : 0; // call all "runChecks" in all registered Check classes - for (Check * const c : Check::instances()) { + for (Check * const c : CheckInstances::get()) { if (Settings::terminated()) return; @@ -1387,7 +1388,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation } if (!doUnusedFunctionOnly) { - for (const Check * const c : Check::instances()) { + for (const Check * const c : CheckInstances::get()) { if (Check::FileInfo * const fi = c->getFileInfo(tokenizer, mSettings, currentConfig)) { if (analyzerInformation) analyzerInformation->setFileInfo(c->name(), fi->toString()); @@ -1712,7 +1713,7 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) s.addEnabled("all"); // call all "getErrorMessages" in all registered Check classes - for (const Check * const c : Check::instances()) + for (const Check * const c : CheckInstances::get()) c->getErrorMessages(&errorlogger, &s); CheckUnusedFunctions::getErrorMessages(errorlogger); @@ -1830,7 +1831,7 @@ bool CppCheck::analyseWholeProgram() } } - for (Check * const c : Check::instances()) + for (Check * const c : CheckInstances::get()) errors |= c->analyseWholeProgram(ctu, mFileInfo, mSettings, mErrorLogger); // TODO: ctu } @@ -1861,7 +1862,7 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st ctuFileInfo.loadFromXml(e); return; } - for (const Check *check : Check::instances()) { + for (const Check *check : CheckInstances::get()) { if (checkattr == check->name()) { if (Check::FileInfo* fi = check->loadFileInfoFromXml(e)) { fi->file0 = filesTxtInfo.sourceFile; @@ -1878,7 +1879,7 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st } else { // Analyse the tokens - for (Check * const c : Check::instances()) + for (Check * const c : CheckInstances::get()) c->analyseWholeProgram(ctuFileInfo, fileInfoList, mSettings, mErrorLogger); } diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index b0e52a814fe..12bd4898d4a 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -57,6 +57,7 @@ + @@ -130,6 +131,7 @@ + diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index b2a42dba2a7..c93b8694065 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -65,6 +65,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/checknullpointer.o \ $(libcppdir)/checkother.o \ $(libcppdir)/checkpostfixoperator.o \ + $(libcppdir)/checks.o \ $(libcppdir)/checksizeof.o \ $(libcppdir)/checkstl.o \ $(libcppdir)/checkstring.o \ @@ -230,6 +231,9 @@ $(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/addoninfo.h ../lib/astut $(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp +$(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/standards.h ../lib/vfvalue.h + $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp + $(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp @@ -260,7 +264,7 @@ $(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/c $(libcppdir)/color.o: ../lib/color.cpp ../lib/color.h ../lib/config.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h +$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checks.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp $(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h diff --git a/test/fixture.h b/test/fixture.h index fe767a3a16a..bbf986d8e4d 100644 --- a/test/fixture.h +++ b/test/fixture.h @@ -21,6 +21,7 @@ #define fixtureH #include "check.h" +#include "checks.h" #include "color.h" #include "config.h" #include "errorlogger.h" @@ -138,7 +139,7 @@ class TestFixture : public ErrorLogger { template static T& getCheck() { - for (Check *check : Check::instances()) { + for (Check *check : CheckInstances::get()) { //cppcheck-suppress useStlAlgorithm if (T* c = dynamic_cast(check)) return *c; diff --git a/test/testcheck.cpp b/test/testcheck.cpp index b07c7e0db0c..3ae2cad3d8f 100644 --- a/test/testcheck.cpp +++ b/test/testcheck.cpp @@ -17,6 +17,7 @@ */ #include "check.h" +#include "checks.h" #include "fixture.h" #include @@ -28,23 +29,11 @@ class TestCheck : public TestFixture { private: void run() override { - TEST_CASE(instancesSorted); TEST_CASE(classInfoFormat); } - void instancesSorted() const { - const auto& checks = Check::instances(); - for (auto i = checks.cbegin(); i != checks.cend(); ++i) { - auto j = i; - ++j; - if (j != checks.cend()) { - ASSERT_EQUALS(true, (*i)->name() < (*j)->name()); - } - } - } - void classInfoFormat() const { - for (const Check * const c : Check::instances()) { + for (const Check * const c : CheckInstances::get()) { const std::string info = c->classInfo(); if (!info.empty()) { ASSERT('\n' != info[0]); // No \n in the beginning diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 38baa798fed..289b22b284e 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -17,6 +17,7 @@ */ #include "check.h" +#include "checks.h" #include "errortypes.h" #include "fixture.h" #include "helpers.h" @@ -285,7 +286,7 @@ class TestGarbage : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // call all "runChecks" in all registered Check classes - for (Check * const c : Check::instances()) { + for (Check * const c : CheckInstances::get()) { c->runChecks(tokenizer, this); } From d9016615387e63473eaf478d7eef10c38e55dad0 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 16 May 2026 19:12:58 +0200 Subject: [PATCH 110/493] Fix #14697 FN uninitMemberVarNoCtor when mixing (un)initialized member variables (#8557) After #8556 --------- Co-authored-by: chrchr-github --- lib/checkclass.cpp | 9 ++++++++- test/testconstructors.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 9c0ad424112..3313fb636ed 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -346,6 +346,8 @@ void CheckClass::constructors() // Variables with default initializers bool hasAnyDefaultInit = false; + bool hasAnySelfInit = false; + const bool cpp14OrLater = mSettings->standards.cpp >= Standards::CPP14; for (Usage& usage : usageList) { const Variable& var = *usage.var; @@ -353,9 +355,11 @@ void CheckClass::constructors() if (var.hasDefault()) { usage.init = true; hasAnyDefaultInit = true; + } else if (cpp14OrLater && !hasAnySelfInit && isInitialized(usage, FunctionType::eConstructor)) { + hasAnySelfInit = true; } } - if (!hasAnyDefaultInit) + if (!hasAnyDefaultInit && !hasAnySelfInit) continue; handleUnionMembers(usageList); @@ -366,6 +370,9 @@ void CheckClass::constructors() continue; const Variable& var = *usage.var; + if (var.typeScope() && var.typeScope()->numConstructors > 0) + continue; + if (diagVars.count(&var) == 0) uninitVarError(var.nameToken(), false, FunctionType::eConstructor, var.scope()->className, var.name(), false, false, true); } diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 7fb5889c88a..0eb91ba8cca 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -769,6 +769,34 @@ class TestConstructors : public TestFixture { " int a, b;\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " explicit S(int);\n" + " S(const S&);\n" + " int i;\n" + "};\n" + "struct T {\n" + " S s;\n" + " int j{};\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + const char code[] = "struct S { int i = 0; };\n" // #14697 + "struct T {\n" + " S s;\n" + " int j;\n" + "};\n" + "struct U {\n" + " std::string a;\n" + " int k;\n" + "};\n"; + const Settings s = settingsBuilder(settings).cpp(Standards::CPP11).build(); + check(code, s); + ASSERT_EQUALS("", errout_str()); + check(code); + ASSERT_EQUALS("[test.cpp:4:9]: (warning) Member variable 'T::j' has no initializer. [uninitMemberVarNoCtor]\n" + "[test.cpp:8:9]: (warning) Member variable 'U::k' has no initializer. [uninitMemberVarNoCtor]\n", + errout_str()); } // ticket #4290 "False Positive: style (noConstructor): The class 'foo' does not have a constructor." From f4cc43a6770d9cdc53c519fabda7e4f9f679c078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Mon, 18 May 2026 10:38:52 +0200 Subject: [PATCH 111/493] ProcessExecutor: avoid explicit usage of suppressions (#4989) The `hasToLog()` call performs this check. --- cli/processexecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index a410f58d5ea..e77a75ba39e 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -515,7 +515,7 @@ void ProcessExecutor::reportInternalChildErr(const std::string &childname, const "cppcheckError", Certainty::normal); - if (!mSuppressions.nomsg.isSuppressed(errmsg, {})) + if (hasToLog(errmsg)) mErrorLogger.reportErr(errmsg); } From 39d9c01abd888f82984c083666fdaa80b9b9b12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Mon, 18 May 2026 10:39:19 +0200 Subject: [PATCH 112/493] testrunner: do not use global check instances (#8561) --- Makefile | 148 +++++++++++++++++------------------ test/fixture.h | 16 +--- test/testassert.cpp | 4 +- test/testautovariables.cpp | 3 +- test/testbool.cpp | 4 +- test/testbufferoverrun.cpp | 19 ++--- test/testclass.cpp | 7 +- test/testcondition.cpp | 11 +-- test/testexceptionsafety.cpp | 4 +- test/testfunctions.cpp | 3 +- test/testinternal.cpp | 4 +- test/testio.cpp | 3 +- test/testleakautovar.cpp | 32 +++----- test/testnullpointer.cpp | 24 +++--- test/testother.cpp | 12 +-- test/testsizeof.cpp | 8 +- test/teststl.cpp | 10 ++- test/teststring.cpp | 4 +- test/testtype.cpp | 12 +-- test/testuninitvar.cpp | 3 +- test/testvaarg.cpp | 4 +- 21 files changed, 161 insertions(+), 174 deletions(-) diff --git a/Makefile b/Makefile index 932a1ad302b..5a348e27001 100644 --- a/Makefile +++ b/Makefile @@ -732,238 +732,238 @@ cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h +test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp -test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/main.cpp test/options.o: test/options.cpp lib/config.h lib/timer.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp -test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp -test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp -test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp -test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp -test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp -test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp -test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp -test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheckersreport.cpp -test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp -test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp -test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp -test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp -test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp -test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h +test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp -test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp -test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexecutor.cpp -test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp -test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp -test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp -test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp -test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h +test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp -test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp -test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkinternal.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp -test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkio.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp -test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkleakautovar.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp -test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp -test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp -test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkmemoryleak.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp -test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/checks.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp -test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp -test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp -test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp -test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpathmatch.cpp -test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp -test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp -test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp -test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp -test/testprogrammemory.o: test/testprogrammemory.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testprogrammemory.o: test/testprogrammemory.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprogrammemory.cpp -test/testregex.o: test/testregex.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testregex.o: test/testregex.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testregex.cpp -test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsarifreport.cpp -test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp -test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytemplate.cpp -test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytokens.cpp -test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytypedef.cpp -test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifyusing.cpp -test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp -test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp -test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp -test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp -test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsummaries.cpp -test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp -test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp -test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp -test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h +test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp -test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtoken.cpp -test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenize.cpp -test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenlist.cpp -test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp -test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp -test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp -test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp -test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp -test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp -test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp -test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp -test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp -test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvfvalue.cpp externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h diff --git a/test/fixture.h b/test/fixture.h index bbf986d8e4d..b927dc5de65 100644 --- a/test/fixture.h +++ b/test/fixture.h @@ -21,7 +21,6 @@ #define fixtureH #include "check.h" -#include "checks.h" #include "color.h" #include "config.h" #include "errorlogger.h" @@ -33,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -136,21 +134,13 @@ class TestFixture : public ErrorLogger { void processOptions(const options& args); - template - static T& getCheck() + static Check& getCheck(Check& check) { - for (Check *check : CheckInstances::get()) { - //cppcheck-suppress useStlAlgorithm - if (T* c = dynamic_cast(check)) - return *c; - } - throw std::runtime_error("instance not found"); + return check; } - template - static void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) + static void runChecks(Check& check, const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - Check& check = getCheck(); check.runChecks(tokenizer, errorLogger); } diff --git a/test/testassert.cpp b/test/testassert.cpp index 412a7cb750b..e14825e46b2 100644 --- a/test/testassert.cpp +++ b/test/testassert.cpp @@ -39,8 +39,8 @@ class TestAssert : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - runChecks(tokenizer, this); + CheckAssert check; + runChecks(check, tokenizer, this); } void run() override { diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 008dc645419..2474c2fe6a5 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -47,7 +47,8 @@ class TestAutoVariables : public TestFixture { SimpleTokenizer tokenizer(settings1, *this, options.cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - runChecks(tokenizer, this); + CheckAutoVariables check; + runChecks(check, tokenizer, this); } void run() override { diff --git a/test/testbool.cpp b/test/testbool.cpp index 61bc1b36d9e..ccf4d7860c4 100644 --- a/test/testbool.cpp +++ b/test/testbool.cpp @@ -88,8 +88,8 @@ class TestBool : public TestFixture { SimpleTokenizer tokenizer(settings, *this, options.cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check... - runChecks(tokenizer, this); + CheckBool check; + runChecks(check, tokenizer, this); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 8a7c1d311b0..5d545606387 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -56,8 +56,8 @@ class TestBufferOverrun : public TestFixture { SimpleTokenizer tokenizer(settings, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for buffer overruns.. - runChecks(tokenizer, this); + CheckBufferOverrun check; + runChecks(check, tokenizer, this); } // TODO: get rid of this @@ -66,8 +66,8 @@ class TestBufferOverrun : public TestFixture { SimpleTokenizer tokenizer(settings0_i, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for buffer overruns.. - runChecks(tokenizer, this); + CheckBufferOverrun check; + runChecks(check, tokenizer, this); } #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) @@ -79,8 +79,8 @@ class TestBufferOverrun : public TestFixture { // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Check for buffer overruns.. - runChecks(tokenizer, this); + CheckBufferOverrun check; + runChecks(check, tokenizer, this); } void run() override { @@ -5169,7 +5169,8 @@ class TestBufferOverrun : public TestFixture { void getErrorMessages() { // Ticket #2292: segmentation fault when using --errorlist - const Check& c = getCheck(); + CheckBufferOverrun check; + const Check& c = getCheck(check); c.getErrorMessages(this, nullptr); // we are not interested in the output - just consume it ignore_errout(); @@ -5362,9 +5363,9 @@ class TestBufferOverrun : public TestFixture { CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); - // Check code.. std::list fileInfo; - Check& c = getCheck(); + CheckBufferOverrun check; + Check& c = getCheck(check); fileInfo.push_back(c.getFileInfo(tokenizer, settings0, "")); c.analyseWholeProgram(*ctu, fileInfo, settings0, *this); // TODO: check result while (!fileInfo.empty()) { diff --git a/test/testclass.cpp b/test/testclass.cpp index 2cecdfe80f6..c1b801c208b 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -9278,7 +9278,8 @@ class TestClass : public TestFixture { void ctu(const std::vector &code) { - Check &check = getCheck(); + CheckClass checkClass; + Check &check = getCheck(checkClass); // getFileInfo std::list fileInfo; @@ -9330,8 +9331,8 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings1, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - const Check& c = getCheck(); + CheckClass check; + const Check& c = getCheck(check); Check::FileInfo * fileInfo = (c.getFileInfo)(tokenizer, settings1, ""); delete fileInfo; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index f0764dd2bd6..9a15349aff0 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -149,8 +149,8 @@ class TestCondition : public TestFixture { // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Run checks.. - runChecks(tokenizer, this); + CheckCondition check; + runChecks(check, tokenizer, this); } #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) @@ -162,8 +162,8 @@ class TestCondition : public TestFixture { // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Run checks.. - runChecks(tokenizer, this); + CheckCondition check; + runChecks(check, tokenizer, this); } void assignAndCompare() { @@ -527,7 +527,8 @@ class TestCondition : public TestFixture { SimpleTokenizer tokenizer(settings1, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - runChecks(tokenizer, this); + CheckCondition check; + runChecks(check, tokenizer, this); } void multicompare() { diff --git a/test/testexceptionsafety.cpp b/test/testexceptionsafety.cpp index 58b26ecbc27..46c995c231b 100644 --- a/test/testexceptionsafety.cpp +++ b/test/testexceptionsafety.cpp @@ -75,8 +75,8 @@ class TestExceptionSafety : public TestFixture { SimpleTokenizer tokenizer(settings1, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check char variable usage.. - runChecks(tokenizer, this); + CheckExceptionSafety check; + runChecks(check, tokenizer, this); } void destructors() { diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index 8bbd3d92c6b..9ddb4c1f43c 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -132,7 +132,8 @@ class TestFunctions : public TestFixture { SimpleTokenizer tokenizer(s, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - runChecks(tokenizer, this); + CheckFunctions check; + runChecks(check, tokenizer, this); } void prohibitedFunctions_posix() { diff --git a/test/testinternal.cpp b/test/testinternal.cpp index 009129c5dc1..10431adcd38 100644 --- a/test/testinternal.cpp +++ b/test/testinternal.cpp @@ -56,8 +56,8 @@ class TestInternal : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - runChecks(tokenizer, this); + CheckInternal check; + runChecks(check, tokenizer, this); } void simplePatternInTokenMatch() { diff --git a/test/testio.cpp b/test/testio.cpp index 02180f12376..67f7aad7fe5 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -113,7 +113,8 @@ class TestIO : public TestFixture { checkIO.checkWrongPrintfScanfArguments(); return; } - runChecks(tokenizer, this); + CheckIO check; + runChecks(check, tokenizer, this); } void coutCerrMisusage() { diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index b038270dcb7..265e31bf3c2 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -226,23 +226,17 @@ class TestLeakAutoVar : public TestFixture { template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { const Settings& settings1 = options.s ? *options.s : settings; - - // Tokenize.. - SimpleTokenizer tokenizer(settings1, *this, options.cpp); - ASSERT_LOC(tokenizer.tokenize(code), file, line); - - // Check for leaks.. - runChecks(tokenizer, this); + check_(file, line, code, settings1, options.cpp); } template - void check_(const char* file, int line, const char (&code)[size], const Settings & s) { + void check_(const char* file, int line, const char (&code)[size], const Settings & s, bool cpp = true) { // Tokenize.. - SimpleTokenizer tokenizer(s, *this); + SimpleTokenizer tokenizer(s, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for leaks.. - runChecks(tokenizer, this); + CheckLeakAutoVar check; + runChecks(check, tokenizer, this); } void assign1() { @@ -3272,8 +3266,8 @@ class TestLeakAutoVarRecursiveCountLimit : public TestFixture { // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Check for leaks.. - runChecks(tokenizer, this); + CheckLeakAutoVar check; + runChecks(check, tokenizer, this); } void run() override { @@ -3319,8 +3313,8 @@ class TestLeakAutoVarStrcpy : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for leaks.. - runChecks(tokenizer, this); + CheckLeakAutoVar check; + runChecks(check, tokenizer, this); } void run() override { @@ -3424,8 +3418,8 @@ class TestLeakAutoVarWindows : public TestFixture { SimpleTokenizer tokenizer(settings, *this, false); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for leaks.. - runChecks(tokenizer, this); + CheckLeakAutoVar check; + runChecks(check, tokenizer, this); } void run() override { @@ -3497,8 +3491,8 @@ class TestLeakAutoVarPosix : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for leaks.. - runChecks(tokenizer, this); + CheckLeakAutoVar check; + runChecks(check, tokenizer, this); } void run() override { diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index c025d7462d4..a154bd0d9c2 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -190,23 +190,17 @@ class TestNullPointer : public TestFixture { template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { const Settings& settings1 = options.inconclusive ? settings_i : settings; - - // Tokenize.. - SimpleTokenizer tokenizer(settings1, *this, options.cpp); - ASSERT_LOC(tokenizer.tokenize(code), file, line); - - // Check for null pointer dereferences.. - runChecks(tokenizer, this); + check_(file, line, code, settings1, options.cpp); } template - void check_(const char* file, int line, const char (&code)[size], bool cpp, const Settings& s) { + void check_(const char* file, int line, const char (&code)[size], const Settings& s, bool cpp = true) { // Tokenize.. SimpleTokenizer tokenizer(s, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for null pointer dereferences.. - runChecks(tokenizer, this); + CheckNullPointer check; + runChecks(check, tokenizer, this); } #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) @@ -217,8 +211,8 @@ class TestNullPointer : public TestFixture { // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Check for null pointer dereferences.. - runChecks(tokenizer, this); + CheckNullPointer check; + runChecks(check, tokenizer, this); } @@ -1349,7 +1343,7 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: i [nullPointer]\n", errout_str()); const Settings s = settingsBuilder(settings).c(Standards::C17).build(); - check(code, false, s); // C17 file => nullptr does not mean NULL + check(code, s, false); // C17 file => nullptr does not mean NULL ASSERT_EQUALS("", errout_str()); check(code, dinit(CheckOptions, $.cpp = false)); @@ -4698,9 +4692,9 @@ class TestNullPointer : public TestFixture { CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); - // Check code.. + CheckNullPointer check; + Check& c = getCheck(check); std::list fileInfo; - Check& c = getCheck(); fileInfo.push_back(c.getFileInfo(tokenizer, settings, "")); c.analyseWholeProgram(*ctu, fileInfo, settings, *this); // TODO: check result while (!fileInfo.empty()) { diff --git a/test/testother.cpp b/test/testother.cpp index cfdcffe05d3..9a18a067231 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -367,8 +367,8 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizer(*settings, *this, opt.cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - runChecks(tokenizer, this); + CheckOther check; + runChecks(check, tokenizer, this); } struct CheckPOptions @@ -384,8 +384,8 @@ class TestOther : public TestFixture { // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Check.. - runChecks(tokenizer, this); + CheckOther check; + runChecks(check, tokenizer, this); } template @@ -12314,8 +12314,8 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizer(settings, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - runChecks(tokenizer, this); + CheckOther check; + runChecks(check, tokenizer, this); } void testEvaluationOrder() { diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index ad8aa3192af..b25afe8d153 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -54,8 +54,8 @@ class TestSizeof : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check... - runChecks(tokenizer, this); + CheckSizeof check; + runChecks(check, tokenizer, this); } #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) @@ -66,8 +66,8 @@ class TestSizeof : public TestFixture { // Tokenize.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Check... - runChecks(tokenizer, this); + CheckSizeof check; + runChecks(check, tokenizer, this); } void sizeofsizeof() { diff --git a/test/teststl.cpp b/test/teststl.cpp index 92933c37449..84dae0b0b35 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -199,7 +199,8 @@ class TestStl : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); - runChecks(tokenizer, this); + CheckStl check; + runChecks(check, tokenizer, this); } // TODO: get rid of this @@ -209,7 +210,8 @@ class TestStl : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); - runChecks(tokenizer, this); + CheckStl check; + runChecks(check, tokenizer, this); } #define checkNormal(...) checkNormal_(__FILE__, __LINE__, __VA_ARGS__) @@ -219,8 +221,8 @@ class TestStl : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - runChecks(tokenizer, this); + CheckStl check; + runChecks(check, tokenizer, this); } void outOfBounds() { diff --git a/test/teststring.cpp b/test/teststring.cpp index 051aa870788..e0e401256e2 100644 --- a/test/teststring.cpp +++ b/test/teststring.cpp @@ -74,8 +74,8 @@ class TestString : public TestFixture { // Tokenize.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Check char variable usage.. - runChecks(tokenizer, this); + CheckString check; + runChecks(check, tokenizer, this); } void stringLiteralWrite() { diff --git a/test/testtype.cpp b/test/testtype.cpp index 280e3357f85..80c3dfd32b8 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -61,8 +61,8 @@ class TestType : public TestFixture { SimpleTokenizer tokenizer(settings1, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - runChecks(tokenizer, this); + CheckType check; + runChecks(check, tokenizer, this); } // TODO: get rid of this @@ -73,8 +73,8 @@ class TestType : public TestFixture { SimpleTokenizer tokenizer(settings1, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - runChecks(tokenizer, this); + CheckType check; + runChecks(check, tokenizer, this); } struct CheckPOptions @@ -93,8 +93,8 @@ class TestType : public TestFixture { // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); - // Check.. - runChecks(tokenizer, this); + CheckType check; + runChecks(check, tokenizer, this); } void checkTooBigShift_Unix32() { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index db499dabf72..6fe563a57ca 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -5580,7 +5580,8 @@ class TestUninitVar : public TestFixture { // Check code.. std::list fileInfo; - Check& c = getCheck(); + CheckUninitVar check; + Check& c = getCheck(check); fileInfo.push_back(c.getFileInfo(tokenizer, settings, "")); c.analyseWholeProgram(*ctu, fileInfo, settings, *this); // TODO: check result while (!fileInfo.empty()) { diff --git a/test/testvaarg.cpp b/test/testvaarg.cpp index 36e1d2cb038..33fb6c11389 100644 --- a/test/testvaarg.cpp +++ b/test/testvaarg.cpp @@ -38,8 +38,8 @@ class TestVaarg : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check.. - runChecks(tokenizer, this); + CheckVaarg check; + runChecks(check, tokenizer, this); } void run() override { From 978b9c5cf6073f1db271fbe494bf820d3c5d3ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Mon, 18 May 2026 10:39:29 +0200 Subject: [PATCH 113/493] Fix #1473: warn when fclose() is used as a while loop condition (#8444) Using fclose() as a while loop condition closes the file on every iteration and operates on an already-closed file handle from the second iteration onward. --------- Signed-off-by: Francois Berder --- lib/checkio.cpp | 32 +++++++++++++++++++++ lib/checkio.h | 1 + man/checkers/fcloseInLoopCondition.md | 40 +++++++++++++++++++++++++++ releasenotes.txt | 1 + test/testio.cpp | 24 +++++++++++++++- 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 man/checkers/fcloseInLoopCondition.md diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 32bedf8024f..4161b9b224d 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -240,6 +240,28 @@ void CheckIO::checkFileUsage() } else if (tok->str() == "fclose") { fileTok = tok->tokAt(2); operation = Filepointer::Operation::CLOSE; + + // #1473 Check if fclose is in a while loop condition + if (fileTok && fileTok->isVariable()) { + const Token* loopTok = tok->astTop()->previous(); + + if (loopTok && loopTok->str() == "while") { + const Token* bodyEnd = nullptr; + const Token* bodyStart = nullptr; + + if (Token::simpleMatch(loopTok->previous(), "}") && loopTok->previous()->scope()->type == ScopeType::eDo) { // Handle do-while loops + bodyEnd = loopTok->previous(); + bodyStart = bodyEnd->link(); + } else { + bodyStart = loopTok->linkAt(1)->next(); + bodyEnd = bodyStart->link(); + } + + // Do not trigger a warning if the loop always exits or if the file is opened again in the loop. + if (!isReturnScope(bodyEnd, mSettings->library) && Token::findmatch(bodyStart, "%var% =", bodyEnd, fileTok->varId()) == nullptr) + fcloseInLoopConditionError(tok, fileTok->str()); + } + } } else if (whitelist.find(tok->str()) != whitelist.end()) { fileTok = tok->tokAt(2); if ((tok->str() == "ungetc" || tok->str() == "ungetwc") && fileTok) @@ -387,6 +409,15 @@ void CheckIO::useClosedFileError(const Token *tok) "useClosedFile", "Used file that is not opened.", CWE910, Certainty::normal); } +void CheckIO::fcloseInLoopConditionError(const Token *tok, const std::string &varname) +{ + reportError(tok, Severity::warning, + "fcloseInLoopCondition", + "fclose() used as loop condition may skip loop body or double-close file handle.\n" + "fclose() closes '" + varname + "' each time it is evaluated. On success the loop body might never execute, on failure fclose() might be called again on the already-closed file handle.", + CWE910, Certainty::normal); +} + void CheckIO::seekOnAppendedFileError(const Token *tok) { reportError(tok, Severity::warning, @@ -2038,6 +2069,7 @@ void CheckIO::getErrorMessages(ErrorLogger *errorLogger, const Settings *setting c.readWriteOnlyFileError(nullptr); c.writeReadOnlyFileError(nullptr); c.useClosedFileError(nullptr); + c.fcloseInLoopConditionError(nullptr, "fp"); c.seekOnAppendedFileError(nullptr); c.incompatibleFileOpenError(nullptr, "tmp"); c.invalidScanfError(nullptr); diff --git a/lib/checkio.h b/lib/checkio.h index e37a942770b..b3c86da3577 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -105,6 +105,7 @@ class CPPCHECKLIB CheckIO : public Check { void readWriteOnlyFileError(const Token *tok); void writeReadOnlyFileError(const Token *tok); void useClosedFileError(const Token *tok); + void fcloseInLoopConditionError(const Token *tok, const std::string &varname); void seekOnAppendedFileError(const Token *tok); void incompatibleFileOpenError(const Token *tok, const std::string &filename); void invalidScanfError(const Token *tok); diff --git a/man/checkers/fcloseInLoopCondition.md b/man/checkers/fcloseInLoopCondition.md new file mode 100644 index 00000000000..db7f0a584c6 --- /dev/null +++ b/man/checkers/fcloseInLoopCondition.md @@ -0,0 +1,40 @@ +# fcloseInLoopCondition + +**Message**: fclose() used as loop condition may skip loop body or double-close file handle.
+**Category**: Resource Management
+**Severity**: Warning
+**Language**: C and C++ + +## Description + +Using `fclose()` as a loop condition leads to two unwanted outcomes: + +- On **success**, the condition is false and the loop body never executes. The intent was likely to process the file inside the loop, but it is already closed. +- On **failure**, the condition is true and the loop body executes but `fclose()` is called again on the already-closed file handle on the next iteration, which is undefined behaviour. + +This pattern is almost always a misunderstanding of what `fclose()` returns, or confusion with a function that reads/processes data incrementally (like `fgets` or `fread`). Unlike those functions, `fclose()` is a one-shot teardown operation and has no meaningful retry or loop-until-done semantic. + +## How to fix + +Call `fclose()` outside the loop condition. If you need to check whether the close succeeded, store the return value and test it separately. + +Before: +```c +FILE *fp = fopen("data.txt", "r"); +while (fclose(fp)) { + /* process file */ +} +``` + +After: +```c +FILE *fp = fopen("data.txt", "r"); +/* process file */ +if (fclose(fp) != 0) { + /* handle close error */ +} +``` + +## Related checkers + +- `useClosedFile` - for using a file handle that has already been closed diff --git a/releasenotes.txt b/releasenotes.txt index ec8c6032da9..5d94da2ebc3 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -8,6 +8,7 @@ New checks: - MISRA C 2012 rule 10.3 now warns on assigning integer literals 0 and 1 to bool in C99 and later while preserving the existing C89 behavior. - funcArgNamesDifferentUnnamed warns on function declarations/definitions where a parameter in either location is unnamed - uninitMemberVarNoCtor warns on user-defined types where some but not all members requiring initialization have in-class initializers. +- fcloseInLoopCondition warns when fclose() is used as a while loop condition, which may skip the loop body or double-close the file handle. C/C++ support: - diff --git a/test/testio.cpp b/test/testio.cpp index 67f7aad7fe5..d3344f76b8d 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -545,7 +545,29 @@ class TestIO : public TestFixture { " FILE *a = fopen(\"aa\", \"r\");\n" " while (fclose(a)) {}\n" "}"); - TODO_ASSERT_EQUALS("[test.cpp:3:5]: (error) Used file that is not opened. [useClosedFile]\n", "", errout_str()); + ASSERT_EQUALS("[test.cpp:3:12]: (warning) fclose() used as loop condition may skip loop body or double-close file handle. [fcloseInLoopCondition]\n", errout_str()); + + check("void foo() {\n" + " FILE *a = fopen(\"aa\", \"r\");\n" + " while (fclose(a)) {\n" + " break;\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout_str()); + + check("void foo() {\n" + " FILE *a = fopen(\"aa\", \"r\");\n" + " while (fclose(a)) {\n" + " a = fopen(\"aa\", \"r\");\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout_str()); + + check("void foo() {\n" + " FILE *a = fopen(\"aa\", \"r\");\n" + " do {} while (fclose(a));\n" + "}"); + ASSERT_EQUALS("[test.cpp:3:18]: (warning) fclose() used as loop condition may skip loop body or double-close file handle. [fcloseInLoopCondition]\n", errout_str()); // #6823 check("void foo() {\n" From 72547b3a7d7a1d98898448364a3d7e60943d9857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Mon, 18 May 2026 11:19:57 +0200 Subject: [PATCH 114/493] refs #12442 - generate a fuzzing corpus by extracting code from `testrunner` (#7232) --- .github/workflows/corpus.yml | 58 ++++++++++++++++++++++++++++++++++++ lib/tokenlist.cpp | 18 +++++++++++ 2 files changed, 76 insertions(+) create mode 100644 .github/workflows/corpus.yml diff --git a/.github/workflows/corpus.yml b/.github/workflows/corpus.yml new file mode 100644 index 00000000000..0c1aeda94de --- /dev/null +++ b/.github/workflows/corpus.yml @@ -0,0 +1,58 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: corpus + +on: + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: + +permissions: + contents: read + +jobs: + corpus: + runs-on: ubuntu-22.04 + if: ${{ github.repository_owner == 'cppcheck-opensource' }} + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ runner.os }} + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install -y fdupes + + - name: build testrunner + run: | + store_dir=$(pwd)/store + mkdir $store_dir + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) CXXOPTS="-Werror" CPPOPTS="-DSTORE_INPUT_DIR=\"\\\"$store_dir\\\"\"" testrunner + + - name: run testrunner + run: | + ./testrunner -q + + - name: de-duplicate files + run: | + set -x + ls -l ./store | wc -l + echo "removing duplicates" + fdupes -qdN ./store > /dev/null + ls -l ./store | wc -l + # print largest size + ls -l ./store | cut -d' ' -f5 | sort -u -n -r | head -n1 + + - uses: actions/upload-artifact@v4 + if: success() + with: + name: corpus + path: ./store diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index f155a75014a..a345332961e 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -333,8 +333,26 @@ bool TokenList::createTokensFromBuffer(const char* data, size_t size) //--------------------------------------------------------------------------- +#ifdef STORE_INPUT_DIR +#include +#include + +static void storeInput(const char* data, size_t size) +{ + static std::atomic_uint64_t num(0); + { + std::ofstream out(STORE_INPUT_DIR "/" + std::to_string(num++)); + out.write(data, size); + } +} +#endif + bool TokenList::createTokensFromBufferInternal(const char* data, size_t size, const std::string& file0) { +#ifdef STORE_INPUT_DIR + storeInput(data, size); +#endif + simplecpp::OutputList outputList; simplecpp::TokenList tokens({data, size}, mFiles, file0, &outputList); From 8bc093cca0a27439a481de4ab1f694bfcfc6a094 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 20 May 2026 08:25:13 +0200 Subject: [PATCH 115/493] Add tests for #6796, #12896 (#8562) --- test/testcondition.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 9a15349aff0..8172f74aab6 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -6472,6 +6472,19 @@ class TestCondition : public TestFixture { " if (INT_MAX > ll * 8) {}\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("bool f(int a, int b) {\n" // #12896 + " if (a < INT_MIN && b > INT_MAX)\n" + " return true;\n" + " return false;\n" + "}\n" + "bool g(int x) {\n" // #6796 + " return (x > INT_MAX) ? true : false;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:13]: (style) Comparing expression of type 'signed int' against value -2147483648. Condition is always false. [compareValueOutOfTypeRangeError]\n" + "[test.cpp:2:28]: (style) Comparing expression of type 'signed int' against value 2147483647. Condition is always false. [compareValueOutOfTypeRangeError]\n" + "[test.cpp:7:17]: (style) Comparing expression of type 'signed int' against value 2147483647. Condition is always false. [compareValueOutOfTypeRangeError]\n", + errout_str()); } void knownConditionCast() { From b82e8664a4602e01129bb908103e3ad6a7534a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 21 May 2026 13:50:34 +0200 Subject: [PATCH 116/493] Fix #14744: Invalid AST for braced init and references/pointers (#8549) --- lib/checkstl.cpp | 3 +-- lib/tokenlist.cpp | 2 +- test/testtokenize.cpp | 31 +++++++++++++++++++------------ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index b1543f4af37..5a5e1b25ea4 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1188,8 +1188,7 @@ void CheckStl::invalidContainer() if (info.tok->variable()->isReference() && !isVariableDecl(info.tok) && reaches(info.tok->variable()->nameToken(), tok, nullptr)) { - if ((assignExpr && Token::Match(assignExpr->astOperand1(), "& %varid%", info.tok->varId())) || // TODO: fix AST - Token::Match(assignExpr, "& %varid% {|(", info.tok->varId())) { + if ((assignExpr && Token::Match(assignExpr->astOperand1()->previous(), "& %varid%", info.tok->varId()))) { return false; } diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index a345332961e..6c4cd7eb981 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1837,7 +1837,7 @@ static Token * createAstAtToken(Token *tok) } typetok = typetok->next(); } - if (Token::Match(typetok, "%var% =") && typetok->varId()) + if (Token::Match(typetok, "%var% [={]")) tok = typetok; // Do not create AST for function declaration diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 7b2bee0d80e..b6f84e1ec56 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -439,6 +439,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(astcompound); TEST_CASE(astfuncdecl); TEST_CASE(astarrayinit); + TEST_CASE(astbracedinit); TEST_CASE(startOfExecutableScope); @@ -6522,21 +6523,21 @@ class TestTokenizer : public TestFixture { tokenizer.createLinks2(); tokenizer.simplifyCAlternativeTokens(); tokenizer.list.front()->assignIndexes(); - } else { // Full - tokenizer.simplifyTokens1(""); - } - // set varid.. - for (Token *tok = tokenizer.list.front(); tok; tok = tok->next()) { - if (tok->str() == "var") - tok->varId(1); - } + // set varid.. + for (Token *tok = tokenizer.list.front(); tok; tok = tok->next()) { + if (tok->str() == "var") + tok->varId(1); + } - // Create AST.. - tokenizer.prepareTernaryOpForAST(); - tokenizer.list.createAst(); + // Create AST.. + tokenizer.prepareTernaryOpForAST(); + tokenizer.list.createAst(); - tokenizer.list.validateAst(false); + tokenizer.list.validateAst(false); + } else { // Full + tokenizer.simplifyTokens1(""); + } // Basic AST validation for (const Token *tok = tokenizer.list.front(); tok; tok = tok->next()) { @@ -7535,6 +7536,12 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("a2[2[ 12, 34,{", testAst("int a[2][2]{ { 1, 2 }, { 3, 4 } };")); } + void astbracedinit() { + ASSERT_EQUALS("ab{", testAst("int &a { b };", AstStyle::Simple, ListSimplification::Full)); + ASSERT_EQUALS("a0{", testAst("int &&a { 0 };", AstStyle::Simple, ListSimplification::Full)); + ASSERT_EQUALS("anullptr{", testAst("int *a { nullptr };", AstStyle::Simple, ListSimplification::Full)); + } + #define isStartOfExecutableScope(offset, code) isStartOfExecutableScope_(offset, code, __FILE__, __LINE__) template bool isStartOfExecutableScope_(int offset, const char (&code)[size], const char* file, int line) { From a84a5a629365447a8f1aea5fec633cfebee64a9c Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 21 May 2026 14:07:06 +0200 Subject: [PATCH 117/493] Add tests for #11152, #13579 (#8571) --- test/testtokenize.cpp | 14 ++++++++++++++ test/testvalueflow.cpp | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b6f84e1ec56..a81130c3114 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -479,6 +479,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(cppKeywordInCSource); TEST_CASE(cppcast); + TEST_CASE(ccast); TEST_CASE(checkHeader1); @@ -8418,6 +8419,19 @@ class TestTokenizer : public TestFixture { } } + void ccast() { + const char code[] = "a = (int)x;\n" // #13579 + "int (*p)[10];\n"; + + SimpleTokenizer tokenizer(settingsDefault, *this); + ASSERT(tokenizer.tokenize(code)); + + const Token* par = Token::findsimplematch(tokenizer.tokens(), "("); + ASSERT(par->isCast()); + par = Token::findsimplematch(par->next(), "("); + ASSERT(!par->isCast()); + } + #define checkHdrs(...) checkHdrs_(__FILE__, __LINE__, __VA_ARGS__) template std::string checkHdrs_(const char* file, int line, const char (&code)[size], bool checkHeadersFlag) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index dc5345ab3e3..c879b9cffd5 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -6290,6 +6290,14 @@ class TestValueFlow : public TestFixture { "}\n"; values = tokenValues(code, "x > 5", ValueFlow::Value::ValueType::UNINIT); ASSERT_EQUALS(0, values.size()); + + code = "void f() {\n" // #11152 + " char b[10];\n" + " sprintf(b, \"abc\");\n" + " printf(\"%s\", b);\n" + "}\n"; + values = tokenValues(code, "b )", ValueFlow::Value::ValueType::UNINIT); + ASSERT_EQUALS(0, values.size()); } void valueFlowConditionExpressions() { From bc04c0dbb3cbde4b5f6d4dc30665d06d0cd8eb33 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 22 May 2026 08:18:49 +0200 Subject: [PATCH 118/493] Fix #14764 FP uselessCallsRemove with brace init (#8565) --- lib/checkstl.cpp | 2 +- test/teststl.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 5a5e1b25ea4..c665d72757e 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2327,7 +2327,7 @@ void CheckStl::uselessCalls() !tok->tokAt(4)->astParent() && tok->next()->variable() && tok->next()->variable()->isStlType(stl_containers_with_empty_and_clear)) uselessCallsEmptyError(tok->next()); - else if (Token::Match(tok, "[{};] std :: remove|remove_if|unique (") && tok->tokAt(5)->nextArgument()) + else if (Token::Match(tok, "[{};] std :: remove|remove_if|unique (") && tok->tokAt(5)->nextArgument() && !tok->tokAt(4)->astParent()) uselessCallsRemoveError(tok->next(), tok->strAt(3)); else if (printPerformance && tok->valueType() && tok->valueType()->type == ValueType::CONTAINER) { if (Token::Match(tok, "%var% = { %var% . begin ( ) ,") && tok->varId() == tok->tokAt(3)->varId()) diff --git a/test/teststl.cpp b/test/teststl.cpp index 84dae0b0b35..18549e08f9f 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4835,6 +4835,12 @@ class TestStl : public TestFixture { "[test.cpp:3:5]: (warning) Return value of std::remove_if() ignored. Elements remain in container. [uselessCallsRemove]\n" "[test.cpp:4:5]: (warning) Return value of std::unique() ignored. Elements remain in container. [uselessCallsRemove]\n", errout_str()); + check("void f(std::string& s) {\n" // #14764 + " auto it{ std::remove(s.begin(), s.end(), 'a') };\n" + " s.erase(it, s.end());\n" + "}"); + ASSERT_EQUALS("", errout_str()); + // #4431 - fp check("bool f() {\n" " return x ? true : (y.empty());\n" From bc33aee25669f7ab8db1f4941ff56e9ce6d22aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Tue, 26 May 2026 08:48:42 +0200 Subject: [PATCH 119/493] Fix #8192: FN condition always false in for loop condition (#8446) When a for loop's condition is impossible given the initial value (e.g. `for (int i = 0; i > 10; i++)`), cppcheck was not emitting a knownConditionTrueFalse warning. Fix by populating memory1, memory2 and memoryAfter with the init state when the condition is immediately false (and no error occured). We can then set the value for the condition token and thus emit a knownConditionTrueFalse warning. Signed-off-by: Francois Berder --- lib/valueflow.cpp | 55 ++++++++++++++++++++++++++++-------------- test/testcondition.cpp | 2 +- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 3819bfc4b41..a63995a9728 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5181,8 +5181,18 @@ static bool valueFlowForLoop2(const Token *tok, if (error) return false; execute(secondExpression, programMemory, &result, &error, settings); - if (result == 0) // 2nd expression is false => no looping + if (result == 0) { + if (!error) { // 2nd expression is false => no looping + ProgramMemory startMemory(programMemory); + ProgramMemory endMemory(programMemory); + + memory1.swap(startMemory); + memory2.swap(endMemory); + memoryAfter.swap(programMemory); + return true; + } return false; + } if (error) { // If a variable is reassigned in second expression, return false bool reassign = false; @@ -5388,23 +5398,32 @@ static void valueFlowForLoop(const TokenList &tokenlist, const SymbolDatabase& s } else { ProgramMemory mem1, mem2, memAfter; if (valueFlowForLoop2(tok, mem1, mem2, memAfter, settings)) { - for (const auto& p : mem1) { - if (!p.second.isIntValue()) - continue; - if (p.second.isImpossible()) - continue; - if (p.first.tok->varId() == 0) - continue; - valueFlowForLoopSimplify(bodyStart, p.first.tok, false, p.second.intvalue, tokenlist, errorLogger, settings); - } - for (const auto& p : mem2) { - if (!p.second.isIntValue()) - continue; - if (p.second.isImpossible()) - continue; - if (p.first.tok->varId() == 0) - continue; - valueFlowForLoopSimplify(bodyStart, p.first.tok, false, p.second.intvalue, tokenlist, errorLogger, settings); + if (mem1 == memAfter) { // #8192 check if loop never runs + Token* condTok = getCondTok(tok); + if (condTok && !condTok->hasKnownIntValue()) { + ValueFlow::Value v(0); + v.setKnown(); + ValueFlow::setTokenValue(condTok, std::move(v), settings); + } + } else { + for (const auto& p : mem1) { + if (!p.second.isIntValue()) + continue; + if (p.second.isImpossible()) + continue; + if (p.first.tok->varId() == 0) + continue; + valueFlowForLoopSimplify(bodyStart, p.first.tok, false, p.second.intvalue, tokenlist, errorLogger, settings); + } + for (const auto& p : mem2) { + if (!p.second.isIntValue()) + continue; + if (p.second.isImpossible()) + continue; + if (p.first.tok->varId() == 0) + continue; + valueFlowForLoopSimplify(bodyStart, p.first.tok, false, p.second.intvalue, tokenlist, errorLogger, settings); + } } for (const auto& p : memAfter) { if (!p.second.isIntValue()) diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 8172f74aab6..46860d9f939 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -5680,7 +5680,7 @@ class TestCondition : public TestFixture { check("void f() {\n" // #8192 " for (int i = 0; i > 10; ++i) {}\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'i>10' is always false\n", "", errout_str()); + ASSERT_EQUALS("[test.cpp:2:23]: (style) Condition 'i>10' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " for (int i = 1000; i < 20; ++i) {}\n" From 5e8ab5e2ac461a6568893519110ce6191ac2fe29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 26 May 2026 20:22:14 +0200 Subject: [PATCH 120/493] release-windows.yml: fixed build with Visual Studio 2026 [skip ci] (#8563) this is caused by `vs2025` now using Visual Studio 2026 --- .github/workflows/release-windows.yml | 2 +- releasenotes.txt | 1 + win_installer/config.wxi | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index bacf32c8eaf..f59e77a2dca 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -56,7 +56,7 @@ jobs: cd pcre-%PCRE_VERSION% || exit /b !errorlevel! git apply --ignore-space-change ..\externals\pcre.patch || exit /b !errorlevel! cmake . -A x64 -DPCRE_BUILD_PCRECPP=OFF -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! - msbuild -m PCRE.sln -p:Configuration=Release -p:Platform=x64 || exit /b !errorlevel! + msbuild -m PCRE.slnx -p:Configuration=Release -p:Platform=x64 || exit /b !errorlevel! copy pcre.h ..\externals || exit /b !errorlevel! copy Release\pcre.lib ..\externals\pcre64.lib || exit /b !errorlevel! diff --git a/releasenotes.txt b/releasenotes.txt index 5d94da2ebc3..86aa9573ca4 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -26,4 +26,5 @@ Other: - Make it possible to specify the regular expression engine using the `engine` element in a rule XML. - Added CLI option `--exitcode-suppress` to specify an error ID which should not result in a non-zero exitcode. - Moved source code from https://github.com/danmar/cppcheck to https://github.com/cppcheck-opensource/cppcheck +- The official Windows binary is now built with Visual Studio 2026. - diff --git a/win_installer/config.wxi b/win_installer/config.wxi index 7bc613d1669..ae7fc8329f3 100644 --- a/win_installer/config.wxi +++ b/win_installer/config.wxi @@ -9,6 +9,6 @@ - + From 47aaa76dc9fb5fa65177cf2322b52cb518cd20a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 26 May 2026 20:22:35 +0200 Subject: [PATCH 121/493] iwyu.yml: disabled `HAVE_RULES` for now since Fedora no longer provides PCRE [skip ci] (#8564) --- .github/workflows/iwyu.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/iwyu.yml b/.github/workflows/iwyu.yml index 05d5643bdf7..3b972dca443 100644 --- a/.github/workflows/iwyu.yml +++ b/.github/workflows/iwyu.yml @@ -71,7 +71,7 @@ jobs: - name: Install missing software on Fedora if: contains(matrix.image, 'fedora') run: | - dnf install -y cmake clang pcre-devel + dnf install -y cmake clang dnf install -y libglvnd-devel # fixes missing dependency for Qt in CMake dnf install -y p7zip-plugins # required as fallback for py7zr in Qt installation dnf install -y python3-pip # fixes missing pip module in jurplel/install-qt-action @@ -125,7 +125,8 @@ jobs: - name: Prepare CMake run: | - cmake -S . -B cmake.output -Werror=dev -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.stdlib == 'libc++' }} + # TODO: re-enable HAVE_RULES + cmake -S . -B cmake.output -Werror=dev -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=Off -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.stdlib == 'libc++' }} env: CC: clang CXX: clang++ @@ -232,7 +233,8 @@ jobs: - name: Prepare CMake run: | - cmake -S . -B cmake.output -Werror=dev -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.use_libcxx }} + # TODO: re-enable HAVE_RULES + cmake -S . -B cmake.output -Werror=dev -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=Off -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.use_libcxx }} env: CC: clang-22 CXX: clang++-22 From 96d4a9626ada9075c9c1b0a76ee08b9ddae483c7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 27 May 2026 09:37:54 +0200 Subject: [PATCH 122/493] Fix #14774 FP bufferAccessOutOfBounds: Wrong size for sizeof( ref ) (#8572) --- lib/vf_common.cpp | 12 +++++++----- test/testvalueflow.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index 261972cba63..282e0b9fddb 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -160,11 +160,13 @@ namespace ValueFlow value.setKnown(); setTokenValue(tok, std::move(value), settings); } else if (Token::simpleMatch(tok, "sizeof (")) { - if (tok->next()->astOperand2() && !tok->next()->astOperand2()->isLiteral() && tok->next()->astOperand2()->valueType() && - (tok->next()->astOperand2()->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions - (tok->next()->astOperand2()->variable() && !tok->next()->astOperand2()->variable()->isArray())) && - !tok->next()->astOperand2()->valueType()->isEnum()) { // <- TODO this is a bailout, handle enum with non-int types - const size_t sz = tok->next()->astOperand2()->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); + const Token* const obj = tok->next()->astOperand2(); + if (obj && !obj->isLiteral() && obj->valueType() && + (obj->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions + (obj->variable() && !obj->variable()->isArray())) && + !obj->valueType()->isEnum()) { // <- TODO this is a bailout, handle enum with non-int types + const auto ptrPointee = obj->valueType()->pointer > 0 ? ValueType::SizeOf::Pointer : ValueType::SizeOf::Pointee; + const size_t sz = obj->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ptrPointee); if (sz) { Value value(sz); value.setKnown(); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index c879b9cffd5..1f4879b7cca 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1396,6 +1396,30 @@ class TestValueFlow : public TestFixture { ASSERT_EQUALS(1U, values.size()); ASSERT_EQUALS(4, values.back().intvalue); + code = "char& r = i;\n" + "sizeof(r);"; + values = tokenValues(code, "( r"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(1, values.back().intvalue); + + code = "char* p;\n" + "sizeof(p);"; + values = tokenValues(code, "( p"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(settings.platform.sizeof_pointer, values.back().intvalue); + + code = "char*& pr = p;\n" + "sizeof(pr);"; + values = tokenValues(code, "( pr"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(settings.platform.sizeof_pointer, values.back().intvalue); + + code = "struct { char& r; char* p; } s{ x, y };\n" + "sizeof(s);\n"; + values = tokenValues(code, "( s"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(2 * settings.platform.sizeof_pointer, values.back().intvalue); + #define CHECK3(A, B, C) \ do { \ code = "void f() {\n" \ From 287ae6c10b23b5fdfa1b43c7f68ed44084eb0631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 27 May 2026 13:12:33 +0200 Subject: [PATCH 123/493] fixed #14788 - bumped simplecpp to 1.7.0 (#8582) --- .selfcheck_suppressions | 1 - externals/simplecpp/simplecpp.cpp | 59 +++++++++++++++++++++++-------- externals/simplecpp/simplecpp.h | 13 ++++--- releasenotes.txt | 1 + test/testpreprocessor.cpp | 4 +-- 5 files changed, 56 insertions(+), 22 deletions(-) diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index 1687753c268..f21492e783a 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -78,5 +78,4 @@ knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp useStlAlgorithm:externals/simplecpp/simplecpp.cpp funcArgNamesDifferentUnnamed:externals/simplecpp/simplecpp.h missingMemberCopy:externals/simplecpp/simplecpp.h -shadowFunction:externals/simplecpp/simplecpp.cpp shadowFunction:externals/simplecpp/simplecpp.h diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index 7afc17ab735..47e674837ba 100644 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -275,8 +275,10 @@ class simplecpp::TokenList::Stream { return ch; } - unsigned char peekChar() { - auto ch = static_cast(peek()); + int peekChar() { + int ch = peek(); + if (ch == EOF) + return ch; // For UTF-16 encoded files the BOM is 0xfeff/0xfffe. If the // character is non-ASCII character then replace it with 0xff @@ -285,7 +287,7 @@ class simplecpp::TokenList::Stream { const auto ch2 = static_cast(peek()); unget(); const int ch16 = makeUtf16Char(ch, ch2); - ch = static_cast(((ch16 >= 0x80) ? 0xff : ch16)); + ch = (ch16 >= 0x80) ? 0xff : ch16; } // Handling of newlines.. @@ -598,7 +600,7 @@ std::string simplecpp::TokenList::stringify(bool linenrs) const return ret.str(); } -static bool isNameChar(unsigned char ch) +static bool isNameChar(int ch) { return std::isalnum(ch) || ch == '_' || ch == '$'; } @@ -635,10 +637,10 @@ static bool isStringLiteralPrefix(const std::string &str) str == "R" || str == "uR" || str == "UR" || str == "LR" || str == "u8R"; } -void simplecpp::TokenList::lineDirective(unsigned int fileIndex, unsigned int line, Location &location) +void simplecpp::TokenList::lineDirective(unsigned int fileIndex_, unsigned int line, Location &location) { - if (fileIndex != location.fileIndex || line >= location.line) { - location.fileIndex = fileIndex; + if (fileIndex_ != location.fileIndex || line >= location.line) { + location.fileIndex = fileIndex_; location.line = line; return; } @@ -771,8 +773,21 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, ch = stream.readChar(); } stream.ungetChar(); - push_back(new Token(currentToken, location)); - location.adjust(currentToken); + std::string::size_type pos = 0; + unsigned int spliced = 0; + while ((pos = currentToken.find('\\', pos)) != std::string::npos) { + if (pos + 1 < currentToken.size() && currentToken[pos + 1] == '\n') { + currentToken.erase(pos, 2); + ++spliced; + } else { + ++pos; + } + } + if (!currentToken.empty()) { + push_back(new Token(currentToken, location)); + location.adjust(currentToken); + } + location.line += spliced; continue; } } @@ -1739,6 +1754,9 @@ namespace simplecpp { return tok; } + /** + * @throws Error thrown in case of __VA_OPT__ issues + */ bool parseDefine(const Token *nametoken) { nameTokDef = nametoken; variadic = false; @@ -2201,6 +2219,8 @@ namespace simplecpp { } output.push_back(newMacroToken(tok->str(), loc, true, tok)); + if (it != macros.end()) + output.back()->markExpandedFrom(&it->second); return tok->next; } @@ -3379,6 +3399,17 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL } output.clear(); return; + } catch (const simplecpp::Macro::Error& e) { + if (outputList) { + simplecpp::Output err{ + Output::DUI_ERROR, + {}, + e.what + }; + outputList->emplace_back(std::move(err)); + } + output.clear(); + return; } } @@ -3507,14 +3538,14 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL else it->second = macro; } - } catch (const std::runtime_error &) { + } catch (const std::runtime_error &err) { if (outputList) { - simplecpp::Output err{ + simplecpp::Output out{ Output::SYNTAX_ERROR, rawtok->location, - "Failed to parse #define" + std::string("Failed to parse #define, ") + err.what() }; - outputList->emplace_back(std::move(err)); + outputList->emplace_back(std::move(out)); } output.clear(); return; @@ -3671,7 +3702,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL bool closingAngularBracket = false; if (tok) { const std::string &sourcefile = rawtokens.file(rawtok->location); - const bool systemheader = (tok && tok->op == '<'); + const bool systemheader = tok->op == '<'; std::string header; if (systemheader) { diff --git a/externals/simplecpp/simplecpp.h b/externals/simplecpp/simplecpp.h index d499b132b69..f29166ff061 100644 --- a/externals/simplecpp/simplecpp.h +++ b/externals/simplecpp/simplecpp.h @@ -174,9 +174,9 @@ namespace simplecpp { bool isOneOf(const char ops[]) const; bool startsWithOneOf(const char c[]) const; bool endsWithOneOf(const char c[]) const; - static bool isNumberLike(const std::string& str) { - return std::isdigit(static_cast(str[0])) || - (str.size() > 1U && (str[0] == '-' || str[0] == '+') && std::isdigit(static_cast(str[1]))); + static bool isNumberLike(const std::string& s) { + return std::isdigit(static_cast(s[0])) || + (s.size() > 1U && (s[0] == '-' || s[0] == '+') && std::isdigit(static_cast(s[1]))); } TokenString macro; @@ -213,6 +213,9 @@ namespace simplecpp { bool isExpandedFrom(const Macro* m) const { return mExpandedFrom.find(m) != mExpandedFrom.end(); } + void markExpandedFrom(const Macro* m) { + mExpandedFrom.insert(m); + } void printAll() const; void printOut() const; @@ -376,7 +379,7 @@ namespace simplecpp { const std::string& file(const Location& loc) const; private: - TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename, OutputList *outputList, int unused); + TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename, OutputList *outputList, int /*unused*/); void combineOperators(); @@ -396,7 +399,7 @@ namespace simplecpp { void constFoldQuestionOp(Token *&tok1); std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList); - void lineDirective(unsigned int fileIndex, unsigned int line, Location &location); + void lineDirective(unsigned int fileIndex_, unsigned int line, Location &location); const Token* lastLineTok(int maxsize=1000) const; const Token* isLastLinePreprocessor(int maxsize=1000) const; diff --git a/releasenotes.txt b/releasenotes.txt index 86aa9573ca4..3e5a76b6915 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -27,4 +27,5 @@ Other: - Added CLI option `--exitcode-suppress` to specify an error ID which should not result in a non-zero exitcode. - Moved source code from https://github.com/danmar/cppcheck to https://github.com/cppcheck-opensource/cppcheck - The official Windows binary is now built with Visual Studio 2026. +- Updated simplecpp to 1.7.0. - diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 6846d49ff30..7e01f6f233b 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -1996,12 +1996,12 @@ class TestPreprocessor : public TestFixture { void invalid_define_1() { (void)getcode(settings0, *this, "#define =\n"); - ASSERT_EQUALS("[file.c:1:2]: (error) Failed to parse #define [syntaxError]\n", errout_str()); + ASSERT_EQUALS("[file.c:1:2]: (error) Failed to parse #define, bad macro syntax [syntaxError]\n", errout_str()); } void invalid_define_2() { // #4036 (void)getcode(settings0, *this, "#define () {(int f(x) }\n"); - ASSERT_EQUALS("[file.c:1:2]: (error) Failed to parse #define [syntaxError]\n", errout_str()); + ASSERT_EQUALS("[file.c:1:2]: (error) Failed to parse #define, bad macro syntax [syntaxError]\n", errout_str()); } void inline_suppressions() { From 652e06d4a82ed6cc3a49b0cbc0e0218e35f11a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= Date: Wed, 27 May 2026 11:23:16 +0000 Subject: [PATCH 124/493] gtk.cfg: Fix gtk_widget_destroy definition and usage (#8546) gtk_widget_destroy is only for GtkWidget derived objects. --- cfg/gtk.cfg | 28 +++++++++++++++++++++++----- test/cfg/gtk.c | 11 +++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index b561aad91b2..14cd032945e 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -1003,7 +1003,6 @@ g_zlib_decompressor_new g_object_ref g_object_unref - gtk_widget_destroy
g_tree_new @@ -1019,6 +1018,11 @@ g_file_attribute_matcher_ref g_file_attribute_matcher_unref + + gtk_window_new + gtk_widget_destroy + gtk_window_destroy + false @@ -9787,6 +9791,14 @@ false + + + false + + + + false @@ -21229,10 +21241,6 @@ false - - - false - false @@ -21889,6 +21897,13 @@ false + + false + + + + + false @@ -23070,6 +23085,9 @@ + + + diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c index bcee84c8264..cab41ffa1cd 100644 --- a/test/cfg/gtk.c +++ b/test/cfg/gtk.c @@ -585,3 +585,14 @@ void g_tree_test() { printf("%p\n", tree2); // cppcheck-suppress memleak } + +void gtk_widget_destroy_test() { + GtkWidget *widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_show(widget); + // cppcheck-suppress memleak + + widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_show(widget); + // cppcheck-suppress mismatchAllocDealloc + g_object_unref(widget); +} From 2cd2f46ae747d1ee4e47bf2c4588696bdfc7d262 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 27 May 2026 14:25:34 +0200 Subject: [PATCH 125/493] Fix #11614 FN knownConditionTrueFalse when assigned to bool (#8569) --- .selfcheck_suppressions | 1 + lib/checkcondition.cpp | 8 ++++++-- test/testcondition.cpp | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index f21492e783a..dcb7c06c893 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -76,6 +76,7 @@ funcArgNamesDifferentUnnamed:externals/tinyxml2/tinyxml2.h nullPointerRedundantCheck:externals/tinyxml2/tinyxml2.cpp knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp useStlAlgorithm:externals/simplecpp/simplecpp.cpp +knownConditionTrueFalse:externals/simplecpp/simplecpp.cpp funcArgNamesDifferentUnnamed:externals/simplecpp/simplecpp.h missingMemberCopy:externals/simplecpp/simplecpp.h shadowFunction:externals/simplecpp/simplecpp.h diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index cec3293ad27..f70d9172832 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1540,8 +1540,11 @@ void CheckCondition::alwaysTrueFalse() { // is this a condition.. const Token *parent = tok->astParent(); - while (Token::Match(parent, "%oror%|&&")) + bool hasComp = false; + while (Token::Match(parent, "%oror%|&&")) { + hasComp = true; parent = parent->astParent(); + } if (!parent) continue; if (parent->str() == "?" && precedes(tok, parent)) @@ -1555,10 +1558,11 @@ void CheckCondition::alwaysTrueFalse() condition = parent->astParent()->astParent()->previous(); else if (Token::Match(tok, "%comp%")) condition = tok; - else if (tok->str() == "(" && astIsBool(parent) && Token::Match(parent, "%assign%")) + else if ((tok->str() == "(" || (hasComp && Token::Match(tok, "!|%var%"))) && astIsBool(parent) && Token::Match(parent, "%assign%")) condition = tok; else continue; + } // Skip already diagnosed values if (diag(tok, false)) diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 46860d9f939..e5aedae6609 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -3675,7 +3675,7 @@ class TestCondition : public TestFixture { " f ? result = 42 : ret = -1;\n" " return ret;\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:4:9]: (style) Condition 'f' is always false [knownConditionTrueFalse]\n", errout_str()); check("int f(void *handle) {\n" " if (!handle) return 0;\n" @@ -6227,6 +6227,20 @@ class TestCondition : public TestFixture { check("enum E { E1 = 1, E2 = 2 };\n" "void f(int i) { if (i == E1 || E2) {} }\n"); ASSERT_EQUALS("[test.cpp:2:29]: (style) Condition 'i==E1||E2' is always true [knownConditionTrueFalse]\n", errout_str()); + + check("void f(bool a, bool b) {\n" // #11614 + " if (b) {\n" + " bool x = !b || a;\n" + " }\n" + "}\n" + "void g(bool a, bool b) {\n" + " if (!b) {\n" + " bool x = a || b;\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:18]: (style) Condition '!b' is always false [knownConditionTrueFalse]\n" + "[test.cpp:7:9] -> [test.cpp:8:23]: (style) Condition 'b' is always false [knownConditionTrueFalse]\n", + errout_str()); } void pointerAdditionResultNotNull() { From c3e93833aeae1a3acd8d4be2d8475a2f3c62633d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 27 May 2026 14:26:28 +0200 Subject: [PATCH 126/493] Refs #13296: Fix FP clarifyCondition for cast to pointer to member function (#8577) Co-authored-by: chrchr-github --- lib/tokenlist.cpp | 2 +- test/testtokenize.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 6c4cd7eb981..1ab00ee3574 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -547,7 +547,7 @@ static bool iscast(const Token *tok, bool cpp) if (!Token::Match(tok2, "%name%|*|::")) return false; - if (tok2->isStandardType() && (tok2->strAt(1) != "(" || Token::Match(tok2->next(), "( * *| )"))) + if (tok2->isStandardType() && (tok2->strAt(1) != "(" || Token::simpleMatch(tok2->linkAt(1)->tokAt(-1), "* )"))) type = true; } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index a81130c3114..a7e8c40cd37 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8421,7 +8421,8 @@ class TestTokenizer : public TestFixture { void ccast() { const char code[] = "a = (int)x;\n" // #13579 - "int (*p)[10];\n"; + "int (*p)[10];\n" + "b = (void (S::*)(int) const)&y;"; SimpleTokenizer tokenizer(settingsDefault, *this); ASSERT(tokenizer.tokenize(code)); @@ -8430,6 +8431,8 @@ class TestTokenizer : public TestFixture { ASSERT(par->isCast()); par = Token::findsimplematch(par->next(), "("); ASSERT(!par->isCast()); + par = Token::findsimplematch(par->next(), "("); + ASSERT(par->isCast()); } #define checkHdrs(...) checkHdrs_(__FILE__, __LINE__, __VA_ARGS__) From cf483821bbef296f596fdb8217be01da2b59cdaf Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 27 May 2026 18:17:13 +0200 Subject: [PATCH 127/493] Fix CI: unmatchedSuppression in simplecpp.cpp (#8589) --- .selfcheck_suppressions | 1 - 1 file changed, 1 deletion(-) diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index dcb7c06c893..f21492e783a 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -76,7 +76,6 @@ funcArgNamesDifferentUnnamed:externals/tinyxml2/tinyxml2.h nullPointerRedundantCheck:externals/tinyxml2/tinyxml2.cpp knownConditionTrueFalse:externals/tinyxml2/tinyxml2.cpp useStlAlgorithm:externals/simplecpp/simplecpp.cpp -knownConditionTrueFalse:externals/simplecpp/simplecpp.cpp funcArgNamesDifferentUnnamed:externals/simplecpp/simplecpp.h missingMemberCopy:externals/simplecpp/simplecpp.h shadowFunction:externals/simplecpp/simplecpp.h From 594b44263611dd561a7e807cf9b461f6a1fa406b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 27 May 2026 18:32:05 +0200 Subject: [PATCH 128/493] Fix #11754 Confusing message: Size of pointer 'p' used instead of size of its data. (#8566) --- lib/checksizeof.cpp | 3 ++- test/testsizeof.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index 134cca92b7f..e211764ad3a 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -233,7 +233,8 @@ void CheckSizeof::checkSizeofForPointerSize() // Now check for the sizeof usage: Does the level of pointer indirection match? const Token * const tokLink = tokSize->linkAt(1); if (tokLink && tokLink->strAt(-1) == "*") { - if (variable && variable->valueType() && variable->valueType()->pointer == 1 && variable->valueType()->type != ValueType::VOID) + if (variable && variable->valueType() && variable->valueType()->pointer == 1 && variable->valueType()->type != ValueType::VOID && + variable->valueType()->isTypeEqual(tokSize->next()->astOperand2()->valueType())) sizeofForPointerError(variable, variable->str()); else if (variable2 && variable2->valueType() && variable2->valueType()->pointer == 1 && variable2->valueType()->type != ValueType::VOID) sizeofForPointerError(variable2, variable2->str()); diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index b25afe8d153..fca8cb7ed7a 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -722,6 +722,12 @@ class TestSizeof : public TestFixture { " return AtomName;\n" "}"); ASSERT_EQUALS("", errout_str()); + + check("void* f(size_t n) {\n" // #11754 + " char* p = malloc(n * sizeof(void*));\n" + " return p;\n" + "}"); + ASSERT_EQUALS("", errout_str()); } void checkPointerSizeofStruct() { From 6e46c6ba91cf69cb6ea65885933bcd25a08ed769 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 27 May 2026 18:39:55 +0200 Subject: [PATCH 129/493] Fix #14790 Performance regression (hang) in 2.21dev (#8587) --- lib/tokenlist.cpp | 2 +- test/testtokenize.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 1ab00ee3574..f98335badb7 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -609,7 +609,7 @@ static bool iscpp11init_impl(const Token * const tok) if (Token::Match(nameToken, "]|*")) { const Token* tok2 = nameToken; if (tok2->link()) { - while (tok2 && tok2->link()) + while (tok2 && precedes(tok2->link(), nameToken)) tok2 = tok2->link()->previous(); } else diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index a7e8c40cd37..5f4d59503e2 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8712,6 +8712,10 @@ class TestTokenizer : public TestFixture { "{ 1", Token::Cpp11init::CPP11INIT); + testIsCpp11init("void f() { g([] { if (int x = 1; x) {} }); }", // #14790 + "{ int", + Token::Cpp11init::NOINIT); // don't hang + ASSERT_NO_THROW(tokenizeAndStringify("template struct X {};\n" // don't crash "template auto f(T t) -> X {}\n")); ASSERT_EQUALS("[test.cpp:2:22]: (debug) auto token with no type. [autoNoType]\n", errout_str()); From 91ceb735c8806d72a8f969202c48b95b6d364963 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 28 May 2026 10:49:09 +0200 Subject: [PATCH 130/493] Update entry for uninitMemberVarNoCtor in releasenotes.txt (#8585) [skip ci] --- releasenotes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes.txt b/releasenotes.txt index 3e5a76b6915..4fb45b90070 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -7,7 +7,7 @@ Major bug fixes & crashes: New checks: - MISRA C 2012 rule 10.3 now warns on assigning integer literals 0 and 1 to bool in C99 and later while preserving the existing C89 behavior. - funcArgNamesDifferentUnnamed warns on function declarations/definitions where a parameter in either location is unnamed -- uninitMemberVarNoCtor warns on user-defined types where some but not all members requiring initialization have in-class initializers. +- uninitMemberVarNoCtor warns on user-defined types where (1) some but not all members requiring initialization have in-class initializers or (2) there is a mixture of members which do/do not require initialization. - fcloseInLoopCondition warns when fclose() is used as a while loop condition, which may skip the loop body or double-close the file handle. C/C++ support: From f1379d63a5e0ab4ce360e56e96e1b128c5c87e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 28 May 2026 13:47:32 +0200 Subject: [PATCH 131/493] split the actual check implementations from the instances (#5323) --- Makefile | 114 +++++++-------- lib/astutils.cpp | 2 +- lib/check.h | 65 +-------- lib/check64bit.cpp | 14 +- lib/check64bit.h | 34 ++--- lib/checkassert.cpp | 14 +- lib/checkassert.h | 27 ++-- lib/checkautovariables.cpp | 40 +++--- lib/checkautovariables.h | 47 +++--- lib/checkbool.cpp | 48 +++---- lib/checkbool.h | 47 +++--- lib/checkbufferoverrun.cpp | 63 ++++----- lib/checkbufferoverrun.h | 57 ++++---- lib/checkclass.cpp | 192 ++++++++++++------------- lib/checkclass.h | 95 ++++++------- lib/checkcondition.cpp | 100 ++++++------- lib/checkcondition.h | 59 ++++---- lib/checkexceptionsafety.cpp | 34 ++--- lib/checkexceptionsafety.h | 49 ++++--- lib/checkfunctions.cpp | 60 ++++---- lib/checkfunctions.h | 49 +++---- lib/{check.cpp => checkimpl.cpp} | 53 ++----- lib/checkimpl.h | 85 +++++++++++ lib/checkinternal.cpp | 34 ++--- lib/checkinternal.h | 34 ++--- lib/checkio.cpp | 96 ++++++------- lib/checkio.h | 50 +++---- lib/checkleakautovar.cpp | 48 +++---- lib/checkleakautovar.h | 30 ++-- lib/checkmemoryleak.cpp | 172 +++++++++++----------- lib/checkmemoryleak.h | 213 +++++++++++++++------------- lib/checknullpointer.cpp | 51 +++---- lib/checknullpointer.h | 63 ++++----- lib/checkother.cpp | 236 +++++++++++++++---------------- lib/checkother.h | 152 ++++++++++---------- lib/checkpostfixoperator.cpp | 9 +- lib/checkpostfixoperator.h | 29 ++-- lib/checksizeof.cpp | 44 +++--- lib/checksizeof.h | 46 +++--- lib/checkstl.cpp | 146 +++++++++---------- lib/checkstl.h | 66 ++++----- lib/checkstring.cpp | 38 ++--- lib/checkstring.h | 44 +++--- lib/checktype.cpp | 41 +++--- lib/checktype.h | 42 +++--- lib/checkuninitvar.cpp | 55 +++---- lib/checkuninitvar.h | 58 ++++---- lib/checkunusedvar.cpp | 23 +-- lib/checkunusedvar.h | 45 +++--- lib/checkvaarg.cpp | 18 +-- lib/checkvaarg.h | 37 ++--- lib/cppcheck.vcxproj | 13 +- lib/valueflow.cpp | 2 +- oss-fuzz/Makefile | 60 ++++---- test/test64bit.cpp | 3 +- test/testcharvar.cpp | 2 +- test/testclass.cpp | 38 ++--- test/testconstructors.cpp | 2 +- test/testincompletestatement.cpp | 2 +- test/testio.cpp | 2 +- test/testmemleak.cpp | 25 ++-- test/testnullpointer.cpp | 4 +- test/testother.cpp | 6 +- test/testpostfixoperator.cpp | 3 +- test/testuninitvar.cpp | 6 +- test/testunusedprivfunc.cpp | 2 +- test/testunusedvar.cpp | 8 +- tools/dmake/dmake.cpp | 3 +- 68 files changed, 1729 insertions(+), 1720 deletions(-) rename lib/{check.cpp => checkimpl.cpp} (60%) create mode 100644 lib/checkimpl.h diff --git a/Makefile b/Makefile index 5a348e27001..684e79179cf 100644 --- a/Makefile +++ b/Makefile @@ -208,7 +208,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/addoninfo.o \ $(libcppdir)/analyzerinfo.o \ $(libcppdir)/astutils.o \ - $(libcppdir)/check.o \ $(libcppdir)/check64bit.o \ $(libcppdir)/checkassert.o \ $(libcppdir)/checkautovariables.o \ @@ -221,6 +220,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/checkersreport.o \ $(libcppdir)/checkexceptionsafety.o \ $(libcppdir)/checkfunctions.o \ + $(libcppdir)/checkimpl.o \ $(libcppdir)/checkinternal.o \ $(libcppdir)/checkio.o \ $(libcppdir)/checkleakautovar.o \ @@ -483,7 +483,7 @@ check-nonneg: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/regex.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/regex.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h @@ -498,31 +498,28 @@ $(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/ad $(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: lib/astutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/astutils.o: lib/astutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check.o: lib/check.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check.cpp - -$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h @@ -534,58 +531,61 @@ $(libcppdir)/checkersidmapping.o: lib/checkersidmapping.cpp lib/checkers.h lib/c $(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/addoninfo.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp + +$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp -$(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/standards.h lib/vfvalue.h +$(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkimpl.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/standards.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp $(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp $(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h @@ -744,28 +744,28 @@ test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/c test/options.o: test/options.cpp lib/config.h lib/timer.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp -test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp -test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp -test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp -test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp -test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h @@ -777,7 +777,7 @@ test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h @@ -786,10 +786,10 @@ test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmd test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp -test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp -test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h @@ -798,7 +798,7 @@ test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/a test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp -test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h @@ -813,7 +813,7 @@ test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h l test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp -test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h @@ -822,16 +822,16 @@ test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checker test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp -test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp -test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp -test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp -test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h @@ -840,16 +840,16 @@ test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checker test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp -test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp -test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp -test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h @@ -861,7 +861,7 @@ test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/che test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp -test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h @@ -897,16 +897,16 @@ test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp -test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp -test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h @@ -936,25 +936,25 @@ test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp -test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp -test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp -test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp -test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 56a9489d00e..8dfd03596d3 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2157,7 +2157,7 @@ bool isWithoutSideEffects(const Token* tok, bool checkArrayAccess, bool checkRef if (tok && tok->varId()) { const Variable* var = tok->variable(); return var && ((!var->isClass() && (checkReference || !var->isReference())) || var->isPointer() || - (checkArrayAccess ? var->isArray() || (var->isStlType() && !var->isStlType(CheckClass::stl_containers_not_const)) : var->isStlType())); + (checkArrayAccess ? var->isArray() || (var->isStlType() && !var->isStlType(CheckClassImpl::stl_containers_not_const)) : var->isStlType())); } return true; } diff --git a/lib/check.h b/lib/check.h index 9a50e64baa1..768cc889c62 100644 --- a/lib/check.h +++ b/lib/check.h @@ -22,7 +22,6 @@ //--------------------------------------------------------------------------- #include "config.h" -#include "errortypes.h" #include #include @@ -36,14 +35,8 @@ namespace CTU { class FileInfo; } -namespace ValueFlow { - class Value; -} - class Settings; -class Token; class ErrorLogger; -class ErrorMessage; class Tokenizer; /** Use WRONG_DATA in checkers to mark conditions that check that data is correct */ @@ -57,21 +50,14 @@ class Tokenizer; * All checking classes must inherit from this class */ class CPPCHECKLIB Check { -public: - /** This constructor is used when registering the CheckClass */ - explicit Check(std::string aname); - protected: - /** This constructor is used when running checks. */ - Check(std::string aname, const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger), mName(std::move(aname)) {} - -private: - static std::list &instances_internal(); - -public: + /** This constructor is used when registering the check */ + explicit Check(std::string aname) + : mName(std::move(aname)) + {} virtual ~Check() = default; +public: Check(const Check &) = delete; Check& operator=(const Check &) = delete; @@ -89,13 +75,6 @@ class CPPCHECKLIB Check { /** get information about this class, used to generate documentation */ virtual std::string classInfo() const = 0; - /** - * Write given error to stdout in xml format. - * This is for for printout out the error list with --errorlist - * @param errmsg Error message to write - */ - static void writeToErrorList(const ErrorMessage &errmsg); - /** Base class used for whole-program analysis */ class CPPCHECKLIB FileInfo { public: @@ -121,40 +100,6 @@ class CPPCHECKLIB Check { return false; } -protected: - static std::string getMessageId(const ValueFlow::Value &value, const char id[]); - - const Tokenizer* const mTokenizer{}; - const Settings* const mSettings{}; - ErrorLogger* const mErrorLogger{}; - - /** report an error */ - void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg) { - reportError(tok, severity, id, msg, CWE(0U), Certainty::normal); - } - - /** report an error */ - void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty) { - const std::list callstack(1, tok); - reportError(callstack, severity, id, msg, cwe, certainty); - } - - /** report an error */ - void reportError(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty); - - void reportError(ErrorPath errorPath, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty); - - /** log checker */ - void logChecker(const char id[]); - - ErrorPath getErrorPath(const Token* errtok, const ValueFlow::Value* value, std::string bug) const; - - /** - * Use WRONG_DATA in checkers when you check for wrong data. That - * will call this method - */ - bool wrongData(const Token *tok, const char *str); - private: const std::string mName; }; diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index b33ab5bdbcb..e1e6f086ff3 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -51,7 +51,7 @@ static bool isFunctionPointer(const Token* tok) return Tokenizer::isFunctionPointer(tok->variable()->nameToken()); } -void Check64BitPortability::pointerassignment() +void Check64BitPortabilityImpl::pointerassignment() { if (!mSettings->severity.isEnabled(Severity::portability)) return; @@ -139,7 +139,7 @@ void Check64BitPortability::pointerassignment() } } -void Check64BitPortability::assignmentAddressToIntegerError(const Token *tok) +void Check64BitPortabilityImpl::assignmentAddressToIntegerError(const Token *tok) { reportError(tok, Severity::portability, "AssignmentAddressToInteger", @@ -150,7 +150,7 @@ void Check64BitPortability::assignmentAddressToIntegerError(const Token *tok) "way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, Certainty::normal); } -void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok) +void Check64BitPortabilityImpl::assignmentIntegerToAddressError(const Token *tok) { reportError(tok, Severity::portability, "AssignmentIntegerToAddress", @@ -161,7 +161,7 @@ void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok) "way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, Certainty::normal); } -void Check64BitPortability::returnPointerError(const Token *tok) +void Check64BitPortabilityImpl::returnPointerError(const Token *tok) { reportError(tok, Severity::portability, "CastAddressToIntegerAtReturn", @@ -172,7 +172,7 @@ void Check64BitPortability::returnPointerError(const Token *tok) "to 32-bit integer. The safe way is to return a type such as intptr_t.", CWE758, Certainty::normal); } -void Check64BitPortability::returnIntegerError(const Token *tok) +void Check64BitPortabilityImpl::returnIntegerError(const Token *tok) { reportError(tok, Severity::portability, "CastIntegerToAddressAtReturn", @@ -185,13 +185,13 @@ void Check64BitPortability::returnIntegerError(const Token *tok) void Check64BitPortability::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - Check64BitPortability check64BitPortability(&tokenizer, &tokenizer.getSettings(), errorLogger); + Check64BitPortabilityImpl check64BitPortability(&tokenizer, &tokenizer.getSettings(), errorLogger); check64BitPortability.pointerassignment(); } void Check64BitPortability::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - Check64BitPortability c(nullptr, settings, errorLogger); + Check64BitPortabilityImpl c(nullptr, settings, errorLogger); c.assignmentAddressToIntegerError(nullptr); c.assignmentIntegerToAddressError(nullptr); c.returnIntegerError(nullptr); diff --git a/lib/check64bit.h b/lib/check64bit.h index 79397e98e5f..1996d91ee23 100644 --- a/lib/check64bit.h +++ b/lib/check64bit.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -44,36 +45,35 @@ class CPPCHECKLIB Check64BitPortability : public Check { public: /** This constructor is used when registering the Check64BitPortability */ - Check64BitPortability() : Check(myName()) {} + Check64BitPortability() : Check("64-bit portability") {} private: - /** This constructor is used when running checks. */ - Check64BitPortability(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - /** Check for pointer assignment */ - void pointerassignment(); - - void assignmentAddressToIntegerError(const Token *tok); - void assignmentIntegerToAddressError(const Token *tok); - void returnIntegerError(const Token *tok); - void returnPointerError(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - static std::string myName() { - return "64-bit portability"; - } - std::string classInfo() const override { return "Check if there is 64-bit portability issues:\n" "- assign address to/from int/long\n" "- casting address from/to integer when returning from function\n"; } }; + +class CPPCHECKLIB Check64BitPortabilityImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + Check64BitPortabilityImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + + /** Check for pointer assignment */ + void pointerassignment(); + + void assignmentAddressToIntegerError(const Token *tok); + void assignmentIntegerToAddressError(const Token *tok); + void returnIntegerError(const Token *tok); + void returnPointerError(const Token *tok); +}; /// @} //--------------------------------------------------------------------------- #endif // check64bitH diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index ce2d7c62169..5242b595e67 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -39,7 +39,7 @@ // CWE ids used static const CWE CWE398(398U); // Indicator of Poor Code Quality -void CheckAssert::assertWithSideEffects() +void CheckAssertImpl::assertWithSideEffects() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -117,7 +117,7 @@ void CheckAssert::assertWithSideEffects() //--------------------------------------------------------------------------- -void CheckAssert::sideEffectInAssertError(const Token *tok, const std::string& functionName) +void CheckAssertImpl::sideEffectInAssertError(const Token *tok, const std::string& functionName) { reportError(tok, Severity::warning, "assertWithSideEffect", @@ -129,7 +129,7 @@ void CheckAssert::sideEffectInAssertError(const Token *tok, const std::string& f "builds, this is a bug.", CWE398, Certainty::normal); } -void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& varname) +void CheckAssertImpl::assignmentInAssertError(const Token *tok, const std::string& varname) { reportError(tok, Severity::warning, "assignmentInAssert", @@ -142,7 +142,7 @@ void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& v } // checks if side effects happen on the variable prior to tmp -void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope) +void CheckAssertImpl::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope) { if (!assignTok->isAssignmentOp() && assignTok->tokType() != Token::eIncDecOp) return; @@ -172,7 +172,7 @@ void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *a // TODO: function calls on var } -bool CheckAssert::inSameScope(const Token* returnTok, const Token* assignTok) +bool CheckAssertImpl::inSameScope(const Token* returnTok, const Token* assignTok) { // TODO: even if a return is in the same scope, the assignment might not affect it. return returnTok->scope() == assignTok->scope(); @@ -180,13 +180,13 @@ bool CheckAssert::inSameScope(const Token* returnTok, const Token* assignTok) void CheckAssert::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckAssert checkAssert(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckAssertImpl checkAssert(&tokenizer, &tokenizer.getSettings(), errorLogger); checkAssert.assertWithSideEffects(); } void CheckAssert::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckAssert c(nullptr, settings, errorLogger); + CheckAssertImpl c(nullptr, settings, errorLogger); c.sideEffectInAssertError(nullptr, "function"); c.assignmentInAssertError(nullptr, "var"); } diff --git a/lib/checkassert.h b/lib/checkassert.h index b01831a5eec..3fac8f5af83 100644 --- a/lib/checkassert.h +++ b/lib/checkassert.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -42,14 +43,22 @@ class Tokenizer; class CPPCHECKLIB CheckAssert : public Check { public: - CheckAssert() : Check(myName()) {} + CheckAssert() : Check("Assert") {} private: - CheckAssert(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** run checks, the token list is not simplified */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).\n"; + } +}; + +class CPPCHECKLIB CheckAssertImpl : public CheckImpl { +public: + CheckAssertImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} void assertWithSideEffects(); @@ -58,16 +67,6 @@ class CPPCHECKLIB CheckAssert : public Check { void sideEffectInAssertError(const Token *tok, const std::string& functionName); void assignmentInAssertError(const Token *tok, const std::string &varname); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Assert"; - } - - std::string classInfo() const override { - return "Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index fdc5deceefa..0d3cae1c2fa 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -202,7 +202,7 @@ static bool variableIsUsedInScope(const Token* start, nonneg int varId, const Sc return false; } -void CheckAutoVariables::assignFunctionArg() +void CheckAutoVariablesImpl::assignFunctionArg() { const bool printStyle = mSettings->severity.isEnabled(Severity::style); const bool printWarning = mSettings->severity.isEnabled(Severity::warning); @@ -280,7 +280,7 @@ static bool isMemberAssignment(const Token* tok, const Token*& rhs, const Settin return true; } -void CheckAutoVariables::autoVariables() +void CheckAutoVariablesImpl::autoVariables() { logChecker("CheckAutoVariables::autoVariables"); @@ -343,7 +343,7 @@ void CheckAutoVariables::autoVariables() } } -bool CheckAutoVariables::checkAutoVariableAssignment(const Token *expr, bool inconclusive, const Token *startToken) +bool CheckAutoVariablesImpl::checkAutoVariableAssignment(const Token *expr, bool inconclusive, const Token *startToken) { if (!startToken) startToken = Token::findsimplematch(expr, "=")->next(); @@ -386,7 +386,7 @@ bool CheckAutoVariables::checkAutoVariableAssignment(const Token *expr, bool inc //--------------------------------------------------------------------------- -void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inconclusive) +void CheckAutoVariablesImpl::errorAutoVariableAssignment(const Token *tok, bool inconclusive) { diag(tok); @@ -409,7 +409,7 @@ void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inco } } -void CheckAutoVariables::errorUselessAssignmentArg(const Token *tok) +void CheckAutoVariablesImpl::errorUselessAssignmentArg(const Token *tok) { reportError(tok, Severity::style, @@ -417,7 +417,7 @@ void CheckAutoVariables::errorUselessAssignmentArg(const Token *tok) "Assignment of function parameter has no effect outside the function.", CWE398, Certainty::normal); } -void CheckAutoVariables::errorUselessAssignmentPtrArg(const Token *tok) +void CheckAutoVariablesImpl::errorUselessAssignmentPtrArg(const Token *tok) { reportError(tok, Severity::warning, @@ -425,7 +425,7 @@ void CheckAutoVariables::errorUselessAssignmentPtrArg(const Token *tok) "Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?", CWE398, Certainty::normal); } -bool CheckAutoVariables::diag(const Token* tokvalue) +bool CheckAutoVariablesImpl::diag(const Token* tokvalue) { if (!tokvalue) return true; @@ -562,7 +562,7 @@ static bool isAssignedToNonLocal(const Token* tok) return !var->isLocal() || var->isStatic(); } -void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token * end) +void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const Token * end) { const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); if (!start) @@ -705,7 +705,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token } } -void CheckAutoVariables::checkVarLifetime() +void CheckAutoVariablesImpl::checkVarLifetime() { logChecker("CheckAutoVariables::checkVarLifetime"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -716,7 +716,7 @@ void CheckAutoVariables::checkVarLifetime() } } -void CheckAutoVariables::errorReturnDanglingLifetime(const Token *tok, const ValueFlow::Value *val) +void CheckAutoVariablesImpl::errorReturnDanglingLifetime(const Token *tok, const ValueFlow::Value *val) { const bool inconclusive = val ? val->isInconclusive() : false; ErrorPath errorPath = val ? val->errorPath : ErrorPath(); @@ -725,7 +725,7 @@ void CheckAutoVariables::errorReturnDanglingLifetime(const Token *tok, const Val reportError(std::move(errorPath), Severity::error, "returnDanglingLifetime", msg + " that will be invalid when returning.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckAutoVariables::errorInvalidLifetime(const Token *tok, const ValueFlow::Value* val) +void CheckAutoVariablesImpl::errorInvalidLifetime(const Token *tok, const ValueFlow::Value* val) { const bool inconclusive = val ? val->isInconclusive() : false; ErrorPath errorPath = val ? val->errorPath : ErrorPath(); @@ -734,7 +734,7 @@ void CheckAutoVariables::errorInvalidLifetime(const Token *tok, const ValueFlow: reportError(std::move(errorPath), Severity::error, "invalidLifetime", msg + " that is out of scope.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckAutoVariables::errorDanglingTemporaryLifetime(const Token* tok, const ValueFlow::Value* val, const Token* tempTok) +void CheckAutoVariablesImpl::errorDanglingTemporaryLifetime(const Token* tok, const ValueFlow::Value* val, const Token* tempTok) { const bool inconclusive = val ? val->isInconclusive() : false; ErrorPath errorPath = val ? val->errorPath : ErrorPath(); @@ -749,7 +749,7 @@ void CheckAutoVariables::errorDanglingTemporaryLifetime(const Token* tok, const inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val, bool isStatic) +void CheckAutoVariablesImpl::errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val, bool isStatic) { const bool inconclusive = val ? val->isInconclusive() : false; ErrorPath errorPath = val ? val->errorPath : ErrorPath(); @@ -760,21 +760,21 @@ void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow: reportError(std::move(errorPath), Severity::error, "danglingLifetime", msg + ".", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckAutoVariables::errorDanglingTempReference(const Token* tok, ErrorPath errorPath, bool inconclusive) +void CheckAutoVariablesImpl::errorDanglingTempReference(const Token* tok, ErrorPath errorPath, bool inconclusive) { errorPath.emplace_back(tok, ""); reportError( std::move(errorPath), Severity::error, "danglingTempReference", "Using reference to dangling temporary.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckAutoVariables::errorReturnReference(const Token* tok, ErrorPath errorPath, bool inconclusive) +void CheckAutoVariablesImpl::errorReturnReference(const Token* tok, ErrorPath errorPath, bool inconclusive) { errorPath.emplace_back(tok, ""); reportError( std::move(errorPath), Severity::error, "returnReference", "Reference to local variable returned.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckAutoVariables::errorDanglingReference(const Token *tok, const Variable *var, ErrorPath errorPath) +void CheckAutoVariablesImpl::errorDanglingReference(const Token *tok, const Variable *var, ErrorPath errorPath) { std::string tokName = tok ? tok->str() : "x"; std::string varName = var ? var->name() : "y"; @@ -783,14 +783,14 @@ void CheckAutoVariables::errorDanglingReference(const Token *tok, const Variable reportError(std::move(errorPath), Severity::error, "danglingReference", msg, CWE562, Certainty::normal); } -void CheckAutoVariables::errorReturnTempReference(const Token* tok, ErrorPath errorPath, bool inconclusive) +void CheckAutoVariablesImpl::errorReturnTempReference(const Token* tok, ErrorPath errorPath, bool inconclusive) { errorPath.emplace_back(tok, ""); reportError( std::move(errorPath), Severity::error, "returnTempReference", "Reference to temporary returned.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueFlow::Value *val) +void CheckAutoVariablesImpl::errorInvalidDeallocation(const Token *tok, const ValueFlow::Value *val) { const Variable *var = val ? val->tokvalue->variable() : (tok ? tok->variable() : nullptr); @@ -819,7 +819,7 @@ void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueF void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckAutoVariables checkAutoVariables(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckAutoVariablesImpl checkAutoVariables(&tokenizer, &tokenizer.getSettings(), errorLogger); checkAutoVariables.assignFunctionArg(); checkAutoVariables.autoVariables(); checkAutoVariables.checkVarLifetime(); @@ -827,7 +827,7 @@ void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger *erro void CheckAutoVariables::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckAutoVariables c(nullptr,settings,errorLogger); + CheckAutoVariablesImpl c(nullptr,settings,errorLogger); c.errorAutoVariableAssignment(nullptr, false); c.errorReturnReference(nullptr, ErrorPath{}, false); c.errorDanglingReference(nullptr, nullptr, ErrorPath{}); diff --git a/lib/checkautovariables.h b/lib/checkautovariables.h index d94f254508f..39e6ceb10d5 100644 --- a/lib/checkautovariables.h +++ b/lib/checkautovariables.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include "errortypes.h" @@ -47,16 +48,33 @@ namespace ValueFlow { class CPPCHECKLIB CheckAutoVariables : public Check { public: /** This constructor is used when registering the CheckClass */ - CheckAutoVariables() : Check(myName()) {} + CheckAutoVariables() : Check("Auto Variables") {} private: - /** This constructor is used when running checks. */ - CheckAutoVariables(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "A pointer to a variable is only valid as long as the variable is in scope.\n" + "Check:\n" + "- returning a pointer to auto or temporary variable\n" + "- assigning address of an variable to an effective parameter of a function\n" + "- returning reference to local/temporary variable\n" + "- returning address of function parameter\n" + "- suspicious assignment of pointer argument\n" + "- useless assignment of function argument\n"; + } +}; + +class CPPCHECKLIB CheckAutoVariablesImpl : public CheckImpl +{ +public: + /** This constructor is used when running checks. */ + CheckAutoVariablesImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** assign function argument */ void assignFunctionArg(); @@ -69,7 +87,6 @@ class CPPCHECKLIB CheckAutoVariables : public Check { bool checkAutoVariableAssignment(const Token *expr, bool inconclusive, const Token *startToken = nullptr); void checkVarLifetime(); - void checkVarLifetimeScope(const Token * start, const Token * end); void errorAutoVariableAssignment(const Token *tok, bool inconclusive); @@ -85,24 +102,8 @@ class CPPCHECKLIB CheckAutoVariables : public Check { void errorUselessAssignmentArg(const Token *tok); void errorUselessAssignmentPtrArg(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Auto Variables"; - } - - std::string classInfo() const override { - return "A pointer to a variable is only valid as long as the variable is in scope.\n" - "Check:\n" - "- returning a pointer to auto or temporary variable\n" - "- assigning address of an variable to an effective parameter of a function\n" - "- returning reference to local/temporary variable\n" - "- returning address of function parameter\n" - "- suspicious assignment of pointer argument\n" - "- useless assignment of function argument\n"; - } - /** returns true if tokvalue has already been diagnosed */ +private: bool diag(const Token* tokvalue); std::set mDiagDanglingTemp; diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index c9a66876317..e4f55f26085 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -43,7 +43,7 @@ static bool isBool(const Variable* var) } //--------------------------------------------------------------------------- -void CheckBool::checkIncrementBoolean() +void CheckBoolImpl::checkIncrementBoolean() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("incrementboolean")) return; @@ -60,7 +60,7 @@ void CheckBool::checkIncrementBoolean() } } -void CheckBool::incrementBooleanError(const Token *tok) +void CheckBoolImpl::incrementBooleanError(const Token *tok) { reportError( tok, @@ -83,7 +83,7 @@ static bool isConvertedToBool(const Token* tok) // if (bool & bool) -> if (bool && bool) // if (bool | bool) -> if (bool || bool) //--------------------------------------------------------------------------- -void CheckBool::checkBitwiseOnBoolean() +void CheckBoolImpl::checkBitwiseOnBoolean() { if (!mSettings->isPremiumEnabled("bitwiseOnBoolean") && !mSettings->severity.isEnabled(Severity::style) && @@ -127,7 +127,7 @@ void CheckBool::checkBitwiseOnBoolean() } } -void CheckBool::bitwiseOnBooleanError(const Token* tok, const std::string& expression, const std::string& op, bool isCompound) +void CheckBoolImpl::bitwiseOnBooleanError(const Token* tok, const std::string& expression, const std::string& op, bool isCompound) { std::string msg = "Boolean expression '" + expression + "' is used in bitwise operation."; if (!isCompound) @@ -144,7 +144,7 @@ void CheckBool::bitwiseOnBooleanError(const Token* tok, const std::string& expre // if (!x==3) <- Probably meant to be "x!=3" //--------------------------------------------------------------------------- -void CheckBool::checkComparisonOfBoolWithInt() +void CheckBoolImpl::checkComparisonOfBoolWithInt() { if (!mSettings->severity.isEnabled(Severity::warning) || !mTokenizer->isCPP()) return; @@ -171,7 +171,7 @@ void CheckBool::checkComparisonOfBoolWithInt() } } -void CheckBool::comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression) +void CheckBoolImpl::comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression) { reportError(tok, Severity::warning, "comparisonOfBoolWithInvalidComparator", "Comparison of a boolean value using relational operator (<, >, <= or >=).\n" @@ -195,7 +195,7 @@ static bool tokenIsFunctionReturningBool(const Token* tok) return false; } -void CheckBool::checkComparisonOfFuncReturningBool() +void CheckBoolImpl::checkComparisonOfFuncReturningBool() { if (!mSettings->severity.isEnabled(Severity::style)) return; @@ -239,7 +239,7 @@ void CheckBool::checkComparisonOfFuncReturningBool() } } -void CheckBool::comparisonOfFuncReturningBoolError(const Token *tok, const std::string &expression) +void CheckBoolImpl::comparisonOfFuncReturningBoolError(const Token *tok, const std::string &expression) { reportError(tok, Severity::style, "comparisonOfFuncReturningBoolError", "Comparison of a function returning boolean value using relational (<, >, <= or >=) operator.\n" @@ -248,7 +248,7 @@ void CheckBool::comparisonOfFuncReturningBoolError(const Token *tok, const std:: " operator could cause unexpected results.", CWE398, Certainty::normal); } -void CheckBool::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const std::string &expression1, const std::string &expression2) +void CheckBoolImpl::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const std::string &expression1, const std::string &expression2) { reportError(tok, Severity::style, "comparisonOfTwoFuncsReturningBoolError", "Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n" @@ -261,7 +261,7 @@ void CheckBool::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const s // Comparison of bool with bool //------------------------------------------------------------------------------- -void CheckBool::checkComparisonOfBoolWithBool() +void CheckBoolImpl::checkComparisonOfBoolWithBool() { if (!mSettings->severity.isEnabled(Severity::style)) return; @@ -302,7 +302,7 @@ void CheckBool::checkComparisonOfBoolWithBool() } } -void CheckBool::comparisonOfBoolWithBoolError(const Token *tok, const std::string &expression) +void CheckBoolImpl::comparisonOfBoolWithBoolError(const Token *tok, const std::string &expression) { reportError(tok, Severity::style, "comparisonOfBoolWithBoolError", "Comparison of a variable having boolean value using relational (<, >, <= or >=) operator.\n" @@ -312,7 +312,7 @@ void CheckBool::comparisonOfBoolWithBoolError(const Token *tok, const std::strin } //----------------------------------------------------------------------------- -void CheckBool::checkAssignBoolToPointer() +void CheckBoolImpl::checkAssignBoolToPointer() { logChecker("CheckBool::checkAssignBoolToPointer"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -325,7 +325,7 @@ void CheckBool::checkAssignBoolToPointer() } } -void CheckBool::assignBoolToPointerError(const Token *tok) +void CheckBoolImpl::assignBoolToPointerError(const Token *tok) { reportError(tok, Severity::error, "assignBoolToPointer", "Boolean value assigned to pointer.", CWE587, Certainty::normal); @@ -333,7 +333,7 @@ void CheckBool::assignBoolToPointerError(const Token *tok) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CheckBool::checkComparisonOfBoolExpressionWithInt() +void CheckBoolImpl::checkComparisonOfBoolExpressionWithInt() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("compareBoolExpressionWithInt")) return; @@ -393,7 +393,7 @@ void CheckBool::checkComparisonOfBoolExpressionWithInt() } } -void CheckBool::comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1) +void CheckBoolImpl::comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1) { if (not0or1) reportError(tok, Severity::warning, "compareBoolExpressionWithInt", @@ -404,7 +404,7 @@ void CheckBool::comparisonOfBoolExpressionWithIntError(const Token *tok, bool no } -void CheckBool::pointerArithBool() +void CheckBoolImpl::pointerArithBool() { logChecker("CheckBool::pointerArithBool"); @@ -427,7 +427,7 @@ void CheckBool::pointerArithBool() } } -void CheckBool::pointerArithBoolCond(const Token *tok) +void CheckBoolImpl::pointerArithBoolCond(const Token *tok) { if (!tok) return; @@ -447,7 +447,7 @@ void CheckBool::pointerArithBoolCond(const Token *tok) pointerArithBoolError(tok); } -void CheckBool::pointerArithBoolError(const Token *tok) +void CheckBoolImpl::pointerArithBoolError(const Token *tok) { reportError(tok, Severity::error, @@ -456,7 +456,7 @@ void CheckBool::pointerArithBoolError(const Token *tok) "Converting pointer arithmetic result to bool. The boolean result is always true unless there is pointer arithmetic overflow, and overflow is undefined behaviour. Probably a dereference is forgotten.", CWE571, Certainty::normal); } -void CheckBool::checkAssignBoolToFloat() +void CheckBoolImpl::checkAssignBoolToFloat() { if (!mTokenizer->isCPP()) return; @@ -473,13 +473,13 @@ void CheckBool::checkAssignBoolToFloat() } } -void CheckBool::assignBoolToFloatError(const Token *tok) +void CheckBoolImpl::assignBoolToFloatError(const Token *tok) { reportError(tok, Severity::style, "assignBoolToFloat", "Boolean value assigned to floating point variable.", CWE704, Certainty::normal); } -void CheckBool::returnValueOfFunctionReturningBool() +void CheckBoolImpl::returnValueOfFunctionReturningBool() { if (!mSettings->severity.isEnabled(Severity::style)) return; @@ -507,14 +507,14 @@ void CheckBool::returnValueOfFunctionReturningBool() } } -void CheckBool::returnValueBoolError(const Token *tok) +void CheckBoolImpl::returnValueBoolError(const Token *tok) { reportError(tok, Severity::style, "returnNonBoolInBooleanFunction", "Non-boolean value returned from function returning bool"); } void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckBool checkBool(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckBoolImpl checkBool(&tokenizer, &tokenizer.getSettings(), errorLogger); // Checks checkBool.checkComparisonOfBoolExpressionWithInt(); @@ -531,7 +531,7 @@ void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) void CheckBool::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckBool c(nullptr, settings, errorLogger); + CheckBoolImpl c(nullptr, settings, errorLogger); c.assignBoolToPointerError(nullptr); c.assignBoolToFloatError(nullptr); c.comparisonOfFuncReturningBoolError(nullptr, "func_name"); diff --git a/lib/checkbool.h b/lib/checkbool.h index 65e5d0254ea..607d9c4a4b7 100644 --- a/lib/checkbool.h +++ b/lib/checkbool.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -41,16 +42,34 @@ class Tokenizer; class CPPCHECKLIB CheckBool : public Check { public: /** @brief This constructor is used when registering the CheckClass */ - CheckBool() : Check(myName()) {} + CheckBool() : Check("Boolean") {} private: - /** @brief This constructor is used when running checks. */ - CheckBool(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Boolean type checks\n" + "- using increment on boolean\n" + "- comparison of a boolean expression with an integer other than 0 or 1\n" + "- comparison of a function returning boolean value using relational operator\n" + "- comparison of a boolean value with boolean value using relational operator\n" + "- using bool in bitwise expression\n" + "- pointer addition in condition (either dereference is forgot or pointer overflow is required to make the condition false)\n" + "- Assigning bool value to pointer or float\n" + "- Returning an integer other than 0 or 1 from a function with boolean return value\n"; + } +}; + +class CPPCHECKLIB CheckBoolImpl : public CheckImpl +{ +public: + /** @brief This constructor is used when running checks. */ + CheckBoolImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** @brief %Check for comparison of function returning bool*/ void checkComparisonOfFuncReturningBool(); @@ -94,24 +113,6 @@ class CPPCHECKLIB CheckBool : public Check { void comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1); void pointerArithBoolError(const Token *tok); void returnValueBoolError(const Token *tok); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Boolean"; - } - - std::string classInfo() const override { - return "Boolean type checks\n" - "- using increment on boolean\n" - "- comparison of a boolean expression with an integer other than 0 or 1\n" - "- comparison of a function returning boolean value using relational operator\n" - "- comparison of a boolean value with boolean value using relational operator\n" - "- using bool in bitwise expression\n" - "- pointer addition in condition (either dereference is forgot or pointer overflow is required to make the condition false)\n" - "- Assigning bool value to pointer or float\n" - "- Returning an integer other than 0 or 1 from a function with boolean return value\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 3ba41882316..592e4268f58 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -284,7 +284,7 @@ static std::vector getOverrunIndexValues(const Token* tok, return {}; } -void CheckBufferOverrun::arrayIndex() +void CheckBufferOverrunImpl::arrayIndex() { logChecker("CheckBufferOverrun::arrayIndex"); @@ -405,9 +405,9 @@ static std::string arrayIndexMessage(const Token* tok, return errmsg.str(); } -void CheckBufferOverrun::arrayIndexError(const Token* tok, - const std::vector& dimensions, - const std::vector& indexes) +void CheckBufferOverrunImpl::arrayIndexError(const Token* tok, + const std::vector& dimensions, + const std::vector& indexes) { if (!tok) { reportError(tok, Severity::error, "arrayIndexOutOfBounds", "Array 'arr[16]' accessed at index 16, which is out of bounds.", CWE_BUFFER_OVERRUN, Certainty::normal); @@ -434,9 +434,9 @@ void CheckBufferOverrun::arrayIndexError(const Token* tok, index->isInconclusive() ? Certainty::inconclusive : Certainty::normal); } -void CheckBufferOverrun::negativeIndexError(const Token* tok, - const std::vector& dimensions, - const std::vector& indexes) +void CheckBufferOverrunImpl::negativeIndexError(const Token* tok, + const std::vector& dimensions, + const std::vector& indexes) { if (!tok) { reportError(tok, Severity::error, "negativeIndex", "Negative array index", CWE_BUFFER_UNDERRUN, Certainty::normal); @@ -464,7 +464,7 @@ void CheckBufferOverrun::negativeIndexError(const Token* tok, //--------------------------------------------------------------------------- -void CheckBufferOverrun::pointerArithmetic() +void CheckBufferOverrunImpl::pointerArithmetic() { if (!mSettings->severity.isEnabled(Severity::portability) && !mSettings->isPremiumEnabled("pointerOutOfBounds")) return; @@ -528,7 +528,7 @@ void CheckBufferOverrun::pointerArithmetic() } } -void CheckBufferOverrun::pointerArithmeticError(const Token *tok, const Token *indexToken, const ValueFlow::Value *indexValue) +void CheckBufferOverrunImpl::pointerArithmeticError(const Token *tok, const Token *indexToken, const ValueFlow::Value *indexValue) { if (!tok) { reportError(tok, Severity::portability, "pointerOutOfBounds", "Pointer arithmetic overflow.", CWE_POINTER_ARITHMETIC_OVERFLOW, Certainty::normal); @@ -552,7 +552,7 @@ void CheckBufferOverrun::pointerArithmeticError(const Token *tok, const Token *i //--------------------------------------------------------------------------- -ValueFlow::Value CheckBufferOverrun::getBufferSize(const Token *bufTok) const +ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) const { if (!bufTok->valueType()) return ValueFlow::Value(-1); @@ -634,7 +634,7 @@ static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::Mi } -void CheckBufferOverrun::bufferOverflow() +void CheckBufferOverrunImpl::bufferOverflow() { logChecker("CheckBufferOverrun::bufferOverflow"); @@ -691,14 +691,14 @@ void CheckBufferOverrun::bufferOverflow() } } -void CheckBufferOverrun::bufferOverflowError(const Token *tok, const ValueFlow::Value *value, Certainty certainty) +void CheckBufferOverrunImpl::bufferOverflowError(const Token *tok, const ValueFlow::Value *value, Certainty certainty) { reportError(getErrorPath(tok, value, "Buffer overrun"), Severity::error, "bufferAccessOutOfBounds", "Buffer is accessed out of bounds: " + (tok ? getRealBufferTok(tok)->expressionString() : "buf"), CWE_BUFFER_OVERRUN, certainty); } //--------------------------------------------------------------------------- -void CheckBufferOverrun::arrayIndexThenCheck() +void CheckBufferOverrunImpl::arrayIndexThenCheck() { if (!mSettings->severity.isEnabled(Severity::style)) return; @@ -742,7 +742,7 @@ void CheckBufferOverrun::arrayIndexThenCheck() } } -void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::string &indexName) +void CheckBufferOverrunImpl::arrayIndexThenCheckError(const Token *tok, const std::string &indexName) { reportError(tok, Severity::style, "arrayIndexThenCheck", "$symbol:" + indexName + "\n" @@ -755,7 +755,7 @@ void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::s //--------------------------------------------------------------------------- -void CheckBufferOverrun::stringNotZeroTerminated() +void CheckBufferOverrunImpl::stringNotZeroTerminated() { // this is currently 'inconclusive'. See TestBufferOverrun::terminateStrncpy3 if (!mSettings->severity.isEnabled(Severity::warning) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) @@ -808,7 +808,7 @@ void CheckBufferOverrun::stringNotZeroTerminated() } } -void CheckBufferOverrun::terminateStrncpyError(const Token *tok, const std::string &varname) +void CheckBufferOverrunImpl::terminateStrncpyError(const Token *tok, const std::string &varname) { const std::string shortMessage = "The buffer '$symbol' may not be null-terminated after the call to strncpy()."; reportError(tok, Severity::warning, "terminateStrncpy", @@ -821,7 +821,7 @@ void CheckBufferOverrun::terminateStrncpyError(const Token *tok, const std::stri } //--------------------------------------------------------------------------- -void CheckBufferOverrun::argumentSize() +void CheckBufferOverrunImpl::argumentSize() { // Check '%type% x[10]' arguments if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("argumentSize")) @@ -869,7 +869,7 @@ void CheckBufferOverrun::argumentSize() } } -void CheckBufferOverrun::argumentSizeError(const Token *tok, const std::string &functionName, nonneg int paramIndex, const std::string ¶mExpression, const Variable *paramVar, const Variable *functionArg) +void CheckBufferOverrunImpl::argumentSizeError(const Token *tok, const std::string &functionName, nonneg int paramIndex, const std::string ¶mExpression, const Variable *paramVar, const Variable *functionArg) { const std::string strParamNum = std::to_string(paramIndex + 1) + getOrdinalText(paramIndex + 1); ErrorPath errorPath; @@ -920,7 +920,7 @@ namespace }; } -bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset, int type) +bool CheckBufferOverrunImpl::isCtuUnsafeBufferUsage(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset, int type) { if (!offset) return false; @@ -941,12 +941,12 @@ bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Settings &settings, const return true; } -bool CheckBufferOverrun::isCtuUnsafeArrayIndex(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset) +bool CheckBufferOverrunImpl::isCtuUnsafeArrayIndex(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset) { return isCtuUnsafeBufferUsage(settings, argtok, offset, 1); } -bool CheckBufferOverrun::isCtuUnsafePointerArith(const Settings &settings, const Token *argtok, CTU::FileInfo::Value* offset) +bool CheckBufferOverrunImpl::isCtuUnsafePointerArith(const Settings &settings, const Token *argtok, CTU::FileInfo::Value* offset) { return isCtuUnsafeBufferUsage(settings, argtok, offset, 2); } @@ -954,8 +954,8 @@ bool CheckBufferOverrun::isCtuUnsafePointerArith(const Settings &settings, const /** @brief Parse current TU and extract file info */ Check::FileInfo *CheckBufferOverrun::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const { - const std::list &unsafeArrayIndex = CTU::getUnsafeUsage(tokenizer, settings, isCtuUnsafeArrayIndex); - const std::list &unsafePointerArith = CTU::getUnsafeUsage(tokenizer, settings, isCtuUnsafePointerArith); + const std::list &unsafeArrayIndex = CTU::getUnsafeUsage(tokenizer, settings, CheckBufferOverrunImpl::isCtuUnsafeArrayIndex); + const std::list &unsafePointerArith = CTU::getUnsafeUsage(tokenizer, settings, CheckBufferOverrunImpl::isCtuUnsafePointerArith); if (unsafeArrayIndex.empty() && unsafePointerArith.empty()) { return nullptr; } @@ -967,7 +967,6 @@ Check::FileInfo *CheckBufferOverrun::getFileInfo(const Tokenizer &tokenizer, con Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const { - // cppcheck-suppress shadowFunction - TODO: fix this const std::string arrayIndex("array-index"); const std::string pointerArith("pointer-arith"); @@ -991,7 +990,7 @@ Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLEle /** @brief Analyse all file infos for all TU */ bool CheckBufferOverrun::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) { - CheckBufferOverrun dummy(nullptr, &settings, &errorLogger); + CheckBufferOverrunImpl dummy(nullptr, &settings, &errorLogger); dummy. logChecker("CheckBufferOverrun::analyseWholeProgram"); @@ -1058,7 +1057,7 @@ bool CheckBufferOverrun::analyseWholeProgram1(const std::mapgetSymbolDatabase(); @@ -1130,7 +1129,7 @@ void CheckBufferOverrun::objectIndex() } } -void CheckBufferOverrun::objectIndexError(const Token *tok, const ValueFlow::Value *v, bool known) +void CheckBufferOverrunImpl::objectIndexError(const Token *tok, const ValueFlow::Value *v, bool known) { ErrorPath errorPath; std::string name; @@ -1167,7 +1166,7 @@ static bool isVLAIndex(const Token* tok) return isVLAIndex(tok->astOperand1()) || isVLAIndex(tok->astOperand2()); } -void CheckBufferOverrun::negativeArraySize() +void CheckBufferOverrunImpl::negativeArraySize() { logChecker("CheckBufferOverrun::negativeArraySize"); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1197,7 +1196,7 @@ void CheckBufferOverrun::negativeArraySize() } } -void CheckBufferOverrun::negativeArraySizeError(const Token* tok) +void CheckBufferOverrunImpl::negativeArraySizeError(const Token* tok) { const std::string arrayName = tok ? tok->expressionString() : std::string(); const std::string line1 = arrayName.empty() ? std::string() : ("$symbol:" + arrayName + '\n'); @@ -1206,7 +1205,7 @@ void CheckBufferOverrun::negativeArraySizeError(const Token* tok) "Declaration of array '" + arrayName + "' with negative size is undefined behaviour", CWE758, Certainty::normal); } -void CheckBufferOverrun::negativeMemoryAllocationSizeError(const Token* tok, const ValueFlow::Value* value) +void CheckBufferOverrunImpl::negativeMemoryAllocationSizeError(const Token* tok, const ValueFlow::Value* value) { const std::string msg = "Memory allocation size is negative."; ErrorPath errorPath = getErrorPath(tok, value, msg); @@ -1217,7 +1216,7 @@ void CheckBufferOverrun::negativeMemoryAllocationSizeError(const Token* tok, con void CheckBufferOverrun::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckBufferOverrun checkBufferOverrun(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckBufferOverrunImpl checkBufferOverrun(&tokenizer, &tokenizer.getSettings(), errorLogger); checkBufferOverrun.arrayIndex(); checkBufferOverrun.pointerArithmetic(); checkBufferOverrun.bufferOverflow(); @@ -1230,7 +1229,7 @@ void CheckBufferOverrun::runChecks(const Tokenizer &tokenizer, ErrorLogger *erro void CheckBufferOverrun::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckBufferOverrun c(nullptr, settings, errorLogger); + CheckBufferOverrunImpl c(nullptr, settings, errorLogger); c.arrayIndexError(nullptr, std::vector(), std::vector()); c.pointerArithmeticError(nullptr, nullptr, nullptr); c.negativeIndexError(nullptr, std::vector(), std::vector()); diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 9c6e1f0386d..fdf47121bb8 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include "ctu.h" @@ -60,23 +61,44 @@ namespace ValueFlow class CPPCHECKLIB CheckBufferOverrun : public Check { public: /** This constructor is used when registering the CheckClass */ - CheckBufferOverrun() : Check(myName()) {} + CheckBufferOverrun() : Check("Bounds checking") {} private: - /** This constructor is used when running checks. */ - CheckBufferOverrun(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - /** @brief Parse current TU and extract file info */ Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; /** @brief Analyse all file infos for all TU */ bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; + + std::string classInfo() const override { + return "Out of bounds checking:\n" + "- Array index out of bounds\n" + "- Pointer arithmetic overflow\n" + "- Buffer overflow\n" + "- Dangerous usage of strncat()\n" + "- Using array index before checking it\n" + "- Partial string write that leads to buffer that is not zero terminated.\n" + "- Check for large enough arrays being passed to functions\n" + "- Allocating memory with a negative size\n"; + } + + static bool analyseWholeProgram1(const std::map> &callsMap, const CTU::FileInfo::UnsafeUsage &unsafeUsage, + int type, ErrorLogger &errorLogger, int maxCtuDepth, const std::string& file0); +}; + +class CPPCHECKLIB CheckBufferOverrunImpl : public CheckImpl +{ +public: + /** This constructor is used when running checks. */ + CheckBufferOverrunImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + void arrayIndex(); void arrayIndexError(const Token* tok, const std::vector& dimensions, @@ -113,27 +135,6 @@ class CPPCHECKLIB CheckBufferOverrun : public Check { static bool isCtuUnsafeBufferUsage(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset, int type); static bool isCtuUnsafeArrayIndex(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset); static bool isCtuUnsafePointerArith(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset); - - Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; - static bool analyseWholeProgram1(const std::map> &callsMap, const CTU::FileInfo::UnsafeUsage &unsafeUsage, - int type, ErrorLogger &errorLogger, int maxCtuDepth, const std::string& file0); - - - static std::string myName() { - return "Bounds checking"; - } - - std::string classInfo() const override { - return "Out of bounds checking:\n" - "- Array index out of bounds\n" - "- Pointer arithmetic overflow\n" - "- Buffer overflow\n" - "- Dangerous usage of strncat()\n" - "- Using array index before checking it\n" - "- Partial string write that leads to buffer that is not zero terminated.\n" - "- Check for large enough arrays being passed to functions\n" - "- Allocating memory with a negative size\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 3313fb636ed..c5b8507f301 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -106,12 +106,12 @@ static bool isVclTypeInit(const Type *type) } //--------------------------------------------------------------------------- -CheckClass::CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger), +CheckClassImpl::CheckClassImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger), mSymbolDatabase(tokenizer?tokenizer->getSymbolDatabase():nullptr) {} -bool CheckClass::isInitialized(const CheckClass::Usage& usage, FunctionType funcType) const +bool CheckClassImpl::isInitialized(const Usage& usage, FunctionType funcType) const { const Variable& var = *usage.var; @@ -170,7 +170,7 @@ bool CheckClass::isInitialized(const CheckClass::Usage& usage, FunctionType func return false; } -void CheckClass::handleUnionMembers(std::vector& usageList) +void CheckClassImpl::handleUnionMembers(std::vector& usageList) { // Assign 1 union member => assign all union members for (const Usage& usage : usageList) { @@ -199,7 +199,7 @@ void CheckClass::handleUnionMembers(std::vector& usageList) // ClassCheck: Check that all class constructors are ok. //--------------------------------------------------------------------------- -void CheckClass::constructors() +void CheckClassImpl::constructors() { const bool printStyle = mSettings->severity.isEnabled(Severity::style); const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); @@ -385,7 +385,7 @@ static bool isPermissibleConversion(const std::string& type) return type == "std::initializer_list" || type == "std::nullptr_t"; } -void CheckClass::checkExplicitConstructors() +void CheckClassImpl::checkExplicitConstructors() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("noExplicitConstructor")) return; @@ -454,7 +454,7 @@ static bool hasNonCopyableBase(const Scope *scope, bool *unknown) return false; } -void CheckClass::copyconstructors() +void CheckClassImpl::copyconstructors() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -611,7 +611,7 @@ void CheckClass::copyconstructors() } */ -void CheckClass::copyConstructorShallowCopyError(const Token *tok, const std::string& varname) +void CheckClassImpl::copyConstructorShallowCopyError(const Token *tok, const std::string& varname) { reportError(tok, Severity::warning, "copyCtorPointerCopying", "$symbol:" + varname + "\nValue of pointer '$symbol', which points to allocated memory, is copied in copy constructor instead of allocating new memory.", CWE398, Certainty::normal); @@ -637,22 +637,22 @@ static std::string noMemberErrorMessage(const Scope *scope, const char function[ return errmsg; } -void CheckClass::noCopyConstructorError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive) +void CheckClassImpl::noCopyConstructorError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive) { reportError(alloc, Severity::warning, "noCopyConstructor", noMemberErrorMessage(scope, "copy constructor", isdefault), CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckClass::noOperatorEqError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive) +void CheckClassImpl::noOperatorEqError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive) { reportError(alloc, Severity::warning, "noOperatorEq", noMemberErrorMessage(scope, "operator=", isdefault), CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckClass::noDestructorError(const Scope *scope, bool isdefault, const Token *alloc) +void CheckClassImpl::noDestructorError(const Scope *scope, bool isdefault, const Token *alloc) { reportError(alloc, Severity::warning, "noDestructor", noMemberErrorMessage(scope, "destructor", isdefault), CWE398, Certainty::normal); } -bool CheckClass::canNotCopy(const Scope *scope) +bool CheckClassImpl::canNotCopy(const Scope *scope) { bool constructor = false; bool publicAssign = false; @@ -676,7 +676,7 @@ bool CheckClass::canNotCopy(const Scope *scope) return constructor && !(publicAssign || publicCopy); } -bool CheckClass::canNotMove(const Scope *scope) +bool CheckClassImpl::canNotMove(const Scope *scope) { bool constructor = false; bool publicAssign = false; @@ -721,7 +721,7 @@ static void getAllVariableMembers(const Scope *scope, std::vector CheckClass::createUsageList(const Scope *scope) +std::vector CheckClassImpl::createUsageList(const Scope *scope) { std::vector ret; std::vector varlist; @@ -733,7 +733,7 @@ std::vector CheckClass::createUsageList(const Scope *scope) return ret; } -void CheckClass::assignVar(std::vector &usageList, nonneg int varid) +void CheckClassImpl::assignVar(std::vector &usageList, nonneg int varid) { auto it = std::find_if(usageList.begin(), usageList.end(), [varid](const Usage& usage) { return usage.var->declarationId() == varid; @@ -742,7 +742,7 @@ void CheckClass::assignVar(std::vector &usageList, nonneg int varid) it->assign = true; } -void CheckClass::assignVar(std::vector &usageList, const Token* vartok) +void CheckClassImpl::assignVar(std::vector &usageList, const Token* vartok) { if (vartok->varId() > 0) { assignVar(usageList, vartok->varId()); @@ -756,7 +756,7 @@ void CheckClass::assignVar(std::vector &usageList, const Token* vartok) it->assign = true; } -void CheckClass::initVar(std::vector &usageList, nonneg int varid) +void CheckClassImpl::initVar(std::vector &usageList, nonneg int varid) { auto it = std::find_if(usageList.begin(), usageList.end(), [varid](const Usage& usage) { return usage.var->declarationId() == varid; @@ -765,13 +765,13 @@ void CheckClass::initVar(std::vector &usageList, nonneg int varid) it->init = true; } -void CheckClass::assignAllVar(std::vector &usageList) +void CheckClassImpl::assignAllVar(std::vector &usageList) { for (Usage & i : usageList) i.assign = true; } -void CheckClass::assignAllVarsVisibleFromScope(std::vector& usageList, const Scope* scope) +void CheckClassImpl::assignAllVarsVisibleFromScope(std::vector& usageList, const Scope* scope) { for (Usage& usage : usageList) { if (usage.var->scope() == scope) @@ -787,7 +787,7 @@ void CheckClass::assignAllVarsVisibleFromScope(std::vector& usageList, co } } -void CheckClass::clearAllVar(std::vector &usageList) +void CheckClassImpl::clearAllVar(std::vector &usageList) { for (Usage & i : usageList) { i.assign = false; @@ -795,7 +795,7 @@ void CheckClass::clearAllVar(std::vector &usageList) } } -bool CheckClass::isBaseClassMutableMemberFunc(const Token *tok, const Scope *scope) +bool CheckClassImpl::isBaseClassMutableMemberFunc(const Token *tok, const Scope *scope) { // Iterate through each base class... for (const Type::BaseInfo & i : scope->definedType->derivedFrom) { @@ -822,7 +822,7 @@ bool CheckClass::isBaseClassMutableMemberFunc(const Token *tok, const Scope *sco return false; } -void CheckClass::initializeVarList(const Function &func, std::list &callstack, const Scope *scope, std::vector &usage) const +void CheckClassImpl::initializeVarList(const Function &func, std::list &callstack, const Scope *scope, std::vector &usage) const { if (!func.functionScope) return; @@ -1154,7 +1154,7 @@ void CheckClass::initializeVarList(const Function &func, std::listseverity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedPrivateFunction")) return; @@ -1422,7 +1422,7 @@ void CheckClass::privateFunctions() } } -void CheckClass::unusedPrivateFunctionError(const Token* tok1, const Token *tok2, const std::string &classname, const std::string &funcname) +void CheckClassImpl::unusedPrivateFunctionError(const Token* tok1, const Token *tok2, const std::string &classname, const std::string &funcname) { std::list toks{ tok1 }; if (tok2) @@ -1444,7 +1444,7 @@ static const Scope* findFunctionOf(const Scope* scope) return nullptr; } -void CheckClass::checkMemset() +void CheckClassImpl::checkMemset() { logChecker("CheckClass::checkMemset"); const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); @@ -1540,7 +1540,7 @@ void CheckClass::checkMemset() } } -void CheckClass::checkMemsetType(const Scope *start, const Token *tok, const Scope *type, bool allocation, std::set parsedTypes) +void CheckClassImpl::checkMemsetType(const Scope *start, const Token *tok, const Scope *type, bool allocation, std::set parsedTypes) { // If type has been checked there is no need to check it again if (parsedTypes.find(type) != parsedTypes.end()) @@ -1606,7 +1606,7 @@ void CheckClass::checkMemsetType(const Scope *start, const Token *tok, const Sco } } -void CheckClass::mallocOnClassWarning(const Token* tok, const std::string &memfunc, const Token* classTok) +void CheckClassImpl::mallocOnClassWarning(const Token* tok, const std::string &memfunc, const Token* classTok) { std::list toks = { tok, classTok }; reportError(toks, Severity::warning, "mallocOnClassWarning", @@ -1616,7 +1616,7 @@ void CheckClass::mallocOnClassWarning(const Token* tok, const std::string &memfu "since no constructor is called and class members remain uninitialized. Consider using 'new' instead.", CWE762, Certainty::normal); } -void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc, const Token* classTok, const std::string &classname) +void CheckClassImpl::mallocOnClassError(const Token* tok, const std::string &memfunc, const Token* classTok, const std::string &classname) { std::list toks = { tok, classTok }; reportError(toks, Severity::error, "mallocOnClassError", @@ -1627,7 +1627,7 @@ void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc "since no constructor is called and class members remain uninitialized. Consider using 'new' instead.", CWE665, Certainty::normal); } -void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type, bool isContainer) +void CheckClassImpl::memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type, bool isContainer) { const std::string typeStr = isContainer ? std::string() : (type + " that contains a "); const std::string msg = "$symbol:" + memfunc + "\n" @@ -1639,14 +1639,14 @@ void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const reportError(tok, Severity::error, "memsetClass", msg, CWE762, Certainty::normal); } -void CheckClass::memsetErrorReference(const Token *tok, const std::string &memfunc, const std::string &type) +void CheckClassImpl::memsetErrorReference(const Token *tok, const std::string &memfunc, const std::string &type) { reportError(tok, Severity::error, "memsetClassReference", "$symbol:" + memfunc +"\n" "Using '" + memfunc + "' on " + type + " that contains a reference.", CWE665, Certainty::normal); } -void CheckClass::memsetErrorFloat(const Token *tok, const std::string &type) +void CheckClassImpl::memsetErrorFloat(const Token *tok, const std::string &type) { reportError(tok, Severity::portability, "memsetClassFloat", "Using memset() on " + type + " which contains a floating point number.\n" "Using memset() on " + type + " which contains a floating point number." @@ -1661,7 +1661,7 @@ void CheckClass::memsetErrorFloat(const Token *tok, const std::string &type) // operator= should return a reference to *this //--------------------------------------------------------------------------- -void CheckClass::operatorEqRetRefThis() +void CheckClassImpl::operatorEqRetRefThis() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("operatorEqRetRefThis")) return; @@ -1680,13 +1680,13 @@ void CheckClass::operatorEqRetRefThis() } } -void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last) +void CheckClassImpl::checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last) { std::set analyzedFunctions; checkReturnPtrThis(scope, func, tok, last, analyzedFunctions); } -void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last, std::set& analyzedFunctions) +void CheckClassImpl::checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last, std::set& analyzedFunctions) { bool foundReturn = false; @@ -1772,17 +1772,17 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co operatorEqMissingReturnStatementError(func->token, func->access == AccessControl::Public); } -void CheckClass::operatorEqRetRefThisError(const Token *tok) +void CheckClassImpl::operatorEqRetRefThisError(const Token *tok) { reportError(tok, Severity::style, "operatorEqRetRefThis", "'operator=' should return reference to 'this' instance.", CWE398, Certainty::normal); } -void CheckClass::operatorEqShouldBeLeftUnimplementedError(const Token *tok) +void CheckClassImpl::operatorEqShouldBeLeftUnimplementedError(const Token *tok) { reportError(tok, Severity::style, "operatorEqShouldBeLeftUnimplemented", "'operator=' should either return reference to 'this' instance or be declared private and left unimplemented.", CWE398, Certainty::normal); } -void CheckClass::operatorEqMissingReturnStatementError(const Token *tok, bool error) +void CheckClassImpl::operatorEqMissingReturnStatementError(const Token *tok, bool error) { if (error) { reportError(tok, Severity::error, "operatorEqMissingReturnStatement", "No 'return' statement in non-void function causes undefined behavior.", CWE398, Certainty::normal); @@ -1805,7 +1805,7 @@ void CheckClass::operatorEqMissingReturnStatementError(const Token *tok, bool er // assignment to self. //--------------------------------------------------------------------------- -void CheckClass::operatorEqToSelf() +void CheckClassImpl::operatorEqToSelf() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("operatorEqToSelf")) return; @@ -1846,7 +1846,7 @@ void CheckClass::operatorEqToSelf() } } -bool CheckClass::hasAllocationInIfScope(const Function *func, const Scope* scope, const Token *ifStatementScopeStart) const +bool CheckClassImpl::hasAllocationInIfScope(const Function *func, const Scope* scope, const Token *ifStatementScopeStart) const { const Token *end; if (ifStatementScopeStart->str() == "{") @@ -1856,12 +1856,12 @@ bool CheckClass::hasAllocationInIfScope(const Function *func, const Scope* scope return hasAllocation(func, scope, ifStatementScopeStart, end); } -bool CheckClass::hasAllocation(const Function *func, const Scope* scope) const +bool CheckClassImpl::hasAllocation(const Function *func, const Scope* scope) const { return hasAllocation(func, scope, func->functionScope->bodyStart, func->functionScope->bodyEnd); } -bool CheckClass::hasAllocation(const Function *func, const Scope* scope, const Token *start, const Token *end) const +bool CheckClassImpl::hasAllocation(const Function *func, const Scope* scope, const Token *start, const Token *end) const { if (!end) end = func->functionScope->bodyEnd; @@ -1907,7 +1907,7 @@ static bool isFalseKeyword(const Token* tok) * Checks if self-assignment test is inverse * For example 'if (this == &rhs)' */ -CheckClass::Bool CheckClass::isInverted(const Token *tok, const Token *rhs) +CheckClassImpl::Bool CheckClassImpl::isInverted(const Token *tok, const Token *rhs) { bool res = true; for (const Token *itr = tok; itr && itr->str()!="("; itr=itr->astParent()) { @@ -1936,7 +1936,7 @@ CheckClass::Bool CheckClass::isInverted(const Token *tok, const Token *rhs) return Bool::False; } -const Token * CheckClass::getIfStmtBodyStart(const Token *tok, const Token *rhs) +const Token * CheckClassImpl::getIfStmtBodyStart(const Token *tok, const Token *rhs) { const Token *top = tok->astTop(); if (Token::simpleMatch(top->link(), ") {")) { @@ -1952,7 +1952,7 @@ const Token * CheckClass::getIfStmtBodyStart(const Token *tok, const Token *rhs) return nullptr; } -bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs, const Token *&out_ifStatementScopeStart) +bool CheckClassImpl::hasAssignSelf(const Function *func, const Token *rhs, const Token *&out_ifStatementScopeStart) { if (!rhs) return false; @@ -1986,7 +1986,7 @@ bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs, const Tok return false; } -void CheckClass::operatorEqToSelfError(const Token *tok) +void CheckClassImpl::operatorEqToSelfError(const Token *tok) { reportError(tok, Severity::warning, "operatorEqToSelf", "'operator=' should check for assignment to self to avoid problems with dynamic memory.\n" @@ -1998,7 +1998,7 @@ void CheckClass::operatorEqToSelfError(const Token *tok) // A destructor in a base class should be virtual //--------------------------------------------------------------------------- -void CheckClass::virtualDestructor() +void CheckClassImpl::virtualDestructor() { // This error should only be given if: // * base class doesn't have virtual destructor @@ -2133,7 +2133,7 @@ void CheckClass::virtualDestructor() virtualDestructorError(func->tokenDef, func->name(), "", true); } -void CheckClass::virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived, bool inconclusive) +void CheckClassImpl::virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived, bool inconclusive) { if (inconclusive) { if (mSettings->severity.isEnabled(Severity::warning)) @@ -2154,7 +2154,7 @@ void CheckClass::virtualDestructorError(const Token *tok, const std::string &Bas // warn for "this-x". The indented code may be "this->x" //--------------------------------------------------------------------------- -void CheckClass::thisSubtraction() +void CheckClassImpl::thisSubtraction() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -2174,7 +2174,7 @@ void CheckClass::thisSubtraction() } } -void CheckClass::thisSubtractionError(const Token *tok) +void CheckClassImpl::thisSubtractionError(const Token *tok) { reportError(tok, Severity::warning, "thisSubtraction", "Suspicious pointer subtraction. Did you intend to write '->'?", CWE398, Certainty::normal); } @@ -2183,7 +2183,7 @@ void CheckClass::thisSubtractionError(const Token *tok) // can member function be const? //--------------------------------------------------------------------------- -void CheckClass::checkConst() +void CheckClassImpl::checkConst() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("functionConst") && @@ -2319,7 +2319,7 @@ static const Token* getFuncTokFromThis(const Token* tok) { return Token::Match(tok, "%name% (") ? tok : nullptr; } -bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const +bool CheckClassImpl::isMemberVar(const Scope *scope, const Token *tok) const { bool again = false; @@ -2406,7 +2406,7 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const return false; } -bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) +bool CheckClassImpl::isMemberFunc(const Scope *scope, const Token *tok) { if (!tok->function()) { if (Token::simpleMatch(tok->astParent(), ".") && Token::simpleMatch(tok->astParent()->astOperand1(), "this")) @@ -2449,7 +2449,7 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) return false; } -bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) +bool CheckClassImpl::isConstMemberFunc(const Scope *scope, const Token *tok) { if (!tok->function()) return false; @@ -2474,7 +2474,7 @@ bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) return false; } -const std::set CheckClass::stl_containers_not_const = { "map", "unordered_map", "std :: map|unordered_map <" }; // start pattern +const std::set CheckClassImpl::stl_containers_not_const = { "map", "unordered_map", "std :: map|unordered_map <" }; // start pattern static bool isNonConstPtrCast(const Token* tok) { @@ -2484,7 +2484,7 @@ static bool isNonConstPtrCast(const Token* tok) return !vt || (vt->pointer > 0 && !vt->isConst(vt->pointer)); } -bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, MemberAccess& memberAccessed) const +bool CheckClassImpl::checkConstFunc(const Scope *scope, const Function *func, MemberAccess& memberAccessed) const { if (mTokenizer->hasIfdef(func->functionScope->bodyStart, func->functionScope->bodyEnd)) return false; @@ -2758,12 +2758,12 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member return true; } -void CheckClass::checkConstError(const Token *tok, const std::string &classname, const std::string &funcname, bool suggestStatic, bool foundAllBaseClasses) +void CheckClassImpl::checkConstError(const Token *tok, const std::string &classname, const std::string &funcname, bool suggestStatic, bool foundAllBaseClasses) { checkConstError2(tok, nullptr, classname, funcname, suggestStatic, foundAllBaseClasses); } -void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const std::string &classname, const std::string &funcname, bool suggestStatic, bool foundAllBaseClasses) +void CheckClassImpl::checkConstError2(const Token *tok1, const Token *tok2, const std::string &classname, const std::string &funcname, bool suggestStatic, bool foundAllBaseClasses) { std::list toks{ tok1 }; if (tok2) @@ -2804,7 +2804,7 @@ namespace { // avoid one-definition-rule violation }; } -void CheckClass::initializerListOrder() +void CheckClassImpl::initializerListOrder() { if (!mSettings->isPremiumEnabled("initializerList")) { if (!mSettings->severity.isEnabled(Severity::style)) @@ -2883,7 +2883,7 @@ void CheckClass::initializerListOrder() } } -void CheckClass::initializerListError(const Token *tok1, const Token *tok2, const std::string &classname, const std::string &varname, const std::string& argname) +void CheckClassImpl::initializerListError(const Token *tok1, const Token *tok2, const std::string &classname, const std::string &varname, const std::string& argname) { std::list toks = { tok1, tok2 }; const std::string msg = argname.empty() ? @@ -2904,7 +2904,7 @@ void CheckClass::initializerListError(const Token *tok1, const Token *tok2, cons // Check for self initialization in initialization list //--------------------------------------------------------------------------- -void CheckClass::checkSelfInitialization() +void CheckClassImpl::checkSelfInitialization() { logChecker("CheckClass::checkSelfInitialization"); @@ -2933,7 +2933,7 @@ void CheckClass::checkSelfInitialization() } } -void CheckClass::selfInitializationError(const Token* tok, const std::string& varname) +void CheckClassImpl::selfInitializationError(const Token* tok, const std::string& varname) { reportError(tok, Severity::error, "selfInitialization", "$symbol:" + varname + "\nMember variable '$symbol' is initialized by itself.", CWE665, Certainty::normal); } @@ -2943,7 +2943,7 @@ void CheckClass::selfInitializationError(const Token* tok, const std::string& va // Check for virtual function calls in constructor/destructor //--------------------------------------------------------------------------- -void CheckClass::checkVirtualFunctionCallInConstructor() +void CheckClassImpl::checkVirtualFunctionCallInConstructor() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -2973,8 +2973,8 @@ void CheckClass::checkVirtualFunctionCallInConstructor() } } -const std::list & CheckClass::getVirtualFunctionCalls(const Function & function, - std::map> & virtualFunctionCallsMap) +const std::list & CheckClassImpl::getVirtualFunctionCalls(const Function & function, + std::map> & virtualFunctionCallsMap) { const auto found = utils::as_const(virtualFunctionCallsMap).find(&function); if (found != virtualFunctionCallsMap.end()) @@ -3031,7 +3031,7 @@ const std::list & CheckClass::getVirtualFunctionCalls(const Funct return virtualFunctionCalls; } -void CheckClass::getFirstVirtualFunctionCallStack( +void CheckClassImpl::getFirstVirtualFunctionCallStack( std::map> & virtualFunctionCallsMap, const Token * callToken, std::list & pureFuncStack) @@ -3051,7 +3051,7 @@ void CheckClass::getFirstVirtualFunctionCallStack( getFirstVirtualFunctionCallStack(virtualFunctionCallsMap, firstCall, pureFuncStack); } -void CheckClass::virtualFunctionCallInConstructorError( +void CheckClassImpl::virtualFunctionCallInConstructorError( const Function * scopeFunction, const std::list & tokStack, const std::string &funcname) @@ -3089,7 +3089,7 @@ void CheckClass::virtualFunctionCallInConstructorError( "Virtual function '" + funcname + "' is called from " + scopeFunctionTypeName + " '" + constructorName + "' at line " + std::to_string(lineNumber) + ". Dynamic binding is not used.", CWE(0U), Certainty::normal); } -void CheckClass::pureVirtualFunctionCallInConstructorError( +void CheckClassImpl::pureVirtualFunctionCallInConstructorError( const Function * scopeFunction, const std::list & tokStack, const std::string &purefuncname) @@ -3114,7 +3114,7 @@ void CheckClass::pureVirtualFunctionCallInConstructorError( // Check for members hiding inherited members with the same name //--------------------------------------------------------------------------- -void CheckClass::checkDuplInheritedMembers() +void CheckClassImpl::checkDuplInheritedMembers() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("duplInheritedMember")) return; @@ -3203,7 +3203,7 @@ static std::vector getDuplInheritedMemberFunctionsRecursive( return results; } -void CheckClass::checkDuplInheritedMembersRecursive(const Type* typeCurrent, const Type* typeBase) +void CheckClassImpl::checkDuplInheritedMembersRecursive(const Type* typeCurrent, const Type* typeBase) { const auto resultsVar = getDuplInheritedMembersRecursive(typeCurrent, typeBase); for (const auto& r : resultsVar) { @@ -3222,9 +3222,9 @@ void CheckClass::checkDuplInheritedMembersRecursive(const Type* typeCurrent, con } } -void CheckClass::duplInheritedMembersError(const Token *tok1, const Token* tok2, - const std::string &derivedName, const std::string &baseName, - const std::string &memberName, bool derivedIsStruct, bool baseIsStruct, bool isFunction) +void CheckClassImpl::duplInheritedMembersError(const Token *tok1, const Token* tok2, + const std::string &derivedName, const std::string &baseName, + const std::string &memberName, bool derivedIsStruct, bool baseIsStruct, bool isFunction) { ErrorPath errorPath; const std::string member = isFunction ? "function" : "variable"; @@ -3250,7 +3250,7 @@ enum class CtorType : std::uint8_t { WITH_BODY }; -void CheckClass::checkCopyCtorAndEqOperator() +void CheckClassImpl::checkCopyCtorAndEqOperator() { // TODO: This is disabled because of #8388 // The message must be clarified. How is the behaviour different? @@ -3302,7 +3302,7 @@ void CheckClass::checkCopyCtorAndEqOperator() } } -void CheckClass::copyCtorAndEqOperatorError(const Token *tok, const std::string &classname, bool isStruct, bool hasCopyCtor) +void CheckClassImpl::copyCtorAndEqOperatorError(const Token *tok, const std::string &classname, bool isStruct, bool hasCopyCtor) { const std::string message = "$symbol:" + classname + "\n" "The " + std::string(isStruct ? "struct" : "class") + " '$symbol' has '" + @@ -3312,7 +3312,7 @@ void CheckClass::copyCtorAndEqOperatorError(const Token *tok, const std::string reportError(tok, Severity::warning, "copyCtorAndEqOperator", message); } -void CheckClass::checkOverride() +void CheckClassImpl::checkOverride() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("missingOverride")) return; @@ -3336,7 +3336,7 @@ void CheckClass::checkOverride() } } -void CheckClass::overrideError(const Function *funcInBase, const Function *funcInDerived) +void CheckClassImpl::overrideError(const Function *funcInBase, const Function *funcInDerived) { const std::string functionName = funcInDerived ? ((funcInDerived->isDestructor() ? "~" : "") + funcInDerived->name()) : ""; const std::string funcType = (funcInDerived && funcInDerived->isDestructor()) ? "destructor" : "function"; @@ -3354,7 +3354,7 @@ void CheckClass::overrideError(const Function *funcInBase, const Function *funcI Certainty::normal); } -void CheckClass::uselessOverrideError(const Function *funcInBase, const Function *funcInDerived, bool isSameCode) +void CheckClassImpl::uselessOverrideError(const Function *funcInBase, const Function *funcInDerived, bool isSameCode) { const std::string functionName = funcInDerived ? ((funcInDerived->isDestructor() ? "~" : "") + funcInDerived->name()) : ""; const std::string funcType = (funcInDerived && funcInDerived->isDestructor()) ? "destructor" : "function"; @@ -3418,7 +3418,7 @@ static bool compareTokenRanges(const Token* start1, const Token* end1, const Tok return isEqual; } -void CheckClass::checkUselessOverride() +void CheckClassImpl::checkUselessOverride() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("uselessOverride")) return; @@ -3499,7 +3499,7 @@ static const Variable* getSingleReturnVar(const Scope* scope) { return tok->variable(); } -void CheckClass::checkReturnByReference() +void CheckClassImpl::checkReturnByReference() { if (!mSettings->severity.isEnabled(Severity::performance) && !mSettings->isPremiumEnabled("returnByReference")) return; @@ -3542,14 +3542,14 @@ void CheckClass::checkReturnByReference() } } -void CheckClass::returnByReferenceError(const Function* func, const Variable* var) +void CheckClassImpl::returnByReferenceError(const Function* func, const Variable* var) { const Token* tok = func ? func->tokenDef : nullptr; const std::string message = "Function '" + (func ? func->name() : "func") + "()' should return member '" + (var ? var->name() : "var") + "' by const reference."; reportError(tok, Severity::performance, "returnByReference", message); } -void CheckClass::checkThisUseAfterFree() +void CheckClassImpl::checkThisUseAfterFree() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -3598,7 +3598,7 @@ void CheckClass::checkThisUseAfterFree() } } -bool CheckClass::checkThisUseAfterFreeRecursive(const Scope *classScope, const Function *func, const Variable *selfPointer, std::set callstack, const Token *&freeToken) +bool CheckClassImpl::checkThisUseAfterFreeRecursive(const Scope *classScope, const Function *func, const Variable *selfPointer, std::set callstack, const Token *&freeToken) { if (!func || !func->functionScope) return false; @@ -3637,7 +3637,7 @@ bool CheckClass::checkThisUseAfterFreeRecursive(const Scope *classScope, const F return false; } -void CheckClass::thisUseAfterFree(const Token *self, const Token *free, const Token *use) +void CheckClassImpl::thisUseAfterFree(const Token *self, const Token *free, const Token *use) { std::string selfPointer = self ? self->str() : "ptr"; ErrorPath errorPath = { ErrorPathItem(self, "Assuming '" + selfPointer + "' is used as 'this'"), ErrorPathItem(free, "Delete '" + selfPointer + "', invalidating 'this'"), ErrorPathItem(use, "Call method when 'this' is invalid") }; @@ -3649,7 +3649,7 @@ void CheckClass::thisUseAfterFree(const Token *self, const Token *free, const To CWE(0), Certainty::normal); } -void CheckClass::checkUnsafeClassRefMember() +void CheckClassImpl::checkUnsafeClassRefMember() { if (!mSettings->safeChecks.classes || !mSettings->severity.isEnabled(Severity::warning)) return; @@ -3673,7 +3673,7 @@ void CheckClass::checkUnsafeClassRefMember() } } -void CheckClass::unsafeClassRefMemberError(const Token *tok, const std::string &varname) +void CheckClassImpl::unsafeClassRefMemberError(const Token *tok, const std::string &varname) { reportError(tok, Severity::warning, "unsafeClassRefMember", "$symbol:" + varname + "\n" @@ -3833,7 +3833,7 @@ bool CheckClass::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list @@ -54,18 +55,56 @@ class CPPCHECKLIB CheckClass : public Check { public: /** @brief This constructor is used when registering the CheckClass */ - CheckClass() : Check(myName()) {} - - /** @brief Set of the STL types whose operator[] is not const */ - static const std::set stl_containers_not_const; - -private: - /** @brief This constructor is used when running checks. */ - CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger); + CheckClass() : Check("Class") {} /** @brief Run checks on the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + /** @brief Parse current TU and extract file info */ + Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings& /*settings*/, const std::string& currentConfig) const override; + + Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; + + /** @brief Analyse all file infos for all TU */ + bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; + + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Check the code for each class.\n" + "- Missing constructors and copy constructors\n" + //"- Missing allocation of memory in copy constructor\n" + "- Constructors which should be explicit\n" + "- Are all variables initialized by the constructors?\n" + "- Are all variables assigned by 'operator='?\n" + "- Warn if memset, memcpy etc are used on a class\n" + "- Warn if memory for classes is allocated with malloc()\n" + "- If it's a base class, check that the destructor is virtual\n" + "- Are there unused private functions?\n" + "- 'operator=' should check for assignment to self\n" + "- Constness for member functions\n" + "- Order of initializations\n" + "- Suggest usage of initialization list\n" + "- Initialization of a member with itself\n" + "- Suspicious subtraction from 'this'\n" + "- Call of pure virtual function in constructor/destructor\n" + "- Duplicated inherited data members\n" + // disabled for now "- If 'copy constructor' defined, 'operator=' also should be defined and vice versa\n" + "- Check that arbitrary usage of public interface does not result in division by zero\n" + "- Delete \"self pointer\" and then access 'this'\n" + "- Check that the 'override' keyword is used when overriding virtual functions\n" + "- Check that the 'one definition rule' is not violated\n"; + } +}; + +class CPPCHECKLIB CheckClassImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + CheckClassImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger); + + /** @brief Set of the STL types whose operator[] is not const */ + static const std::set stl_containers_not_const; + /** @brief %Check that all class constructors are ok */ void constructors(); @@ -137,14 +176,6 @@ class CPPCHECKLIB CheckClass : public Check { /** @brief Unsafe class check - const reference member */ void checkUnsafeClassRefMember(); - /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings& /*settings*/, const std::string& currentConfig) const override; - - Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; - - /** @brief Analyse all file infos for all TU */ - bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - const SymbolDatabase* mSymbolDatabase{}; // Reporting errors.. @@ -187,38 +218,6 @@ class CPPCHECKLIB CheckClass : public Check { void unsafeClassRefMemberError(const Token *tok, const std::string &varname); void checkDuplInheritedMembersRecursive(const Type* typeCurrent, const Type* typeBase); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Class"; - } - - std::string classInfo() const override { - return "Check the code for each class.\n" - "- Missing constructors and copy constructors\n" - //"- Missing allocation of memory in copy constructor\n" - "- Constructors which should be explicit\n" - "- Are all variables initialized by the constructors?\n" - "- Are all variables assigned by 'operator='?\n" - "- Warn if memset, memcpy etc are used on a class\n" - "- Warn if memory for classes is allocated with malloc()\n" - "- If it's a base class, check that the destructor is virtual\n" - "- Are there unused private functions?\n" - "- 'operator=' should check for assignment to self\n" - "- Constness for member functions\n" - "- Order of initializations\n" - "- Suggest usage of initialization list\n" - "- Initialization of a member with itself\n" - "- Suspicious subtraction from 'this'\n" - "- Call of pure virtual function in constructor/destructor\n" - "- Duplicated inherited data members\n" - // disabled for now "- If 'copy constructor' defined, 'operator=' also should be defined and vice versa\n" - "- Check that arbitrary usage of public interface does not result in division by zero\n" - "- Delete \"self pointer\" and then access 'this'\n" - "- Check that the 'override' keyword is used when overriding virtual functions\n" - "- Check that the 'one definition rule' is not violated\n"; - } - // operatorEqRetRefThis helper functions void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last); void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last, std::set& analyzedFunctions); diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index f70d9172832..163b05cc445 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -52,7 +52,7 @@ static const CWE CWE571(571U); // Expression is Always True //--------------------------------------------------------------------------- -bool CheckCondition::diag(const Token* tok, bool insert) +bool CheckConditionImpl::diag(const Token* tok, bool insert) { if (!tok) return false; @@ -73,14 +73,14 @@ bool CheckCondition::diag(const Token* tok, bool insert) return true; } -bool CheckCondition::diag(const Token* tok1, const Token* tok2) +bool CheckConditionImpl::diag(const Token* tok1, const Token* tok2) { const bool b1 = diag(tok1); const bool b2 = diag(tok2); return b1 && b2; } -bool CheckCondition::isAliased(const std::set &vars) const +bool CheckConditionImpl::isAliased(const std::set &vars) const { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { if (Token::Match(tok, "= & %var% ;") && vars.find(tok->tokAt(2)->varId()) != vars.end()) @@ -89,7 +89,7 @@ bool CheckCondition::isAliased(const std::set &vars) const return false; } -void CheckCondition::assignIf() +void CheckConditionImpl::assignIf() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("assignIfError")) return; @@ -162,12 +162,12 @@ static bool isParameterChanged(const Token *partok) } /** parse scopes recursively */ -bool CheckCondition::assignIfParseScope(const Token * const assignTok, - const Token * const startTok, - const nonneg int varid, - const bool islocal, - const char bitop, - const MathLib::bigint num) +bool CheckConditionImpl::assignIfParseScope(const Token * const assignTok, + const Token * const startTok, + const nonneg int varid, + const bool islocal, + const char bitop, + const MathLib::bigint num) { bool ret = false; @@ -240,7 +240,7 @@ bool CheckCondition::assignIfParseScope(const Token * const assignTok, return false; } -void CheckCondition::assignIfError(const Token *tok1, const Token *tok2, const std::string &condition, bool result) +void CheckConditionImpl::assignIfError(const Token *tok1, const Token *tok2, const std::string &condition, bool result) { if (tok2 && diag(tok2->tokAt(2))) return; @@ -252,7 +252,7 @@ void CheckCondition::assignIfError(const Token *tok1, const Token *tok2, const s } -void CheckCondition::mismatchingBitAndError(const Token *tok1, const MathLib::bigint num1, const Token *tok2, const MathLib::bigint num2) +void CheckConditionImpl::mismatchingBitAndError(const Token *tok1, const MathLib::bigint num1, const Token *tok2, const MathLib::bigint num2) { std::list locations = { tok1, tok2 }; @@ -308,7 +308,7 @@ static bool isOperandExpanded(const Token *tok) return false; } -void CheckCondition::checkBadBitmaskCheck() +void CheckConditionImpl::checkBadBitmaskCheck() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("badBitmaskCheck")) return; @@ -348,7 +348,7 @@ void CheckCondition::checkBadBitmaskCheck() } } -void CheckCondition::badBitmaskCheckError(const Token *tok, bool isNoOp) +void CheckConditionImpl::badBitmaskCheckError(const Token *tok, bool isNoOp) { if (isNoOp) reportError(tok, Severity::style, "badBitmaskCheck", "Operator '|' with one operand equal to zero is redundant.", CWE571, Certainty::normal); @@ -356,7 +356,7 @@ void CheckCondition::badBitmaskCheckError(const Token *tok, bool isNoOp) reportError(tok, Severity::warning, "badBitmaskCheck", "Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?", CWE571, Certainty::normal); } -void CheckCondition::comparison() +void CheckConditionImpl::comparison() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("comparisonError")) return; @@ -421,7 +421,7 @@ void CheckCondition::comparison() } } -void CheckCondition::comparisonError(const Token *tok, const std::string &bitop, MathLib::bigint value1, const std::string &op, MathLib::bigint value2, bool result) +void CheckConditionImpl::comparisonError(const Token *tok, const std::string &bitop, MathLib::bigint value1, const std::string &op, MathLib::bigint value2, bool result) { std::ostringstream expression; expression << std::hex << "(X " << bitop << " 0x" << value1 << ") " << op << " 0x" << value2; @@ -435,7 +435,7 @@ void CheckCondition::comparisonError(const Token *tok, const std::string &bitop, reportError(tok, Severity::style, "comparisonError", errmsg, CWE398, Certainty::normal); } -bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * const cond2, bool pure) const +bool CheckConditionImpl::isOverlappingCond(const Token * const cond1, const Token * const cond2, bool pure) const { if (!cond1 || !cond2) return false; @@ -476,7 +476,7 @@ bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * return false; } -void CheckCondition::duplicateCondition() +void CheckConditionImpl::duplicateCondition() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("duplicateCondition")) return; @@ -515,7 +515,7 @@ void CheckCondition::duplicateCondition() } } -void CheckCondition::duplicateConditionError(const Token *tok1, const Token *tok2, ErrorPath errorPath) +void CheckConditionImpl::duplicateConditionError(const Token *tok1, const Token *tok2, ErrorPath errorPath) { if (diag(tok1, tok2)) return; @@ -527,7 +527,7 @@ void CheckCondition::duplicateConditionError(const Token *tok1, const Token *tok reportError(std::move(errorPath), Severity::style, "duplicateCondition", msg, CWE398, Certainty::normal); } -void CheckCondition::multiCondition() +void CheckConditionImpl::multiCondition() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("multiCondition")) return; @@ -570,7 +570,7 @@ void CheckCondition::multiCondition() } } -void CheckCondition::overlappingElseIfConditionError(const Token *tok, nonneg int line1) +void CheckConditionImpl::overlappingElseIfConditionError(const Token *tok, nonneg int line1) { if (diag(tok)) return; @@ -581,7 +581,7 @@ void CheckCondition::overlappingElseIfConditionError(const Token *tok, nonneg in reportError(tok, Severity::style, "multiCondition", errmsg.str(), CWE398, Certainty::normal); } -void CheckCondition::oppositeElseIfConditionError(const Token *ifCond, const Token *elseIfCond, ErrorPath errorPath) +void CheckConditionImpl::oppositeElseIfConditionError(const Token *ifCond, const Token *elseIfCond, ErrorPath errorPath) { if (diag(ifCond, elseIfCond)) return; @@ -629,7 +629,7 @@ static bool isNestedInLambda(const Scope* inner, const Scope* outer) return false; } -void CheckCondition::multiCondition2() +void CheckConditionImpl::multiCondition2() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("identicalConditionAfterEarlyExit") && @@ -861,7 +861,7 @@ static std::string innerSmtString(const Token * tok) return top->str(); } -void CheckCondition::oppositeInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) +void CheckConditionImpl::oppositeInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) { if (diag(tok1, tok2)) return; @@ -876,7 +876,7 @@ void CheckCondition::oppositeInnerConditionError(const Token *tok1, const Token* reportError(std::move(errorPath), Severity::warning, "oppositeInnerCondition", msg, CWE398, Certainty::normal); } -void CheckCondition::overlappingInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) +void CheckConditionImpl::overlappingInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) { if (diag(tok1, tok2)) return; @@ -891,7 +891,7 @@ void CheckCondition::overlappingInnerConditionError(const Token *tok1, const To reportError(std::move(errorPath), Severity::warning, "overlappingInnerCondition", msg, CWE398, Certainty::normal); } -void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) +void CheckConditionImpl::identicalInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) { if (diag(tok1, tok2)) return; @@ -906,7 +906,7 @@ void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token reportError(std::move(errorPath), Severity::warning, "identicalInnerCondition", msg, CWE398, Certainty::normal); } -void CheckCondition::identicalConditionAfterEarlyExitError(const Token *cond1, const Token* cond2, ErrorPath errorPath) +void CheckConditionImpl::identicalConditionAfterEarlyExitError(const Token *cond1, const Token* cond2, ErrorPath errorPath) { if (diag(cond1, cond2)) return; @@ -1156,7 +1156,7 @@ static bool isIfConstexpr(const Token* tok) { return Token::simpleMatch(top->astOperand1(), "if") && top->astOperand1()->isConstexpr(); } -void CheckCondition::checkIncorrectLogicOperator() +void CheckConditionImpl::checkIncorrectLogicOperator() { const bool printStyle = mSettings->severity.isEnabled(Severity::style); const bool printWarning = mSettings->severity.isEnabled(Severity::warning); @@ -1367,7 +1367,7 @@ void CheckCondition::checkIncorrectLogicOperator() } } -void CheckCondition::incorrectLogicOperatorError(const Token *tok, const std::string &condition, bool always, bool inconclusive, ErrorPath errors) +void CheckConditionImpl::incorrectLogicOperatorError(const Token *tok, const std::string &condition, bool always, bool inconclusive, ErrorPath errors) { if (diag(tok)) return; @@ -1384,7 +1384,7 @@ void CheckCondition::incorrectLogicOperatorError(const Token *tok, const std::st "Are these conditions necessary? Did you intend to use || instead? Are the numbers correct? Are you comparing the correct variables?", CWE570, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckCondition::redundantConditionError(const Token *tok, const std::string &text, bool inconclusive) +void CheckConditionImpl::redundantConditionError(const Token *tok, const std::string &text, bool inconclusive) { if (diag(tok)) return; @@ -1394,7 +1394,7 @@ void CheckCondition::redundantConditionError(const Token *tok, const std::string //----------------------------------------------------------------------------- // Detect "(var % val1) > val2" where val2 is >= val1. //----------------------------------------------------------------------------- -void CheckCondition::checkModuloAlwaysTrueFalse() +void CheckConditionImpl::checkModuloAlwaysTrueFalse() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -1424,7 +1424,7 @@ void CheckCondition::checkModuloAlwaysTrueFalse() } } -void CheckCondition::moduloAlwaysTrueFalseError(const Token* tok, const std::string& maxVal) +void CheckConditionImpl::moduloAlwaysTrueFalseError(const Token* tok, const std::string& maxVal) { if (diag(tok)) return; @@ -1450,7 +1450,7 @@ static int countPar(const Token *tok1, const Token *tok2) // Clarify condition '(x = a < 0)' into '((x = a) < 0)' or '(x = (a < 0))' // Clarify condition '(a & b == c)' into '((a & b) == c)' or '(a & (b == c))' //--------------------------------------------------------------------------- -void CheckCondition::clarifyCondition() +void CheckConditionImpl::clarifyCondition() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("clarifyCondition")) return; @@ -1491,7 +1491,7 @@ void CheckCondition::clarifyCondition() } } -void CheckCondition::clarifyConditionError(const Token *tok, bool assign, bool boolop) +void CheckConditionImpl::clarifyConditionError(const Token *tok, bool assign, bool boolop) { std::string errmsg; @@ -1514,7 +1514,7 @@ void CheckCondition::clarifyConditionError(const Token *tok, bool assign, bool b errmsg, CWE398, Certainty::normal); } -void CheckCondition::alwaysTrueFalse() +void CheckConditionImpl::alwaysTrueFalse() { const bool pedantic = mSettings->isPremiumEnabled("alwaysTrue") || mSettings->isPremiumEnabled("alwaysFalse") || @@ -1613,8 +1613,8 @@ void CheckCondition::alwaysTrueFalse() { const ValueFlow::Value *zeroValue = nullptr; const Token *nonZeroExpr = nullptr; - if (CheckOther::comparisonNonZeroExpressionLessThanZero(tok, zeroValue, nonZeroExpr, /*suppress*/ true) || - CheckOther::testIfNonZeroExpressionIsPositive(tok, zeroValue, nonZeroExpr)) + if (CheckOtherImpl::comparisonNonZeroExpressionLessThanZero(tok, zeroValue, nonZeroExpr, /*suppress*/ true) || + CheckOtherImpl::testIfNonZeroExpressionIsPositive(tok, zeroValue, nonZeroExpr)) continue; } @@ -1673,7 +1673,7 @@ static std::string getConditionString(const Token* condition) return "Condition"; } -void CheckCondition::alwaysTrueFalseError(const Token* tok, const Token* condition, const ValueFlow::Value* value) +void CheckConditionImpl::alwaysTrueFalseError(const Token* tok, const Token* condition, const ValueFlow::Value* value) { const bool alwaysTrue = value && (value->intvalue != 0 || value->isImpossible()); const std::string expr = tok ? tok->expressionString() : std::string("x"); @@ -1687,7 +1687,7 @@ void CheckCondition::alwaysTrueFalseError(const Token* tok, const Token* conditi (alwaysTrue ? CWE571 : CWE570), Certainty::normal); } -void CheckCondition::checkInvalidTestForOverflow() +void CheckConditionImpl::checkInvalidTestForOverflow() { // Interesting blogs: // https://www.airs.com/blog/archives/120 @@ -1775,7 +1775,7 @@ void CheckCondition::checkInvalidTestForOverflow() } } -void CheckCondition::invalidTestForOverflow(const Token* tok, const ValueType *valueType, const std::string &replace) +void CheckConditionImpl::invalidTestForOverflow(const Token* tok, const ValueType *valueType, const std::string &replace) { const std::string expr = (tok ? tok->expressionString() : std::string("x + c < x")); const std::string overflow = (valueType && valueType->pointer) ? "pointer overflow" : "signed integer overflow"; @@ -1790,7 +1790,7 @@ void CheckCondition::invalidTestForOverflow(const Token* tok, const ValueType *v } -void CheckCondition::checkPointerAdditionResultNotNull() +void CheckConditionImpl::checkPointerAdditionResultNotNull() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -1831,13 +1831,13 @@ void CheckCondition::checkPointerAdditionResultNotNull() } } -void CheckCondition::pointerAdditionResultNotNullError(const Token *tok, const Token *calc) +void CheckConditionImpl::pointerAdditionResultNotNullError(const Token *tok, const Token *calc) { const std::string s = calc ? calc->expressionString() : "ptr+1"; reportError(tok, Severity::warning, "pointerAdditionResultNotNull", "Comparison is wrong. Result of '" + s + "' can't be 0 unless there is pointer overflow, and pointer overflow is undefined behaviour."); } -void CheckCondition::checkDuplicateConditionalAssign() +void CheckConditionImpl::checkDuplicateConditionalAssign() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("duplicateConditionalAssign")) return; @@ -1894,7 +1894,7 @@ void CheckCondition::checkDuplicateConditionalAssign() } } -void CheckCondition::duplicateConditionalAssignError(const Token *condTok, const Token* assignTok, bool isRedundant) +void CheckConditionImpl::duplicateConditionalAssignError(const Token *condTok, const Token* assignTok, bool isRedundant) { ErrorPath errors; std::string msg = "Duplicate expression for the condition and assignment."; @@ -1916,7 +1916,7 @@ void CheckCondition::duplicateConditionalAssignError(const Token *condTok, const } -void CheckCondition::checkAssignmentInCondition() +void CheckConditionImpl::checkAssignmentInCondition() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("assignmentInCondition")) return; @@ -1950,7 +1950,7 @@ void CheckCondition::checkAssignmentInCondition() } } -void CheckCondition::assignmentInCondition(const Token *eq) +void CheckConditionImpl::assignmentInCondition(const Token *eq) { std::string expr = eq ? eq->expressionString() : "x=y"; @@ -1963,7 +1963,7 @@ void CheckCondition::assignmentInCondition(const Token *eq) Certainty::normal); } -void CheckCondition::checkCompareValueOutOfTypeRange() +void CheckConditionImpl::checkCompareValueOutOfTypeRange() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("compareValueOutOfTypeRangeError")) return; @@ -2084,7 +2084,7 @@ void CheckCondition::checkCompareValueOutOfTypeRange() } } -void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparisonTok, const std::string &type, MathLib::bigint value, bool result) +void CheckConditionImpl::compareValueOutOfTypeRangeError(const Token *comparisonTok, const std::string &type, MathLib::bigint value, bool result) { reportError( comparisonTok, @@ -2097,7 +2097,7 @@ void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparisonTok, void CheckCondition::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckCondition checkCondition(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckConditionImpl checkCondition(&tokenizer, &tokenizer.getSettings(), errorLogger); checkCondition.multiCondition(); checkCondition.clarifyCondition(); // not simplified because ifAssign checkCondition.multiCondition2(); @@ -2117,7 +2117,7 @@ void CheckCondition::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLog void CheckCondition::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckCondition c(nullptr, settings, errorLogger); + CheckConditionImpl c(nullptr, settings, errorLogger); c.assignIfError(nullptr, nullptr, "", false); c.badBitmaskCheckError(nullptr); diff --git a/lib/checkcondition.h b/lib/checkcondition.h index 2ea20158b11..be06dfbbfd2 100644 --- a/lib/checkcondition.h +++ b/lib/checkcondition.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include "mathlib.h" #include "errortypes.h" @@ -50,15 +51,39 @@ namespace ValueFlow { class CPPCHECKLIB CheckCondition : public Check { public: /** This constructor is used when registering the CheckAssignIf */ - CheckCondition() : Check(myName()) {} + CheckCondition() : Check("Condition") {} private: - /** This constructor is used when running checks. */ - CheckCondition(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Match conditions with assignments and other conditions:\n" + "- Mismatching assignment and comparison => comparison is always true/false\n" + "- Mismatching lhs and rhs in comparison => comparison is always true/false\n" + "- Detect usage of | where & should be used\n" + "- Duplicate condition and assignment\n" + "- Detect matching 'if' and 'else if' conditions\n" + "- Mismatching bitand (a &= 0xf0; a &= 1; => a = 0)\n" + "- Opposite inner condition is always false\n" + "- Identical condition after early exit is always false\n" + "- Condition that is always true/false\n" + "- Mutual exclusion over || always evaluating to true\n" + "- Comparisons of modulo results that are always true/false.\n" + "- Known variable values => condition is always true/false\n" + "- Invalid test for overflow. Some mainstream compilers remove such overflow tests when optimising code.\n" + "- Suspicious assignment of container/iterator in condition => condition is always true.\n"; + } +}; + + +class CPPCHECKLIB CheckConditionImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + CheckConditionImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** mismatching assignment / comparison */ void assignIf(); @@ -157,30 +182,6 @@ class CPPCHECKLIB CheckCondition : public Check { void checkCompareValueOutOfTypeRange(); void compareValueOutOfTypeRangeError(const Token *comparisonTok, const std::string &type, MathLib::bigint value, bool result); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Condition"; - } - - std::string classInfo() const override { - return "Match conditions with assignments and other conditions:\n" - "- Mismatching assignment and comparison => comparison is always true/false\n" - "- Mismatching lhs and rhs in comparison => comparison is always true/false\n" - "- Detect usage of | where & should be used\n" - "- Duplicate condition and assignment\n" - "- Detect matching 'if' and 'else if' conditions\n" - "- Mismatching bitand (a &= 0xf0; a &= 1; => a = 0)\n" - "- Opposite inner condition is always false\n" - "- Identical condition after early exit is always false\n" - "- Condition that is always true/false\n" - "- Mutual exclusion over || always evaluating to true\n" - "- Comparisons of modulo results that are always true/false.\n" - "- Known variable values => condition is always true/false\n" - "- Invalid test for overflow. Some mainstream compilers remove such overflow tests when optimising code.\n" - "- Suspicious assignment of container/iterator in condition => condition is always true.\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index 6da5281e80a..463e47bea1c 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -40,7 +40,7 @@ static const CWE CWE480(480U); // Use of Incorrect Operator //--------------------------------------------------------------------------- -void CheckExceptionSafety::destructors() +void CheckExceptionSafetyImpl::destructors() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -78,7 +78,7 @@ void CheckExceptionSafety::destructors() } } -void CheckExceptionSafety::destructorsError(const Token * const tok, const std::string &className) +void CheckExceptionSafetyImpl::destructorsError(const Token * const tok, const std::string &className) { reportError(tok, Severity::warning, "exceptThrowInDestructor", "Class " + className + " is not safe, destructor throws exception\n" @@ -88,7 +88,7 @@ void CheckExceptionSafety::destructorsError(const Token * const tok, const std:: } -void CheckExceptionSafety::deallocThrow() +void CheckExceptionSafetyImpl::deallocThrow() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("exceptDeallocThrow")) return; @@ -151,7 +151,7 @@ void CheckExceptionSafety::deallocThrow() } } -void CheckExceptionSafety::deallocThrowError(const Token * const tok, const std::string &varname) +void CheckExceptionSafetyImpl::deallocThrowError(const Token * const tok, const std::string &varname) { reportError(tok, Severity::warning, "exceptDeallocThrow", "Exception thrown in invalid state, '" + varname + "' points at deallocated memory.", CWE398, Certainty::normal); @@ -163,7 +163,7 @@ void CheckExceptionSafety::deallocThrowError(const Token * const tok, const std: // throw err; // <- should be just "throw;" // } //--------------------------------------------------------------------------- -void CheckExceptionSafety::checkRethrowCopy() +void CheckExceptionSafetyImpl::checkRethrowCopy() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("exceptRethrowCopy")) return; @@ -196,7 +196,7 @@ void CheckExceptionSafety::checkRethrowCopy() } } -void CheckExceptionSafety::rethrowCopyError(const Token * const tok, const std::string &varname) +void CheckExceptionSafetyImpl::rethrowCopyError(const Token * const tok, const std::string &varname) { reportError(tok, Severity::style, "exceptRethrowCopy", "Throwing a copy of the caught exception instead of rethrowing the original exception.\n" @@ -207,7 +207,7 @@ void CheckExceptionSafety::rethrowCopyError(const Token * const tok, const std:: //--------------------------------------------------------------------------- // try {} catch (std::exception err) {} <- Should be "std::exception& err" //--------------------------------------------------------------------------- -void CheckExceptionSafety::checkCatchExceptionByValue() +void CheckExceptionSafetyImpl::checkCatchExceptionByValue() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("catchExceptionByValue")) return; @@ -228,7 +228,7 @@ void CheckExceptionSafety::checkCatchExceptionByValue() } } -void CheckExceptionSafety::catchExceptionByValueError(const Token *tok) +void CheckExceptionSafetyImpl::catchExceptionByValueError(const Token *tok) { reportError(tok, Severity::style, "catchExceptionByValue", "Exception should be caught by reference.\n" @@ -281,7 +281,7 @@ static const Token * functionThrows(const Function * function) // void func() throw() { throw x; } // void func() __attribute__((nothrow)); void func() { throw x; } //-------------------------------------------------------------------------- -void CheckExceptionSafety::nothrowThrows() +void CheckExceptionSafetyImpl::nothrowThrows() { logChecker("CheckExceptionSafety::nothrowThrows"); @@ -313,12 +313,12 @@ void CheckExceptionSafety::nothrowThrows() } } -void CheckExceptionSafety::noexceptThrowError(const Token * const tok) +void CheckExceptionSafetyImpl::noexceptThrowError(const Token * const tok) { reportError(tok, Severity::error, "throwInNoexceptFunction", "Unhandled exception thrown in function declared not to throw exceptions.", CWE398, Certainty::normal); } -void CheckExceptionSafety::entryPointThrowError(const Token * const tok) +void CheckExceptionSafetyImpl::entryPointThrowError(const Token * const tok) { reportError(tok, Severity::error, "throwInEntryPoint", "Unhandled exception thrown in function that is an entry point.", CWE398, Certainty::normal); } @@ -326,7 +326,7 @@ void CheckExceptionSafety::entryPointThrowError(const Token * const tok) //-------------------------------------------------------------------------- // void func() { functionWithExceptionSpecification(); } //-------------------------------------------------------------------------- -void CheckExceptionSafety::unhandledExceptionSpecification() +void CheckExceptionSafetyImpl::unhandledExceptionSpecification() { if ((!mSettings->severity.isEnabled(Severity::style) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) && !mSettings->isPremiumEnabled("unhandledExceptionSpecification")) @@ -356,7 +356,7 @@ void CheckExceptionSafety::unhandledExceptionSpecification() } } -void CheckExceptionSafety::unhandledExceptionSpecificationError(const Token * const tok1, const Token * const tok2, const std::string & funcname) +void CheckExceptionSafetyImpl::unhandledExceptionSpecificationError(const Token * const tok1, const Token * const tok2, const std::string & funcname) { const std::string str1(tok1 ? tok1->str() : "foo"); const std::list locationList = { tok1, tok2 }; @@ -369,7 +369,7 @@ void CheckExceptionSafety::unhandledExceptionSpecificationError(const Token * co //-------------------------------------------------------------------------- // 7.6.18.4 If no exception is presently being handled, evaluating a throw-expression with no operand calls std​::​​terminate(). //-------------------------------------------------------------------------- -void CheckExceptionSafety::rethrowNoCurrentException() +void CheckExceptionSafetyImpl::rethrowNoCurrentException() { logChecker("CheckExceptionSafety::rethrowNoCurrentException"); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -400,7 +400,7 @@ void CheckExceptionSafety::rethrowNoCurrentException() } } -void CheckExceptionSafety::rethrowNoCurrentExceptionError(const Token *tok) +void CheckExceptionSafetyImpl::rethrowNoCurrentExceptionError(const Token *tok) { reportError(tok, Severity::error, "rethrowNoCurrentException", "Rethrowing current exception with 'throw;', it seems there is no current exception to rethrow." @@ -414,7 +414,7 @@ void CheckExceptionSafety::runChecks(const Tokenizer &tokenizer, ErrorLogger *er if (tokenizer.isC()) return; - CheckExceptionSafety checkExceptionSafety(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckExceptionSafetyImpl checkExceptionSafety(&tokenizer, &tokenizer.getSettings(), errorLogger); checkExceptionSafety.destructors(); checkExceptionSafety.deallocThrow(); checkExceptionSafety.checkRethrowCopy(); @@ -426,7 +426,7 @@ void CheckExceptionSafety::runChecks(const Tokenizer &tokenizer, ErrorLogger *er void CheckExceptionSafety::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckExceptionSafety c(nullptr, settings, errorLogger); + CheckExceptionSafetyImpl c(nullptr, settings, errorLogger); c.destructorsError(nullptr, "Class"); c.deallocThrowError(nullptr, "p"); c.rethrowCopyError(nullptr, "varname"); diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index 7c5a52b5605..bd44a649b1e 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -22,6 +22,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -46,15 +47,33 @@ class Tokenizer; class CPPCHECKLIB CheckExceptionSafety : public Check { public: /** This constructor is used when registering the CheckClass */ - CheckExceptionSafety() : Check(myName()) {} + CheckExceptionSafety() : Check("Exception Safety") {} private: - /** This constructor is used when running checks. */ - CheckExceptionSafety(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + /** Generate all possible errors (for --errorlist) */ + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + /** wiki formatted description of the class (for --doc) */ + std::string classInfo() const override { + return "Checking exception safety\n" + "- Throwing exceptions in destructors\n" + "- Throwing exception during invalid state\n" + "- Throwing a copy of a caught exception instead of rethrowing the original exception\n" + "- Exception caught by value instead of by reference\n" + "- Throwing exception in noexcept, nothrow(), __attribute__((nothrow)) or __declspec(nothrow) function\n" + "- Unhandled exception specification when calling function foo()\n" + "- Rethrow without currently handled exception\n"; + } +}; + +class CPPCHECKLIB CheckExceptionSafetyImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + CheckExceptionSafetyImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** Don't throw exceptions in destructors */ void destructors(); @@ -87,26 +106,6 @@ class CPPCHECKLIB CheckExceptionSafety : public Check { void unhandledExceptionSpecificationError(const Token * tok1, const Token * tok2, const std::string & funcname); /** Rethrow without currently handled exception */ void rethrowNoCurrentExceptionError(const Token *tok); - - /** Generate all possible errors (for --errorlist) */ - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - /** Short description of class (for --doc) */ - static std::string myName() { - return "Exception Safety"; - } - - /** wiki formatted description of the class (for --doc) */ - std::string classInfo() const override { - return "Checking exception safety\n" - "- Throwing exceptions in destructors\n" - "- Throwing exception during invalid state\n" - "- Throwing a copy of a caught exception instead of rethrowing the original exception\n" - "- Exception caught by value instead of by reference\n" - "- Throwing exception in noexcept, nothrow(), __attribute__((nothrow)) or __declspec(nothrow) function\n" - "- Unhandled exception specification when calling function foo()\n" - "- Rethrow without currently handled exception\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 733b868814e..47a3828de31 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -52,7 +52,7 @@ static const CWE CWE686(686U); // Function Call With Incorrect Argument Type static const CWE CWE687(687U); // Function Call With Incorrectly Specified Argument Value static const CWE CWE688(688U); // Function Call With Incorrect Variable or Reference as Argument -void CheckFunctions::checkProhibitedFunctions() +void CheckFunctionsImpl::checkProhibitedFunctions() { const bool checkAlloca = mSettings->severity.isEnabled(Severity::warning) && ((mTokenizer->isC() && mSettings->standards.c >= Standards::C99) || mSettings->standards.cpp >= Standards::CPP11); @@ -88,7 +88,8 @@ void CheckFunctions::checkProhibitedFunctions() if (wi) { if (mSettings->severity.isEnabled(wi->severity) && ((tok->isC() && mSettings->standards.c >= wi->standards.c) || (tok->isCpp() && mSettings->standards.cpp >= wi->standards.cpp))) { const std::string daca = mSettings->daca ? "prohibited" : ""; - reportError(tok, wi->severity, daca + tok->str() + "Called", wi->message, CWE477, Certainty::normal); + const std::string prefix = daca + tok->str(); + functionCalledError(tok, wi->severity, prefix, wi->message); } } } @@ -96,10 +97,15 @@ void CheckFunctions::checkProhibitedFunctions() } } +void CheckFunctionsImpl::functionCalledError(const Token* tok, Severity severity, const std::string& prefix, const std::string& msg) +{ + reportError(tok, severity, prefix + "Called", msg, CWE477, Certainty::normal); +} + //--------------------------------------------------------------------------- // Check , and //--------------------------------------------------------------------------- -void CheckFunctions::invalidFunctionUsage() +void CheckFunctionsImpl::invalidFunctionUsage() { logChecker("CheckFunctions::invalidFunctionUsage"); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -191,7 +197,7 @@ void CheckFunctions::invalidFunctionUsage() } } -void CheckFunctions::invalidFunctionArgError(const Token *tok, const std::string &functionName, int argnr, const ValueFlow::Value *invalidValue, const std::string &validstr) +void CheckFunctionsImpl::invalidFunctionArgError(const Token *tok, const std::string &functionName, int argnr, const ValueFlow::Value *invalidValue, const std::string &validstr) { std::ostringstream errmsg; errmsg << "$symbol:" << functionName << '\n'; @@ -220,7 +226,7 @@ void CheckFunctions::invalidFunctionArgError(const Token *tok, const std::string Certainty::normal); } -void CheckFunctions::invalidFunctionArgBoolError(const Token *tok, const std::string &functionName, int argnr) +void CheckFunctionsImpl::invalidFunctionArgBoolError(const Token *tok, const std::string &functionName, int argnr) { std::ostringstream errmsg; errmsg << "$symbol:" << functionName << '\n'; @@ -228,7 +234,7 @@ void CheckFunctions::invalidFunctionArgBoolError(const Token *tok, const std::st reportError(tok, Severity::error, "invalidFunctionArgBool", errmsg.str(), CWE628, Certainty::normal); } -void CheckFunctions::invalidFunctionArgStrError(const Token *tok, const std::string &functionName, nonneg int argnr) +void CheckFunctionsImpl::invalidFunctionArgStrError(const Token *tok, const std::string &functionName, nonneg int argnr) { std::ostringstream errmsg; errmsg << "$symbol:" << functionName << '\n'; @@ -239,7 +245,7 @@ void CheckFunctions::invalidFunctionArgStrError(const Token *tok, const std::str //--------------------------------------------------------------------------- // Check for ignored return values. //--------------------------------------------------------------------------- -void CheckFunctions::checkIgnoredReturnValue() +void CheckFunctionsImpl::checkIgnoredReturnValue() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->severity.isEnabled(Severity::style) && @@ -290,13 +296,13 @@ void CheckFunctions::checkIgnoredReturnValue() } } -void CheckFunctions::ignoredReturnValueError(const Token* tok, const std::string& function) +void CheckFunctionsImpl::ignoredReturnValueError(const Token* tok, const std::string& function) { reportError(tok, Severity::warning, "ignoredReturnValue", "$symbol:" + function + "\nReturn value of function $symbol() is not used.", CWE252, Certainty::normal); } -void CheckFunctions::ignoredReturnErrorCode(const Token* tok, const std::string& function) +void CheckFunctionsImpl::ignoredReturnErrorCode(const Token* tok, const std::string& function) { reportError(tok, Severity::style, "ignoredReturnErrorCode", "$symbol:" + function + "\nError code from the return value of function $symbol() is not used.", CWE252, Certainty::normal); @@ -307,7 +313,7 @@ void CheckFunctions::ignoredReturnErrorCode(const Token* tok, const std::string& //--------------------------------------------------------------------------- static const Token *checkMissingReturnScope(const Token *tok, const Library &library); -void CheckFunctions::checkMissingReturn() +void CheckFunctionsImpl::checkMissingReturn() { logChecker("CheckFunctions::checkMissingReturn"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -425,7 +431,7 @@ static const Token *checkMissingReturnScope(const Token *tok, const Library &lib return nullptr; } -void CheckFunctions::missingReturnError(const Token* tok) +void CheckFunctionsImpl::missingReturnError(const Token* tok) { reportError(tok, Severity::error, "missingReturn", "Found an exit path from function with non-void return type that has missing return statement", CWE758, Certainty::normal); @@ -433,7 +439,7 @@ void CheckFunctions::missingReturnError(const Token* tok) //--------------------------------------------------------------------------- // Detect passing wrong values to functions like atan(0, x); //--------------------------------------------------------------------------- -void CheckFunctions::checkMathFunctions() +void CheckFunctionsImpl::checkMathFunctions() { const bool styleC99 = mSettings->severity.isEnabled(Severity::style) && ((mTokenizer->isC() && mSettings->standards.c != Standards::C89) || (mTokenizer->isCPP() && mSettings->standards.cpp != Standards::CPP03)); const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); @@ -494,7 +500,7 @@ void CheckFunctions::checkMathFunctions() } } -void CheckFunctions::mathfunctionCallWarning(const Token *tok, const nonneg int numParam) +void CheckFunctionsImpl::mathfunctionCallWarning(const Token *tok, const nonneg int numParam) { if (tok) { if (numParam == 1) @@ -505,7 +511,7 @@ void CheckFunctions::mathfunctionCallWarning(const Token *tok, const nonneg int reportError(tok, Severity::warning, "wrongmathcall", "Passing value '#' to #() leads to implementation-defined result.", CWE758, Certainty::normal); } -void CheckFunctions::mathfunctionCallWarning(const Token *tok, const std::string& oldexp, const std::string& newexp) +void CheckFunctionsImpl::mathfunctionCallWarning(const Token *tok, const std::string& oldexp, const std::string& newexp) { reportError(tok, Severity::style, "unpreciseMathCall", "Expression '" + oldexp + "' can be replaced by '" + newexp + "' to avoid loss of precision.", CWE758, Certainty::normal); } @@ -513,7 +519,7 @@ void CheckFunctions::mathfunctionCallWarning(const Token *tok, const std::string //--------------------------------------------------------------------------- // memset(p, y, 0 /* bytes to fill */) <- 2nd and 3rd arguments inverted //--------------------------------------------------------------------------- -void CheckFunctions::memsetZeroBytes() +void CheckFunctionsImpl::memsetZeroBytes() { // FIXME: // Replace this with library configuration. @@ -542,7 +548,7 @@ void CheckFunctions::memsetZeroBytes() } } -void CheckFunctions::memsetZeroBytesError(const Token *tok) +void CheckFunctionsImpl::memsetZeroBytesError(const Token *tok) { const std::string summary("memset() called to fill 0 bytes."); const std::string verbose(summary + " The second and third arguments might be inverted." @@ -551,7 +557,7 @@ void CheckFunctions::memsetZeroBytesError(const Token *tok) reportError(tok, Severity::warning, "memsetZeroBytes", summary + "\n" + verbose, CWE687, Certainty::normal); } -void CheckFunctions::memsetInvalid2ndParam() +void CheckFunctionsImpl::memsetInvalid2ndParam() { // FIXME: // Replace this with library configuration. @@ -599,7 +605,7 @@ void CheckFunctions::memsetInvalid2ndParam() } } -void CheckFunctions::memsetFloatError(const Token *tok, const std::string &var_value) +void CheckFunctionsImpl::memsetFloatError(const Token *tok, const std::string &var_value) { const std::string message("The 2nd memset() argument '" + var_value + "' is a float, its representation is implementation defined."); @@ -608,7 +614,7 @@ void CheckFunctions::memsetFloatError(const Token *tok, const std::string &var_v reportError(tok, Severity::portability, "memsetFloat", message + "\n" + verbose, CWE688, Certainty::normal); } -void CheckFunctions::memsetValueOutOfRangeError(const Token *tok, const std::string &value) +void CheckFunctionsImpl::memsetValueOutOfRangeError(const Token *tok, const std::string &value) { const std::string message("The 2nd memset() argument '" + value + "' doesn't fit into an 'unsigned char'."); const std::string verbose(message + " The 2nd parameter is passed as an 'int', but the function fills the block of memory using the 'unsigned char' conversion of this value."); @@ -619,7 +625,7 @@ void CheckFunctions::memsetValueOutOfRangeError(const Token *tok, const std::str // --check-library => warn for unconfigured functions //--------------------------------------------------------------------------- -void CheckFunctions::checkLibraryMatchFunctions() +void CheckFunctionsImpl::checkLibraryMatchFunctions() { if (!mSettings->checkLibrary) return; @@ -697,7 +703,7 @@ void CheckFunctions::checkLibraryMatchFunctions() // Check for problems to compiler apply (Named) Return Value Optimization for local variable // Technically we have different guarantees between standard versions // details: https://en.cppreference.com/w/cpp/language/copy_elision -void CheckFunctions::returnLocalStdMove() +void CheckFunctionsImpl::returnLocalStdMove() { if (!mTokenizer->isCPP() || mSettings->standards.cpp < Standards::CPP11) return; @@ -727,7 +733,7 @@ void CheckFunctions::returnLocalStdMove() } } -void CheckFunctions::copyElisionError(const Token *tok) +void CheckFunctionsImpl::copyElisionError(const Token *tok) { reportError(tok, Severity::performance, @@ -736,7 +742,7 @@ void CheckFunctions::copyElisionError(const Token *tok) " More: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-return-move-local"); } -void CheckFunctions::useStandardLibrary() +void CheckFunctionsImpl::useStandardLibrary() { if (!mSettings->severity.isEnabled(Severity::style)) return; @@ -840,7 +846,7 @@ void CheckFunctions::useStandardLibrary() } } -void CheckFunctions::useStandardLibraryError(const Token *tok, const std::string& expected) +void CheckFunctionsImpl::useStandardLibraryError(const Token *tok, const std::string& expected) { reportError(tok, Severity::style, "useStandardLibrary", @@ -849,7 +855,7 @@ void CheckFunctions::useStandardLibraryError(const Token *tok, const std::string void CheckFunctions::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckFunctions checkFunctions(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckFunctionsImpl checkFunctions(&tokenizer, &tokenizer.getSettings(), errorLogger); checkFunctions.checkIgnoredReturnValue(); checkFunctions.checkMissingReturn(); // Missing "return" in exit path @@ -868,10 +874,10 @@ void CheckFunctions::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLog void CheckFunctions::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckFunctions c(nullptr, settings, errorLogger); + CheckFunctionsImpl c(nullptr, settings, errorLogger); for (auto i = settings->library.functionwarn().cbegin(); i != settings->library.functionwarn().cend(); ++i) { - c.reportError(nullptr, Severity::style, i->first+"Called", i->second.message); + c.functionCalledError(nullptr, Severity::style, i->first, i->second.message); } c.invalidFunctionArgError(nullptr, "func_name", 1, nullptr,"1:4"); diff --git a/lib/checkfunctions.h b/lib/checkfunctions.h index f5954d14043..7ea9e2833a2 100644 --- a/lib/checkfunctions.h +++ b/lib/checkfunctions.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -47,16 +48,34 @@ namespace ValueFlow { class CPPCHECKLIB CheckFunctions : public Check { public: /** This constructor is used when registering the CheckFunctions */ - CheckFunctions() : Check(myName()) {} + CheckFunctions() : Check("Check function usage") {} private: - /** This constructor is used when running checks. */ - CheckFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Check function usage:\n" + "- missing 'return' in non-void function\n" + "- return value of certain functions not used\n" + "- invalid input values for functions\n" + "- Warn if a function is called whose usage is discouraged\n" + "- memset() third argument is zero\n" + "- memset() with a value out of range as the 2nd parameter\n" + "- memset() with a float as the 2nd parameter\n" + "- copy elision optimization for returning value affected by std::move\n" + "- use memcpy()/memset() instead of for loop\n"; + } +}; + +class CPPCHECKLIB CheckFunctionsImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + CheckFunctionsImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** Check for functions that should not be used */ void checkProhibitedFunctions(); @@ -106,25 +125,7 @@ class CPPCHECKLIB CheckFunctions : public Check { void missingReturnError(const Token *tok); void copyElisionError(const Token *tok); void useStandardLibraryError(const Token *tok, const std::string& expected); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Check function usage"; - } - - std::string classInfo() const override { - return "Check function usage:\n" - "- missing 'return' in non-void function\n" - "- return value of certain functions not used\n" - "- invalid input values for functions\n" - "- Warn if a function is called whose usage is discouraged\n" - "- memset() third argument is zero\n" - "- memset() with a value out of range as the 2nd parameter\n" - "- memset() with a float as the 2nd parameter\n" - "- copy elision optimization for returning value affected by std::move\n" - "- use memcpy()/memset() instead of for loop\n"; - } + void functionCalledError(const Token* tok, Severity severity, const std::string& prefix, const std::string& msg); }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/check.cpp b/lib/checkimpl.cpp similarity index 60% rename from lib/check.cpp rename to lib/checkimpl.cpp index 4033378e927..43e56cfa360 100644 --- a/lib/check.cpp +++ b/lib/checkimpl.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,9 +16,7 @@ * along with this program. If not, see . */ -//--------------------------------------------------------------------------- - -#include "check.h" +#include "checkimpl.h" #include "errorlogger.h" #include "settings.h" @@ -26,59 +24,35 @@ #include "tokenize.h" #include "vfvalue.h" -#include -#include +#include #include -//--------------------------------------------------------------------------- - -Check::Check(std::string aname) - : mName(std::move(aname)) -{} - -void Check::writeToErrorList(const ErrorMessage &errmsg) +void CheckImpl::reportError(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty) { - std::cout << errmsg.toXML() << std::endl; -} - + assert(mErrorLogger); -void Check::reportError(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty) -{ // TODO: report debug warning when error is for a disabled severity const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty); - if (mErrorLogger) - mErrorLogger->reportErr(errmsg); - else - writeToErrorList(errmsg); + mErrorLogger->reportErr(errmsg); } -void Check::reportError(ErrorPath errorPath, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty) +void CheckImpl::reportError(ErrorPath errorPath, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty) { + assert(mErrorLogger); + // TODO: report debug warning when error is for a disabled severity const ErrorMessage errmsg(std::move(errorPath), mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty); - if (mErrorLogger) - mErrorLogger->reportErr(errmsg); - else - writeToErrorList(errmsg); + mErrorLogger->reportErr(errmsg); } -bool Check::wrongData(const Token *tok, const char *str) +bool CheckImpl::wrongData(const Token *tok, const char *str) { if (mSettings->daca) reportError(tok, Severity::debug, "DacaWrongData", "Wrong data detected by condition " + std::string(str)); return true; } -std::string Check::getMessageId(const ValueFlow::Value &value, const char id[]) -{ - if (value.condition != nullptr) - return id + std::string("Cond"); - if (value.safe) - return std::string("safe") + static_cast(std::toupper(id[0])) + (id + 1); - return id; -} - -ErrorPath Check::getErrorPath(const Token* errtok, const ValueFlow::Value* value, std::string bug) const +ErrorPath CheckImpl::getErrorPath(const Token* errtok, const ValueFlow::Value* value, std::string bug) const { ErrorPath errorPath; if (!value) { @@ -96,9 +70,8 @@ ErrorPath Check::getErrorPath(const Token* errtok, const ValueFlow::Value* value return errorPath; } -void Check::logChecker(const char id[]) +void CheckImpl::logChecker(const char id[]) { if (!mSettings->buildDir.empty() || mSettings->collectLogCheckers()) reportError(nullptr, Severity::internal, "logChecker", id); } - diff --git a/lib/checkimpl.h b/lib/checkimpl.h new file mode 100644 index 00000000000..35e70bbaae5 --- /dev/null +++ b/lib/checkimpl.h @@ -0,0 +1,85 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2026 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef checkimplH +#define checkimplH + +#include "config.h" +#include "errortypes.h" + +#include +#include + +class Settings; +class ErrorLogger; +class Tokenizer; +class Token; +namespace ValueFlow { + class Value; +} + +class CPPCHECKLIB CheckImpl +{ +protected: + /** This constructor is used when running checks. */ + CheckImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger) {} + +public: + CheckImpl(const CheckImpl &) = delete; + CheckImpl& operator=(const CheckImpl &) = delete; + +protected: + const Tokenizer* const mTokenizer{}; + const Settings* const mSettings{}; + ErrorLogger* const mErrorLogger{}; + + /** report an error */ + void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg) { + reportError(tok, severity, id, msg, CWE(0U), Certainty::normal); + } + + /** report an error */ + void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty) { + const std::list callstack(1, tok); + reportError(callstack, severity, id, msg, cwe, certainty); + } + + /** report an error */ + void reportError(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg) { + reportError(callstack, severity, id, msg, CWE(0U), Certainty::normal); + } + + /** report an error */ + void reportError(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty); + + void reportError(ErrorPath errorPath, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty); + + ErrorPath getErrorPath(const Token* errtok, const ValueFlow::Value* value, std::string bug) const; + + /** + * Use WRONG_DATA in checkers when you check for wrong data. That + * will call this method + */ + bool wrongData(const Token *tok, const char *str); + +public: // TODO: should be protected + void logChecker(const char id[]); +}; + +#endif // checkimplH diff --git a/lib/checkinternal.cpp b/lib/checkinternal.cpp index ed39b4db96a..10af0543cec 100644 --- a/lib/checkinternal.cpp +++ b/lib/checkinternal.cpp @@ -31,7 +31,7 @@ #include #include -void CheckInternal::checkTokenMatchPatterns() +void CheckInternalImpl::checkTokenMatchPatterns() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope *scope : symbolDatabase->functionScopes) { @@ -82,7 +82,7 @@ void CheckInternal::checkTokenMatchPatterns() } } -void CheckInternal::checkRedundantTokCheck() +void CheckInternalImpl::checkRedundantTokCheck() { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { if (Token::Match(tok, "&& Token :: simpleMatch|Match|findsimplematch|findmatch (")) { @@ -117,13 +117,13 @@ void CheckInternal::checkRedundantTokCheck() } -void CheckInternal::checkRedundantTokCheckError(const Token* tok) +void CheckInternalImpl::checkRedundantTokCheckError(const Token* tok) { reportError(tok, Severity::style, "redundantTokCheck", "Unnecessary check of \"" + (tok? tok->expressionString(): "") + "\", match-function already checks if it is null."); } -void CheckInternal::checkTokenSimpleMatchPatterns() +void CheckInternalImpl::checkTokenSimpleMatchPatterns() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope* scope : symbolDatabase->functionScopes) { @@ -207,7 +207,7 @@ namespace { }; } -void CheckInternal::checkMissingPercentCharacter() +void CheckInternalImpl::checkMissingPercentCharacter() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope* scope : symbolDatabase->functionScopes) { @@ -248,7 +248,7 @@ void CheckInternal::checkMissingPercentCharacter() } } -void CheckInternal::checkUnknownPattern() +void CheckInternalImpl::checkUnknownPattern() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope* scope : symbolDatabase->functionScopes) { @@ -282,7 +282,7 @@ void CheckInternal::checkUnknownPattern() } } -void CheckInternal::checkRedundantNextPrevious() +void CheckInternalImpl::checkRedundantNextPrevious() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope* scope : symbolDatabase->functionScopes) { @@ -305,7 +305,7 @@ void CheckInternal::checkRedundantNextPrevious() } } -void CheckInternal::checkExtraWhitespace() +void CheckInternalImpl::checkExtraWhitespace() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope* scope : symbolDatabase->functionScopes) { @@ -331,46 +331,46 @@ void CheckInternal::checkExtraWhitespace() } } -void CheckInternal::simplePatternError(const Token* tok, const std::string& pattern, const std::string &funcname) +void CheckInternalImpl::simplePatternError(const Token* tok, const std::string& pattern, const std::string &funcname) { reportError(tok, Severity::warning, "simplePatternError", "Found simple pattern inside Token::" + funcname + "() call: \"" + pattern + "\"" ); } -void CheckInternal::complexPatternError(const Token* tok, const std::string& pattern, const std::string &funcname) +void CheckInternalImpl::complexPatternError(const Token* tok, const std::string& pattern, const std::string &funcname) { reportError(tok, Severity::error, "complexPatternError", "Found complex pattern inside Token::" + funcname + "() call: \"" + pattern + "\"" ); } -void CheckInternal::missingPercentCharacterError(const Token* tok, const std::string& pattern, const std::string& funcname) +void CheckInternalImpl::missingPercentCharacterError(const Token* tok, const std::string& pattern, const std::string& funcname) { reportError(tok, Severity::error, "missingPercentCharacter", "Missing percent end character in Token::" + funcname + "() pattern: \"" + pattern + "\"" ); } -void CheckInternal::unknownPatternError(const Token* tok, const std::string& pattern) +void CheckInternalImpl::unknownPatternError(const Token* tok, const std::string& pattern) { reportError(tok, Severity::error, "unknownPattern", "Unknown pattern used: \"" + pattern + "\""); } -void CheckInternal::redundantNextPreviousError(const Token* tok, const std::string& func1, const std::string& func2) +void CheckInternalImpl::redundantNextPreviousError(const Token* tok, const std::string& func1, const std::string& func2) { reportError(tok, Severity::style, "redundantNextPrevious", "Call to 'Token::" + func1 + "()' followed by 'Token::" + func2 + "()' can be simplified."); } -void CheckInternal::orInComplexPattern(const Token* tok, const std::string& pattern, const std::string &funcname) +void CheckInternalImpl::orInComplexPattern(const Token* tok, const std::string& pattern, const std::string &funcname) { reportError(tok, Severity::error, "orInComplexPattern", "Token::" + funcname + "() pattern \"" + pattern + "\" contains \"||\" or \"|\". Replace it by \"%oror%\" or \"%or%\"."); } -void CheckInternal::extraWhitespaceError(const Token* tok, const std::string& pattern, const std::string &funcname) +void CheckInternalImpl::extraWhitespaceError(const Token* tok, const std::string& pattern, const std::string &funcname) { reportError(tok, Severity::warning, "extraWhitespaceError", "Found extra whitespace inside Token::" + funcname + "() call: \"" + pattern + "\"" @@ -382,7 +382,7 @@ void CheckInternal::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogg if (!tokenizer.getSettings().checks.isEnabled(Checks::internalCheck)) return; - CheckInternal checkInternal(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckInternalImpl checkInternal(&tokenizer, &tokenizer.getSettings(), errorLogger); checkInternal.checkTokenMatchPatterns(); checkInternal.checkTokenSimpleMatchPatterns(); @@ -395,7 +395,7 @@ void CheckInternal::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogg void CheckInternal::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckInternal c(nullptr, settings, errorLogger); + CheckInternalImpl c(nullptr, settings, errorLogger); c.simplePatternError(nullptr, "class {", "Match"); c.complexPatternError(nullptr, "%type% ( )", "Match"); c.missingPercentCharacterError(nullptr, "%num", "Match"); diff --git a/lib/checkinternal.h b/lib/checkinternal.h index d62d9698b8d..2d95e3ed7e4 100644 --- a/lib/checkinternal.h +++ b/lib/checkinternal.h @@ -25,6 +25,7 @@ #ifdef CHECK_INTERNAL #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -42,15 +43,26 @@ class Settings; class CPPCHECKLIB CheckInternal : public Check { public: /** This constructor is used when registering the CheckClass */ - CheckInternal() : Check(myName()) {} + CheckInternal() : Check("cppcheck internal API usage") {} private: - /** This constructor is used when running checks. */ - CheckInternal(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + // Don't include these checks on the WIKI where people can read what + // checks there are. These checks are not intended for users. + return ""; + } +}; + +class CPPCHECKLIB CheckInternalImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + CheckInternalImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** @brief %Check if a simple pattern is used inside Token::Match or Token::findmatch */ void checkTokenMatchPatterns(); @@ -80,18 +92,6 @@ class CPPCHECKLIB CheckInternal : public Check { void orInComplexPattern(const Token *tok, const std::string &pattern, const std::string &funcname); void extraWhitespaceError(const Token *tok, const std::string &pattern, const std::string &funcname); void checkRedundantTokCheckError(const Token *tok); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "cppcheck internal API usage"; - } - - std::string classInfo() const override { - // Don't include these checks on the WIKI where people can read what - // checks there are. These checks are not intended for users. - return ""; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 4161b9b224d..f1cb4670c50 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -58,7 +58,7 @@ static const CWE CWE910(910U); // Use of Expired File Descriptor //--------------------------------------------------------------------------- // std::cout << std::cout; //--------------------------------------------------------------------------- -void CheckIO::checkCoutCerrMisusage() +void CheckIOImpl::checkCoutCerrMisusage() { if (mTokenizer->isC()) return; @@ -80,7 +80,7 @@ void CheckIO::checkCoutCerrMisusage() } } -void CheckIO::coutCerrMisusageError(const Token* tok, const std::string& streamName) +void CheckIOImpl::coutCerrMisusageError(const Token* tok, const std::string& streamName) { reportError(tok, Severity::error, "coutCerrMisusage", "Invalid usage of output stream: '<< std::" + streamName + "'.", CWE398, Certainty::normal); } @@ -119,7 +119,7 @@ namespace { const std::unordered_set whitelist = { "clearerr", "feof", "ferror", "fgetpos", "ftell", "setbuf", "setvbuf", "ungetc", "ungetwc" }; } -void CheckIO::checkFileUsage() +void CheckIOImpl::checkFileUsage() { const bool windows = mSettings->platform.isWindows(); const bool printPortability = mSettings->severity.isEnabled(Severity::portability); @@ -379,37 +379,37 @@ void CheckIO::checkFileUsage() } } -void CheckIO::fflushOnInputStreamError(const Token *tok, const std::string &varname) +void CheckIOImpl::fflushOnInputStreamError(const Token *tok, const std::string &varname) { reportError(tok, Severity::portability, "fflushOnInputStream", "fflush() called on input stream '" + varname + "' may result in undefined behaviour on non-linux systems.", CWE398, Certainty::normal); } -void CheckIO::ioWithoutPositioningError(const Token *tok) +void CheckIOImpl::ioWithoutPositioningError(const Token *tok) { reportError(tok, Severity::error, "IOWithoutPositioning", "Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour.", CWE664, Certainty::normal); } -void CheckIO::readWriteOnlyFileError(const Token *tok) +void CheckIOImpl::readWriteOnlyFileError(const Token *tok) { reportError(tok, Severity::error, "readWriteOnlyFile", "Read operation on a file that was opened only for writing.", CWE664, Certainty::normal); } -void CheckIO::writeReadOnlyFileError(const Token *tok) +void CheckIOImpl::writeReadOnlyFileError(const Token *tok) { reportError(tok, Severity::error, "writeReadOnlyFile", "Write operation on a file that was opened only for reading.", CWE664, Certainty::normal); } -void CheckIO::useClosedFileError(const Token *tok) +void CheckIOImpl::useClosedFileError(const Token *tok) { reportError(tok, Severity::error, "useClosedFile", "Used file that is not opened.", CWE910, Certainty::normal); } -void CheckIO::fcloseInLoopConditionError(const Token *tok, const std::string &varname) +void CheckIOImpl::fcloseInLoopConditionError(const Token *tok, const std::string &varname) { reportError(tok, Severity::warning, "fcloseInLoopCondition", @@ -418,13 +418,13 @@ void CheckIO::fcloseInLoopConditionError(const Token *tok, const std::string &va CWE910, Certainty::normal); } -void CheckIO::seekOnAppendedFileError(const Token *tok) +void CheckIOImpl::seekOnAppendedFileError(const Token *tok) { reportError(tok, Severity::warning, "seekOnAppendedFile", "Repositioning operation performed on a file opened in append mode has no effect.", CWE398, Certainty::normal); } -void CheckIO::incompatibleFileOpenError(const Token *tok, const std::string &filename) +void CheckIOImpl::incompatibleFileOpenError(const Token *tok, const std::string &filename) { reportError(tok, Severity::warning, "incompatibleFileOpen", "The file '" + filename + "' is opened for read and write access at the same time on different streams", CWE664, Certainty::normal); @@ -434,7 +434,7 @@ void CheckIO::incompatibleFileOpenError(const Token *tok, const std::string &fil //--------------------------------------------------------------------------- // scanf without field width limits can crash with huge input data //--------------------------------------------------------------------------- -void CheckIO::invalidScanf() +void CheckIOImpl::invalidScanf() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("invalidscanf")) return; @@ -481,7 +481,7 @@ void CheckIO::invalidScanf() } } -void CheckIO::invalidScanfError(const Token *tok) +void CheckIOImpl::invalidScanfError(const Token *tok) { const std::string fname = (tok ? tok->str() : std::string("scanf")); reportError(tok, Severity::warning, @@ -553,7 +553,7 @@ static inline bool typesMatch(const std::string& iToTest, const std::string& iTy return (iToTest == iTypename) || (iToTest == iOptionalPrefix + iTypename); } -void CheckIO::checkWrongPrintfScanfArguments() +void CheckIOImpl::checkWrongPrintfScanfArguments() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const bool isWindows = mSettings->platform.isWindows(); @@ -625,11 +625,11 @@ void CheckIO::checkWrongPrintfScanfArguments() } } -void CheckIO::checkFormatString(const Token * const tok, - const Token * const formatStringTok, - const Token * argListTok, - const bool scan, - const bool scanf_s) +void CheckIOImpl::checkFormatString(const Token * const tok, + const Token * const formatStringTok, + const Token * argListTok, + const bool scan, + const bool scanf_s) { const bool isWindows = mSettings->platform.isWindows(); const bool printWarning = mSettings->severity.isEnabled(Severity::warning); @@ -1368,7 +1368,7 @@ void CheckIO::checkFormatString(const Token * const tok, // We currently only support string literals, variables, and functions. /// @todo add non-string literals, and generic expressions -CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings &settings, bool _isCPP) +CheckIOImpl::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings &settings, bool _isCPP) : isCPP(_isCPP) { if (!arg) @@ -1582,7 +1582,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings &settings, } } -CheckIO::ArgumentInfo::~ArgumentInfo() +CheckIOImpl::ArgumentInfo::~ArgumentInfo() { if (tempToken) { while (tempToken->next()) @@ -1597,7 +1597,7 @@ namespace { const std::set stl_string = { "string", "u16string", "u32string", "wstring" }; } -bool CheckIO::ArgumentInfo::isStdVectorOrString() +bool CheckIOImpl::ArgumentInfo::isStdVectorOrString() { if (!isCPP) return false; @@ -1659,7 +1659,7 @@ static const std::set stl_container = { "unordered_map", "unordered_multimap", "unordered_multiset", "unordered_set", "vector" }; -bool CheckIO::ArgumentInfo::isStdContainer(const Token *tok) +bool CheckIOImpl::ArgumentInfo::isStdContainer(const Token *tok) { if (!isCPP) return false; @@ -1691,7 +1691,7 @@ bool CheckIO::ArgumentInfo::isStdContainer(const Token *tok) return false; } -bool CheckIO::ArgumentInfo::isArrayOrPointer() const +bool CheckIOImpl::ArgumentInfo::isArrayOrPointer() const { if (address) return true; @@ -1704,7 +1704,7 @@ bool CheckIO::ArgumentInfo::isArrayOrPointer() const return tok && tok->strAt(1) == "*"; } -bool CheckIO::ArgumentInfo::isComplexType() const +bool CheckIOImpl::ArgumentInfo::isComplexType() const { if (variableInfo->type()) return true; @@ -1716,7 +1716,7 @@ bool CheckIO::ArgumentInfo::isComplexType() const return ((variableInfo->isStlStringType() || (varTypeTok->strAt(1) == "<" && varTypeTok->linkAt(1) && varTypeTok->linkAt(1)->strAt(1) != "::")) && !variableInfo->isArrayOrPointer()); } -bool CheckIO::ArgumentInfo::isKnownType() const +bool CheckIOImpl::ArgumentInfo::isKnownType() const { if (variableInfo) return (typeToken->isStandardType() || typeToken->next()->isStandardType() || isComplexType()); @@ -1726,15 +1726,15 @@ bool CheckIO::ArgumentInfo::isKnownType() const return typeToken->isStandardType() || Token::Match(typeToken, "std :: string|wstring"); } -bool CheckIO::ArgumentInfo::isLibraryType(const Settings &settings) const +bool CheckIOImpl::ArgumentInfo::isLibraryType(const Settings &settings) const { return typeToken && typeToken->isStandardType() && settings.library.podtype(typeToken->str()); } -void CheckIO::wrongPrintfScanfArgumentsError(const Token* tok, - const std::string &functionName, - nonneg int numFormat, - nonneg int numFunction) +void CheckIOImpl::wrongPrintfScanfArgumentsError(const Token* tok, + const std::string &functionName, + nonneg int numFormat, + nonneg int numFunction) { const Severity severity = numFormat > numFunction ? Severity::error : Severity::warning; if (severity != Severity::error && !mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("wrongPrintfScanfArgNum")) @@ -1753,8 +1753,8 @@ void CheckIO::wrongPrintfScanfArgumentsError(const Token* tok, reportError(tok, severity, "wrongPrintfScanfArgNum", errmsg.str(), CWE685, Certainty::normal); } -void CheckIO::wrongPrintfScanfPosixParameterPositionError(const Token* tok, const std::string& functionName, - nonneg int index, nonneg int numFunction) +void CheckIOImpl::wrongPrintfScanfPosixParameterPositionError(const Token* tok, const std::string& functionName, + nonneg int index, nonneg int numFunction) { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("wrongPrintfScanfParameterPositionError")) return; @@ -1768,7 +1768,7 @@ void CheckIO::wrongPrintfScanfPosixParameterPositionError(const Token* tok, cons reportError(tok, Severity::warning, "wrongPrintfScanfParameterPositionError", errmsg.str(), CWE685, Certainty::normal); } -void CheckIO::invalidScanfArgTypeError_s(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) +void CheckIOImpl::invalidScanfArgTypeError_s(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1784,7 +1784,7 @@ void CheckIO::invalidScanfArgTypeError_s(const Token* tok, nonneg int numFormat, errmsg << "."; reportError(tok, severity, "invalidScanfArgType_s", errmsg.str(), CWE686, Certainty::normal); } -void CheckIO::invalidScanfArgTypeError_int(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned) +void CheckIOImpl::invalidScanfArgTypeError_int(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1829,7 +1829,7 @@ void CheckIO::invalidScanfArgTypeError_int(const Token* tok, nonneg int numForma errmsg << "."; reportError(tok, severity, "invalidScanfArgType_int", errmsg.str(), CWE686, Certainty::normal); } -void CheckIO::invalidScanfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) +void CheckIOImpl::invalidScanfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1848,7 +1848,7 @@ void CheckIO::invalidScanfArgTypeError_float(const Token* tok, nonneg int numFor reportError(tok, severity, "invalidScanfArgType_float", errmsg.str(), CWE686, Certainty::normal); } -void CheckIO::invalidPrintfArgTypeError_s(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) +void CheckIOImpl::invalidPrintfArgTypeError_s(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1859,7 +1859,7 @@ void CheckIO::invalidPrintfArgTypeError_s(const Token* tok, nonneg int numFormat errmsg << "."; reportError(tok, severity, "invalidPrintfArgType_s", errmsg.str(), CWE686, Certainty::normal); } -void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) +void CheckIOImpl::invalidPrintfArgTypeError_n(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1870,7 +1870,7 @@ void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, nonneg int numFormat errmsg << "."; reportError(tok, severity, "invalidPrintfArgType_n", errmsg.str(), CWE686, Certainty::normal); } -void CheckIO::invalidPrintfArgTypeError_p(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) +void CheckIOImpl::invalidPrintfArgTypeError_p(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1920,7 +1920,7 @@ static void printfFormatType(std::ostream& os, const std::string& specifier, boo os << "\'"; } -void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) +void CheckIOImpl::invalidPrintfArgTypeError_uint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1934,7 +1934,7 @@ void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, nonneg int numFor reportError(tok, severity, "invalidPrintfArgType_uint", errmsg.str(), CWE686, Certainty::normal); } -void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) +void CheckIOImpl::invalidPrintfArgTypeError_sint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1947,7 +1947,7 @@ void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, nonneg int numFor errmsg << "."; reportError(tok, severity, "invalidPrintfArgType_sint", errmsg.str(), CWE686, Certainty::normal); } -void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) +void CheckIOImpl::invalidPrintfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); if (!mSettings->severity.isEnabled(severity)) @@ -1962,12 +1962,12 @@ void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, nonneg int numFo reportError(tok, severity, "invalidPrintfArgType_float", errmsg.str(), CWE686, Certainty::normal); } -Severity CheckIO::getSeverity(const CheckIO::ArgumentInfo *argInfo) +Severity CheckIOImpl::getSeverity(const ArgumentInfo *argInfo) { return (argInfo && argInfo->typeToken && !argInfo->typeToken->originalName().empty()) ? Severity::portability : Severity::warning; } -void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo) +void CheckIOImpl::argumentType(std::ostream& os, const ArgumentInfo * argInfo) { if (argInfo) { os << "\'"; @@ -2017,7 +2017,7 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo) os << "Unknown"; } -void CheckIO::invalidLengthModifierError(const Token* tok, nonneg int numFormat, const std::string& modifier) +void CheckIOImpl::invalidLengthModifierError(const Token* tok, nonneg int numFormat, const std::string& modifier) { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("invalidLengthModifierError")) return; @@ -2026,7 +2026,7 @@ void CheckIO::invalidLengthModifierError(const Token* tok, nonneg int numFormat, reportError(tok, Severity::warning, "invalidLengthModifierError", errmsg.str(), CWE704, Certainty::normal); } -void CheckIO::invalidScanfFormatWidthError(const Token* tok, nonneg int numFormat, int width, const Variable *var, const std::string& specifier) +void CheckIOImpl::invalidScanfFormatWidthError(const Token* tok, nonneg int numFormat, int width, const Variable *var, const std::string& specifier) { MathLib::bigint arrlen = 0; std::string varname; @@ -2052,7 +2052,7 @@ void CheckIO::invalidScanfFormatWidthError(const Token* tok, nonneg int numForma void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckIO checkIO(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckIOImpl checkIO(&tokenizer, &tokenizer.getSettings(), errorLogger); checkIO.checkWrongPrintfScanfArguments(); checkIO.checkCoutCerrMisusage(); @@ -2062,7 +2062,7 @@ void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) void CheckIO::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckIO c(nullptr, settings, errorLogger); + CheckIOImpl c(nullptr, settings, errorLogger); c.coutCerrMisusageError(nullptr, "cout"); c.fflushOnInputStreamError(nullptr, "stdin"); c.ioWithoutPositioningError(nullptr); diff --git a/lib/checkio.h b/lib/checkio.h index b3c86da3577..acad40de136 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -22,6 +22,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -45,16 +46,35 @@ class CPPCHECKLIB CheckIO : public Check { public: /** @brief This constructor is used when registering CheckIO */ - CheckIO() : Check(myName()) {} + CheckIO() : Check("IO using format string") {} private: - /** @brief This constructor is used when running checks. */ - CheckIO(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks on the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Check format string input/output operations.\n" + "- Bad usage of the function 'sprintf' (overlapping data)\n" + "- Missing or wrong width specifiers in 'scanf' format string\n" + "- Use a file that has been closed\n" + "- File input/output without positioning results in undefined behaviour\n" + "- Read to a file that has only been opened for writing (or vice versa)\n" + "- Repositioning operation on a file opened in append mode\n" + "- The same file can't be open for read and write at the same time on different streams\n" + "- Using fflush() on an input stream\n" + "- Invalid usage of output stream. For example: 'std::cout << std::cout;'\n" + "- Wrong number of arguments given to 'printf' or 'scanf;'\n"; + } +}; + +class CPPCHECKLIB CheckIOImpl : public CheckImpl { +public: + /** @brief This constructor is used when running checks. */ + CheckIOImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** @brief %Check for missusage of std::cout */ void checkCoutCerrMisusage(); @@ -128,26 +148,6 @@ class CPPCHECKLIB CheckIO : public Check { void invalidScanfFormatWidthError(const Token* tok, nonneg int numFormat, int width, const Variable *var, const std::string& specifier); static void argumentType(std::ostream & os, const ArgumentInfo * argInfo); static Severity getSeverity(const ArgumentInfo *argInfo); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "IO using format string"; - } - - std::string classInfo() const override { - return "Check format string input/output operations.\n" - "- Bad usage of the function 'sprintf' (overlapping data)\n" - "- Missing or wrong width specifiers in 'scanf' format string\n" - "- Use a file that has been closed\n" - "- File input/output without positioning results in undefined behaviour\n" - "- Read to a file that has only been opened for writing (or vice versa)\n" - "- Repositioning operation on a file opened in append mode\n" - "- The same file can't be open for read and write at the same time on different streams\n" - "- Using fflush() on an input stream\n" - "- Invalid usage of output stream. For example: 'std::cout << std::cout;'\n" - "- Wrong number of arguments given to 'printf' or 'scanf;'\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 1c9a7283161..7e12872c3d4 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -107,35 +107,35 @@ void VarInfo::possibleUsageAll(const std::pair& functionUsa } -void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, int type) const +void CheckLeakAutoVarImpl::leakError(const Token *tok, const std::string &varname, int type) const { - const CheckMemoryLeak checkmemleak(mTokenizer, mErrorLogger, mSettings); + const CheckMemoryLeakImpl checkmemleak(mTokenizer, mSettings, mErrorLogger); if (Library::isresource(type)) checkmemleak.resourceLeakError(tok, varname); else checkmemleak.memleakError(tok, varname); } -void CheckLeakAutoVar::mismatchError(const Token *deallocTok, const Token *allocTok, const std::string &varname) const +void CheckLeakAutoVarImpl::mismatchError(const Token *deallocTok, const Token *allocTok, const std::string &varname) const { - const CheckMemoryLeak c(mTokenizer, mErrorLogger, mSettings); + const CheckMemoryLeakImpl c(mTokenizer, mSettings, mErrorLogger); const std::list callstack = { allocTok, deallocTok }; c.mismatchAllocDealloc(callstack, varname); } -void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname) const +void CheckLeakAutoVarImpl::deallocUseError(const Token *tok, const std::string &varname) const { - const CheckMemoryLeak c(mTokenizer, mErrorLogger, mSettings); + const CheckMemoryLeakImpl c(mTokenizer, mSettings, mErrorLogger); c.deallocuseError(tok, varname); } -void CheckLeakAutoVar::deallocReturnError(const Token *tok, const Token *deallocTok, const std::string &varname) +void CheckLeakAutoVarImpl::deallocReturnError(const Token *tok, const Token *deallocTok, const std::string &varname) { const std::list locations = { deallocTok, tok }; reportError(locations, Severity::error, "deallocret", "$symbol:" + varname + "\nReturning/dereferencing '$symbol' after it is deallocated / released", CWE672, Certainty::normal); } -void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::pair& functionUsage) +void CheckLeakAutoVarImpl::configurationInfo(const Token* tok, const std::pair& functionUsage) { if (mSettings->checkLibrary && functionUsage.second == VarInfo::USED && (!functionUsage.first || !functionUsage.first->function() || !functionUsage.first->function()->hasBody())) { @@ -149,7 +149,7 @@ void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::pair locations = { prevFreeTok, tok }; @@ -160,7 +160,7 @@ void CheckLeakAutoVar::doubleFreeError(const Token *tok, const Token *prevFreeTo } -void CheckLeakAutoVar::check() +void CheckLeakAutoVarImpl::check() { if (mSettings->clang) return; @@ -303,10 +303,10 @@ static std::vector getComparisonTokens(const Token* tok) return result; } -bool CheckLeakAutoVar::checkScope(const Token * const startToken, - VarInfo &varInfo, - std::set notzero, - nonneg int recursiveCount) +bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, + VarInfo &varInfo, + std::set notzero, + nonneg int recursiveCount) { #if ASAN static const nonneg int recursiveLimit = 300; @@ -887,7 +887,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, } -const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const tok, VarInfo &varInfo, bool inFuncCall) +const Token * CheckLeakAutoVarImpl::checkTokenInsideExpression(const Token * const tok, VarInfo &varInfo, bool inFuncCall) { // Deallocation and then dereferencing pointer.. if (tok->varId() > 0) { @@ -896,7 +896,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t if (var != varInfo.alloctype.end()) { bool unknown = false; if (var->second.status == VarInfo::DEALLOC && tok->valueType() && tok->valueType()->pointer && - CheckNullPointer::isPointerDeRef(tok, unknown, *mSettings, /*checkNullArg*/ false) && !unknown) { + CheckNullPointerImpl::isPointerDeRef(tok, unknown, *mSettings, /*checkNullArg*/ false) && !unknown) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { varInfo.erase(tok->varId()); @@ -956,7 +956,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t } -void CheckLeakAutoVar::changeAllocStatusIfRealloc(std::map &alloctype, const Token *fTok, const Token *retTok) const +void CheckLeakAutoVarImpl::changeAllocStatusIfRealloc(std::map &alloctype, const Token *fTok, const Token *retTok) const { const Library::AllocFunc* f = mSettings->library.getReallocFuncInfo(fTok); if (f && f->arg == -1 && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(fTok)) { @@ -977,7 +977,7 @@ void CheckLeakAutoVar::changeAllocStatusIfRealloc(std::map &alloctype = varInfo.alloctype; const auto var = alloctype.find(arg->varId()); @@ -1014,7 +1014,7 @@ void CheckLeakAutoVar::changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocI } } -void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af) +void CheckLeakAutoVarImpl::functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af) { // Ignore function call? const bool isLeakIgnore = mSettings->library.isLeakIgnore(mSettings->library.getFunctionName(tokName)); @@ -1153,8 +1153,8 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin } -void CheckLeakAutoVar::leakIfAllocated(const Token *vartok, - const VarInfo &varInfo) +void CheckLeakAutoVarImpl::leakIfAllocated(const Token *vartok, + const VarInfo &varInfo) { const std::map &alloctype = varInfo.alloctype; const auto& possibleUsage = varInfo.possibleUsage; @@ -1176,7 +1176,7 @@ static bool isSafeCast(const ValueType* vt, const Settings& settings) return sizeOf == 0 || sizeOf >= settings.platform.sizeof_pointer; } -void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope) +void CheckLeakAutoVarImpl::ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope) { const std::map &alloctype = varInfo.alloctype; const auto& possibleUsage = varInfo.possibleUsage; @@ -1280,13 +1280,13 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO void CheckLeakAutoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckLeakAutoVar checkLeakAutoVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckLeakAutoVarImpl checkLeakAutoVar(&tokenizer, &tokenizer.getSettings(), errorLogger); checkLeakAutoVar.check(); } void CheckLeakAutoVar::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckLeakAutoVar c(nullptr, settings, errorLogger); + CheckLeakAutoVarImpl c(nullptr, settings, errorLogger); c.deallocReturnError(nullptr, nullptr, "p"); c.configurationInfo(nullptr, { nullptr, VarInfo::USED }); // user configuration is needed to complete analysis c.doubleFreeError(nullptr, nullptr, "varname", 0); diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index d7d8d390b3d..ce7e1ddbd8b 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include "library.h" @@ -107,15 +108,24 @@ class CPPCHECKLIB VarInfo { class CPPCHECKLIB CheckLeakAutoVar : public Check { public: /** This constructor is used when registering the CheckLeakAutoVar */ - CheckLeakAutoVar() : Check(myName()) {} + CheckLeakAutoVar() : Check("Leaks (auto variables)") {} private: - /** This constructor is used when running checks. */ - CheckLeakAutoVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Detect when a auto variable is allocated but not deallocated or deallocated twice.\n"; + } +}; + +class CPPCHECKLIB CheckLeakAutoVarImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + CheckLeakAutoVarImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** check for leaks in all scopes */ void check(); @@ -157,16 +167,6 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check { /** message: user configuration is needed to complete analysis */ void configurationInfo(const Token* tok, const std::pair& functionUsage); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Leaks (auto variables)"; - } - - std::string classInfo() const override { - return "Detect when a auto variable is allocated but not deallocated or deallocated twice.\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index b2f97693cd6..cef03b1a538 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -31,6 +31,7 @@ #include "utils.h" #include +#include #include #include #include @@ -45,7 +46,8 @@ static const CWE CWE772(772U); // Missing Release of Resource after Effective L //--------------------------------------------------------------------------- -CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, nonneg int varid, std::list *callstack) const + +CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getAllocationType(const Token *tok2, nonneg int varid, std::list *callstack) const { // What we may have... // * var = (char *)malloc(10); @@ -93,7 +95,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, return New; } - if (mSettings_->hasLib("posix")) { + if (mSettings->hasLib("posix")) { if (Token::Match(tok2, "open|openat|creat|mkstemp|mkostemp|socket (")) { // simple sanity check of function parameters.. // TODO: Make such check for all these functions @@ -112,11 +114,11 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, } // Does tok2 point on a Library allocation function? - const int alloctype = mSettings_->library.getAllocId(tok2, -1); + const int alloctype = mSettings->library.getAllocId(tok2, -1); if (alloctype > 0) { - if (alloctype == mSettings_->library.deallocId("free")) + if (alloctype == mSettings->library.deallocId("free")) return Malloc; - if (alloctype == mSettings_->library.deallocId("fclose")) + if (alloctype == mSettings->library.deallocId("fclose")) return File; return Library::ismemory(alloctype) ? OtherMem : OtherRes; } @@ -143,7 +145,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, } -CheckMemoryLeak::AllocType CheckMemoryLeak::getReallocationType(const Token *tok2, nonneg int varid) const +CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getReallocationType(const Token *tok2, nonneg int varid) const { // What we may have... // * var = (char *)realloc(..; @@ -157,7 +159,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getReallocationType(const Token *tok if (!Token::Match(tok2, "%name% (")) return No; - const Library::AllocFunc *f = mSettings_->library.getReallocFuncInfo(tok2); + const Library::AllocFunc *f = mSettings->library.getReallocFuncInfo(tok2); if (!(f && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(tok2))) return No; const auto args = getArguments(tok2); @@ -171,11 +173,11 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getReallocationType(const Token *tok if (varid > 0 && !Token::Match(arg, "%varid% [,)]", varid)) return No; - const int realloctype = mSettings_->library.getReallocId(tok2, -1); + const int realloctype = mSettings->library.getReallocId(tok2, -1); if (realloctype > 0) { - if (realloctype == mSettings_->library.deallocId("free")) + if (realloctype == mSettings->library.deallocId("free")) return Malloc; - if (realloctype == mSettings_->library.deallocId("fclose")) + if (realloctype == mSettings->library.deallocId("fclose")) return File; return Library::ismemory(realloctype) ? OtherMem : OtherRes; } @@ -183,7 +185,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getReallocationType(const Token *tok } -CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok, nonneg int varid) const +CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getDeallocationType(const Token *tok, nonneg int varid) const { if (tok->isCpp() && tok->str() == "delete" && tok->astOperand1()) { const Token* vartok = tok->astOperand1(); @@ -214,7 +216,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok if (tok->str() == "realloc" && Token::simpleMatch(vartok->next(), ", 0 )")) return Malloc; - if (mSettings_->hasLib("posix")) { + if (mSettings->hasLib("posix")) { if (tok->str() == "close") return Fd; if (tok->str() == "pclose") @@ -222,11 +224,11 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok } // Does tok point on a Library deallocation function? - const int dealloctype = mSettings_->library.getDeallocId(tok, argNr); + const int dealloctype = mSettings->library.getDeallocId(tok, argNr); if (dealloctype > 0) { - if (dealloctype == mSettings_->library.deallocId("free")) + if (dealloctype == mSettings->library.deallocId("free")) return Malloc; - if (dealloctype == mSettings_->library.deallocId("fclose")) + if (dealloctype == mSettings->library.deallocId("fclose")) return File; return Library::ismemory(dealloctype) ? OtherMem : OtherRes; } @@ -238,10 +240,10 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok return No; } -bool CheckMemoryLeak::isReopenStandardStream(const Token *tok) const +bool CheckMemoryLeakImpl::isReopenStandardStream(const Token *tok) const { if (getReallocationType(tok, 0) == File) { - const Library::AllocFunc *f = mSettings_->library.getReallocFuncInfo(tok); + const Library::AllocFunc *f = mSettings->library.getReallocFuncInfo(tok); if (f && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(tok)) { const Token* arg = getArguments(tok).at(f->reallocArg - 1); if (Token::Match(arg, "stdin|stdout|stderr")) @@ -251,9 +253,9 @@ bool CheckMemoryLeak::isReopenStandardStream(const Token *tok) const return false; } -bool CheckMemoryLeak::isOpenDevNull(const Token *tok) const +bool CheckMemoryLeakImpl::isOpenDevNull(const Token *tok) const { - if (mSettings_->hasLib("posix") && tok->str() == "open" && numberOfArguments(tok) == 2) { + if (mSettings->hasLib("posix") && tok->str() == "open" && numberOfArguments(tok) == 2) { const Token* arg = getArguments(tok).at(0); if (Token::simpleMatch(arg, "\"/dev/null\"")) return true; @@ -261,24 +263,18 @@ bool CheckMemoryLeak::isOpenDevNull(const Token *tok) const return false; } -//-------------------------------------------------------------------------- - - -//-------------------------------------------------------------------------- - -void CheckMemoryLeak::memoryLeak(const Token *tok, const std::string &varname, AllocType alloctype) const +void CheckMemoryLeakImpl::memoryLeak(const Token *tok, const std::string &varname, AllocType alloctype) const { - if (alloctype == CheckMemoryLeak::File || - alloctype == CheckMemoryLeak::Pipe || - alloctype == CheckMemoryLeak::Fd || - alloctype == CheckMemoryLeak::OtherRes) + if (alloctype == File || + alloctype == Pipe || + alloctype == Fd || + alloctype == OtherRes) resourceLeakError(tok, varname); else memleakError(tok, varname); } -//--------------------------------------------------------------------------- -void CheckMemoryLeak::reportErr(const Token *tok, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe) const +void CheckMemoryLeakImpl::reportErr(const Token *tok, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe) const { std::list callstack; @@ -288,26 +284,25 @@ void CheckMemoryLeak::reportErr(const Token *tok, Severity severity, const std:: reportErr(callstack, severity, id, msg, cwe); } -void CheckMemoryLeak::reportErr(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe) const +void CheckMemoryLeakImpl::reportErr(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe) const { - const ErrorMessage errmsg(callstack, mTokenizer_ ? &mTokenizer_->list : nullptr, severity, id, msg, cwe, Certainty::normal); - if (mErrorLogger_) - mErrorLogger_->reportErr(errmsg); - else - Check::writeToErrorList(errmsg); + assert(mErrorLogger); + + const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, Certainty::normal); + mErrorLogger->reportErr(errmsg); } -void CheckMemoryLeak::memleakError(const Token *tok, const std::string &varname) const +void CheckMemoryLeakImpl::memleakError(const Token *tok, const std::string &varname) const { reportErr(tok, Severity::error, "memleak", "$symbol:" + varname + "\nMemory leak: $symbol", CWE(401U)); } -void CheckMemoryLeak::memleakUponReallocFailureError(const Token *tok, const std::string &reallocfunction, const std::string &varname) const +void CheckMemoryLeakImpl::memleakUponReallocFailureError(const Token *tok, const std::string &reallocfunction, const std::string &varname) const { reportErr(tok, Severity::error, "memleakOnRealloc", "$symbol:" + varname + "\nCommon " + reallocfunction + " mistake: \'$symbol\' nulled but not freed upon failure", CWE(401U)); } -void CheckMemoryLeak::resourceLeakError(const Token *tok, const std::string &varname) const +void CheckMemoryLeakImpl::resourceLeakError(const Token *tok, const std::string &varname) const { std::string errmsg("Resource leak"); if (!varname.empty()) @@ -315,17 +310,17 @@ void CheckMemoryLeak::resourceLeakError(const Token *tok, const std::string &var reportErr(tok, Severity::error, "resourceLeak", errmsg, CWE(775U)); } -void CheckMemoryLeak::deallocuseError(const Token *tok, const std::string &varname) const +void CheckMemoryLeakImpl::deallocuseError(const Token *tok, const std::string &varname) const { reportErr(tok, Severity::error, "deallocuse", "$symbol:" + varname + "\nDereferencing '$symbol' after it is deallocated / released", CWE(416U)); } -void CheckMemoryLeak::mismatchAllocDealloc(const std::list &callstack, const std::string &varname) const +void CheckMemoryLeakImpl::mismatchAllocDealloc(const std::list &callstack, const std::string &varname) const { reportErr(callstack, Severity::error, "mismatchAllocDealloc", "$symbol:" + varname + "\nMismatching allocation and deallocation: $symbol", CWE(762U)); } -CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Function* func, std::list *callstack) const +CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::functionReturnType(const Function* func, std::list *callstack) const { if (!func || !func->hasBody() || !func->functionScope) return No; @@ -423,7 +418,7 @@ static bool ifvar(const Token *tok, nonneg int varid, const std::string &comp, c // a = malloc(10); a = realloc(a, 100); //--------------------------------------------------------------------------- -void CheckMemoryLeakInFunction::checkReallocUsage() +void CheckMemoryLeakInFunctionImpl::checkReallocUsage() { logChecker("CheckMemoryLeakInFunction::checkReallocUsage"); @@ -494,17 +489,16 @@ void CheckMemoryLeakInFunction::checkReallocUsage() } } } -//--------------------------------------------------------------------------- void CheckMemoryLeakInFunction::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); checkMemoryLeak.checkReallocUsage(); } void CheckMemoryLeakInFunction::getErrorMessages(ErrorLogger *e, const Settings *settings) const { - CheckMemoryLeakInFunction c(nullptr, settings, e); + CheckMemoryLeakInFunctionImpl c(nullptr, settings, e); c.memleakError(nullptr, "varname"); c.resourceLeakError(nullptr, "varname"); c.deallocuseError(nullptr, "varname"); @@ -517,8 +511,7 @@ void CheckMemoryLeakInFunction::getErrorMessages(ErrorLogger *e, const Settings // Checks for memory leaks in classes.. //--------------------------------------------------------------------------- - -void CheckMemoryLeakInClass::check() +void CheckMemoryLeakInClassImpl::check() { logChecker("CheckMemoryLeakInClass::check"); @@ -543,15 +536,15 @@ void CheckMemoryLeakInClass::check() } -void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarname) +void CheckMemoryLeakInClassImpl::variable(const Scope *scope, const Token *tokVarname) { const std::string& varname = tokVarname->str(); const int varid = tokVarname->varId(); const std::string& classname = scope->className; // Check if member variable has been allocated and deallocated.. - CheckMemoryLeak::AllocType memberAlloc = CheckMemoryLeak::No; - CheckMemoryLeak::AllocType memberDealloc = CheckMemoryLeak::No; + AllocType memberAlloc = AllocType::No; + AllocType memberDealloc = AllocType::No; bool allocInConstructor = false; bool deallocInDestructor = false; @@ -563,7 +556,7 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam if (!func.hasBody()) { if (destructor && !func.isDefault()) { // implementation for destructor is not seen and not defaulted => assume it deallocates all variables properly deallocInDestructor = true; - memberDealloc = CheckMemoryLeak::Many; + memberDealloc = AllocType::Many; } continue; } @@ -596,14 +589,14 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam allocTok = tok->astParent()->astParent()->astOperand2(); AllocType alloc = getAllocationType(allocTok, 0); - if (alloc != CheckMemoryLeak::No) { + if (alloc != AllocType::No) { if (constructor) allocInConstructor = true; - if (memberAlloc != No && memberAlloc != alloc) - alloc = CheckMemoryLeak::Many; + if (memberAlloc != AllocType::No && memberAlloc != alloc) + alloc = AllocType::Many; - if (alloc != CheckMemoryLeak::Many && memberDealloc != CheckMemoryLeak::No && memberDealloc != CheckMemoryLeak::Many && memberDealloc != alloc) { + if (alloc != AllocType::Many && memberDealloc != AllocType::No && memberDealloc != AllocType::Many && memberDealloc != alloc) { mismatchAllocDealloc({tok}, classname + "::" + varname); } @@ -619,18 +612,18 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam // some usage in the destructor => assume it's related // to deallocation if (destructor && tok->str() == varname) - dealloc = CheckMemoryLeak::Many; - if (dealloc != CheckMemoryLeak::No) { + dealloc = AllocType::Many; + if (dealloc != AllocType::No) { if (destructor) deallocInDestructor = true; - if (dealloc != CheckMemoryLeak::Many && memberAlloc != CheckMemoryLeak::No && memberAlloc != Many && memberAlloc != dealloc) { + if (dealloc != AllocType::Many && memberAlloc != AllocType::No && memberAlloc != Many && memberAlloc != dealloc) { mismatchAllocDealloc({tok}, classname + "::" + varname); } // several types of allocation/deallocation? - if (memberDealloc != CheckMemoryLeak::No && memberDealloc != dealloc) - dealloc = CheckMemoryLeak::Many; + if (memberDealloc != AllocType::No && memberDealloc != dealloc) + dealloc = AllocType::Many; memberDealloc = dealloc; } @@ -645,12 +638,12 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam if (allocInConstructor && !deallocInDestructor) { unsafeClassError(tokVarname, classname, classname + "::" + varname /*, memberAlloc*/); - } else if (memberAlloc != CheckMemoryLeak::No && memberDealloc == CheckMemoryLeak::No) { + } else if (memberAlloc != AllocType::No && memberDealloc == AllocType::No) { unsafeClassError(tokVarname, classname, classname + "::" + varname /*, memberAlloc*/); } } -void CheckMemoryLeakInClass::unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname) +void CheckMemoryLeakInClassImpl::unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname) { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unsafeClassCanLeak")) return; @@ -663,7 +656,7 @@ void CheckMemoryLeakInClass::unsafeClassError(const Token *tok, const std::strin } -void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Token *classtok) +void CheckMemoryLeakInClassImpl::checkPublicFunctions(const Scope *scope, const Token *classtok) { // Check that public functions deallocate the pointers that they allocate. // There is no checking how these functions are used and therefore it @@ -680,20 +673,20 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Toke func.access == AccessControl::Public && func.hasBody()) { const Token *tok2 = func.functionScope->bodyStart->next(); if (Token::Match(tok2, "%varid% =", varid)) { - const CheckMemoryLeak::AllocType alloc = getAllocationType(tok2->tokAt(2), varid); - if (alloc != CheckMemoryLeak::No) + const AllocType alloc = getAllocationType(tok2->tokAt(2), varid); + if (alloc != AllocType::No) publicAllocationError(tok2, tok2->str()); } else if (Token::Match(tok2, "%type% :: %varid% =", varid) && tok2->str() == scope->className) { - const CheckMemoryLeak::AllocType alloc = getAllocationType(tok2->tokAt(4), varid); - if (alloc != CheckMemoryLeak::No) + const AllocType alloc = getAllocationType(tok2->tokAt(4), varid); + if (alloc != AllocType::No) publicAllocationError(tok2, tok2->strAt(2)); } } } } -void CheckMemoryLeakInClass::publicAllocationError(const Token *tok, const std::string &varname) +void CheckMemoryLeakInClassImpl::publicAllocationError(const Token *tok, const std::string &varname) { reportError(tok, Severity::warning, "publicAllocationError", "$symbol:" + varname + "\nPossible leak in public function. The pointer '$symbol' is not deallocated before it is allocated.", CWE398, Certainty::normal); } @@ -703,19 +696,18 @@ void CheckMemoryLeakInClass::runChecks(const Tokenizer &tokenizer, ErrorLogger * if (!tokenizer.isCPP()) return; - CheckMemoryLeakInClass checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckMemoryLeakInClassImpl checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); checkMemoryLeak.check(); } void CheckMemoryLeakInClass::getErrorMessages(ErrorLogger *e, const Settings *settings) const { - CheckMemoryLeakInClass c(nullptr, settings, e); + CheckMemoryLeakInClassImpl c(nullptr, settings, e); c.publicAllocationError(nullptr, "varname"); c.unsafeClassError(nullptr, "class", "class::varname"); } - -void CheckMemoryLeakStructMember::check() +void CheckMemoryLeakStructMemberImpl::check() { if (mSettings->clang) return; @@ -734,7 +726,7 @@ void CheckMemoryLeakStructMember::check() } } -bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) const +bool CheckMemoryLeakStructMemberImpl::isMalloc(const Variable *variable) const { if (!variable) return false; @@ -756,7 +748,7 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) const return alloc; } -void CheckMemoryLeakStructMember::checkStructVariable(const Variable* const variable) const +void CheckMemoryLeakStructMemberImpl::checkStructVariable(const Variable* const variable) const { if (!variable) return; @@ -976,15 +968,17 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable* const vari void CheckMemoryLeakStructMember::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckMemoryLeakStructMember checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckMemoryLeakStructMemberImpl checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); checkMemoryLeak.check(); } -void CheckMemoryLeakStructMember::getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) const -{} - +void CheckMemoryLeakStructMember::getErrorMessages(ErrorLogger * errorLogger, const Settings * settings) const +{ + (void)errorLogger; + (void)settings; +} -void CheckMemoryLeakNoVar::check() +void CheckMemoryLeakNoVarImpl::check() { logChecker("CheckMemoryLeakNoVar::check"); @@ -1010,7 +1004,7 @@ void CheckMemoryLeakNoVar::check() // Checks if an input argument to a function is the return value of an allocation function // like malloc(), and the function does not release it. //--------------------------------------------------------------------------- -void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) +void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scope) { // parse the executable scope until tok is reached... for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { @@ -1083,7 +1077,7 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) //--------------------------------------------------------------------------- // Checks if a call to an allocation function like malloc() is made and its return value is not assigned. //--------------------------------------------------------------------------- -void CheckMemoryLeakNoVar::checkForUnusedReturnValue(const Scope *scope) +void CheckMemoryLeakNoVarImpl::checkForUnusedReturnValue(const Scope *scope) { for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { const bool isNew = tok->isCpp() && tok->str() == "new"; @@ -1150,7 +1144,7 @@ void CheckMemoryLeakNoVar::checkForUnusedReturnValue(const Scope *scope) // f(shared_ptr(new int(42)), g()); // } //--------------------------------------------------------------------------- -void CheckMemoryLeakNoVar::checkForUnsafeArgAlloc(const Scope *scope) +void CheckMemoryLeakNoVarImpl::checkForUnsafeArgAlloc(const Scope *scope) { // This test only applies to C++ source if (!mTokenizer->isCPP()) @@ -1200,17 +1194,17 @@ void CheckMemoryLeakNoVar::checkForUnsafeArgAlloc(const Scope *scope) } } -void CheckMemoryLeakNoVar::functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall) +void CheckMemoryLeakNoVarImpl::functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall) { reportError(loc, Severity::error, "leakNoVarFunctionCall", "Allocation with " + alloc + ", " + functionCall + " doesn't release it.", CWE772, Certainty::normal); } -void CheckMemoryLeakNoVar::returnValueNotUsedError(const Token *tok, const std::string &alloc) +void CheckMemoryLeakNoVarImpl::returnValueNotUsedError(const Token *tok, const std::string &alloc) { reportError(tok, Severity::error, "leakReturnValNotUsed", "$symbol:" + alloc + "\nReturn value of allocation function '$symbol' is not stored.", CWE771, Certainty::normal); } -void CheckMemoryLeakNoVar::unsafeArgAllocError(const Token *tok, const std::string &funcName, const std::string &ptrType, const std::string& objType) +void CheckMemoryLeakNoVarImpl::unsafeArgAllocError(const Token *tok, const std::string &funcName, const std::string &ptrType, const std::string& objType) { const std::string factoryFunc = ptrType == "shared_ptr" ? "make_shared" : "make_unique"; reportError(tok, Severity::warning, "leakUnsafeArgAlloc", @@ -1222,13 +1216,13 @@ void CheckMemoryLeakNoVar::unsafeArgAllocError(const Token *tok, const std::stri void CheckMemoryLeakNoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckMemoryLeakNoVar checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckMemoryLeakNoVarImpl checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); checkMemoryLeak.check(); } void CheckMemoryLeakNoVar::getErrorMessages(ErrorLogger *e, const Settings *settings) const { - CheckMemoryLeakNoVar c(nullptr, settings, e); + CheckMemoryLeakNoVarImpl c(nullptr, settings, e); c.functionCallLeak(nullptr, "funcName", "funcName"); c.returnValueNotUsedError(nullptr, "funcName"); c.unsafeArgAllocError(nullptr, "funcName", "shared_ptr", "int"); diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index c9fb2274252..047cf3295ae 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -33,6 +33,7 @@ */ #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -52,18 +53,103 @@ enum class Severity : std::uint8_t; /// @addtogroup Core /// @{ -/** @brief Base class for memory leaks checking */ -class CPPCHECKLIB CheckMemoryLeak { + +/** + * @brief %CheckMemoryLeakInFunction detects when a function variable is allocated but not deallocated properly. + * + * The checking is done by looking at each function variable separately. By repeating these 4 steps over and over: + * -# locate a function variable + * -# create a simple token list that describes the usage of the function variable. + * -# simplify the token list. + * -# finally, check if the simplified token list contain any leaks. + */ + +class CPPCHECKLIB CheckMemoryLeakInFunction : public Check { + friend class TestMemleakInFunction; + +public: + /** @brief This constructor is used when registering this class */ + CheckMemoryLeakInFunction() : Check("Memory leaks (function variables)") {} + +private: + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + + /** Report all possible errors (for the --errorlist) */ + void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; + + /** + * Get class information (--doc) + * @return Wiki formatted information about this class + */ + std::string classInfo() const override { + return "Is there any allocated memory when a function goes out of scope\n"; + } +}; + + +/** + * @brief %Check class variables, variables that are allocated in the constructor should be deallocated in the destructor + */ + +class CPPCHECKLIB CheckMemoryLeakInClass : public Check { + friend class TestMemleakInClass; + +public: + CheckMemoryLeakInClass() : Check("Memory leaks (class variables)") {} + +private: + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + + void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; + + std::string classInfo() const override { + return "If the constructor allocate memory then the destructor must deallocate it.\n"; + } +}; + + + +/** @brief detect simple memory leaks for struct members */ + +class CPPCHECKLIB CheckMemoryLeakStructMember : public Check { + friend class TestMemleakStructMember; + +public: + CheckMemoryLeakStructMember() : Check("Memory leaks (struct members)") {} + +private: + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + + void getErrorMessages(ErrorLogger * errorLogger, const Settings * settings) const override; + + std::string classInfo() const override { + return "Don't forget to deallocate struct members\n"; + } +}; + + + +/** @brief detect simple memory leaks (address not taken) */ + +class CPPCHECKLIB CheckMemoryLeakNoVar : public Check { + friend class TestMemleakNoVar; + +public: + CheckMemoryLeakNoVar() : Check("Memory leaks (address not taken)") {} + private: - /** For access to the tokens */ - const Tokenizer * const mTokenizer_; + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - /** ErrorLogger used to report errors */ - ErrorLogger * const mErrorLogger_; + void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; - /** Enabled standards */ - const Settings * const mSettings_; + std::string classInfo() const override { + return "Not taking the address to allocated memory\n"; + } +}; +/** @brief Base class for memory leaks checking */ +class CPPCHECKLIB CheckMemoryLeakImpl : public CheckImpl { +private: /** * Report error. Similar with the function Check::reportError * @param tok the token where the error occurs @@ -85,12 +171,12 @@ class CPPCHECKLIB CheckMemoryLeak { void reportErr(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe) const; public: - CheckMemoryLeak() = delete; - CheckMemoryLeak(const CheckMemoryLeak &) = delete; - CheckMemoryLeak& operator=(const CheckMemoryLeak &) = delete; + CheckMemoryLeakImpl() = delete; + CheckMemoryLeakImpl(const CheckMemoryLeakImpl &) = delete; + CheckMemoryLeakImpl& operator=(const CheckMemoryLeakImpl &) = delete; - CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e, const Settings *s) - : mTokenizer_(t), mErrorLogger_(e), mSettings_(s) {} + CheckMemoryLeakImpl(const Tokenizer *t, const Settings *s, ErrorLogger *e) + : CheckImpl(t, s, e) {} /** @brief What type of allocation are used.. the "Many" means that several types of allocation and deallocation are used */ enum AllocType : std::uint8_t { No, Malloc, New, NewArray, File, Fd, Pipe, OtherMem, OtherRes, Many }; @@ -165,43 +251,16 @@ class CPPCHECKLIB CheckMemoryLeak { * -# finally, check if the simplified token list contain any leaks. */ -class CPPCHECKLIB CheckMemoryLeakInFunction : public Check, public CheckMemoryLeak { - friend class TestMemleakInFunction; - +class CPPCHECKLIB CheckMemoryLeakInFunctionImpl : public CheckMemoryLeakImpl { public: - /** @brief This constructor is used when registering this class */ - CheckMemoryLeakInFunction() : Check(myName()), CheckMemoryLeak(nullptr, nullptr, nullptr) {} - -private: /** @brief This constructor is used when running checks */ - CheckMemoryLeakInFunction(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger, settings) {} - - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + CheckMemoryLeakInFunctionImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} /** * Checking for a memory leak caused by improper realloc usage. */ void checkReallocUsage(); - - /** Report all possible errors (for the --errorlist) */ - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; - - /** - * Get name of class (--doc) - * @return name of class - */ - static std::string myName() { - return "Memory leaks (function variables)"; - } - - /** - * Get class information (--doc) - * @return Wiki formatted information about this class - */ - std::string classInfo() const override { - return "Is there any allocated memory when a function goes out of scope\n"; - } }; @@ -210,17 +269,10 @@ class CPPCHECKLIB CheckMemoryLeakInFunction : public Check, public CheckMemoryLe * @brief %Check class variables, variables that are allocated in the constructor should be deallocated in the destructor */ -class CPPCHECKLIB CheckMemoryLeakInClass : public Check, private CheckMemoryLeak { - friend class TestMemleakInClass; - +class CPPCHECKLIB CheckMemoryLeakInClassImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakInClass() : Check(myName()), CheckMemoryLeak(nullptr, nullptr, nullptr) {} - -private: - CheckMemoryLeakInClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger, settings) {} - - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + CheckMemoryLeakInClassImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); @@ -231,33 +283,17 @@ class CPPCHECKLIB CheckMemoryLeakInClass : public Check, private CheckMemoryLeak void publicAllocationError(const Token *tok, const std::string &varname); void unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname); - - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; - - static std::string myName() { - return "Memory leaks (class variables)"; - } - - std::string classInfo() const override { - return "If the constructor allocate memory then the destructor must deallocate it.\n"; - } }; /** @brief detect simple memory leaks for struct members */ -class CPPCHECKLIB CheckMemoryLeakStructMember : public Check, private CheckMemoryLeak { - friend class TestMemleakStructMember; - +class CPPCHECKLIB CheckMemoryLeakStructMemberImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakStructMember() : Check(myName()), CheckMemoryLeak(nullptr, nullptr, nullptr) {} -private: - CheckMemoryLeakStructMember(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger, settings) {} - - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + CheckMemoryLeakStructMemberImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); @@ -265,33 +301,16 @@ class CPPCHECKLIB CheckMemoryLeakStructMember : public Check, private CheckMemor bool isMalloc(const Variable *variable) const; void checkStructVariable(const Variable* variable) const; - - void getErrorMessages(ErrorLogger* /*errorLogger*/, const Settings* /*settings*/) const override; - - static std::string myName() { - return "Memory leaks (struct members)"; - } - - std::string classInfo() const override { - return "Don't forget to deallocate struct members\n"; - } }; /** @brief detect simple memory leaks (address not taken) */ -class CPPCHECKLIB CheckMemoryLeakNoVar : public Check, private CheckMemoryLeak { - friend class TestMemleakNoVar; - +class CPPCHECKLIB CheckMemoryLeakNoVarImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakNoVar() : Check(myName()), CheckMemoryLeak(nullptr, nullptr, nullptr) {} - -private: - CheckMemoryLeakNoVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger, settings) {} - - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + CheckMemoryLeakNoVarImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); @@ -317,16 +336,6 @@ class CPPCHECKLIB CheckMemoryLeakNoVar : public Check, private CheckMemoryLeak { void functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall); void returnValueNotUsedError(const Token* tok, const std::string &alloc); void unsafeArgAllocError(const Token *tok, const std::string &funcName, const std::string &ptrType, const std::string &objType); - - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; - - static std::string myName() { - return "Memory leaks (address not taken)"; - } - - std::string classInfo() const override { - return "Not taking the address to allocated memory\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 5bd602488b4..2dbff296cf0 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -54,7 +54,7 @@ static bool checkNullpointerFunctionCallPlausibility(const Function* func, unsig return !func || (func->argCount() >= arg && func->getArgumentVar(arg - 1) && func->getArgumentVar(arg - 1)->isPointer()); } -std::list CheckNullPointer::parseFunctionCall(const Token &tok, const Library &library, bool checkNullArg) +std::list CheckNullPointerImpl::parseFunctionCall(const Token &tok, const Library &library, bool checkNullArg) { if (Token::Match(&tok, "%name% ( )") || !tok.tokAt(2)) return {}; @@ -128,21 +128,12 @@ namespace { }; } -/** - * Is there a pointer dereference? Everything that should result in - * a nullpointer dereference error message will result in a true - * return value. If it's unknown if the pointer is dereferenced false - * is returned. - * @param tok token for the pointer - * @param unknown it is not known if there is a pointer dereference (could be reported as a debug message) - * @return true => there is a dereference - */ -bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown) const +bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown) const { return isPointerDeRef(tok, unknown, *mSettings); } -bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings, bool checkNullArg) +bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings, bool checkNullArg) { unknown = false; @@ -155,7 +146,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Set ftok = ftok->previous(); } if (ftok && ftok->previous()) { - const std::list varlist = parseFunctionCall(*ftok->previous(), settings.library, checkNullArg); + const std::list varlist = CheckNullPointerImpl::parseFunctionCall(*ftok->previous(), settings.library, checkNullArg); if (std::find(varlist.cbegin(), varlist.cend(), tok) != varlist.cend()) { return true; } @@ -273,7 +264,7 @@ static bool isNullablePointer(const Token* tok) return false; } -void CheckNullPointer::nullPointerByDeRefAndCheck() +void CheckNullPointerImpl::nullPointerByDeRefAndCheck() { const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive)); @@ -307,7 +298,7 @@ void CheckNullPointer::nullPointerByDeRefAndCheck() // Pointer dereference. bool unknown = false; - if (!isPointerDeRef(tok, unknown)) { + if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, *mSettings)) { if (unknown) nullPointerError(tok, tok->expressionString(), value, true); continue; @@ -318,7 +309,7 @@ void CheckNullPointer::nullPointerByDeRefAndCheck() } } -void CheckNullPointer::nullPointer() +void CheckNullPointerImpl::nullPointer() { logChecker("CheckNullPointer::nullPointer"); nullPointerByDeRefAndCheck(); @@ -332,7 +323,7 @@ namespace { } /** Dereferencing null constant (simplified token list) */ -void CheckNullPointer::nullConstantDereference() +void CheckNullPointerImpl::nullConstantDereference() { logChecker("CheckNullPointer::nullConstantDereference"); @@ -425,14 +416,14 @@ void CheckNullPointer::nullConstantDereference() } } -void CheckNullPointer::nullPointerError(const Token *tok) +void CheckNullPointerImpl::nullPointerError(const Token *tok) { ValueFlow::Value v(0); v.setKnown(); nullPointerError(tok, "", &v, false); } -void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive) +void CheckNullPointerImpl::nullPointerError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive) { const std::string errmsgcond("$symbol:" + varname + '\n' + ValueFlow::eitherTheConditionIsRedundant(value ? value->condition : nullptr) + " or there is possible null pointer dereference: $symbol."); const std::string errmsgdefarg("$symbol:" + varname + "\nPossible null pointer dereference if the default parameter value is used: $symbol"); @@ -486,7 +477,7 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var } } -void CheckNullPointer::arithmetic() +void CheckNullPointerImpl::arithmetic() { logChecker("CheckNullPointer::arithmetic"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -533,7 +524,7 @@ static std::string arithmeticTypeString(const Token *tok) return "arithmetic"; } -void CheckNullPointer::pointerArithmeticError(const Token* tok, const ValueFlow::Value *value, bool inconclusive) +void CheckNullPointerImpl::pointerArithmeticError(const Token* tok, const ValueFlow::Value *value, bool inconclusive) { // cppcheck-suppress shadowFunction - TODO: fix this std::string arithmetic = arithmeticTypeString(tok); @@ -563,7 +554,7 @@ void CheckNullPointer::pointerArithmeticError(const Token* tok, const ValueFlow: inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckNullPointer::redundantConditionWarning(const Token* tok, const ValueFlow::Value *value, const Token *condition, bool inconclusive) +void CheckNullPointerImpl::redundantConditionWarning(const Token* tok, const ValueFlow::Value *value, const Token *condition, bool inconclusive) { // cppcheck-suppress shadowFunction - TODO: fix this std::string arithmetic = arithmeticTypeString(tok); @@ -587,7 +578,7 @@ static bool isUnsafeUsage(const Settings &settings, const Token *vartok, CTU::Fi { (void)value; bool unknown = false; - return CheckNullPointer::isPointerDeRef(vartok, unknown, settings); + return CheckNullPointerImpl::isPointerDeRef(vartok, unknown, settings); } // a Clang-built executable will crash when using the anonymous MyFileInfo later on - so put it in a unique namespace for now @@ -613,9 +604,11 @@ namespace }; } -Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const +Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& currentConfig) const { - const std::list &unsafeUsage = CTU::getUnsafeUsage(tokenizer, settings, isUnsafeUsage); + (void)currentConfig; + + const std::list &unsafeUsage = CTU::getUnsafeUsage(tokenizer, settings, ::isUnsafeUsage); if (unsafeUsage.empty()) return nullptr; @@ -639,9 +632,9 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo &ctu, const std:: { (void)settings; - CheckNullPointer dummy(nullptr, &settings, &errorLogger); + CheckNullPointerImpl dummy(nullptr, &settings, &errorLogger); dummy. - logChecker("CheckNullPointer::analyseWholeProgram"); // unusedfunctions + logChecker("CheckNullPointer::analyseWholeProgram"); if (fileInfo.empty()) return false; @@ -701,7 +694,7 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo &ctu, const std:: void CheckNullPointer::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckNullPointer checkNullPointer(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckNullPointerImpl checkNullPointer(&tokenizer, &tokenizer.getSettings(), errorLogger); checkNullPointer.nullPointer(); checkNullPointer.arithmetic(); checkNullPointer.nullConstantDereference(); @@ -709,7 +702,7 @@ void CheckNullPointer::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorL void CheckNullPointer::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckNullPointer c(nullptr, settings, errorLogger); + CheckNullPointerImpl c(nullptr, settings, errorLogger); c.nullPointerError(nullptr, "pointer", nullptr, false); c.pointerArithmeticError(nullptr, nullptr, false); // TODO: nullPointerArithmeticOutOfMemory diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index c02feae303e..f9f78280fea 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -51,7 +52,36 @@ class CPPCHECKLIB CheckNullPointer : public Check { public: /** @brief This constructor is used when registering the CheckNullPointer */ - CheckNullPointer() : Check(myName()) {} + CheckNullPointer() : Check("Null pointer") {} + +private: + /** @brief Run checks against the normal token list */ + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + + /** @brief Parse current TU and extract file info */ + Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& currentConfig) const override; + + Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; + + /** @brief Analyse all file infos for all TU */ + bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; + + /** Get error messages. Used by --errorlist */ + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + /** class info in WIKI format. Used by --doc */ + std::string classInfo() const override { + return "Null pointers\n" + "- null pointer dereferencing\n" + "- undefined null pointer arithmetic\n"; + } +}; + +class CPPCHECKLIB CheckNullPointerImpl : public CheckImpl { +public: + /** @brief This constructor is used when running checks. */ + CheckNullPointerImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} /** * Is there a pointer dereference? Everything that should result in @@ -66,7 +96,6 @@ class CPPCHECKLIB CheckNullPointer : public Check { static bool isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings, bool checkNullArg = true); -private: /** * @brief parse a function call and extract information about variable usage * @param tok first token @@ -76,13 +105,6 @@ class CPPCHECKLIB CheckNullPointer : public Check { */ static std::list parseFunctionCall(const Token &tok, const Library &library, bool checkNullArg = true); - /** @brief This constructor is used when running checks. */ - CheckNullPointer(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - - /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - /** @brief possible null pointer dereference */ void nullPointer(); @@ -92,29 +114,6 @@ class CPPCHECKLIB CheckNullPointer : public Check { void nullPointerError(const Token *tok); void nullPointerError(const Token *tok, const std::string &varname, const ValueFlow::Value* value, bool inconclusive); - /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; - - Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; - - /** @brief Analyse all file infos for all TU */ - bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - - /** Get error messages. Used by --errorlist */ - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - /** Name of check */ - static std::string myName() { - return "Null pointer"; - } - - /** class info in WIKI format. Used by --doc */ - std::string classInfo() const override { - return "Null pointers\n" - "- null pointer dereferencing\n" - "- undefined null pointer arithmetic\n"; - } - /** * @brief Does one part of the check for nullPointer(). * Dereferencing a pointer and then checking if it's NULL.. diff --git a/lib/checkother.cpp b/lib/checkother.cpp index b454c4410cf..6edbef63c0e 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -80,7 +80,7 @@ static const CWE CWE783(783U); // Operator Precedence Logic Error // - http://www.cplusplus.com/reference/cstdio/getchar/ // - http://www.cplusplus.com/reference/cstdio/ungetc/ ... //---------------------------------------------------------------------------------- -void CheckOther::checkCastIntToCharAndBack() +void CheckOtherImpl::checkCastIntToCharAndBack() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -130,7 +130,7 @@ void CheckOther::checkCastIntToCharAndBack() } } -void CheckOther::checkCastIntToCharAndBackError(const Token *tok, const std::string &strFunctionName) +void CheckOtherImpl::checkCastIntToCharAndBackError(const Token *tok, const std::string &strFunctionName) { reportError( tok, @@ -150,7 +150,7 @@ void CheckOther::checkCastIntToCharAndBackError(const Token *tok, const std::str //--------------------------------------------------------------------------- // Clarify calculation precedence for ternary operators. //--------------------------------------------------------------------------- -void CheckOther::clarifyCalculation() +void CheckOtherImpl::clarifyCalculation() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("clarifyCalculation")) return; @@ -199,7 +199,7 @@ void CheckOther::clarifyCalculation() } } -void CheckOther::clarifyCalculationError(const Token *tok, const std::string &op) +void CheckOtherImpl::clarifyCalculationError(const Token *tok, const std::string &op) { // suspicious calculation const std::string calc("'a" + op + "b?c:d'"); @@ -221,7 +221,7 @@ void CheckOther::clarifyCalculationError(const Token *tok, const std::string &op //--------------------------------------------------------------------------- // Clarify (meaningless) statements like *foo++; with parentheses. //--------------------------------------------------------------------------- -void CheckOther::clarifyStatement() +void CheckOtherImpl::clarifyStatement() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -247,7 +247,7 @@ void CheckOther::clarifyStatement() } } -void CheckOther::clarifyStatementError(const Token *tok) +void CheckOtherImpl::clarifyStatementError(const Token *tok) { reportError(tok, Severity::warning, "clarifyStatement", "In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'?\n" "A statement like '*A++;' might not do what you intended. Postfix 'operator++' is executed before 'operator*'. " @@ -257,7 +257,7 @@ void CheckOther::clarifyStatementError(const Token *tok) //--------------------------------------------------------------------------- // Check for suspicious occurrences of 'if(); {}'. //--------------------------------------------------------------------------- -void CheckOther::checkSuspiciousSemicolon() +void CheckOtherImpl::checkSuspiciousSemicolon() { if (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning)) return; @@ -281,7 +281,7 @@ void CheckOther::checkSuspiciousSemicolon() } } -void CheckOther::suspiciousSemicolonError(const Token* tok) +void CheckOtherImpl::suspiciousSemicolonError(const Token* tok) { reportError(tok, Severity::warning, "suspiciousSemicolon", "Suspicious use of ; at the end of '" + (tok ? tok->str() : std::string()) + "' statement.", CWE398, Certainty::normal); @@ -329,7 +329,7 @@ static bool isDangerousTypeConversion(const Token* const tok) //--------------------------------------------------------------------------- // For C++ code, warn if C-style casts are used on pointer types //--------------------------------------------------------------------------- -void CheckOther::warningOldStylePointerCast() +void CheckOtherImpl::warningOldStylePointerCast() { // Only valid on C++ code if (!mTokenizer->isCPP()) @@ -394,7 +394,7 @@ void CheckOther::warningOldStylePointerCast() } } -void CheckOther::cstyleCastError(const Token *tok, bool isPtr) +void CheckOtherImpl::cstyleCastError(const Token *tok, bool isPtr) { const std::string type = isPtr ? "pointer" : "reference"; reportError(tok, Severity::style, "cstyleCast", @@ -405,7 +405,7 @@ void CheckOther::cstyleCastError(const Token *tok, bool isPtr) "which kind of cast is expected.", CWE398, Certainty::normal); } -void CheckOther::warningDangerousTypeCast() +void CheckOtherImpl::warningDangerousTypeCast() { // Only valid on C++ code if (!mTokenizer->isCPP()) @@ -433,7 +433,7 @@ void CheckOther::warningDangerousTypeCast() } } -void CheckOther::dangerousTypeCastError(const Token *tok, bool isPtr) +void CheckOtherImpl::dangerousTypeCastError(const Token *tok, bool isPtr) { //const std::string type = isPtr ? "pointer" : "reference"; (void)isPtr; @@ -442,7 +442,7 @@ void CheckOther::dangerousTypeCastError(const Token *tok, bool isPtr) CWE398, Certainty::normal); } -void CheckOther::warningIntToPointerCast() +void CheckOtherImpl::warningIntToPointerCast() { if (!mSettings->severity.isEnabled(Severity::portability) && !mSettings->isPremiumEnabled("cstyleCast")) return; @@ -471,14 +471,14 @@ void CheckOther::warningIntToPointerCast() } } -void CheckOther::intToPointerCastError(const Token *tok, const std::string& format) +void CheckOtherImpl::intToPointerCastError(const Token *tok, const std::string& format) { reportError(tok, Severity::portability, "intToPointerCast", "Casting non-zero " + format + " integer literal to pointer.", CWE398, Certainty::normal); } -void CheckOther::suspiciousFloatingPointCast() +void CheckOtherImpl::suspiciousFloatingPointCast() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("suspiciousFloatingPointCast")) return; @@ -528,7 +528,7 @@ void CheckOther::suspiciousFloatingPointCast() } } -void CheckOther::suspiciousFloatingPointCastError(const Token* tok) +void CheckOtherImpl::suspiciousFloatingPointCastError(const Token* tok) { reportError(tok, Severity::style, "suspiciousFloatingPointCast", "Floating-point cast causes loss of precision.\n" @@ -539,7 +539,7 @@ void CheckOther::suspiciousFloatingPointCastError(const Token* tok) // float* f; double* d = (double*)f; <-- Pointer cast to a type with an incompatible binary data representation //--------------------------------------------------------------------------- -void CheckOther::invalidPointerCast() +void CheckOtherImpl::invalidPointerCast() { if (!mSettings->severity.isEnabled(Severity::portability)) return; @@ -579,7 +579,7 @@ void CheckOther::invalidPointerCast() } -void CheckOther::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt) +void CheckOtherImpl::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt) { if (toIsInt) { // If we cast something to int*, this can be useful to play with its binary data representation reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + " to " + to + " is not portable due to different binary data representations on different platforms.", CWE704, inconclusive ? Certainty::inconclusive : Certainty::normal); @@ -592,7 +592,7 @@ void CheckOther::invalidPointerCastError(const Token* tok, const std::string& fr // Detect redundant assignments: x = 0; x = 4; //--------------------------------------------------------------------------- -void CheckOther::checkRedundantAssignment() +void CheckOtherImpl::checkRedundantAssignment() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("redundantAssignment") && @@ -729,7 +729,7 @@ void CheckOther::checkRedundantAssignment() } } -void CheckOther::redundantCopyError(const Token *tok1, const Token* tok2, const std::string& var) +void CheckOtherImpl::redundantCopyError(const Token *tok1, const Token* tok2, const std::string& var) { const std::list callstack = { tok1, tok2 }; reportError(callstack, Severity::performance, "redundantCopy", @@ -737,7 +737,7 @@ void CheckOther::redundantCopyError(const Token *tok1, const Token* tok2, const "Buffer '$symbol' is being written before its old content has been used.", CWE563, Certainty::normal); } -void CheckOther::redundantAssignmentError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive) +void CheckOtherImpl::redundantAssignmentError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive) { ErrorPath errorPath = { ErrorPathItem(tok1, var + " is assigned"), ErrorPathItem(tok2, var + " is overwritten") }; if (inconclusive) @@ -751,7 +751,7 @@ void CheckOther::redundantAssignmentError(const Token *tok1, const Token* tok2, "Variable '$symbol' is reassigned a value before the old one has been used.", CWE563, Certainty::normal); } -void CheckOther::redundantInitializationError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive) +void CheckOtherImpl::redundantInitializationError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive) { ErrorPath errorPath = { ErrorPathItem(tok1, var + " is initialized"), ErrorPathItem(tok2, var + " is overwritten") }; reportError(std::move(errorPath), Severity::style, "redundantInitialization", @@ -760,7 +760,7 @@ void CheckOther::redundantInitializationError(const Token *tok1, const Token* to inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckOther::redundantAssignmentInSwitchError(const Token *tok1, const Token* tok2, const std::string &var) +void CheckOtherImpl::redundantAssignmentInSwitchError(const Token *tok1, const Token* tok2, const std::string &var) { ErrorPath errorPath = { ErrorPathItem(tok1, "$symbol is assigned"), ErrorPathItem(tok2, "$symbol is overwritten") }; reportError(std::move(errorPath), Severity::style, "redundantAssignInSwitch", @@ -768,7 +768,7 @@ void CheckOther::redundantAssignmentInSwitchError(const Token *tok1, const Token "Variable '$symbol' is reassigned a value before the old one has been used. 'break;' missing?", CWE563, Certainty::normal); } -void CheckOther::redundantAssignmentSameValueError(const Token *tok, const ValueFlow::Value* val, const std::string &var) +void CheckOtherImpl::redundantAssignmentSameValueError(const Token *tok, const ValueFlow::Value* val, const std::string &var) { auto errorPath = val->errorPath; errorPath.emplace_back(tok, ""); @@ -792,7 +792,7 @@ static inline bool isFunctionOrBreakPattern(const Token *tok) return Token::Match(tok, "%name% (") || Token::Match(tok, "break|continue|return|exit|goto|throw"); } -void CheckOther::redundantBitwiseOperationInSwitchError() +void CheckOtherImpl::redundantBitwiseOperationInSwitchError() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -909,7 +909,7 @@ void CheckOther::redundantBitwiseOperationInSwitchError() } } -void CheckOther::redundantBitwiseOperationInSwitchError(const Token *tok, const std::string &varname) +void CheckOtherImpl::redundantBitwiseOperationInSwitchError(const Token *tok, const std::string &varname) { reportError(tok, Severity::style, "redundantBitwiseOperationInSwitch", @@ -921,7 +921,7 @@ void CheckOther::redundantBitwiseOperationInSwitchError(const Token *tok, const //--------------------------------------------------------------------------- // Check for statements like case A||B: in switch() //--------------------------------------------------------------------------- -void CheckOther::checkSuspiciousCaseInSwitch() +void CheckOtherImpl::checkSuspiciousCaseInSwitch() { if (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning)) return; @@ -955,7 +955,7 @@ void CheckOther::checkSuspiciousCaseInSwitch() } } -void CheckOther::suspiciousCaseInSwitchError(const Token* tok, const std::string& operatorString) +void CheckOtherImpl::suspiciousCaseInSwitchError(const Token* tok, const std::string& operatorString) { reportError(tok, Severity::warning, "suspiciousCase", "Found suspicious case label in switch(). Operator '" + operatorString + "' probably doesn't work as intended.\n" @@ -1005,7 +1005,7 @@ static bool isVardeclInSwitch(const Token* tok) // Detect dead code, that follows such a statement. e.g.: // return(0); foo(); //--------------------------------------------------------------------------- -void CheckOther::checkUnreachableCode() +void CheckOtherImpl::checkUnreachableCode() { // misra-c-2012-2.1 // misra-c-2023-2.1 @@ -1125,7 +1125,7 @@ void CheckOther::checkUnreachableCode() } } -void CheckOther::duplicateBreakError(const Token *tok, bool inconclusive) +void CheckOtherImpl::duplicateBreakError(const Token *tok, bool inconclusive) { reportError(tok, Severity::style, "duplicateBreak", "Consecutive return, break, continue, goto or throw statements are unnecessary.\n" @@ -1133,7 +1133,7 @@ void CheckOther::duplicateBreakError(const Token *tok, bool inconclusive) "The second statement can never be executed, and so should be removed.", CWE561, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckOther::unreachableCodeError(const Token *tok, const Token* noreturn, bool inconclusive) +void CheckOtherImpl::unreachableCodeError(const Token *tok, const Token* noreturn, bool inconclusive) { std::string msg = "Statements following "; if (noreturn && (noreturn->function() || mSettings->library.isnoreturn(noreturn))) @@ -1147,7 +1147,7 @@ void CheckOther::unreachableCodeError(const Token *tok, const Token* noreturn, b msg, CWE561, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckOther::redundantContinueError(const Token *tok) +void CheckOtherImpl::redundantContinueError(const Token *tok) { reportError(tok, Severity::style, "redundantContinue", "'continue' is redundant since it is the last statement in a loop.", CWE561, Certainty::normal); @@ -1183,7 +1183,7 @@ static bool isSimpleExpr(const Token* tok, const Variable* var, const Settings& //--------------------------------------------------------------------------- // Check scope of variables.. //--------------------------------------------------------------------------- -void CheckOther::checkVariableScope() +void CheckOtherImpl::checkVariableScope() { if (mSettings->clang) return; @@ -1335,7 +1335,7 @@ static bool isOnlyUsedInCurrentScope(const Variable* var, const Token *tok, cons return !Token::findmatch(tok->scope()->bodyEnd, "%varid%", var->scope()->bodyEnd, var->declarationId()); } -bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& used) const +bool CheckOtherImpl::checkInnerScope(const Token *tok, const Variable* var, bool& used) const { const Scope* scope = tok->next()->scope(); bool loopVariable = scope->isLoopScope(); @@ -1446,7 +1446,7 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us return true; } -void CheckOther::variableScopeError(const Token *tok, const std::string &varname) +void CheckOtherImpl::variableScopeError(const Token *tok, const std::string &varname) { reportError(tok, Severity::style, @@ -1473,7 +1473,7 @@ void CheckOther::variableScopeError(const Token *tok, const std::string &varname //--------------------------------------------------------------------------- // Comma in return statement: return a+1, b++;. (experimental) //--------------------------------------------------------------------------- -void CheckOther::checkCommaSeparatedReturn() +void CheckOtherImpl::checkCommaSeparatedReturn() { // TODO: This is experimental for now. See #5076 if ((true) || !mSettings->severity.isEnabled(Severity::style)) // NOLINT(readability-simplify-boolean-expr,readability-redundant-parentheses) @@ -1500,7 +1500,7 @@ void CheckOther::checkCommaSeparatedReturn() } } -void CheckOther::commaSeparatedReturnError(const Token *tok) +void CheckOtherImpl::commaSeparatedReturnError(const Token *tok) { reportError(tok, Severity::style, @@ -1538,7 +1538,7 @@ static bool isLargeContainer(const Variable* var, const Settings& settings) return arraySize > maxByValueSize; } -void CheckOther::checkPassByReference() +void CheckOtherImpl::checkPassByReference() { if (!mSettings->severity.isEnabled(Severity::performance) || mTokenizer->isC()) return; @@ -1617,7 +1617,7 @@ void CheckOther::checkPassByReference() } } -void CheckOther::passedByValueError(const Variable* var, bool inconclusive, bool isRangeBasedFor) +void CheckOtherImpl::passedByValueError(const Variable* var, bool inconclusive, bool isRangeBasedFor) { std::string id = isRangeBasedFor ? "iterateByValue" : "passedByValue"; const std::string action = isRangeBasedFor ? "declared as": "passed by"; @@ -1682,7 +1682,7 @@ static bool isCastToVoid(const Variable* var) return false; } -void CheckOther::checkConstVariable() +void CheckOtherImpl::checkConstVariable() { if ((!mSettings->severity.isEnabled(Severity::style) || mTokenizer->isC()) && !mSettings->isPremiumEnabled("constVariable")) return; @@ -1875,7 +1875,7 @@ static const Function* getEnclosingFunction(const Variable* var) return scope ? scope->function : nullptr; } -void CheckOther::checkConstPointer() +void CheckOtherImpl::checkConstPointer() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("constParameter") && @@ -2051,7 +2051,7 @@ void CheckOther::checkConstPointer() } } -void CheckOther::constVariableError(const Variable *var, const Function *function) +void CheckOtherImpl::constVariableError(const Variable *var, const Function *function) { if (!var) { reportError(nullptr, Severity::style, "constParameter", "Parameter 'x' can be declared with const"); @@ -2089,7 +2089,7 @@ void CheckOther::constVariableError(const Variable *var, const Function *functio // Check usage of char variables.. //--------------------------------------------------------------------------- -void CheckOther::checkCharVariable() +void CheckOtherImpl::checkCharVariable() { const bool warning = mSettings->severity.isEnabled(Severity::warning); const bool portability = mSettings->severity.isEnabled(Severity::portability); @@ -2140,7 +2140,7 @@ void CheckOther::checkCharVariable() } } -void CheckOther::signedCharArrayIndexError(const Token *tok) +void CheckOtherImpl::signedCharArrayIndexError(const Token *tok) { reportError(tok, Severity::warning, @@ -2151,7 +2151,7 @@ void CheckOther::signedCharArrayIndexError(const Token *tok) "because of sign extension.", CWE128, Certainty::normal); } -void CheckOther::unknownSignCharArrayIndexError(const Token *tok) +void CheckOtherImpl::unknownSignCharArrayIndexError(const Token *tok) { reportError(tok, Severity::portability, @@ -2161,7 +2161,7 @@ void CheckOther::unknownSignCharArrayIndexError(const Token *tok) "treated depending on whether 'char' is signed or unsigned on target platform.", CWE758, Certainty::normal); } -void CheckOther::charBitOpError(const Token *tok) +void CheckOtherImpl::charBitOpError(const Token *tok) { reportError(tok, Severity::warning, @@ -2348,7 +2348,7 @@ static bool isConstTop(const Token *tok) return false; } -void CheckOther::checkIncompleteStatement() +void CheckOtherImpl::checkIncompleteStatement() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("constStatement")) @@ -2410,7 +2410,7 @@ void CheckOther::checkIncompleteStatement() } } -void CheckOther::constStatementError(const Token *tok, const std::string &type, bool inconclusive) +void CheckOtherImpl::constStatementError(const Token *tok, const std::string &type, bool inconclusive) { const Token *valueTok = tok; while (valueTok && valueTok->isCast()) @@ -2465,7 +2465,7 @@ void CheckOther::constStatementError(const Token *tok, const std::string &type, //--------------------------------------------------------------------------- // Detect division by zero. //--------------------------------------------------------------------------- -void CheckOther::checkZeroDivision() +void CheckOtherImpl::checkZeroDivision() { logChecker("CheckOther::checkZeroDivision"); @@ -2486,7 +2486,7 @@ void CheckOther::checkZeroDivision() } } -void CheckOther::zerodivError(const Token *tok, const ValueFlow::Value *value) +void CheckOtherImpl::zerodivError(const Token *tok, const ValueFlow::Value *value) { if (!tok && !value) { reportError(tok, Severity::error, "zerodiv", "Division by zero.", CWE369, Certainty::normal); @@ -2515,7 +2515,7 @@ void CheckOther::zerodivError(const Token *tok, const ValueFlow::Value *value) // double d = 1.0 / 0.0 + 100.0; //--------------------------------------------------------------------------- -void CheckOther::checkNanInArithmeticExpression() +void CheckOtherImpl::checkNanInArithmeticExpression() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("nanInArithmeticExpression")) return; @@ -2530,7 +2530,7 @@ void CheckOther::checkNanInArithmeticExpression() } } -void CheckOther::nanInArithmeticExpressionError(const Token *tok) +void CheckOtherImpl::nanInArithmeticExpressionError(const Token *tok) { reportError(tok, Severity::style, "nanInArithmeticExpression", "Using NaN/Inf in a computation.\n" @@ -2541,7 +2541,7 @@ void CheckOther::nanInArithmeticExpressionError(const Token *tok) //--------------------------------------------------------------------------- // Creating instance of classes which are destroyed immediately //--------------------------------------------------------------------------- -void CheckOther::checkMisusedScopedObject() +void CheckOtherImpl::checkMisusedScopedObject() { // Skip this check for .c files if (mTokenizer->isC()) @@ -2616,7 +2616,7 @@ void CheckOther::checkMisusedScopedObject() } } -void CheckOther::misusedScopeObjectError(const Token *tok, const std::string& varname, bool isAssignment) +void CheckOtherImpl::misusedScopeObjectError(const Token *tok, const std::string& varname, bool isAssignment) { std::string msg = "Instance of '$symbol' object is destroyed immediately"; msg += isAssignment ? ", assignment has no effect." : "."; @@ -2641,7 +2641,7 @@ static const Token * getSingleExpressionInBlock(const Token * tok) // check for duplicate code in if and else branches // if (a) { b = true; } else { b = true; } //----------------------------------------------------------------------------- -void CheckOther::checkDuplicateBranch() +void CheckOtherImpl::checkDuplicateBranch() { // This is inconclusive since in practice most warnings are noise: // * There can be unfixed low-priority todos. The code is fine as it @@ -2720,7 +2720,7 @@ void CheckOther::checkDuplicateBranch() } } -void CheckOther::duplicateBranchError(const Token *tok1, const Token *tok2, ErrorPath errors) +void CheckOtherImpl::duplicateBranchError(const Token *tok1, const Token *tok2, ErrorPath errors) { errors.emplace_back(tok2, ""); errors.emplace_back(tok1, ""); @@ -2737,7 +2737,7 @@ void CheckOther::duplicateBranchError(const Token *tok1, const Token *tok2, Erro // char* p = malloc(100); // free(p + 10); //----------------------------------------------------------------------------- -void CheckOther::checkInvalidFree() +void CheckOtherImpl::checkInvalidFree() { std::map inconclusive; std::map allocation; @@ -2811,7 +2811,7 @@ void CheckOther::checkInvalidFree() } } -void CheckOther::invalidFreeError(const Token *tok, const std::string &allocation, bool inconclusive) +void CheckOtherImpl::invalidFreeError(const Token *tok, const std::string &allocation, bool inconclusive) { std::string alloc = allocation; if (alloc != "new") @@ -2870,7 +2870,7 @@ isStaticAssert(const Settings &settings, const Token *tok) return false; } -void CheckOther::checkDuplicateExpression() +void CheckOtherImpl::checkDuplicateExpression() { { const bool styleEnabled = mSettings->severity.isEnabled(Severity::style); @@ -3068,7 +3068,7 @@ void CheckOther::checkDuplicateExpression() } } -void CheckOther::oppositeExpressionError(const Token *opTok, ErrorPath errors) +void CheckOtherImpl::oppositeExpressionError(const Token *opTok, ErrorPath errors) { errors.emplace_back(opTok, ""); @@ -3080,7 +3080,7 @@ void CheckOther::oppositeExpressionError(const Token *opTok, ErrorPath errors) "determine if it is correct.", CWE398, Certainty::normal); } -void CheckOther::duplicateExpressionError(const Token *tok1, const Token *tok2, const Token *opTok, ErrorPath errors, bool hasMultipleExpr) +void CheckOtherImpl::duplicateExpressionError(const Token *tok1, const Token *tok2, const Token *opTok, ErrorPath errors, bool hasMultipleExpr) { errors.emplace_back(opTok, ""); @@ -3108,7 +3108,7 @@ void CheckOther::duplicateExpressionError(const Token *tok1, const Token *tok2, "determine if it is correct.", CWE398, Certainty::normal); } -void CheckOther::duplicateAssignExpressionError(const Token *tok1, const Token *tok2, bool inconclusive) +void CheckOtherImpl::duplicateAssignExpressionError(const Token *tok1, const Token *tok2, bool inconclusive) { const std::list toks = { tok2, tok1 }; @@ -3122,7 +3122,7 @@ void CheckOther::duplicateAssignExpressionError(const Token *tok1, const Token * "determine if it is correct.", CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckOther::duplicateExpressionTernaryError(const Token *tok, ErrorPath errors) +void CheckOtherImpl::duplicateExpressionTernaryError(const Token *tok, ErrorPath errors) { errors.emplace_back(tok, ""); reportError(std::move(errors), Severity::style, "duplicateExpressionTernary", "Same expression in both branches of ternary operator.\n" @@ -3130,14 +3130,14 @@ void CheckOther::duplicateExpressionTernaryError(const Token *tok, ErrorPath err "the same code is executed regardless of the condition.", CWE398, Certainty::normal); } -void CheckOther::duplicateValueTernaryError(const Token *tok) +void CheckOtherImpl::duplicateValueTernaryError(const Token *tok) { reportError(tok, Severity::style, "duplicateValueTernary", "Same value in both branches of ternary operator.\n" "Finding the same value in both branches of ternary operator is suspicious as " "the same code is executed regardless of the condition.", CWE398, Certainty::normal); } -void CheckOther::selfAssignmentError(const Token *tok, const std::string &varname) +void CheckOtherImpl::selfAssignmentError(const Token *tok, const std::string &varname) { reportError(tok, Severity::style, "selfAssignment", @@ -3154,7 +3154,7 @@ void CheckOther::selfAssignmentError(const Token *tok, const std::string &varnam // Reference: // - http://www.cplusplus.com/reference/cmath/ //----------------------------------------------------------------------------- -void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse() +void CheckOtherImpl::checkComparisonFunctionIsAlwaysTrueOrFalse() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -3184,7 +3184,7 @@ void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse() } } } -void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* tok, const std::string &functionName, const std::string &varName, const bool result) +void CheckOtherImpl::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* tok, const std::string &functionName, const std::string &varName, const bool result) { const std::string strResult = bool_to_string(result); const CWE cweResult = result ? CWE571 : CWE570; @@ -3199,7 +3199,7 @@ void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* to //--------------------------------------------------------------------------- // Check testing sign of unsigned variables and pointers. //--------------------------------------------------------------------------- -void CheckOther::checkSignOfUnsignedVariable() +void CheckOtherImpl::checkSignOfUnsignedVariable() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unsignedLessThanZero")) return; @@ -3230,7 +3230,7 @@ void CheckOther::checkSignOfUnsignedVariable() } } -bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr, bool suppress) +bool CheckOtherImpl::comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr, bool suppress) { if (!tok->isComparisonOp() || !tok->astOperand1() || !tok->astOperand2()) return false; @@ -3256,7 +3256,7 @@ bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const return vt && (vt->pointer || vt->sign == ValueType::UNSIGNED); } -bool CheckOther::testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr) +bool CheckOtherImpl::testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr) { if (!tok->isComparisonOp() || !tok->astOperand1() || !tok->astOperand2()) return false; @@ -3278,7 +3278,7 @@ bool CheckOther::testIfNonZeroExpressionIsPositive(const Token *tok, const Value return vt && (vt->pointer || vt->sign == ValueType::UNSIGNED); } -void CheckOther::unsignedLessThanZeroError(const Token *tok, const ValueFlow::Value * v, const std::string &varname) +void CheckOtherImpl::unsignedLessThanZeroError(const Token *tok, const ValueFlow::Value * v, const std::string &varname) { reportError(getErrorPath(tok, v, "Unsigned less than zero"), Severity::style, "unsignedLessThanZero", "$symbol:" + varname + "\n" @@ -3287,20 +3287,20 @@ void CheckOther::unsignedLessThanZeroError(const Token *tok, const ValueFlow::Va "is either pointless or an error to check if it is.", CWE570, Certainty::normal); } -void CheckOther::pointerLessThanZeroError(const Token *tok, const ValueFlow::Value *v) +void CheckOtherImpl::pointerLessThanZeroError(const Token *tok, const ValueFlow::Value *v) { reportError(getErrorPath(tok, v, "Pointer less than zero"), Severity::style, "pointerLessThanZero", "A pointer can not be negative so it is either pointless or an error to check if it is.", CWE570, Certainty::normal); } -void CheckOther::unsignedPositiveError(const Token *tok, const ValueFlow::Value * v, const std::string &varname) +void CheckOtherImpl::unsignedPositiveError(const Token *tok, const ValueFlow::Value * v, const std::string &varname) { reportError(getErrorPath(tok, v, "Unsigned positive"), Severity::style, "unsignedPositive", "$symbol:" + varname + "\n" "Unsigned expression '$symbol' can't be negative so it is unnecessary to test it.", CWE570, Certainty::normal); } -void CheckOther::pointerPositiveError(const Token *tok, const ValueFlow::Value * v) +void CheckOtherImpl::pointerPositiveError(const Token *tok, const ValueFlow::Value * v) { reportError(getErrorPath(tok, v, "Pointer positive"), Severity::style, "pointerPositive", "A pointer can not be negative so it is either pointless or an error to check if it is not.", CWE570, Certainty::normal); @@ -3383,7 +3383,7 @@ static bool checkVariableAssignment(const Token* tok, const ValueType* vtLhs, co return scope && scope->function && (!scope->functionOf || scope->function->isConst() || scope->function->isStatic()); } -void CheckOther::checkRedundantCopy() +void CheckOtherImpl::checkRedundantCopy() { if (!mSettings->severity.isEnabled(Severity::performance) || mTokenizer->isC() || !mSettings->certainty.isEnabled(Certainty::inconclusive)) return; @@ -3421,7 +3421,7 @@ void CheckOther::checkRedundantCopy() } } -void CheckOther::redundantCopyError(const Token *tok,const std::string& varname) +void CheckOtherImpl::redundantCopyError(const Token *tok,const std::string& varname) { reportError(tok, Severity::performance, "redundantCopyLocalConst", "$symbol:" + varname + "\n" @@ -3441,7 +3441,7 @@ static bool isNegative(const Token *tok, const Settings &settings) return tok->valueType() && tok->valueType()->sign == ValueType::SIGNED && tok->getValueLE(-1LL, settings); } -void CheckOther::checkNegativeBitwiseShift() +void CheckOtherImpl::checkNegativeBitwiseShift() { const bool portability = mSettings->severity.isEnabled(Severity::portability); @@ -3483,7 +3483,7 @@ void CheckOther::checkNegativeBitwiseShift() } -void CheckOther::negativeBitwiseShiftError(const Token *tok, int op) +void CheckOtherImpl::negativeBitwiseShiftError(const Token *tok, int op) { if (op == 1) // LHS - this is used by intention in various software, if it @@ -3497,7 +3497,7 @@ void CheckOther::negativeBitwiseShiftError(const Token *tok, int op) //--------------------------------------------------------------------------- // Check for incompletely filled buffers. //--------------------------------------------------------------------------- -void CheckOther::checkIncompleteArrayFill() +void CheckOtherImpl::checkIncompleteArrayFill() { if (!mSettings->certainty.isEnabled(Certainty::inconclusive)) return; @@ -3546,7 +3546,7 @@ void CheckOther::checkIncompleteArrayFill() } } -void CheckOther::incompleteArrayFillError(const Token* tok, const std::string& buffer, const std::string& function, bool boolean) +void CheckOtherImpl::incompleteArrayFillError(const Token* tok, const std::string& buffer, const std::string& function, bool boolean) { if (boolean) reportError(tok, Severity::portability, "incompleteArrayFill", @@ -3566,7 +3566,7 @@ void CheckOther::incompleteArrayFillError(const Token* tok, const std::string& b // Detect NULL being passed to variadic function. //--------------------------------------------------------------------------- -void CheckOther::checkVarFuncNullUB() +void CheckOtherImpl::checkVarFuncNullUB() { if (!mSettings->severity.isEnabled(Severity::portability)) return; @@ -3604,7 +3604,7 @@ void CheckOther::checkVarFuncNullUB() } } -void CheckOther::varFuncNullUBError(const Token *tok) +void CheckOtherImpl::varFuncNullUBError(const Token *tok) { reportError(tok, Severity::portability, @@ -3651,7 +3651,7 @@ void CheckOther::varFuncNullUBError(const Token *tok) "}", CWE475, Certainty::normal); } -void CheckOther::checkRedundantPointerOp() +void CheckOtherImpl::checkRedundantPointerOp() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("redundantPointerOp")) return; @@ -3690,14 +3690,14 @@ void CheckOther::checkRedundantPointerOp() } } -void CheckOther::redundantPointerOpError(const Token* tok, const std::string &varname, bool inconclusive, bool addressOfDeref) +void CheckOtherImpl::redundantPointerOpError(const Token* tok, const std::string &varname, bool inconclusive, bool addressOfDeref) { std::string msg = "$symbol:" + varname + "\nRedundant pointer operation on '$symbol' - it's already a "; msg += addressOfDeref ? "pointer." : "variable."; reportError(tok, Severity::style, "redundantPointerOp", msg, CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckOther::checkInterlockedDecrement() +void CheckOtherImpl::checkInterlockedDecrement() { if (!mSettings->platform.isWindows()) { return; @@ -3737,13 +3737,13 @@ void CheckOther::checkInterlockedDecrement() } } -void CheckOther::raceAfterInterlockedDecrementError(const Token* tok) +void CheckOtherImpl::raceAfterInterlockedDecrementError(const Token* tok) { reportError(tok, Severity::error, "raceAfterInterlockedDecrement", "Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.", CWE362, Certainty::normal); } -void CheckOther::checkUnusedLabel() +void CheckOtherImpl::checkUnusedLabel() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("unusedLabel")) return; @@ -3766,7 +3766,7 @@ void CheckOther::checkUnusedLabel() } } -void CheckOther::unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef) +void CheckOtherImpl::unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef) { if (tok && !mSettings->severity.isEnabled(inSwitch ? Severity::warning : Severity::style) && !mSettings->isPremiumEnabled("unusedLabel")) return; @@ -3860,7 +3860,7 @@ static bool checkEvaluationOrderCpp17(const Token * tok, const Token * tok2, con return foundUndefined || foundUnspecified; } -void CheckOther::checkEvaluationOrder() +void CheckOtherImpl::checkEvaluationOrder() { logChecker("CheckOther::checkEvaluationOrder"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -3922,7 +3922,7 @@ void CheckOther::checkEvaluationOrder() } } -void CheckOther::unknownEvaluationOrder(const Token* tok, bool isUnspecifiedBehavior) +void CheckOtherImpl::unknownEvaluationOrder(const Token* tok, bool isUnspecifiedBehavior) { isUnspecifiedBehavior ? reportError(tok, Severity::portability, "unknownEvaluationOrder", @@ -3931,7 +3931,7 @@ void CheckOther::unknownEvaluationOrder(const Token* tok, bool isUnspecifiedBeha "Expression '" + (tok ? tok->expressionString() : std::string("x = x++;")) + "' depends on order of evaluation of side effects", CWE768, Certainty::normal); } -void CheckOther::checkAccessOfMovedVariable() +void CheckOtherImpl::checkAccessOfMovedVariable() { if (!mTokenizer->isCPP() || mSettings->standards.cpp < Standards::CPP11) return; @@ -3978,7 +3978,7 @@ void CheckOther::checkAccessOfMovedVariable() } } -void CheckOther::accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive) +void CheckOtherImpl::accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive) { if (!tok) { reportError(tok, Severity::warning, "accessMoved", "Access of moved variable 'v'.", CWE672, Certainty::normal); @@ -4007,7 +4007,7 @@ void CheckOther::accessMovedError(const Token *tok, const std::string &varname, -void CheckOther::checkFuncArgNamesDifferent() +void CheckOtherImpl::checkFuncArgNamesDifferent() { const bool style = mSettings->severity.isEnabled(Severity::style); const bool inconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); @@ -4090,8 +4090,8 @@ void CheckOther::checkFuncArgNamesDifferent() } } -void CheckOther::funcArgNamesDifferent(const std::string & functionName, nonneg int index, - const Token* declaration, const Token* definition) +void CheckOtherImpl::funcArgNamesDifferent(const std::string & functionName, nonneg int index, + const Token* declaration, const Token* definition) { std::list tokens = { declaration,definition }; const std::string id = (declaration != nullptr) == (definition != nullptr) ? "funcArgNamesDifferent" : "funcArgNamesDifferentUnnamed"; @@ -4102,10 +4102,10 @@ void CheckOther::funcArgNamesDifferent(const std::string & functionName, nonneg (definition ? definition->str() : "") + "'.", CWE628, Certainty::inconclusive); } -void CheckOther::funcArgOrderDifferent(const std::string & functionName, - const Token* declaration, const Token* definition, - const std::vector & declarations, - const std::vector & definitions) +void CheckOtherImpl::funcArgOrderDifferent(const std::string & functionName, + const Token* declaration, const Token* definition, + const std::vector & declarations, + const std::vector & definitions) { std::list tokens = { !declarations.empty() ? declarations[0] ? declarations[0] : declaration : nullptr, @@ -4153,7 +4153,7 @@ static const Token *findShadowed(const Scope *scope, const Variable& var, int li return shadowed; } -void CheckOther::checkShadowVariables() +void CheckOtherImpl::checkShadowVariables() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("shadowVariable")) return; @@ -4213,8 +4213,8 @@ void CheckOther::checkShadowVariables() } } -void CheckOther::shadowError(const Token *shadows, const std::string &shadowsType, - const Token *shadowed, const std::string &shadowedType) +void CheckOtherImpl::shadowError(const Token *shadows, const std::string &shadowsType, + const Token *shadowed, const std::string &shadowedType) { ErrorPath errorPath; errorPath.emplace_back(shadowed, "Shadowed " + shadowedType); @@ -4254,7 +4254,7 @@ static bool isVariableExprHidden(const Token* tok) return false; } -void CheckOther::checkKnownArgument() +void CheckOtherImpl::checkKnownArgument() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("knownArgument")) return; @@ -4323,7 +4323,7 @@ void CheckOther::checkKnownArgument() } } -void CheckOther::knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value, const std::string &varexpr, bool isVariableExpressionHidden) +void CheckOtherImpl::knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value, const std::string &varexpr, bool isVariableExpressionHidden) { if (!tok) { reportError(tok, Severity::style, "knownArgument", "Argument 'x-x' to function 'func' is always 0. It does not matter what value 'x' has."); @@ -4355,7 +4355,7 @@ void CheckOther::knownArgumentError(const Token *tok, const Token *ftok, const V reportError(std::move(errorPath), Severity::style, id, errmsg, CWE570, Certainty::normal); } -void CheckOther::checkKnownPointerToBool() +void CheckOtherImpl::checkKnownPointerToBool() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("knownPointerToBool")) return; @@ -4385,7 +4385,7 @@ void CheckOther::checkKnownPointerToBool() } } -void CheckOther::knownPointerToBoolError(const Token* tok, const ValueFlow::Value* value) +void CheckOtherImpl::knownPointerToBoolError(const Token* tok, const ValueFlow::Value* value) { if (!tok) { reportError(tok, Severity::style, "knownPointerToBool", "Pointer expression 'p' converted to bool is always true."); @@ -4398,7 +4398,7 @@ void CheckOther::knownPointerToBoolError(const Token* tok, const ValueFlow::Valu reportError(std::move(errorPath), Severity::style, "knownPointerToBool", errmsg, CWE570, Certainty::normal); } -void CheckOther::checkComparePointers() +void CheckOtherImpl::checkComparePointers() { logChecker("CheckOther::checkComparePointers"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -4439,7 +4439,7 @@ void CheckOther::checkComparePointers() } } -void CheckOther::comparePointersError(const Token *tok, const ValueFlow::Value *v1, const ValueFlow::Value *v2) +void CheckOtherImpl::comparePointersError(const Token *tok, const ValueFlow::Value *v1, const ValueFlow::Value *v2) { ErrorPath errorPath; std::string verb = "Comparing"; @@ -4459,7 +4459,7 @@ void CheckOther::comparePointersError(const Token *tok, const ValueFlow::Value * std::move(errorPath), Severity::error, id, verb + " pointers that point to different objects", CWE758, Certainty::normal); } -void CheckOther::checkModuloOfOne() +void CheckOtherImpl::checkModuloOfOne() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("moduloofone")) return; @@ -4481,7 +4481,7 @@ void CheckOther::checkModuloOfOne() } } -void CheckOther::checkModuloOfOneError(const Token *tok) +void CheckOtherImpl::checkModuloOfOneError(const Token *tok) { reportError(tok, Severity::style, "moduloofone", "Modulo of one is always equal to zero"); } @@ -4569,7 +4569,7 @@ static bool isZeroInitializer(const Token *tok) } -void CheckOther::checkUnionZeroInit() +void CheckOtherImpl::checkUnionZeroInit() { if (!mSettings->severity.isEnabled(Severity::portability)) return; @@ -4607,8 +4607,8 @@ void CheckOther::checkUnionZeroInit() } } -void CheckOther::unionZeroInitError(const Token *tok, - const UnionMember& largestMember) +void CheckOtherImpl::unionZeroInitError(const Token *tok, + const UnionMember& largestMember) { reportError(tok, Severity::portability, "UnionZeroInit", (tok != nullptr ? "$symbol:" + tok->str() + "\n" : "") + @@ -4679,7 +4679,7 @@ static bool getBufAndOffset(const Token *expr, const Token *&buf, MathLib::bigin return true; } -void CheckOther::checkOverlappingWrite() +void CheckOtherImpl::checkOverlappingWrite() { logChecker("CheckOther::checkOverlappingWrite"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -4777,19 +4777,19 @@ void CheckOther::checkOverlappingWrite() } } -void CheckOther::overlappingWriteUnion(const Token *tok) +void CheckOtherImpl::overlappingWriteUnion(const Token *tok) { reportError(tok, Severity::error, "overlappingWriteUnion", "Overlapping read/write of union is undefined behavior"); } -void CheckOther::overlappingWriteFunction(const Token *tok, const std::string& funcname) +void CheckOtherImpl::overlappingWriteFunction(const Token *tok, const std::string& funcname) { reportError(tok, Severity::error, "overlappingWriteFunction", "Overlapping read/write in " + funcname + "() is undefined behavior"); } void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckOther checkOther(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckOtherImpl checkOther(&tokenizer, &tokenizer.getSettings(), errorLogger); // Checks checkOther.warningOldStylePointerCast(); @@ -4841,7 +4841,7 @@ void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckOther c(nullptr, settings, errorLogger); + CheckOtherImpl c(nullptr, settings, errorLogger); // error c.zerodivError(nullptr, nullptr); diff --git a/lib/checkother.h b/lib/checkother.h index f779141f499..6f6460bdfde 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include "errortypes.h" @@ -55,22 +56,85 @@ class CPPCHECKLIB CheckOther : public Check { public: /** @brief This constructor is used when registering the CheckClass */ - CheckOther() : Check(myName()) {} + CheckOther() : Check("Other") {} - /** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is less than zero? */ - static bool comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr, bool suppress = false); +private: + /** @brief Run checks against the normal token list */ + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - /** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is positive? */ - static bool testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr); + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; -private: + std::string classInfo() const override { + return "Other checks\n" + + // error + "- division with zero\n" + "- scoped object destroyed immediately after construction\n" + "- assignment in an assert statement\n" + "- free() or delete of an invalid memory location\n" + "- bitwise operation with negative right operand\n" + "- cast the return values of getc(),fgetc() and getchar() to character and compare it to EOF\n" + "- race condition with non-interlocked access after InterlockedDecrement() call\n" + "- expression 'x = x++;' depends on order of evaluation of side effects\n" + "- overlapping write of union\n" + + // warning + "- either division by zero or useless condition\n" + "- access of moved or forwarded variable.\n" + + // performance + "- redundant data copying for const variable\n" + "- subsequent assignment or copying to a variable or buffer\n" + "- passing parameter by value\n" + + // portability + "- Passing NULL pointer to function with variable number of arguments leads to UB.\n" + + // style + "- C-style pointer cast in C++ code\n" + "- casting between incompatible pointer types\n" + "- [Incomplete statement](IncompleteStatement)\n" + "- [check how signed char variables are used](CharVar)\n" + "- variable scope can be limited\n" + "- unusual pointer arithmetic. For example: \"abc\" + 'd'\n" + "- redundant assignment, increment, or bitwise operation in a switch statement\n" + "- redundant strcpy in a switch statement\n" + "- Suspicious case labels in switch()\n" + "- assignment of a variable to itself\n" + "- Comparison of values leading always to true or false\n" + "- Clarify calculation with parentheses\n" + "- suspicious comparison of '\\0' with a char\\* variable\n" + "- duplicate break statement\n" + "- unreachable code\n" + "- testing if unsigned variable is negative/positive\n" + "- Suspicious use of ; at the end of 'if/for/while' statement.\n" + "- Array filled incompletely using memset/memcpy/memmove.\n" + "- NaN (not a number) value used in arithmetic expression.\n" + "- comma in return statement (the comma can easily be misread as a semicolon).\n" + "- prefer erfc, expm1 or log1p to avoid loss of precision.\n" + "- identical code in both branches of if/else or ternary operator.\n" + "- redundant pointer operation on pointer like &\\*some_ptr.\n" + "- find unused 'goto' labels.\n" + "- function declaration and definition argument names different.\n" + "- function declaration and definition argument order different.\n" + "- shadow variable.\n" + "- variable can be declared const.\n" + "- calculating modulo of one.\n" + "- known function argument, suspicious calculation.\n"; + } +}; + +class CPPCHECKLIB CheckOtherImpl : public CheckImpl { +public: /** @brief This constructor is used when running checks. */ - CheckOther(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} + CheckOtherImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is less than zero? */ + static bool comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr, bool suppress = false); - /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + /** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is positive? */ + static bool testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr); /** @brief Clarify calculation for ".. a * b ? .." */ void clarifyCalculation(); @@ -265,74 +329,6 @@ class CPPCHECKLIB CheckOther : public Check { void checkModuloOfOneError(const Token *tok); void unionZeroInitError(const Token *tok, const UnionMember& largestMember); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Other"; - } - - std::string classInfo() const override { - return "Other checks\n" - - // error - "- division with zero\n" - "- scoped object destroyed immediately after construction\n" - "- assignment in an assert statement\n" - "- free() or delete of an invalid memory location\n" - "- bitwise operation with negative right operand\n" - "- cast the return values of getc(),fgetc() and getchar() to character and compare it to EOF\n" - "- race condition with non-interlocked access after InterlockedDecrement() call\n" - "- expression 'x = x++;' depends on order of evaluation of side effects\n" - "- overlapping write of union\n" - - // warning - "- either division by zero or useless condition\n" - "- access of moved or forwarded variable.\n" - "- potentially dangerous C style type cast of pointer/reference to object.\n" - - // performance - "- redundant data copying for const variable\n" - "- subsequent assignment or copying to a variable or buffer\n" - "- passing parameter by value\n" - - // portability - "- Passing NULL pointer to function with variable number of arguments leads to UB.\n" - "- Casting non-zero integer literal in decimal or octal format to pointer.\n" - "- Incorrect zero initialization of unions can lead to access of uninitialized memory.\n" - - // style - "- C-style pointer cast in C++ code\n" - "- casting between incompatible pointer types\n" - "- [Incomplete statement](IncompleteStatement)\n" - "- [check how signed char variables are used](CharVar)\n" - "- variable scope can be limited\n" - "- unusual pointer arithmetic. For example: \"abc\" + 'd'\n" - "- redundant assignment, increment, or bitwise operation in a switch statement\n" - "- redundant strcpy in a switch statement\n" - "- Suspicious case labels in switch()\n" - "- assignment of a variable to itself\n" - "- Comparison of values leading always to true or false\n" - "- Clarify calculation with parentheses\n" - "- suspicious comparison of '\\0' with a char\\* variable\n" - "- duplicate break statement\n" - "- unreachable code\n" - "- testing if unsigned variable is negative/positive\n" - "- Suspicious use of ; at the end of 'if/for/while' statement.\n" - "- Array filled incompletely using memset/memcpy/memmove.\n" - "- NaN (not a number) value used in arithmetic expression.\n" - "- comma in return statement (the comma can easily be misread as a semicolon).\n" - "- prefer erfc, expm1 or log1p to avoid loss of precision.\n" - "- identical code in both branches of if/else or ternary operator.\n" - "- redundant pointer operation on pointer like &\\*some_ptr.\n" - "- find unused 'goto' labels.\n" - "- function declaration and definition argument names different.\n" - "- function declaration and definition argument order different.\n" - "- shadow variable.\n" - "- variable can be declared const.\n" - "- calculating modulo of one.\n" - "- known function argument, suspicious calculation.\n"; - } - bool diag(const Token* tok) { return !mRedundantAssignmentDiag.emplace(tok).second; } diff --git a/lib/checkpostfixoperator.cpp b/lib/checkpostfixoperator.cpp index d771177b2d2..0b02313b672 100644 --- a/lib/checkpostfixoperator.cpp +++ b/lib/checkpostfixoperator.cpp @@ -37,8 +37,7 @@ // CWE ids used static const CWE CWE398(398U); // Indicator of Poor Code Quality - -void CheckPostfixOperator::postfixOperator() +void CheckPostfixOperatorImpl::postfixOperator() { if (!mSettings->severity.isEnabled(Severity::performance)) return; @@ -84,7 +83,7 @@ void CheckPostfixOperator::postfixOperator() //--------------------------------------------------------------------------- -void CheckPostfixOperator::postfixOperatorError(const Token *tok) +void CheckPostfixOperatorImpl::postfixOperatorError(const Token *tok) { reportError(tok, Severity::performance, "postfixOperator", "Prefer prefix ++/-- operators for non-primitive types.\n" @@ -100,12 +99,12 @@ void CheckPostfixOperator::runChecks(const Tokenizer &tokenizer, ErrorLogger *er if (tokenizer.isC()) return; - CheckPostfixOperator checkPostfixOperator(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckPostfixOperatorImpl checkPostfixOperator(&tokenizer, &tokenizer.getSettings(), errorLogger); checkPostfixOperator.postfixOperator(); } void CheckPostfixOperator::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckPostfixOperator c(nullptr, settings, errorLogger); + CheckPostfixOperatorImpl c(nullptr, settings, errorLogger); c.postfixOperatorError(nullptr); } diff --git a/lib/checkpostfixoperator.h b/lib/checkpostfixoperator.h index c9f58a7e143..03ab54eed11 100644 --- a/lib/checkpostfixoperator.h +++ b/lib/checkpostfixoperator.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -44,30 +45,28 @@ class CPPCHECKLIB CheckPostfixOperator : public Check { public: /** This constructor is used when registering the CheckPostfixOperator */ - CheckPostfixOperator() : Check(myName()) {} + CheckPostfixOperator() : Check("Using postfix operators") {} private: - /** This constructor is used when running checks. */ - CheckPostfixOperator(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + std::string classInfo() const override { + return "Warn if using postfix operators ++ or -- rather than prefix operator\n"; + } +}; + +class CPPCHECKLIB CheckPostfixOperatorImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + CheckPostfixOperatorImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** Check postfix operators */ void postfixOperator(); /** Report Error */ void postfixOperatorError(const Token *tok); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Using postfix operators"; - } - - std::string classInfo() const override { - return "Warn if using postfix operators ++ or -- rather than prefix operator\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index e211764ad3a..ab398dda570 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -39,7 +39,7 @@ static const CWE CWE467(467U); // Use of sizeof() on a Pointer Type static const CWE CWE682(682U); // Incorrect Calculation //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -void CheckSizeof::checkSizeofForNumericParameter() +void CheckSizeofImpl::checkSizeofForNumericParameter() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -57,7 +57,7 @@ void CheckSizeof::checkSizeofForNumericParameter() } } -void CheckSizeof::sizeofForNumericParameterError(const Token *tok) +void CheckSizeofImpl::sizeofForNumericParameterError(const Token *tok) { reportError(tok, Severity::warning, "sizeofwithnumericparameter", "Suspicious usage of 'sizeof' with a numeric constant as parameter.\n" @@ -69,7 +69,7 @@ void CheckSizeof::sizeofForNumericParameterError(const Token *tok) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -void CheckSizeof::checkSizeofForArrayParameter() +void CheckSizeofImpl::checkSizeofForArrayParameter() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -94,7 +94,7 @@ void CheckSizeof::checkSizeofForArrayParameter() } } -void CheckSizeof::sizeofForArrayParameterError(const Token *tok) +void CheckSizeofImpl::sizeofForArrayParameterError(const Token *tok) { reportError(tok, Severity::warning, "sizeofwithsilentarraypointer", "Using 'sizeof' on array given as function argument " @@ -110,7 +110,7 @@ void CheckSizeof::sizeofForArrayParameterError(const Token *tok) ); } -void CheckSizeof::checkSizeofForPointerSize() +void CheckSizeofImpl::checkSizeofForPointerSize() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -263,7 +263,7 @@ void CheckSizeof::checkSizeofForPointerSize() } } -void CheckSizeof::sizeofForPointerError(const Token *tok, const std::string &varname) +void CheckSizeofImpl::sizeofForPointerError(const Token *tok, const std::string &varname) { reportError(tok, Severity::warning, "pointerSize", "Size of pointer '" + varname + "' used instead of size of its data.\n" @@ -272,7 +272,7 @@ void CheckSizeof::sizeofForPointerError(const Token *tok, const std::string &var "write 'sizeof(*" + varname + ")'.", CWE467, Certainty::normal); } -void CheckSizeof::divideBySizeofError(const Token *tok, const std::string &memfunc) +void CheckSizeofImpl::divideBySizeofError(const Token *tok, const std::string &memfunc) { reportError(tok, Severity::warning, "sizeofDivisionMemfunc", "Division by result of sizeof(). " + memfunc + "() expects a size in bytes, did you intend to multiply instead?", CWE682, Certainty::normal); @@ -280,7 +280,7 @@ void CheckSizeof::divideBySizeofError(const Token *tok, const std::string &memfu //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void CheckSizeof::sizeofsizeof() +void CheckSizeofImpl::sizeofsizeof() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -295,7 +295,7 @@ void CheckSizeof::sizeofsizeof() } } -void CheckSizeof::sizeofsizeofError(const Token *tok) +void CheckSizeofImpl::sizeofsizeofError(const Token *tok) { reportError(tok, Severity::warning, "sizeofsizeof", "Calling 'sizeof' on 'sizeof'.\n" @@ -306,7 +306,7 @@ void CheckSizeof::sizeofsizeofError(const Token *tok) //----------------------------------------------------------------------------- -void CheckSizeof::sizeofCalculation() +void CheckSizeofImpl::sizeofCalculation() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -344,7 +344,7 @@ void CheckSizeof::sizeofCalculation() } } -void CheckSizeof::sizeofCalculationError(const Token *tok, bool inconclusive) +void CheckSizeofImpl::sizeofCalculationError(const Token *tok, bool inconclusive) { reportError(tok, Severity::warning, "sizeofCalculation", "Found calculation inside sizeof().", CWE682, inconclusive ? Certainty::inconclusive : Certainty::normal); @@ -352,7 +352,7 @@ void CheckSizeof::sizeofCalculationError(const Token *tok, bool inconclusive) //----------------------------------------------------------------------------- -void CheckSizeof::sizeofFunction() +void CheckSizeofImpl::sizeofFunction() { if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("sizeofFunctionCall")) return; @@ -386,7 +386,7 @@ void CheckSizeof::sizeofFunction() } } -void CheckSizeof::sizeofFunctionError(const Token *tok) +void CheckSizeofImpl::sizeofFunctionError(const Token *tok) { reportError(tok, Severity::warning, "sizeofFunctionCall", "Found function call inside sizeof().", CWE682, Certainty::normal); @@ -395,7 +395,7 @@ void CheckSizeof::sizeofFunctionError(const Token *tok) //----------------------------------------------------------------------------- // Check for code like sizeof()*sizeof() or sizeof(ptr)/value //----------------------------------------------------------------------------- -void CheckSizeof::suspiciousSizeofCalculation() +void CheckSizeofImpl::suspiciousSizeofCalculation() { if (!mSettings->severity.isEnabled(Severity::warning) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) return; @@ -425,13 +425,13 @@ void CheckSizeof::suspiciousSizeofCalculation() } } -void CheckSizeof::multiplySizeofError(const Token *tok) +void CheckSizeofImpl::multiplySizeofError(const Token *tok) { reportError(tok, Severity::warning, "multiplySizeof", "Multiplying sizeof() with sizeof() indicates a logic error.", CWE682, Certainty::inconclusive); } -void CheckSizeof::divideSizeofError(const Token *tok) +void CheckSizeofImpl::divideSizeofError(const Token *tok) { reportError(tok, Severity::warning, "divideSizeof", "Division of result of sizeof() on pointer type.\n" @@ -439,7 +439,7 @@ void CheckSizeof::divideSizeofError(const Token *tok) "not the size of the memory area it points to.", CWE682, Certainty::inconclusive); } -void CheckSizeof::sizeofVoid() +void CheckSizeofImpl::sizeofVoid() { if (!mSettings->severity.isEnabled(Severity::portability)) return; @@ -477,21 +477,21 @@ void CheckSizeof::sizeofVoid() } } -void CheckSizeof::sizeofVoidError(const Token *tok) +void CheckSizeofImpl::sizeofVoidError(const Token *tok) { const std::string message = "Behaviour of 'sizeof(void)' is not covered by the ISO C standard."; const std::string verbose = message + " A value for 'sizeof(void)' is defined only as part of a GNU C extension, which defines 'sizeof(void)' to be 1."; reportError(tok, Severity::portability, "sizeofVoid", message + "\n" + verbose, CWE682, Certainty::normal); } -void CheckSizeof::sizeofDereferencedVoidPointerError(const Token *tok, const std::string &varname) +void CheckSizeofImpl::sizeofDereferencedVoidPointerError(const Token *tok, const std::string &varname) { const std::string message = "'*" + varname + "' is of type 'void', the behaviour of 'sizeof(void)' is not covered by the ISO C standard."; const std::string verbose = message + " A value for 'sizeof(void)' is defined only as part of a GNU C extension, which defines 'sizeof(void)' to be 1."; reportError(tok, Severity::portability, "sizeofDereferencedVoidPointer", message + "\n" + verbose, CWE682, Certainty::normal); } -void CheckSizeof::arithOperationsOnVoidPointerError(const Token* tok, const std::string &varname, const std::string &vartype) +void CheckSizeofImpl::arithOperationsOnVoidPointerError(const Token* tok, const std::string &varname, const std::string &vartype) { const std::string message = "'$symbol' is of type '" + vartype + "'. When using void pointers in calculations, the behaviour is undefined."; const std::string verbose = message + " Arithmetic operations on 'void *' is a GNU C extension, which defines the 'sizeof(void)' to be 1."; @@ -500,7 +500,7 @@ void CheckSizeof::arithOperationsOnVoidPointerError(const Token* tok, const std: void CheckSizeof::runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) { - CheckSizeof checkSizeof(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckSizeofImpl checkSizeof(&tokenizer, &tokenizer.getSettings(), errorLogger); // Checks checkSizeof.sizeofsizeof(); @@ -515,7 +515,7 @@ void CheckSizeof::runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger void CheckSizeof::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const { - CheckSizeof c(nullptr, settings, errorLogger); + CheckSizeofImpl c(nullptr, settings, errorLogger); c.sizeofForArrayParameterError(nullptr); c.sizeofForPointerError(nullptr, "varname"); c.divideBySizeofError(nullptr, "memset"); diff --git a/lib/checksizeof.h b/lib/checksizeof.h index 4c10ca88dac..0ec4b298de5 100644 --- a/lib/checksizeof.h +++ b/lib/checksizeof.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -41,16 +42,33 @@ class Tokenizer; class CPPCHECKLIB CheckSizeof : public Check { public: /** @brief This constructor is used when registering the CheckClass */ - CheckSizeof() : Check(myName()) {} + CheckSizeof() : Check("Sizeof") {} private: - /** @brief This constructor is used when running checks. */ - CheckSizeof(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) override; + void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; + + std::string classInfo() const override { + return "sizeof() usage checks\n" + "- sizeof for array given as function argument\n" + "- sizeof for numeric given as function argument\n" + "- using sizeof(pointer) instead of the size of pointed data\n" + "- look for 'sizeof sizeof ..'\n" + "- look for calculations inside sizeof()\n" + "- look for function calls inside sizeof()\n" + "- look for suspicious calculations with sizeof()\n" + "- using 'sizeof(void)' which is undefined\n"; + } +}; + +class CPPCHECKLIB CheckSizeofImpl : public CheckImpl { +public: + /** @brief This constructor is used when running checks. */ + CheckSizeofImpl(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** @brief %Check for 'sizeof sizeof ..' */ void sizeofsizeof(); @@ -88,24 +106,6 @@ class CPPCHECKLIB CheckSizeof : public Check { void sizeofVoidError(const Token *tok); void sizeofDereferencedVoidPointerError(const Token *tok, const std::string &varname); void arithOperationsOnVoidPointerError(const Token* tok, const std::string &varname, const std::string &vartype); - - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; - - static std::string myName() { - return "Sizeof"; - } - - std::string classInfo() const override { - return "sizeof() usage checks\n" - "- sizeof for array given as function argument\n" - "- sizeof for numeric given as function argument\n" - "- using sizeof(pointer) instead of the size of pointed data\n" - "- look for 'sizeof sizeof ..'\n" - "- look for calculations inside sizeof()\n" - "- look for function calls inside sizeof()\n" - "- look for suspicious calculations with sizeof()\n" - "- using 'sizeof(void)' which is undefined\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index c665d72757e..2980fe2d86e 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -127,7 +127,7 @@ static const Token* getContainerFromSize(const Library::Container* container, co return nullptr; } -void CheckStl::outOfBounds() +void CheckStlImpl::outOfBounds() { logChecker("CheckStl::outOfBounds"); @@ -215,7 +215,7 @@ static std::string indexValueString(const ValueFlow::Value& indexValue, const st return indexString; } -void CheckStl::outOfBoundsError(const Token *tok, const std::string &containerName, const ValueFlow::Value *containerSize, const std::string &index, const ValueFlow::Value *indexValue) +void CheckStlImpl::outOfBoundsError(const Token *tok, const std::string &containerName, const ValueFlow::Value *containerSize, const std::string &index, const ValueFlow::Value *indexValue) { // Do not warn if both the container size and index value are possible if (containerSize && indexValue && containerSize->isPossible() && indexValue->isPossible()) @@ -274,7 +274,7 @@ void CheckStl::outOfBoundsError(const Token *tok, const std::string &containerNa (containerSize && containerSize->isInconclusive()) || (indexValue && indexValue->isInconclusive()) ? Certainty::inconclusive : Certainty::normal); } -bool CheckStl::isContainerSize(const Token *containerToken, const Token *expr) const +bool CheckStlImpl::isContainerSize(const Token *containerToken, const Token *expr) const { if (!Token::simpleMatch(expr, "( )")) return false; @@ -285,7 +285,7 @@ bool CheckStl::isContainerSize(const Token *containerToken, const Token *expr) c return containerToken->valueType()->container->getYield(expr->strAt(-1)) == Library::Container::Yield::SIZE; } -bool CheckStl::isContainerSizeGE(const Token * containerToken, const Token *expr) const +bool CheckStlImpl::isContainerSizeGE(const Token * containerToken, const Token *expr) const { if (!expr) return false; @@ -314,7 +314,7 @@ bool CheckStl::isContainerSizeGE(const Token * containerToken, const Token *expr return false; } -void CheckStl::outOfBoundsIndexExpression() +void CheckStlImpl::outOfBoundsIndexExpression() { logChecker("CheckStl::outOfBoundsIndexExpression"); for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { @@ -334,7 +334,7 @@ void CheckStl::outOfBoundsIndexExpression() } } -void CheckStl::outOfBoundsIndexExpressionError(const Token *tok, const Token *index) +void CheckStlImpl::outOfBoundsIndexExpressionError(const Token *tok, const Token *index) { const std::string varname = tok ? tok->str() : std::string("var"); const std::string i = index ? index->expressionString() : (varname + ".size()"); @@ -352,12 +352,12 @@ void CheckStl::outOfBoundsIndexExpressionError(const Token *tok, const Token *in // Error message for bad iterator usage.. -void CheckStl::invalidIteratorError(const Token *tok, const std::string &iteratorName) +void CheckStlImpl::invalidIteratorError(const Token *tok, const std::string &iteratorName) { reportError(tok, Severity::error, "invalidIterator1", "$symbol:"+iteratorName+"\nInvalid iterator: $symbol", CWE664, Certainty::normal); } -void CheckStl::iteratorsError(const Token* tok, const std::string& containerName1, const std::string& containerName2) +void CheckStlImpl::iteratorsError(const Token* tok, const std::string& containerName1, const std::string& containerName2) { reportError(tok, Severity::error, "iterators1", "$symbol:" + containerName1 + "\n" @@ -365,7 +365,7 @@ void CheckStl::iteratorsError(const Token* tok, const std::string& containerName "Same iterator is used with different containers '" + containerName1 + "' and '" + containerName2 + "'.", CWE664, Certainty::normal); } -void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName) +void CheckStlImpl::iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName) { std::list callstack = { tok, containerTok }; reportError(callstack, @@ -379,7 +379,7 @@ void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const } // Error message used when dereferencing an iterator that has been erased.. -void CheckStl::dereferenceErasedError(const Token *erased, const Token* deref, const std::string &itername, bool inconclusive) +void CheckStlImpl::dereferenceErasedError(const Token *erased, const Token* deref, const std::string &itername, bool inconclusive) { if (erased) { std::list callstack = { deref, erased }; @@ -449,7 +449,7 @@ static bool isVector(const Token* tok) return Token::simpleMatch(decltok, "std :: vector"); } -void CheckStl::iterators() +void CheckStlImpl::iterators() { logChecker("CheckStl::iterators"); @@ -634,7 +634,7 @@ void CheckStl::iterators() } } -void CheckStl::mismatchingContainerIteratorError(const Token* containerTok, const Token* iterTok, const Token* containerTok2) +void CheckStlImpl::mismatchingContainerIteratorError(const Token* containerTok, const Token* iterTok, const Token* containerTok2) { const std::string container(containerTok ? containerTok->expressionString() : std::string("v1")); const std::string container2(containerTok2 ? containerTok2->expressionString() : std::string("v2")); @@ -648,7 +648,7 @@ void CheckStl::mismatchingContainerIteratorError(const Token* containerTok, cons } // Error message for bad iterator usage.. -void CheckStl::mismatchingContainersError(const Token* tok1, const Token* tok2) +void CheckStlImpl::mismatchingContainersError(const Token* tok1, const Token* tok2) { const std::string expr1(tok1 ? tok1->expressionString() : std::string("v1")); const std::string expr2(tok2 ? tok2->expressionString() : std::string("v2")); @@ -660,7 +660,7 @@ void CheckStl::mismatchingContainersError(const Token* tok1, const Token* tok2) Certainty::normal); } -void CheckStl::mismatchingContainerExpressionError(const Token *tok1, const Token *tok2) +void CheckStlImpl::mismatchingContainerExpressionError(const Token *tok1, const Token *tok2) { const std::string expr1(tok1 ? tok1->expressionString() : std::string("v1")); const std::string expr2(tok2 ? tok2->expressionString() : std::string("v2")); @@ -669,7 +669,7 @@ void CheckStl::mismatchingContainerExpressionError(const Token *tok1, const Toke expr1 + "' and '" + expr2 + "' are used together.", CWE664, Certainty::normal); } -void CheckStl::sameIteratorExpressionError(const Token *tok) +void CheckStlImpl::sameIteratorExpressionError(const Token *tok) { reportError(tok, Severity::style, "sameIteratorExpression", "Same iterators expression are used for algorithm.", CWE664, Certainty::normal); } @@ -754,7 +754,7 @@ static ValueFlow::Value getLifetimeIteratorValue(const Token* tok, MathLib::bigi return ValueFlow::Value{}; } -bool CheckStl::checkIteratorPair(const Token* tok1, const Token* tok2) +bool CheckStlImpl::checkIteratorPair(const Token* tok1, const Token* tok2) { if (!tok1) return false; @@ -806,7 +806,7 @@ namespace { }; } -void CheckStl::mismatchingContainers() +void CheckStlImpl::mismatchingContainers() { logChecker("CheckStl::misMatchingContainers"); @@ -866,7 +866,7 @@ void CheckStl::mismatchingContainers() } } -void CheckStl::mismatchingContainerIterator() +void CheckStlImpl::mismatchingContainerIterator() { logChecker("CheckStl::misMatchingContainerIterator"); @@ -1118,7 +1118,7 @@ static const Token* endOfExpression(const Token* tok) return endToken; } -void CheckStl::invalidContainer() +void CheckStlImpl::invalidContainer() { logChecker("CheckStl::invalidContainer"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1231,7 +1231,7 @@ void CheckStl::invalidContainer() } } -void CheckStl::invalidContainerLoopError(const Token* tok, const Token* loopTok, ErrorPath errorPath) +void CheckStlImpl::invalidContainerLoopError(const Token* tok, const Token* loopTok, ErrorPath errorPath) { const std::string method = tok ? tok->str() : "erase"; errorPath.emplace_back(loopTok, "Iterating container here."); @@ -1246,7 +1246,7 @@ void CheckStl::invalidContainerLoopError(const Token* tok, const Token* loopTok, reportError(std::move(errorPath), Severity::error, "invalidContainerLoop", msg, CWE664, Certainty::normal); } -void CheckStl::invalidContainerError(const Token *tok, const ValueFlow::Value *val, ErrorPath errorPath) +void CheckStlImpl::invalidContainerError(const Token *tok, const ValueFlow::Value *val, ErrorPath errorPath) { const bool inconclusive = val ? val->isInconclusive() : false; if (val) @@ -1256,7 +1256,7 @@ void CheckStl::invalidContainerError(const Token *tok, const ValueFlow::Value *v reportError(std::move(errorPath), Severity::error, "invalidContainer", msg + " that may be invalid.", CWE664, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckStl::invalidContainerReferenceError(const Token* tok, const Token* contTok, ErrorPath errorPath) +void CheckStlImpl::invalidContainerReferenceError(const Token* tok, const Token* contTok, ErrorPath errorPath) { std::string name = contTok ? contTok->expressionString() : "x"; std::string msg = "Reference to " + name; @@ -1264,7 +1264,7 @@ void CheckStl::invalidContainerReferenceError(const Token* tok, const Token* con reportError(std::move(errorPath), Severity::error, "invalidContainerReference", msg + " that may be invalid.", CWE664, Certainty::normal); } -void CheckStl::stlOutOfBounds() +void CheckStlImpl::stlOutOfBounds() { logChecker("CheckStl::stlOutOfBounds"); @@ -1350,7 +1350,7 @@ void CheckStl::stlOutOfBounds() } } -void CheckStl::stlOutOfBoundsError(const Token *tok, const std::string &num, const std::string &var, bool at) +void CheckStlImpl::stlOutOfBoundsError(const Token *tok, const std::string &num, const std::string &var, bool at) { if (at) reportError(tok, Severity::error, "stlOutOfBounds", "$symbol:" + var + "\nWhen " + num + "==$symbol.size(), $symbol.at(" + num + ") is out of bounds.", CWE788, Certainty::normal); @@ -1358,7 +1358,7 @@ void CheckStl::stlOutOfBoundsError(const Token *tok, const std::string &num, con reportError(tok, Severity::error, "stlOutOfBounds", "$symbol:" + var + "\nWhen " + num + "==$symbol.size(), $symbol[" + num + "] is out of bounds.", CWE788, Certainty::normal); } -void CheckStl::negativeIndex() +void CheckStlImpl::negativeIndex() { logChecker("CheckStl::negativeIndex"); @@ -1382,7 +1382,7 @@ void CheckStl::negativeIndex() } } -void CheckStl::negativeIndexError(const Token *tok, const ValueFlow::Value &index) +void CheckStlImpl::negativeIndexError(const Token *tok, const ValueFlow::Value &index) { ErrorPath errorPath = getErrorPath(tok, &index, "Negative array index"); std::ostringstream errmsg; @@ -1396,7 +1396,7 @@ void CheckStl::negativeIndexError(const Token *tok, const ValueFlow::Value &inde reportError(std::move(errorPath), severity, "negativeContainerIndex", errmsg.str(), CWE786, certainty); } -void CheckStl::erase() +void CheckStlImpl::erase() { logChecker("CheckStl::erase"); @@ -1417,7 +1417,7 @@ void CheckStl::erase() } } -void CheckStl::eraseCheckLoopVar(const Scope &scope, const Variable *var) +void CheckStlImpl::eraseCheckLoopVar(const Scope &scope, const Variable *var) { bool inconclusiveType=false; if (!isIterator(var, inconclusiveType)) @@ -1461,7 +1461,7 @@ void CheckStl::eraseCheckLoopVar(const Scope &scope, const Variable *var) } } -void CheckStl::stlBoundaries() +void CheckStlImpl::stlBoundaries() { logChecker("CheckStl::stlBoundaries"); @@ -1486,7 +1486,7 @@ void CheckStl::stlBoundaries() } // Error message for bad boundary usage.. -void CheckStl::stlBoundariesError(const Token *tok) +void CheckStlImpl::stlBoundariesError(const Token *tok) { reportError(tok, Severity::error, "stlBoundaries", "Dangerous comparison using operator< on iterator.\n" @@ -1515,7 +1515,7 @@ static bool if_findCompare(const Token * const tokBack, bool stdStringLike) return false; } -void CheckStl::if_find() +void CheckStlImpl::if_find() { const bool printWarning = mSettings->severity.isEnabled(Severity::warning); const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); @@ -1592,7 +1592,7 @@ void CheckStl::if_find() } -void CheckStl::if_findError(const Token *tok, bool str) +void CheckStlImpl::if_findError(const Token *tok, bool str) { if (str && mSettings->standards.cpp >= Standards::CPP20) reportError(tok, Severity::performance, "stlIfStrFind", @@ -1683,7 +1683,7 @@ static const Token *findInsertValue(const Token *tok, const Token *containerTok, return nullptr; } -void CheckStl::checkFindInsert() +void CheckStlImpl::checkFindInsert() { if (!mSettings->severity.isEnabled(Severity::performance)) return; @@ -1729,7 +1729,7 @@ void CheckStl::checkFindInsert() } } -void CheckStl::checkFindInsertError(const Token *tok) +void CheckStlImpl::checkFindInsertError(const Token *tok) { std::string replaceExpr; if (tok && Token::simpleMatch(tok->astParent(), "=") && tok == tok->astParent()->astOperand2() && Token::simpleMatch(tok->astParent()->astOperand1(), "[")) { @@ -1761,7 +1761,7 @@ static bool isCpp03ContainerSizeSlow(const Token *tok) return var && var->isStlType("list"); } -void CheckStl::size() +void CheckStlImpl::size() { if (!mSettings->severity.isEnabled(Severity::performance)) return; @@ -1810,7 +1810,7 @@ void CheckStl::size() } } -void CheckStl::sizeError(const Token *tok) +void CheckStlImpl::sizeError(const Token *tok) { const std::string varname = tok ? tok->str() : std::string("list"); reportError(tok, Severity::performance, "stlSize", @@ -1822,7 +1822,7 @@ void CheckStl::sizeError(const Token *tok) "guaranteed to take constant time.", CWE398, Certainty::normal); } -void CheckStl::redundantCondition() +void CheckStlImpl::redundantCondition() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("redundantIfRemove")) return; @@ -1855,7 +1855,7 @@ void CheckStl::redundantCondition() } } -void CheckStl::redundantIfRemoveError(const Token *tok) +void CheckStlImpl::redundantIfRemoveError(const Token *tok) { reportError(tok, Severity::style, "redundantIfRemove", "Redundant checking of STL container element existence before removing it.\n" @@ -1863,7 +1863,7 @@ void CheckStl::redundantIfRemoveError(const Token *tok) "It is safe to call the remove method on a non-existing element.", CWE398, Certainty::normal); } -void CheckStl::missingComparison() +void CheckStlImpl::missingComparison() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -1927,7 +1927,7 @@ void CheckStl::missingComparison() } } -void CheckStl::missingComparisonError(const Token *incrementToken1, const Token *incrementToken2) +void CheckStlImpl::missingComparisonError(const Token *incrementToken1, const Token *incrementToken2) { std::list callstack = { incrementToken1,incrementToken2 }; @@ -2023,7 +2023,7 @@ namespace { }; } -void CheckStl::string_c_str() +void CheckStlImpl::string_c_str() { const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); @@ -2219,25 +2219,25 @@ void CheckStl::string_c_str() } } -void CheckStl::string_c_strThrowError(const Token* tok) +void CheckStlImpl::string_c_strThrowError(const Token* tok) { reportError(tok, Severity::error, "stlcstrthrow", "Dangerous usage of c_str(). The value returned by c_str() is invalid after throwing exception.\n" "Dangerous usage of c_str(). The string is destroyed after the c_str() call so the thrown pointer is invalid."); } -void CheckStl::string_c_strError(const Token* tok) +void CheckStlImpl::string_c_strError(const Token* tok) { reportError(tok, Severity::error, "stlcstr", "Dangerous usage of c_str(). The value returned by c_str() is invalid after this call.\n" "Dangerous usage of c_str(). The c_str() return value is only valid until its string is deleted.", CWE664, Certainty::normal); } -void CheckStl::string_c_strReturn(const Token* tok) +void CheckStlImpl::string_c_strReturn(const Token* tok) { reportError(tok, Severity::performance, "stlcstrReturn", "Returning the result of c_str() in a function that returns std::string is slow and redundant.\n" "The conversion from const char* as returned by c_str() to std::string creates an unnecessary string copy. Solve that by directly returning the string.", CWE704, Certainty::normal); } -void CheckStl::string_c_strParam(const Token* tok, nonneg int number, const std::string& argtype) +void CheckStlImpl::string_c_strParam(const Token* tok, nonneg int number, const std::string& argtype) { std::ostringstream oss; oss << "Passing the result of c_str() to a function that takes " << argtype << " as argument no. " << number << " is slow and redundant.\n" @@ -2245,28 +2245,28 @@ void CheckStl::string_c_strParam(const Token* tok, nonneg int number, const std: reportError(tok, Severity::performance, "stlcstrParam", oss.str(), CWE704, Certainty::normal); } -void CheckStl::string_c_strConstructor(const Token* tok, const std::string& argtype) +void CheckStlImpl::string_c_strConstructor(const Token* tok, const std::string& argtype) { std::string msg = "Constructing a " + argtype + " from the result of c_str() is slow and redundant.\n" "Constructing a " + argtype + " from const char* requires a call to strlen(). Solve that by directly passing the string."; reportError(tok, Severity::performance, "stlcstrConstructor", msg, CWE704, Certainty::normal); } -void CheckStl::string_c_strAssignment(const Token* tok, const std::string& argtype) +void CheckStlImpl::string_c_strAssignment(const Token* tok, const std::string& argtype) { std::string msg = "Assigning the result of c_str() to a " + argtype + " is slow and redundant.\n" "Assigning a const char* to a " + argtype + " requires a call to strlen(). Solve that by directly assigning the string."; reportError(tok, Severity::performance, "stlcstrAssignment", msg, CWE704, Certainty::normal); } -void CheckStl::string_c_strConcat(const Token* tok) +void CheckStlImpl::string_c_strConcat(const Token* tok) { std::string msg = "Concatenating the result of c_str() and a std::string is slow and redundant.\n" "Concatenating a const char* with a std::string requires a call to strlen(). Solve that by directly concatenating the strings."; reportError(tok, Severity::performance, "stlcstrConcat", msg, CWE704, Certainty::normal); } -void CheckStl::string_c_strStream(const Token* tok) +void CheckStlImpl::string_c_strStream(const Token* tok) { std::string msg = "Passing the result of c_str() to a stream is slow and redundant.\n" "Passing a const char* to a stream requires a call to strlen(). Solve that by directly passing the string."; @@ -2287,7 +2287,7 @@ namespace { } -void CheckStl::uselessCalls() +void CheckStlImpl::uselessCalls() { const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); const bool printWarning = mSettings->severity.isEnabled(Severity::warning); @@ -2348,7 +2348,7 @@ void CheckStl::uselessCalls() } -void CheckStl::uselessCallsReturnValueError(const Token *tok, const std::string &varname, const std::string &function) +void CheckStlImpl::uselessCallsReturnValueError(const Token *tok, const std::string &varname, const std::string &function) { std::ostringstream errmsg; errmsg << "$symbol:" << varname << '\n'; @@ -2361,7 +2361,7 @@ void CheckStl::uselessCallsReturnValueError(const Token *tok, const std::string reportError(tok, Severity::warning, "uselessCallsCompare", errmsg.str(), CWE628, Certainty::normal); } -void CheckStl::uselessCallsSwapError(const Token *tok, const std::string &varname) +void CheckStlImpl::uselessCallsSwapError(const Token *tok, const std::string &varname) { reportError(tok, Severity::performance, "uselessCallsSwap", "$symbol:" + varname + "\n" @@ -2371,7 +2371,7 @@ void CheckStl::uselessCallsSwapError(const Token *tok, const std::string &varnam "code is inefficient. Is the object or the parameter wrong here?", CWE628, Certainty::normal); } -void CheckStl::uselessCallsSubstrError(const Token *tok, SubstrErrorType type) +void CheckStlImpl::uselessCallsSubstrError(const Token *tok, SubstrErrorType type) { std::string msg = "Ineffective call of function 'substr' because "; switch (type) { @@ -2391,19 +2391,19 @@ void CheckStl::uselessCallsSubstrError(const Token *tok, SubstrErrorType type) reportError(tok, Severity::performance, "uselessCallsSubstr", msg, CWE398, Certainty::normal); } -void CheckStl::uselessCallsConstructorError(const Token *tok) +void CheckStlImpl::uselessCallsConstructorError(const Token *tok) { const std::string container = tok ? tok->str() : ""; const std::string msg = "Inefficient constructor call: container '" + container + "' is assigned a partial copy of itself. Use erase() or resize() instead."; reportError(tok, Severity::performance, "uselessCallsConstructor", msg, CWE398, Certainty::normal); } -void CheckStl::uselessCallsEmptyError(const Token *tok) +void CheckStlImpl::uselessCallsEmptyError(const Token *tok) { reportError(tok, Severity::warning, "uselessCallsEmpty", "Ineffective call of function 'empty()'. Did you intend to call 'clear()' instead?", CWE398, Certainty::normal); } -void CheckStl::uselessCallsRemoveError(const Token *tok, const std::string& function) +void CheckStlImpl::uselessCallsRemoveError(const Token *tok, const std::string& function) { reportError(tok, Severity::warning, "uselessCallsRemove", "$symbol:" + function + "\n" @@ -2414,7 +2414,7 @@ void CheckStl::uselessCallsRemoveError(const Token *tok, const std::string& func // Check for iterators being dereferenced before being checked for validity. // E.g. if (*i && i != str.end()) { } -void CheckStl::checkDereferenceInvalidIterator() +void CheckStlImpl::checkDereferenceInvalidIterator() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -2478,7 +2478,7 @@ void CheckStl::checkDereferenceInvalidIterator() } -void CheckStl::checkDereferenceInvalidIterator2() +void CheckStlImpl::checkDereferenceInvalidIterator2() { const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive)); @@ -2550,7 +2550,7 @@ void CheckStl::checkDereferenceInvalidIterator2() emptyAdvance = tok->astParent(); } } - if (!CheckNullPointer::isPointerDeRef(tok, unknown, *mSettings) && !isInvalidIterator && !emptyAdvance) { + if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, *mSettings) && !isInvalidIterator && !emptyAdvance) { if (!unknown) continue; inconclusive = true; @@ -2574,7 +2574,7 @@ void CheckStl::checkDereferenceInvalidIterator2() } } -void CheckStl::dereferenceInvalidIteratorError(const Token* tok, const ValueFlow::Value *value, bool inconclusive) +void CheckStlImpl::dereferenceInvalidIteratorError(const Token* tok, const ValueFlow::Value *value, bool inconclusive) { const std::string& varname = tok ? tok->expressionString() : "var"; const std::string errmsgcond("$symbol:" + varname + '\n' + ValueFlow::eitherTheConditionIsRedundant(value ? value->condition : nullptr) + " or there is possible dereference of an invalid iterator: $symbol."); @@ -2603,7 +2603,7 @@ void CheckStl::dereferenceInvalidIteratorError(const Token* tok, const ValueFlow } } -void CheckStl::dereferenceInvalidIteratorError(const Token* deref, const std::string &iterName) +void CheckStlImpl::dereferenceInvalidIteratorError(const Token* deref, const std::string &iterName) { reportError(deref, Severity::warning, "derefInvalidIterator", @@ -2612,7 +2612,7 @@ void CheckStl::dereferenceInvalidIteratorError(const Token* deref, const std::st "Possible dereference of an invalid iterator: $symbol. Make sure to check that the iterator is valid before dereferencing it - not after.", CWE825, Certainty::normal); } -void CheckStl::useStlAlgorithmError(const Token *tok, const std::string &algoName) +void CheckStlImpl::useStlAlgorithmError(const Token *tok, const std::string &algoName) { reportError(tok, Severity::style, "useStlAlgorithm", "Consider using " + algoName + " algorithm instead of a raw loop.", CWE398, Certainty::normal); @@ -3000,7 +3000,7 @@ namespace { }; } // namespace -void CheckStl::useStlAlgorithm() +void CheckStlImpl::useStlAlgorithm() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("useStlAlgorithm")) return; @@ -3236,7 +3236,7 @@ void CheckStl::useStlAlgorithm() } } -void CheckStl::knownEmptyContainerError(const Token *tok, const std::string& algo) +void CheckStlImpl::knownEmptyContainerError(const Token *tok, const std::string& algo) { const std::string var = tok ? tok->expressionString() : std::string("var"); @@ -3267,7 +3267,7 @@ static bool isKnownEmptyContainer(const Token* tok) }); } -void CheckStl::knownEmptyContainer() +void CheckStlImpl::knownEmptyContainer() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("knownEmptyContainer")) return; @@ -3310,7 +3310,7 @@ void CheckStl::knownEmptyContainer() } } -void CheckStl::eraseIteratorOutOfBoundsError(const Token *ftok, const Token* itertok, const ValueFlow::Value* val) +void CheckStlImpl::eraseIteratorOutOfBoundsError(const Token *ftok, const Token* itertok, const ValueFlow::Value* val) { if (!ftok || !itertok || !val) { reportError(ftok, Severity::error, "eraseIteratorOutOfBounds", @@ -3355,7 +3355,7 @@ static const ValueFlow::Value* getOOBIterValue(const Token* tok, const ValueFlow return it != tok->values().end() ? &*it : nullptr; } -void CheckStl::eraseIteratorOutOfBounds() +void CheckStlImpl::eraseIteratorOutOfBounds() { logChecker("CheckStl::eraseIteratorOutOfBounds"); for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { @@ -3402,21 +3402,21 @@ static bool isLocalMutex(const Variable* var, const Scope* scope) return !var->isReference() && !var->isRValueReference() && !var->isStatic() && var->scope() == scope; } -void CheckStl::globalLockGuardError(const Token* tok) +void CheckStlImpl::globalLockGuardError(const Token* tok) { reportError(tok, Severity::warning, "globalLockGuard", "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.", CWE833, Certainty::normal); } -void CheckStl::localMutexError(const Token* tok) +void CheckStlImpl::localMutexError(const Token* tok) { reportError(tok, Severity::warning, "localMutex", "The lock is ineffective because the mutex is locked at the same scope as the mutex itself.", CWE667, Certainty::normal); } -void CheckStl::checkMutexes() +void CheckStlImpl::checkMutexes() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -3459,7 +3459,7 @@ void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) return; } - CheckStl checkStl(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckStlImpl checkStl(&tokenizer, &tokenizer.getSettings(), errorLogger); checkStl.erase(); checkStl.if_find(); checkStl.checkFindInsert(); @@ -3492,7 +3492,7 @@ void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const { - CheckStl c(nullptr, settings, errorLogger); + CheckStlImpl c(nullptr, settings, errorLogger); c.outOfBoundsError(nullptr, "container", nullptr, "x", nullptr); c.invalidIteratorError(nullptr, "iterator"); c.iteratorsError(nullptr, "container1", "container2"); @@ -3524,7 +3524,7 @@ void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings* settin c.redundantIfRemoveError(nullptr); c.uselessCallsReturnValueError(nullptr, "str", "find"); c.uselessCallsSwapError(nullptr, "str"); - c.uselessCallsSubstrError(nullptr, SubstrErrorType::COPY); + c.uselessCallsSubstrError(nullptr, CheckStlImpl::SubstrErrorType::COPY); c.uselessCallsConstructorError(nullptr); c.uselessCallsEmptyError(nullptr); c.uselessCallsRemoveError(nullptr, "remove"); diff --git a/lib/checkstl.h b/lib/checkstl.h index 03a634f1ed1..626e39f4276 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include "errortypes.h" @@ -48,16 +49,43 @@ namespace ValueFlow class CPPCHECKLIB CheckStl : public Check { public: /** This constructor is used when registering the CheckClass */ - CheckStl() : Check(myName()) {} + CheckStl() : Check("STL usage") {} private: - /** This constructor is used when running checks. */ - CheckStl(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** run checks, the token list is not simplified */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; + + std::string classInfo() const override { + return "Check for invalid usage of STL:\n" + "- out of bounds errors\n" + "- misuse of iterators when iterating through a container\n" + "- mismatching containers in calls\n" + "- same iterators in calls\n" + "- dereferencing an erased iterator\n" + "- for vectors: using iterator/pointer after push_back has been used\n" + "- optimisation: use empty() instead of size() to guarantee fast code\n" + "- suspicious condition when using find\n" + "- unnecessary searching in associative containers\n" + "- redundant condition\n" + "- common mistakes when using string::c_str()\n" + "- useless calls of string and STL functions\n" + "- dereferencing an invalid iterator\n" + "- erasing an iterator that is out of bounds\n" + "- reading from empty STL container\n" + "- iterating over an empty STL container\n" + "- consider using an STL algorithm instead of raw loop\n" + "- incorrect locking with mutex\n"; + } +}; + +class CPPCHECKLIB CheckStlImpl : public CheckImpl { +public: + /** This constructor is used when running checks. */ + CheckStlImpl(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** Accessing container out of bounds using ValueFlow */ void outOfBounds(); @@ -209,34 +237,6 @@ class CPPCHECKLIB CheckStl : public Check { void globalLockGuardError(const Token *tok); void localMutexError(const Token *tok); - - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; - - static std::string myName() { - return "STL usage"; - } - - std::string classInfo() const override { - return "Check for invalid usage of STL:\n" - "- out of bounds errors\n" - "- misuse of iterators when iterating through a container\n" - "- mismatching containers in calls\n" - "- same iterators in calls\n" - "- dereferencing an erased iterator\n" - "- for vectors: using iterator/pointer after push_back has been used\n" - "- optimisation: use empty() instead of size() to guarantee fast code\n" - "- suspicious condition when using find\n" - "- unnecessary searching in associative containers\n" - "- redundant condition\n" - "- common mistakes when using string::c_str()\n" - "- useless calls of string and STL functions\n" - "- dereferencing an invalid iterator\n" - "- erasing an iterator that is out of bounds\n" - "- reading from empty STL container\n" - "- iterating over an empty STL container\n" - "- consider using an STL algorithm instead of raw loop\n" - "- incorrect locking with mutex\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 580597bb10d..916885e094a 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -47,7 +47,7 @@ static const CWE CWE758(758U); // Reliance on Undefined, Unspecified, or Imple //--------------------------------------------------------------------------- // Writing string literal is UB //--------------------------------------------------------------------------- -void CheckString::stringLiteralWrite() +void CheckStringImpl::stringLiteralWrite() { logChecker("CheckString::stringLiteralWrite"); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -66,7 +66,7 @@ void CheckString::stringLiteralWrite() } } -void CheckString::stringLiteralWriteError(const Token *tok, const Token *strValue) +void CheckStringImpl::stringLiteralWriteError(const Token *tok, const Token *strValue) { std::list callstack{ tok }; if (strValue) @@ -89,7 +89,7 @@ void CheckString::stringLiteralWriteError(const Token *tok, const Token *strValu // Check for string comparison involving two static strings. // if(strcmp("00FF00","00FF00")==0) // <- statement is always true //--------------------------------------------------------------------------- -void CheckString::checkAlwaysTrueOrFalseStringCompare() +void CheckStringImpl::checkAlwaysTrueOrFalseStringCompare() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -133,7 +133,7 @@ void CheckString::checkAlwaysTrueOrFalseStringCompare() } } -void CheckString::alwaysTrueFalseStringCompareError(const Token *tok, const std::string& str1, const std::string& str2) +void CheckStringImpl::alwaysTrueFalseStringCompareError(const Token *tok, const std::string& str1, const std::string& str2) { constexpr std::size_t stringLen = 10; const std::string string1 = (str1.size() < stringLen) ? str1 : (str1.substr(0, stringLen-2) + ".."); @@ -145,7 +145,7 @@ void CheckString::alwaysTrueFalseStringCompareError(const Token *tok, const std: "Therefore the comparison is unnecessary and looks suspicious.", (str1==str2)?CWE571:CWE570, Certainty::normal); } -void CheckString::alwaysTrueStringVariableCompareError(const Token *tok, const std::string& str1, const std::string& str2) +void CheckStringImpl::alwaysTrueStringVariableCompareError(const Token *tok, const std::string& str1, const std::string& str2) { reportError(tok, Severity::warning, "stringCompare", "Comparison of identical string variables.\n" @@ -158,7 +158,7 @@ void CheckString::alwaysTrueStringVariableCompareError(const Token *tok, const s // Detect "str == '\0'" where "*str == '\0'" is correct. // Comparing char* with each other instead of using strcmp() //----------------------------------------------------------------------------- -void CheckString::checkSuspiciousStringCompare() +void CheckStringImpl::checkSuspiciousStringCompare() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -197,14 +197,14 @@ void CheckString::checkSuspiciousStringCompare() } } -void CheckString::suspiciousStringCompareError(const Token* tok, const std::string& var, bool isLong) +void CheckStringImpl::suspiciousStringCompareError(const Token* tok, const std::string& var, bool isLong) { const std::string cmpFunc = isLong ? "wcscmp" : "strcmp"; reportError(tok, Severity::warning, "literalWithCharPtrCompare", "$symbol:" + var + "\nString literal compared with variable '$symbol'. Did you intend to use " + cmpFunc + "() instead?", CWE595, Certainty::normal); } -void CheckString::suspiciousStringCompareError_char(const Token* tok, const std::string& var) +void CheckStringImpl::suspiciousStringCompareError_char(const Token* tok, const std::string& var) { reportError(tok, Severity::warning, "charLiteralWithCharPtrCompare", "$symbol:" + var + "\nChar literal compared with pointer '$symbol'. Did you intend to dereference it?", CWE595, Certainty::normal); @@ -220,7 +220,7 @@ static bool isChar(const Variable* var) return (var && !var->isPointer() && !var->isArray() && (var->typeStartToken()->str() == "char" || var->typeStartToken()->str() == "wchar_t")); } -void CheckString::strPlusChar() +void CheckStringImpl::strPlusChar() { logChecker("CheckString::strPlusChar"); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -236,7 +236,7 @@ void CheckString::strPlusChar() } } -void CheckString::strPlusCharError(const Token *tok) +void CheckStringImpl::strPlusCharError(const Token *tok) { std::string charType = "char"; if (tok && tok->astOperand2() && tok->astOperand2()->variable()) @@ -272,7 +272,7 @@ static bool isMacroUsage(const Token* tok) // Implicit casts of string literals to bool // Comparing string literal with strlen() with wrong length //--------------------------------------------------------------------------- -void CheckString::checkIncorrectStringCompare() +void CheckStringImpl::checkIncorrectStringCompare() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -321,12 +321,12 @@ void CheckString::checkIncorrectStringCompare() } } -void CheckString::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string) +void CheckStringImpl::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string) { reportError(tok, Severity::warning, "incorrectStringCompare", "$symbol:" + func + "\nString literal " + string + " doesn't match length argument for $symbol().", CWE570, Certainty::normal); } -void CheckString::incorrectStringBooleanError(const Token *tok, const std::string& string) +void CheckStringImpl::incorrectStringBooleanError(const Token *tok, const std::string& string) { const bool charLiteral = isCharLiteral(string); const std::string literalType = charLiteral ? "char" : "string"; @@ -341,7 +341,7 @@ void CheckString::incorrectStringBooleanError(const Token *tok, const std::strin // always true: strcmp(str,"a")==0 || strcmp(str,"b") // TODO: Library configuration for string comparison functions //--------------------------------------------------------------------------- -void CheckString::overlappingStrcmp() +void CheckStringImpl::overlappingStrcmp() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -403,7 +403,7 @@ void CheckString::overlappingStrcmp() } } -void CheckString::overlappingStrcmpError(const Token *eq0, const Token *ne0) +void CheckStringImpl::overlappingStrcmpError(const Token *eq0, const Token *ne0) { std::string eq0Expr(eq0 ? eq0->expressionString() : std::string("strcmp(x,\"abc\")")); if (eq0 && eq0->astParent()->str() == "!") @@ -420,7 +420,7 @@ void CheckString::overlappingStrcmpError(const Token *eq0, const Token *ne0) // Overlapping source and destination passed to sprintf(). // TODO: Library configuration for overlapping arguments //--------------------------------------------------------------------------- -void CheckString::sprintfOverlappingData() +void CheckStringImpl::sprintfOverlappingData() { logChecker("CheckString::sprintfOverlappingData"); @@ -457,7 +457,7 @@ void CheckString::sprintfOverlappingData() } } -void CheckString::sprintfOverlappingDataError(const Token *funcTok, const Token *tok, const std::string &varname) +void CheckStringImpl::sprintfOverlappingDataError(const Token *funcTok, const Token *tok, const std::string &varname) { const std::string func = funcTok ? funcTok->str() : "s[n]printf"; @@ -473,7 +473,7 @@ void CheckString::sprintfOverlappingDataError(const Token *funcTok, const Token void CheckString::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckString checkString(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckStringImpl checkString(&tokenizer, &tokenizer.getSettings(), errorLogger); // Checks checkString.strPlusChar(); @@ -487,7 +487,7 @@ void CheckString::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger void CheckString::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckString c(nullptr, settings, errorLogger); + CheckStringImpl c(nullptr, settings, errorLogger); c.stringLiteralWriteError(nullptr, nullptr); c.sprintfOverlappingDataError(nullptr, nullptr, "varname"); c.strPlusCharError(nullptr); diff --git a/lib/checkstring.h b/lib/checkstring.h index 76002f8ed3d..9edefc3f8b0 100644 --- a/lib/checkstring.h +++ b/lib/checkstring.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -41,16 +42,32 @@ class Tokenizer; class CPPCHECKLIB CheckString : public Check { public: /** @brief This constructor is used when registering the CheckClass */ - CheckString() : Check(myName()) {} + CheckString() : Check("String") {} private: - /** @brief This constructor is used when running checks. */ - CheckString(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Detect misusage of C-style strings:\n" + "- overlapping buffers passed to sprintf as source and destination\n" + "- incorrect length arguments for 'substr' and 'strncmp'\n" + "- suspicious condition (runtime comparison of string literals)\n" + "- suspicious condition (string/char literals as boolean)\n" + "- suspicious comparison of a string literal with a char\\* variable\n" + "- suspicious comparison of '\\0' with a char\\* variable\n" + "- overlapping strcmp() expression\n"; + } +}; + +class CPPCHECKLIB CheckStringImpl : public CheckImpl { +public: + /** @brief This constructor is used when running checks. */ + CheckStringImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** @brief undefined behaviour, writing string literal */ void stringLiteralWrite(); @@ -82,23 +99,6 @@ class CPPCHECKLIB CheckString : public Check { void suspiciousStringCompareError(const Token* tok, const std::string& var, bool isLong); void suspiciousStringCompareError_char(const Token* tok, const std::string& var); void overlappingStrcmpError(const Token* eq0, const Token *ne0); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "String"; - } - - std::string classInfo() const override { - return "Detect misusage of C-style strings:\n" - "- overlapping buffers passed to sprintf as source and destination\n" - "- incorrect length arguments for 'substr' and 'strncmp'\n" - "- suspicious condition (runtime comparison of string literals)\n" - "- suspicious condition (string/char literals as boolean)\n" - "- suspicious comparison of a string literal with a char\\* variable\n" - "- suspicious comparison of '\\0' with a char\\* variable\n" - "- overlapping strcmp() expression\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checktype.cpp b/lib/checktype.cpp index eb222fbe6f5..1679d98e80f 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -56,7 +56,7 @@ static const CWE CWE758(758U); // Reliance on Undefined, Unspecified, or Imple static const CWE CWE190(190U); // Integer Overflow or Wraparound -void CheckType::checkTooBigBitwiseShift() +void CheckTypeImpl::checkTooBigBitwiseShift() { // unknown sizeof(int) => can't run this checker if (mSettings->platform.type == Platform::Type::Unspecified) @@ -110,7 +110,7 @@ void CheckType::checkTooBigBitwiseShift() } } -void CheckType::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits) +void CheckTypeImpl::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits) { constexpr char id[] = "shiftTooManyBits"; @@ -129,7 +129,7 @@ void CheckType::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const Val reportError(std::move(errorPath), rhsbits.errorSeverity() ? Severity::error : Severity::warning, id, errmsg.str(), CWE758, rhsbits.isInconclusive() ? Certainty::inconclusive : Certainty::normal); } -void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits) +void CheckTypeImpl::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits) { constexpr char id[] = "shiftTooManyBitsSigned"; @@ -164,7 +164,7 @@ void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, con // Checking for integer overflow //--------------------------------------------------------------------------- -void CheckType::checkIntegerOverflow() +void CheckTypeImpl::checkIntegerOverflow() { // unknown sizeof(int) => can't run this checker if (mSettings->platform.type == Platform::Type::Unspecified || mSettings->platform.int_bit >= MathLib::bigint_bits) @@ -215,7 +215,16 @@ void CheckType::checkIntegerOverflow() } } -void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &value, bool isOverflow) +static std::string getMessageId(const ValueFlow::Value &value, const char id[]) +{ + if (value.condition != nullptr) + return id + std::string("Cond"); + if (value.safe) + return std::string("safe") + static_cast(std::toupper(id[0])) + (id + 1); + return id; +} + +void CheckTypeImpl::integerOverflowError(const Token *tok, const ValueFlow::Value &value, bool isOverflow) { const std::string expr(tok ? tok->expressionString() : ""); const std::string type = isOverflow ? "overflow" : "underflow"; @@ -242,7 +251,7 @@ void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &v // Checking for sign conversion when operand can be negative //--------------------------------------------------------------------------- -void CheckType::checkSignConversion() +void CheckTypeImpl::checkSignConversion() { if (!mSettings->severity.isEnabled(Severity::warning)) return; @@ -274,7 +283,7 @@ void CheckType::checkSignConversion() } } -void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, const bool constvalue) +void CheckTypeImpl::signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, const bool constvalue) { const std::string expr(tok ? tok->expressionString() : "var"); @@ -292,7 +301,7 @@ void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *ne ErrorPath errorPath = getErrorPath(tok,negativeValue,"Negative value is converted to an unsigned value"); reportError(std::move(errorPath), Severity::warning, - Check::getMessageId(*negativeValue, "signConversion").c_str(), + getMessageId(*negativeValue, "signConversion").c_str(), msg.str(), CWE195, negativeValue->isInconclusive() ? Certainty::inconclusive : Certainty::normal); @@ -327,7 +336,7 @@ static bool checkTypeCombination(ValueType src, ValueType tgt, const Settings& s }); } -void CheckType::checkLongCast() +void CheckTypeImpl::checkLongCast() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("truncLongCastAssignment")) return; @@ -405,7 +414,7 @@ static void makeBaseTypeString(std::string& typeStr) typeStr.erase(typeStr.begin(), typeStr.begin() + pos + 6 + 1); } -void CheckType::longCastAssignError(const Token *tok, const ValueType* src, const ValueType* tgt) +void CheckTypeImpl::longCastAssignError(const Token *tok, const ValueType* src, const ValueType* tgt) { std::string srcStr = src ? src->str() : "int"; makeBaseTypeString(srcStr); @@ -418,7 +427,7 @@ void CheckType::longCastAssignError(const Token *tok, const ValueType* src, cons srcStr + " result is assigned to " + tgtStr + " variable. If the variable is " + tgtStr + " to avoid loss of information, then there is loss of information. To avoid loss of information you must cast a calculation operand to " + tgtStr + ", for example 'l = a * b;' => 'l = (" + tgtStr + ")a * b;'.", CWE197, Certainty::normal); } -void CheckType::longCastReturnError(const Token *tok, const ValueType* src, const ValueType* tgt) +void CheckTypeImpl::longCastReturnError(const Token *tok, const ValueType* src, const ValueType* tgt) { std::string srcStr = src ? src->str() : "int"; makeBaseTypeString(srcStr); @@ -435,7 +444,7 @@ void CheckType::longCastReturnError(const Token *tok, const ValueType* src, cons // Checking for float to integer overflow //--------------------------------------------------------------------------- -void CheckType::checkFloatToIntegerOverflow() +void CheckTypeImpl::checkFloatToIntegerOverflow() { logChecker("CheckType::checkFloatToIntegerOverflow"); @@ -475,7 +484,7 @@ void CheckType::checkFloatToIntegerOverflow() } } -void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list &floatValues) +void CheckTypeImpl::checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list &floatValues) { // Conversion of float to integer? if (!vtint || !vtint->isIntegral()) @@ -512,7 +521,7 @@ void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *v } } -void CheckType::floatToIntegerOverflowError(const Token *tok, const ValueFlow::Value &value) +void CheckTypeImpl::floatToIntegerOverflowError(const Token *tok, const ValueFlow::Value &value) { std::ostringstream errmsg; errmsg << "Undefined behaviour: float (" << value.floatValue << ") to integer conversion overflow."; @@ -525,7 +534,7 @@ void CheckType::floatToIntegerOverflowError(const Token *tok, const ValueFlow::V void CheckType::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { // These are not "simplified" because casts can't be ignored - CheckType checkType(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckTypeImpl checkType(&tokenizer, &tokenizer.getSettings(), errorLogger); checkType.checkTooBigBitwiseShift(); checkType.checkIntegerOverflow(); checkType.checkSignConversion(); @@ -535,7 +544,7 @@ void CheckType::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) void CheckType::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckType c(nullptr, settings, errorLogger); + CheckTypeImpl c(nullptr, settings, errorLogger); c.tooBigBitwiseShiftError(nullptr, 32, ValueFlow::Value(64)); c.tooBigSignedBitwiseShiftError(nullptr, 31, ValueFlow::Value(31)); c.integerOverflowError(nullptr, ValueFlow::Value(1LL<<32)); diff --git a/lib/checktype.h b/lib/checktype.h index d90e11f6fd1..a65ed7ea084 100644 --- a/lib/checktype.h +++ b/lib/checktype.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -47,16 +48,31 @@ namespace ValueFlow class CPPCHECKLIB CheckType : public Check { public: /** @brief This constructor is used when registering the CheckClass */ - CheckType() : Check(myName()) {} + CheckType() : Check("Type") {} private: - /** @brief This constructor is used when running checks. */ - CheckType(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "Type checks\n" + "- bitwise shift by too many bits (only enabled when --platform is used)\n" + "- signed integer overflow (only enabled when --platform is used)\n" + "- dangerous sign conversion, when signed value can be negative\n" + "- possible loss of information when assigning int result to long variable\n" + "- possible loss of information when returning int result as long return value\n" + "- float conversion overflow\n"; + } +}; + +class CPPCHECKLIB CheckTypeImpl : public CheckImpl { +public: + /** @brief This constructor is used when running checks. */ + CheckTypeImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** @brief %Check for bitwise shift with too big right operand */ void checkTooBigBitwiseShift(); @@ -81,22 +97,6 @@ class CPPCHECKLIB CheckType : public Check { void longCastAssignError(const Token *tok, const ValueType* src = nullptr, const ValueType* tgt = nullptr); void longCastReturnError(const Token *tok, const ValueType* src = nullptr, const ValueType* tgt = nullptr); void floatToIntegerOverflowError(const Token *tok, const ValueFlow::Value &value); - - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "Type"; - } - - std::string classInfo() const override { - return "Type checks\n" - "- bitwise shift by too many bits (only enabled when --platform is used)\n" - "- signed integer overflow (only enabled when --platform is used)\n" - "- dangerous sign conversion, when signed value can be negative\n" - "- possible loss of information when assigning int result to long variable\n" - "- possible loss of information when returning int result as long return value\n" - "- float conversion overflow\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index b88debda6f8..819bfa9d85a 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -21,6 +21,7 @@ #include "checkuninitvar.h" #include "astutils.h" +#include "checkimpl.h" #include "ctu.h" #include "errorlogger.h" #include "library.h" @@ -97,7 +98,7 @@ static std::map getVariableValues(const Token* tok) { return ret; } -bool CheckUninitVar::diag(const Token* tok) +bool CheckUninitVarImpl::diag(const Token* tok) { if (!tok) return true; @@ -106,7 +107,7 @@ bool CheckUninitVar::diag(const Token* tok) return !mUninitDiags.insert(tok).second; } -void CheckUninitVar::check() +void CheckUninitVarImpl::check() { logChecker("CheckUninitVar::check"); @@ -126,7 +127,7 @@ void CheckUninitVar::check() } } -void CheckUninitVar::checkScope(const Scope* scope, const std::set &arrayTypeDefs) +void CheckUninitVarImpl::checkScope(const Scope* scope, const std::set &arrayTypeDefs) { for (const Variable &var : scope->varlist) { if ((mTokenizer->isCPP() && var.type() && !var.isPointer() && var.type()->needInitialization != Type::NeedInitialization::True) || @@ -231,7 +232,7 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set } } -void CheckUninitVar::checkStruct(const Token *tok, const Variable &structvar) +void CheckUninitVarImpl::checkStruct(const Token *tok, const Variable &structvar) { const Token *typeToken = structvar.typeStartToken(); while (Token::Match(typeToken, "%name% ::")) @@ -392,7 +393,7 @@ static bool isVariableUsed(const Token *tok, const Variable& var) return !parent2 || parent2->isConstOp() || (parent2->str() == "=" && parent2->astOperand2() == parent); } -bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, Alloc* const alloc, const std::string &membervar, std::map& variableValue) +bool CheckUninitVarImpl::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, Alloc* const alloc, const std::string &membervar, std::map& variableValue) { const bool suppressErrors(possibleInit && *possibleInit); // Assume that this is a variable declaration, rather than a fundef const bool printDebug = mSettings->debugwarnings; @@ -852,7 +853,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var return false; } -const Token* CheckUninitVar::checkExpr(const Token* tok, const Variable& var, const Alloc alloc, bool known, bool* bailout) const +const Token* CheckUninitVarImpl::checkExpr(const Token* tok, const Variable& var, const Alloc alloc, bool known, bool* bailout) const { if (!tok) return nullptr; @@ -881,7 +882,7 @@ const Token* CheckUninitVar::checkExpr(const Token* tok, const Variable& var, co return nullptr; } -bool CheckUninitVar::checkIfForWhileHead(const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, Alloc alloc, const std::string &membervar) +bool CheckUninitVarImpl::checkIfForWhileHead(const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, Alloc alloc, const std::string &membervar) { const Token * const endpar = startparentheses->link(); if (Token::Match(startparentheses, "( ! %name% %oror%") && startparentheses->tokAt(2)->getValue(0)) @@ -918,7 +919,7 @@ bool CheckUninitVar::checkIfForWhileHead(const Token *startparentheses, const Va } /** recursively check loop, return error token */ -const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Variable& var, const Alloc alloc, const std::string &membervar, bool &bailout, bool &alwaysReturns) const +const Token* CheckUninitVarImpl::checkLoopBodyRecursive(const Token *start, const Variable& var, const Alloc alloc, const std::string &membervar, bool &bailout, bool &alwaysReturns) const { assert(start->str() == "{"); @@ -1086,7 +1087,7 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va return errorToken; } -bool CheckUninitVar::checkLoopBody(const Token *tok, const Variable& var, const Alloc alloc, const std::string &membervar, const bool suppressErrors) +bool CheckUninitVarImpl::checkLoopBody(const Token *tok, const Variable& var, const Alloc alloc, const std::string &membervar, const bool suppressErrors) { bool bailout = false; bool alwaysReturns = false; @@ -1103,7 +1104,7 @@ bool CheckUninitVar::checkLoopBody(const Token *tok, const Variable& var, const return bailout || alwaysReturns; } -void CheckUninitVar::checkRhs(const Token *tok, const Variable &var, Alloc alloc, nonneg int number_of_if, const std::string &membervar) +void CheckUninitVarImpl::checkRhs(const Token *tok, const Variable &var, Alloc alloc, nonneg int number_of_if, const std::string &membervar) { bool rhs = false; int indent = 0; @@ -1150,7 +1151,7 @@ static bool astIsRhs(const Token *tok) return tok && tok->astParent() && tok == tok->astParent()->astOperand2(); } -const Token* CheckUninitVar::isVariableUsage(const Token *vartok, const Library& library, bool pointer, Alloc alloc, int indirect) +const Token* CheckUninitVarImpl::isVariableUsage(const Token *vartok, const Library& library, bool pointer, Alloc alloc, int indirect) { const bool cpp = vartok->isCpp(); const Token *valueExpr = vartok; // non-dereferenced , no address of value as variable @@ -1352,7 +1353,7 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, const Library& return derefValue ? derefValue : valueExpr; } -const Token* CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect) const +const Token* CheckUninitVarImpl::isVariableUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect) const { return isVariableUsage(vartok, mSettings->library, pointer, alloc, indirect); } @@ -1363,7 +1364,7 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, * is passed "by reference" then it is not necessarily "used". * @return -1 => unknown 0 => not used 1 => used */ -int CheckUninitVar::isFunctionParUsage(const Token *vartok, const Library& library, bool pointer, Alloc alloc, int indirect) +int CheckUninitVarImpl::isFunctionParUsage(const Token *vartok, const Library& library, bool pointer, Alloc alloc, int indirect) { bool unknown = false; const Token *parent = getAstParentSkipPossibleCastAndAddressOf(vartok, &unknown); @@ -1433,12 +1434,12 @@ int CheckUninitVar::isFunctionParUsage(const Token *vartok, const Library& libra return -1; } -int CheckUninitVar::isFunctionParUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect) const +int CheckUninitVarImpl::isFunctionParUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect) const { - return CheckUninitVar::isFunctionParUsage(vartok, mSettings->library, pointer, alloc, indirect); + return isFunctionParUsage(vartok, mSettings->library, pointer, alloc, indirect); } -bool CheckUninitVar::isMemberVariableAssignment(const Token *tok, const std::string &membervar) const +bool CheckUninitVarImpl::isMemberVariableAssignment(const Token *tok, const std::string &membervar) const { if (Token::Match(tok, "%name% . %name%") && tok->strAt(2) == membervar) { if (Token::Match(tok->tokAt(3), "[=.[]")) @@ -1507,7 +1508,7 @@ bool CheckUninitVar::isMemberVariableAssignment(const Token *tok, const std::str return false; } -bool CheckUninitVar::isMemberVariableUsage(const Token *tok, bool isPointer, Alloc alloc, const std::string &membervar) const +bool CheckUninitVarImpl::isMemberVariableUsage(const Token *tok, bool isPointer, Alloc alloc, const std::string &membervar) const { if (Token::Match(tok->previous(), "[(,] %name% . %name% [,)]") && tok->strAt(2) == membervar) { @@ -1549,12 +1550,12 @@ bool CheckUninitVar::isMemberVariableUsage(const Token *tok, bool isPointer, All return false; } -void CheckUninitVar::uninitdataError(const Token *tok, const std::string &varname) +void CheckUninitVarImpl::uninitdataError(const Token *tok, const std::string &varname) { reportError(tok, Severity::error, "uninitdata", "$symbol:" + varname + "\nMemory is allocated but not initialized: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, Certainty::normal); } -void CheckUninitVar::uninitvarError(const Token *tok, const std::string &varname, ErrorPath errorPath) +void CheckUninitVarImpl::uninitvarError(const Token *tok, const std::string &varname, ErrorPath errorPath) { if (diag(tok)) return; @@ -1567,7 +1568,7 @@ void CheckUninitVar::uninitvarError(const Token *tok, const std::string &varname Certainty::normal); } -void CheckUninitVar::uninitvarError(const Token* tok, const ValueFlow::Value& v) +void CheckUninitVarImpl::uninitvarError(const Token* tok, const ValueFlow::Value& v) { if (!mSettings->isEnabled(&v)) return; @@ -1604,7 +1605,7 @@ void CheckUninitVar::uninitvarError(const Token* tok, const ValueFlow::Value& v) certainty); } -void CheckUninitVar::uninitStructMemberError(const Token *tok, const std::string &membername) +void CheckUninitVarImpl::uninitStructMemberError(const Token *tok, const std::string &membername) { reportError(tok, Severity::error, @@ -1612,7 +1613,7 @@ void CheckUninitVar::uninitStructMemberError(const Token *tok, const std::string "$symbol:" + membername + "\nUninitialized struct member: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, Certainty::normal); } -void CheckUninitVar::valueFlowUninit() +void CheckUninitVarImpl::valueFlowUninit() { logChecker("CheckUninitVar::valueFlowUninit"); @@ -1663,7 +1664,7 @@ void CheckUninitVar::valueFlowUninit() if (yield != Library::Container::Yield::AT_INDEX && yield != Library::Container::Yield::ITEM) continue; } - const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, *mSettings); + const bool deref = CheckNullPointerImpl::isPointerDeRef(tok, unknown, *mSettings); uninitderef = deref && v->indirect == 0; const bool isleaf = isLeafDot(tok) || uninitderef; if (!isleaf && Token::Match(tok->astParent(), ". %name%") && @@ -1696,7 +1697,7 @@ void CheckUninitVar::valueFlowUninit() static bool isVariableUsage(const Settings &settings, const Token *vartok, MathLib::bigint *value) { (void)value; - return CheckUninitVar::isVariableUsage(vartok, settings.library, true, CheckUninitVar::Alloc::ARRAY); + return !!CheckUninitVarImpl::isVariableUsage(vartok, settings.library, true, CheckUninitVarImpl::Alloc::ARRAY); } // a Clang-built executable will crash when using the anonymous MyFileInfo later on - so put it in a unique namespace for now @@ -1752,7 +1753,7 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo &ctu, const std::li { (void)settings; - CheckUninitVar dummy(nullptr, &settings, &errorLogger); + CheckUninitVarImpl dummy(nullptr, &settings, &errorLogger); dummy. logChecker("CheckUninitVar::analyseWholeProgram"); @@ -1798,14 +1799,14 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo &ctu, const std::li void CheckUninitVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckUninitVar checkUninitVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckUninitVarImpl checkUninitVar(&tokenizer, &tokenizer.getSettings(), errorLogger); checkUninitVar.valueFlowUninit(); checkUninitVar.check(); } void CheckUninitVar::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const { - CheckUninitVar c(nullptr, settings, errorLogger); + CheckUninitVarImpl c(nullptr, settings, errorLogger); ValueFlow::Value v{}; diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index b79e9c22be0..f484c13e55c 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include "mathlib.h" #include "errortypes.h" @@ -61,20 +62,36 @@ class CPPCHECKLIB CheckUninitVar : public Check { public: /** @brief This constructor is used when registering the CheckUninitVar */ - CheckUninitVar() : Check(myName()) {} + CheckUninitVar() : Check("Uninitialized variables") {} - enum Alloc : std::uint8_t { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY }; +private: + /** @brief Run checks against the normal token list */ + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - static const Token *isVariableUsage(const Token *vartok, const Library &library, bool pointer, Alloc alloc, int indirect = 0); - const Token *isVariableUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect = 0) const; + /** @brief Parse current TU and extract file info */ + Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; -private: + Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; + + /** @brief Analyse all file infos for all TU */ + bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; + + void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; + + std::string classInfo() const override { + return "Uninitialized variables\n" + "- using uninitialized local variables\n" + "- using allocated data before it has been initialized\n"; + } +}; + +class CPPCHECKLIB CheckUninitVarImpl : public CheckImpl { +public: /** @brief This constructor is used when running checks. */ - CheckUninitVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} + CheckUninitVarImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + enum Alloc : std::uint8_t { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY }; bool diag(const Token* tok); /** Check for uninitialized variables */ @@ -92,17 +109,12 @@ class CPPCHECKLIB CheckUninitVar : public Check { bool isMemberVariableAssignment(const Token *tok, const std::string &membervar) const; bool isMemberVariableUsage(const Token *tok, bool isPointer, Alloc alloc, const std::string &membervar) const; + static const Token *isVariableUsage(const Token *vartok, const Library &library, bool pointer, Alloc alloc, int indirect = 0); + const Token *isVariableUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect = 0) const; + /** ValueFlow-based checking for uninitialized variables */ void valueFlowUninit(); - /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; - - Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; - - /** @brief Analyse all file infos for all TU */ - bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - void uninitvarError(const Token* tok, const ValueFlow::Value& v); void uninitdataError(const Token *tok, const std::string &varname); void uninitvarError(const Token *tok, const std::string &varname, ErrorPath errorPath); @@ -118,18 +130,6 @@ class CPPCHECKLIB CheckUninitVar : public Check { void uninitStructMemberError(const Token *tok, const std::string &membername); std::set mUninitDiags; - - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; - - static std::string myName() { - return "Uninitialized variables"; - } - - std::string classInfo() const override { - return "Uninitialized variables\n" - "- using uninitialized local variables\n" - "- using allocated data before it has been initialized\n"; - } }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 9531237a208..4c5f8175f66 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -699,7 +699,7 @@ static void useFunctionArgs(const Token *tok, Variables& variables) //--------------------------------------------------------------------------- // Usage of function variables //--------------------------------------------------------------------------- -void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const scope, Variables& variables) const +void CheckUnusedVarImpl::checkFunctionVariableUsage_iterateScopes(const Scope* const scope, Variables& variables) const { // Find declarations if the scope is executable.. if (scope->isExecutable()) { @@ -1173,7 +1173,7 @@ static bool isReturnedByRef(const Variable* var, const Function* func) }); } -void CheckUnusedVar::checkFunctionVariableUsage() +void CheckUnusedVarImpl::checkFunctionVariableUsage() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->checkLibrary && !mSettings->isPremiumEnabled("unusedVariable")) return; @@ -1479,7 +1479,7 @@ void CheckUnusedVar::checkFunctionVariableUsage() } } -void CheckUnusedVar::unusedVariableError(const Token *tok, const std::string &varname) +void CheckUnusedVarImpl::unusedVariableError(const Token *tok, const std::string &varname) { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedVariable")) return; @@ -1487,7 +1487,7 @@ void CheckUnusedVar::unusedVariableError(const Token *tok, const std::string &va reportError(tok, Severity::style, "unusedVariable", "$symbol:" + varname + "\nUnused variable: $symbol", CWE563, Certainty::normal); } -void CheckUnusedVar::allocatedButUnusedVariableError(const Token *tok, const std::string &varname) +void CheckUnusedVarImpl::allocatedButUnusedVariableError(const Token *tok, const std::string &varname) { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedVariable")) return; @@ -1495,7 +1495,7 @@ void CheckUnusedVar::allocatedButUnusedVariableError(const Token *tok, const std reportError(tok, Severity::style, "unusedAllocatedMemory", "$symbol:" + varname + "\nVariable '$symbol' is allocated memory that is never used.", CWE563, Certainty::normal); } -void CheckUnusedVar::unreadVariableError(const Token *tok, const std::string &varname, bool modified) +void CheckUnusedVarImpl::unreadVariableError(const Token *tok, const std::string &varname, bool modified) { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedVariable")) return; @@ -1506,7 +1506,7 @@ void CheckUnusedVar::unreadVariableError(const Token *tok, const std::string &va reportError(tok, Severity::style, "unreadVariable", "$symbol:" + varname + "\nVariable '$symbol' is assigned a value that is never used.", CWE563, Certainty::normal); } -void CheckUnusedVar::unassignedVariableError(const Token *tok, const std::string &varname) +void CheckUnusedVarImpl::unassignedVariableError(const Token *tok, const std::string &varname) { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedVariable")) return; @@ -1517,7 +1517,7 @@ void CheckUnusedVar::unassignedVariableError(const Token *tok, const std::string //--------------------------------------------------------------------------- // Check that all struct members are used //--------------------------------------------------------------------------- -void CheckUnusedVar::checkStructMemberUsage() +void CheckUnusedVarImpl::checkStructMemberUsage() { if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedStructMember") && !mSettings->isPremiumEnabled("unusedVariable")) return; @@ -1698,12 +1698,12 @@ void CheckUnusedVar::checkStructMemberUsage() } } -void CheckUnusedVar::unusedStructMemberError(const Token* tok, const std::string& structname, const std::string& varname, const std::string& prefix) +void CheckUnusedVarImpl::unusedStructMemberError(const Token* tok, const std::string& structname, const std::string& varname, const std::string& prefix) { reportError(tok, Severity::style, "unusedStructMember", "$symbol:" + structname + "::" + varname + '\n' + prefix + " member '$symbol' is never used.", CWE563, Certainty::normal); } -bool CheckUnusedVar::isEmptyType(const Type* type) +bool CheckUnusedVarImpl::isEmptyType(const Type* type) { // a type that has no variables and no constructor @@ -1726,7 +1726,7 @@ bool CheckUnusedVar::isEmptyType(const Type* type) void CheckUnusedVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckUnusedVar checkUnusedVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, &tokenizer.getSettings(), errorLogger); // Coding style checks checkUnusedVar.checkStructMemberUsage(); @@ -1735,10 +1735,11 @@ void CheckUnusedVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLog void CheckUnusedVar::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckUnusedVar c(nullptr, settings, errorLogger); + CheckUnusedVarImpl c(nullptr, settings, errorLogger); c.unusedVariableError(nullptr, "varname"); c.allocatedButUnusedVariableError(nullptr, "varname"); c.unreadVariableError(nullptr, "varname", false); c.unassignedVariableError(nullptr, "varname"); c.unusedStructMemberError(nullptr, "structname", "variable"); } + diff --git a/lib/checkunusedvar.h b/lib/checkunusedvar.h index 5ab79514cf9..1d2227c15bf 100644 --- a/lib/checkunusedvar.h +++ b/lib/checkunusedvar.h @@ -22,6 +22,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -46,16 +47,32 @@ class CPPCHECKLIB CheckUnusedVar : public Check { public: /** @brief This constructor is used when registering the CheckClass */ - CheckUnusedVar() : Check(myName()) {} + CheckUnusedVar() : Check("UnusedVar") {} private: - /** @brief This constructor is used when running checks. */ - CheckUnusedVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} - /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + + std::string classInfo() const override { + return "UnusedVar checks\n" + + // style + "- unused variable\n" + "- allocated but unused variable\n" + "- unread variable\n" + "- unassigned variable\n" + "- unused struct member\n"; + } +}; + +class CPPCHECKLIB CheckUnusedVarImpl : public CheckImpl { +public: + /** @brief This constructor is used when running checks. */ + CheckUnusedVarImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + /** @brief %Check for unused function variables */ void checkFunctionVariableUsage_iterateScopes(const Scope* scope, Variables& variables) const; void checkFunctionVariableUsage(); @@ -72,25 +89,7 @@ class CPPCHECKLIB CheckUnusedVar : public Check { void unreadVariableError(const Token *tok, const std::string &varname, bool modified); void unassignedVariableError(const Token *tok, const std::string &varname); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - - static std::string myName() { - return "UnusedVar"; - } - - std::string classInfo() const override { - return "UnusedVar checks\n" - - // style - "- unused variable\n" - "- allocated but unused variable\n" - "- unread variable\n" - "- unassigned variable\n" - "- unused struct member\n"; - } - std::map mIsEmptyTypeMap; - }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index e6efc8f5ed9..18eb246e0e7 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -39,7 +39,7 @@ static const CWE CWE664(664U); // Improper Control of a Resource Through its L static const CWE CWE688(688U); // Function Call With Incorrect Variable or Reference as Argument static const CWE CWE758(758U); // Reliance on Undefined, Unspecified, or Implementation-Defined Behavior -void CheckVaarg::va_start_argument() +void CheckVaargImpl::va_start_argument() { const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const std::size_t functions = symbolDatabase->functionScopes.size(); @@ -73,13 +73,13 @@ void CheckVaarg::va_start_argument() } } -void CheckVaarg::wrongParameterTo_va_start_error(const Token *tok, const std::string& paramIsName, const std::string& paramShouldName) +void CheckVaargImpl::wrongParameterTo_va_start_error(const Token *tok, const std::string& paramIsName, const std::string& paramShouldName) { reportError(tok, Severity::warning, "va_start_wrongParameter", "'" + paramIsName + "' given to va_start() is not last named argument of the function. Did you intend to pass '" + paramShouldName + "'?", CWE688, Certainty::normal); } -void CheckVaarg::referenceAs_va_start_error(const Token *tok, const std::string& paramName) +void CheckVaargImpl::referenceAs_va_start_error(const Token *tok, const std::string& paramName) { reportError(tok, Severity::error, "va_start_referencePassed", "Using reference '" + paramName + "' as parameter for va_start() results in undefined behaviour.", CWE758, Certainty::normal); @@ -90,7 +90,7 @@ void CheckVaarg::referenceAs_va_start_error(const Token *tok, const std::string& // Detect va_list usage after va_end() //--------------------------------------------------------------------------- -void CheckVaarg::va_list_usage() +void CheckVaargImpl::va_list_usage() { if (mSettings->clang) return; @@ -155,19 +155,19 @@ void CheckVaarg::va_list_usage() } } -void CheckVaarg::va_end_missingError(const Token *tok, const std::string& varname) +void CheckVaargImpl::va_end_missingError(const Token *tok, const std::string& varname) { reportError(tok, Severity::error, "va_end_missing", "va_list '" + varname + "' was opened but not closed by va_end().", CWE664, Certainty::normal); } -void CheckVaarg::va_list_usedBeforeStartedError(const Token *tok, const std::string& varname) +void CheckVaargImpl::va_list_usedBeforeStartedError(const Token *tok, const std::string& varname) { reportError(tok, Severity::error, "va_list_usedBeforeStarted", "va_list '" + varname + "' used before va_start() was called.", CWE664, Certainty::normal); } -void CheckVaarg::va_start_subsequentCallsError(const Token *tok, const std::string& varname) +void CheckVaargImpl::va_start_subsequentCallsError(const Token *tok, const std::string& varname) { reportError(tok, Severity::error, "va_start_subsequentCalls", "va_start() or va_copy() called subsequently on '" + varname + "' without va_end() in between.", CWE664, Certainty::normal); @@ -175,14 +175,14 @@ void CheckVaarg::va_start_subsequentCallsError(const Token *tok, const std::stri void CheckVaarg::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckVaarg check(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckVaargImpl check(&tokenizer, &tokenizer.getSettings(), errorLogger); check.va_start_argument(); check.va_list_usage(); } void CheckVaarg::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { - CheckVaarg c(nullptr, settings, errorLogger); + CheckVaargImpl c(nullptr, settings, errorLogger); c.wrongParameterTo_va_start_error(nullptr, "arg1", "arg2"); c.referenceAs_va_start_error(nullptr, "arg1"); c.va_end_missingError(nullptr, "vl"); diff --git a/lib/checkvaarg.h b/lib/checkvaarg.h index 7af5d98d66f..e07d653456a 100644 --- a/lib/checkvaarg.h +++ b/lib/checkvaarg.h @@ -23,6 +23,7 @@ //--------------------------------------------------------------------------- #include "check.h" +#include "checkimpl.h" #include "config.h" #include @@ -41,29 +42,13 @@ class Tokenizer; class CPPCHECKLIB CheckVaarg : public Check { public: - CheckVaarg() : Check(myName()) {} - -private: - CheckVaarg(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} + CheckVaarg() : Check("Vaarg") {} void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void va_start_argument(); - void va_list_usage(); - - void wrongParameterTo_va_start_error(const Token *tok, const std::string& paramIsName, const std::string& paramShouldName); - void referenceAs_va_start_error(const Token *tok, const std::string& paramName); - void va_end_missingError(const Token *tok, const std::string& varname); - void va_list_usedBeforeStartedError(const Token *tok, const std::string& varname); - void va_start_subsequentCallsError(const Token *tok, const std::string& varname); - +private: void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; - static std::string myName() { - return "Vaarg"; - } - std::string classInfo() const override { return "Check for misusage of variable argument lists:\n" "- Wrong parameter passed to va_start()\n" @@ -74,6 +59,22 @@ class CPPCHECKLIB CheckVaarg : public Check { } }; +class CPPCHECKLIB CheckVaargImpl : public CheckImpl +{ +public: + CheckVaargImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : CheckImpl(tokenizer, settings, errorLogger) {} + + void va_start_argument(); + void va_list_usage(); + + void wrongParameterTo_va_start_error(const Token *tok, const std::string& paramIsName, const std::string& paramShouldName); + void referenceAs_va_start_error(const Token *tok, const std::string& paramName); + void va_end_missingError(const Token *tok, const std::string& varname); + void va_list_usedBeforeStartedError(const Token *tok, const std::string& varname); + void va_start_subsequentCallsError(const Token *tok, const std::string& varname); +}; + /// @} //--------------------------------------------------------------------------- diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 12bd4898d4a..5e5b9ae743a 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -32,12 +32,6 @@ - - Create - Create - Create - Create - @@ -50,6 +44,12 @@ + + Create + Create + Create + Create + @@ -124,6 +124,7 @@ + diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index a63995a9728..64a48285fdc 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5716,7 +5716,7 @@ static void valueFlowSubFunction(const TokenList& tokenlist, // Remove uninit values if argument is passed by value if (argtok->variable() && !argtok->variable()->isPointer() && argvalues.size() == 1 && argvalues.front().isUninitValue()) { - if (CheckUninitVar::isVariableUsage(argtok, settings.library, false, CheckUninitVar::Alloc::NO_ALLOC, 0)) + if (CheckUninitVarImpl::isVariableUsage(argtok, settings.library, false, CheckUninitVarImpl::Alloc::NO_ALLOC, 0)) continue; } diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index c93b8694065..bf40964b338 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -45,7 +45,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/addoninfo.o \ $(libcppdir)/analyzerinfo.o \ $(libcppdir)/astutils.o \ - $(libcppdir)/check.o \ $(libcppdir)/check64bit.o \ $(libcppdir)/checkassert.o \ $(libcppdir)/checkautovariables.o \ @@ -58,6 +57,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/checkersreport.o \ $(libcppdir)/checkexceptionsafety.o \ $(libcppdir)/checkfunctions.o \ + $(libcppdir)/checkimpl.o \ $(libcppdir)/checkinternal.o \ $(libcppdir)/checkio.o \ $(libcppdir)/checkleakautovar.o \ @@ -153,7 +153,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -D_LARGEFILE_SOURCE -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/regex.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/regex.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h @@ -168,31 +168,28 @@ $(libcppdir)/addoninfo.o: ../lib/addoninfo.cpp ../externals/picojson/picojson.h $(libcppdir)/analyzerinfo.o: ../lib/analyzerinfo.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check.o: ../lib/check.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check.cpp - -$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/addoninfo.h ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/addoninfo.h ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: ../lib/checkers.cpp ../lib/checkers.h ../lib/config.h @@ -204,58 +201,61 @@ $(libcppdir)/checkersidmapping.o: ../lib/checkersidmapping.cpp ../lib/checkers.h $(libcppdir)/checkersreport.o: ../lib/checkersreport.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkersreport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h + $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp + +$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp -$(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/standards.h ../lib/vfvalue.h +$(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/standards.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp $(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp $(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h diff --git a/test/test64bit.cpp b/test/test64bit.cpp index 6f9a5fbda2f..da837fd9a96 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -49,8 +49,7 @@ class Test64BitPortability : public TestFixture { SimpleTokenizer tokenizer(settings, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check char variable usage.. - Check64BitPortability check64BitPortability(&tokenizer, &settings, this); + Check64BitPortabilityImpl check64BitPortability(&tokenizer, &settings, this); check64BitPortability.pointerassignment(); } diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index 624efcff539..bb98dfad48d 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -47,7 +47,7 @@ class TestCharVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check char variable usage.. - CheckOther checkOther(&tokenizer, &settings, this); + CheckOtherImpl checkOther(&tokenizer, &settings, this); checkOther.checkCharVariable(); } diff --git a/test/testclass.cpp b/test/testclass.cpp index c1b801c208b..35994e98cf4 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -270,7 +270,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); (checkClass.checkCopyCtorAndEqOperator)(); } @@ -371,7 +371,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings0, this); + CheckClassImpl checkClass(&tokenizer, &settings0, this); (checkClass.checkExplicitConstructors)(); } @@ -528,7 +528,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, &settings1, this); (checkClass.checkDuplInheritedMembers)(); } @@ -752,7 +752,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings3, this); + CheckClassImpl checkClass(&tokenizer, &settings3, this); checkClass.copyconstructors(); } @@ -1223,7 +1223,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings0, this); + CheckClassImpl checkClass(&tokenizer, &settings0, this); checkClass.operatorEqRetRefThis(); } @@ -1694,7 +1694,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, &settings1, this); checkClass.operatorEqToSelf(); } @@ -2657,7 +2657,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &s, this); + CheckClassImpl checkClass(&tokenizer, &s, this); checkClass.virtualDestructor(); } @@ -2994,7 +2994,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); checkClass.checkMemset(); } @@ -3640,7 +3640,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, &settings1, this); checkClass.thisSubtraction(); } @@ -3680,7 +3680,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); (checkClass.checkConst)(); } @@ -7863,7 +7863,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings2, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClass checkClass(&tokenizer, &settings2, this); + CheckClassImpl checkClass(&tokenizer, &settings2, this); checkClass.initializerListOrder(); } @@ -8017,7 +8017,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); checkClass.initializationListUsage(); } @@ -8241,7 +8241,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings0, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClass checkClass(&tokenizer, &settings0, this); + CheckClassImpl checkClass(&tokenizer, &settings0, this); (checkClass.checkSelfInitialization)(); } @@ -8351,7 +8351,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); checkClass.checkVirtualFunctionCallInConstructor(); } @@ -8696,7 +8696,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); (checkClass.checkOverride)(); } @@ -8908,7 +8908,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); (checkClass.checkUselessOverride)(); } @@ -9098,7 +9098,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); (checkClass.checkUnsafeClassRefMember)(); } @@ -9116,7 +9116,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, &settings1, this); (checkClass.checkThisUseAfterFree)(); } @@ -9353,7 +9353,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check.. - CheckClass checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, &settings, this); (checkClass.checkReturnByReference)(); } diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 0eb91ba8cca..8bec74529b6 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -52,7 +52,7 @@ class TestConstructors : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check class constructors.. - CheckClass checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, &settings1, this); checkClass.constructors(); } diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 3d8f5d4d713..bd94b52af0e 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -50,7 +50,7 @@ class TestIncompleteStatement : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for incomplete statements.. - CheckOther checkOther(&tokenizer, &settings1, this); + CheckOtherImpl checkOther(&tokenizer, &settings1, this); checkOther.checkIncompleteStatement(); } diff --git a/test/testio.cpp b/test/testio.cpp index d3344f76b8d..bc6e40034f6 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -109,7 +109,7 @@ class TestIO : public TestFixture { // Check.. if (options.onlyFormatStr) { - CheckIO checkIO(&tokenizer, &settings1, this); + CheckIOImpl checkIO(&tokenizer, &settings1, this); checkIO.checkWrongPrintfScanfArguments(); return; } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 1ed88120886..8982215d8e3 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -39,13 +39,12 @@ class TestMemleak : public TestFixture { #define functionReturnType(...) functionReturnType_(__FILE__, __LINE__, __VA_ARGS__) template - CheckMemoryLeak::AllocType functionReturnType_(const char* file, int line, const char (&code)[size]) { + CheckMemoryLeakImpl::AllocType functionReturnType_(const char* file, int line, const char (&code)[size]) { // Tokenize.. SimpleTokenizer tokenizer(settingsDefault, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - const CheckMemoryLeak c(&tokenizer, this, &settingsDefault); - + const CheckMemoryLeakImpl c(&tokenizer, &settingsDefault, this); return (c.functionReturnType)(&tokenizer.getSymbolDatabase()->scopeList.front().functionList.front()); } @@ -53,19 +52,19 @@ class TestMemleak : public TestFixture { { const char code[] = "const char *foo()\n" "{ return 0; }"; - ASSERT_EQUALS(CheckMemoryLeak::No, functionReturnType(code)); + ASSERT_EQUALS(CheckMemoryLeakImpl::No, functionReturnType(code)); } { const char code[] = "Fred *newFred()\n" "{ return new Fred; }"; - ASSERT_EQUALS(CheckMemoryLeak::New, functionReturnType(code)); + ASSERT_EQUALS(CheckMemoryLeakImpl::New, functionReturnType(code)); } { const char code[] = "char *foo()\n" "{ return new char[100]; }"; - ASSERT_EQUALS(CheckMemoryLeak::NewArray, functionReturnType(code)); + ASSERT_EQUALS(CheckMemoryLeakImpl::NewArray, functionReturnType(code)); } { @@ -74,7 +73,7 @@ class TestMemleak : public TestFixture { " char *p = new char[100];\n" " return p;\n" "}"; - ASSERT_EQUALS(CheckMemoryLeak::NewArray, functionReturnType(code)); + ASSERT_EQUALS(CheckMemoryLeakImpl::NewArray, functionReturnType(code)); } } @@ -94,8 +93,8 @@ class TestMemleak : public TestFixture { // there is no allocation const Token *tok = Token::findsimplematch(tokenizer.tokens(), "ret ="); - const CheckMemoryLeak check(&tokenizer, nullptr, &settingsDefault); - ASSERT_EQUALS(CheckMemoryLeak::No, check.getAllocationType(tok->tokAt(2), 1)); + const CheckMemoryLeakImpl check(&tokenizer, &settingsDefault, nullptr); + ASSERT_EQUALS(CheckMemoryLeakImpl::No, check.getAllocationType(tok->tokAt(2), 1)); } }; @@ -120,7 +119,7 @@ class TestMemleakInFunction : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings, this); + CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, &settings, this); checkMemoryLeak.checkReallocUsage(); } @@ -502,7 +501,7 @@ class TestMemleakInClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakInClass checkMemoryLeak(&tokenizer, &settings, this); + CheckMemoryLeakInClassImpl checkMemoryLeak(&tokenizer, &settings, this); (checkMemoryLeak.check)(); } @@ -1707,7 +1706,7 @@ class TestMemleakStructMember : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakStructMember checkMemoryLeakStructMember(&tokenizer, &settings, this); + CheckMemoryLeakStructMemberImpl checkMemoryLeakStructMember(&tokenizer, &settings, this); (checkMemoryLeakStructMember.check)(); } @@ -2389,7 +2388,7 @@ class TestMemleakNoVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakNoVar checkMemoryLeakNoVar(&tokenizer, &settings, this); + CheckMemoryLeakNoVarImpl checkMemoryLeakNoVar(&tokenizer, &settings, this); (checkMemoryLeakNoVar.check)(); } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index a154bd0d9c2..3e9d4011500 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -4351,7 +4351,7 @@ class TestNullPointer : public TestFixture { Library library; ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); - const std::list null = CheckNullPointer::parseFunctionCall(*xtok, library); + const std::list null = CheckNullPointerImpl::parseFunctionCall(*xtok, library); ASSERT_EQUALS(0U, null.size()); } @@ -4369,7 +4369,7 @@ class TestNullPointer : public TestFixture { Library library; ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); - const std::list null = CheckNullPointer::parseFunctionCall(*xtok, library); + const std::list null = CheckNullPointerImpl::parseFunctionCall(*xtok, library); ASSERT_EQUALS(1U, null.size()); ASSERT_EQUALS("a", null.front()->str()); } diff --git a/test/testother.cpp b/test/testother.cpp index 9a18a067231..321657c668f 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2055,7 +2055,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizerCpp(settings, *this); ASSERT_LOC(tokenizerCpp.tokenize(code), file, line); - CheckOther checkOtherCpp(&tokenizerCpp, &settings, this); + CheckOtherImpl checkOtherCpp(&tokenizerCpp, &settings, this); checkOtherCpp.warningOldStylePointerCast(); checkOtherCpp.warningDangerousTypeCast(); } @@ -2341,7 +2341,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizerCpp(settings, *this); ASSERT_LOC(tokenizerCpp.tokenize(code), file, line); - CheckOther checkOtherCpp(&tokenizerCpp, &settings, this); + CheckOtherImpl checkOtherCpp(&tokenizerCpp, &settings, this); checkOtherCpp.warningIntToPointerCast(); } @@ -2380,7 +2380,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckOther checkOtherCpp(&tokenizer, &settings, this); + CheckOtherImpl checkOtherCpp(&tokenizer, &settings, this); checkOtherCpp.invalidPointerCast(); } diff --git a/test/testpostfixoperator.cpp b/test/testpostfixoperator.cpp index 9e95fabc949..1d01217231a 100644 --- a/test/testpostfixoperator.cpp +++ b/test/testpostfixoperator.cpp @@ -38,8 +38,7 @@ class TestPostfixOperator : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for postfix operators.. - CheckPostfixOperator checkPostfixOperator(&tokenizer, &settings, this); + CheckPostfixOperatorImpl checkPostfixOperator(&tokenizer, &settings, this); checkPostfixOperator.postfixOperator(); } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 6fe563a57ca..6ad2047ddd7 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -127,7 +127,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVar checkuninitvar(&tokenizer, &settings1, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, &settings1, this); checkuninitvar.check(); } @@ -137,7 +137,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVar checkuninitvar(&tokenizer, &settings, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, &settings, this); checkuninitvar.check(); } @@ -3673,7 +3673,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVar checkuninitvar(&tokenizer, &settings, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, &settings, this); (checkuninitvar.valueFlowUninit)(); } diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 5a364347163..3b419814dca 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -104,7 +104,7 @@ class TestUnusedPrivateFunction : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused private functions.. - CheckClass checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, &settings1, this); checkClass.privateFunctions(); } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 13d288a3fdd..d0ad22b004d 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -290,7 +290,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for unused variables.. - CheckUnusedVar checkUnusedVar(&tokenizer, &settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, &settings, this); checkUnusedVar.checkFunctionVariableUsage(); } @@ -310,7 +310,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for unused variables.. - CheckUnusedVar checkUnusedVar(&tokenizer, &settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, &settings, this); (checkUnusedVar.checkStructMemberUsage)(); } @@ -323,7 +323,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused variables.. - CheckUnusedVar checkUnusedVar(&tokenizer, &settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, &settings, this); (checkUnusedVar.checkStructMemberUsage)(); } @@ -336,7 +336,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused variables.. - CheckUnusedVar checkUnusedVar(&tokenizer, &settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, &settings, this); (checkUnusedVar.checkFunctionVariableUsage)(); } diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index 80f3aa35b83..3d08943f5ba 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -495,6 +495,7 @@ int main(int argc, char **argv) } libfiles_h.emplace("analyzer.h"); libfiles_h.emplace("calculate.h"); + libfiles_h.emplace("check.h"); libfiles_h.emplace("config.h"); libfiles_h.emplace("filesettings.h"); libfiles_h.emplace("findtoken.h"); @@ -559,7 +560,7 @@ int main(int argc, char **argv) for (const std::string &libfile: libfiles_prio) { const std::string l = libfile.substr(4); - outstr += make_vcxproj_cl_entry(l, l == "check.cpp" ? Precompile : Compile); + outstr += make_vcxproj_cl_entry(l, l == "checkimpl.cpp" ? Precompile : Compile); } }, [&](std::string &outstr){ outstr += make_vcxproj_cl_entry(R"(..\externals\simplecpp\simplecpp.h)", Include); From 98ac18eeb23068afe80ef72e853aac72a29a6d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 29 May 2026 10:26:43 +0200 Subject: [PATCH 132/493] pass `Settings` by reference in checks (#8593) --- lib/check.h | 2 +- lib/check64bit.cpp | 12 +- lib/check64bit.h | 4 +- lib/checkassert.cpp | 10 +- lib/checkassert.h | 4 +- lib/checkautovariables.cpp | 52 +++--- lib/checkautovariables.h | 4 +- lib/checkbool.cpp | 32 ++-- lib/checkbool.h | 4 +- lib/checkbufferoverrun.cpp | 48 ++--- lib/checkbufferoverrun.h | 4 +- lib/checkclass.cpp | 132 +++++++------- lib/checkclass.h | 4 +- lib/checkcondition.cpp | 120 ++++++------- lib/checkcondition.h | 4 +- lib/checkexceptionsafety.cpp | 22 +-- lib/checkexceptionsafety.h | 4 +- lib/checkfunctions.cpp | 98 +++++----- lib/checkfunctions.h | 4 +- lib/checkimpl.cpp | 6 +- lib/checkimpl.h | 4 +- lib/checkinternal.cpp | 4 +- lib/checkinternal.h | 4 +- lib/checkio.cpp | 62 +++---- lib/checkio.h | 4 +- lib/checkleakautovar.cpp | 66 +++---- lib/checkleakautovar.h | 4 +- lib/checkmemoryleak.cpp | 80 ++++----- lib/checkmemoryleak.h | 18 +- lib/checknullpointer.cpp | 24 +-- lib/checknullpointer.h | 4 +- lib/checkother.cpp | 298 +++++++++++++++---------------- lib/checkother.h | 4 +- lib/checkpostfixoperator.cpp | 6 +- lib/checkpostfixoperator.h | 4 +- lib/checksizeof.cpp | 24 +-- lib/checksizeof.h | 4 +- lib/checkstl.cpp | 112 ++++++------ lib/checkstl.h | 4 +- lib/checkstring.cpp | 20 +-- lib/checkstring.h | 4 +- lib/checktype.cpp | 72 ++++---- lib/checktype.h | 4 +- lib/checkuninitvar.cpp | 34 ++-- lib/checkuninitvar.h | 4 +- lib/checkunusedvar.cpp | 40 ++--- lib/checkunusedvar.h | 4 +- lib/checkvaarg.cpp | 8 +- lib/checkvaarg.h | 4 +- lib/cppcheck.cpp | 2 +- test/test64bit.cpp | 2 +- test/testbufferoverrun.cpp | 2 +- test/testcharvar.cpp | 2 +- test/testclass.cpp | 38 ++-- test/testconstructors.cpp | 2 +- test/testincompletestatement.cpp | 2 +- test/testio.cpp | 2 +- test/testmemleak.cpp | 12 +- test/testother.cpp | 6 +- test/testpostfixoperator.cpp | 2 +- test/testuninitvar.cpp | 6 +- test/testunusedprivfunc.cpp | 2 +- test/testunusedvar.cpp | 8 +- 63 files changed, 791 insertions(+), 791 deletions(-) diff --git a/lib/check.h b/lib/check.h index 768cc889c62..019b77e148e 100644 --- a/lib/check.h +++ b/lib/check.h @@ -65,7 +65,7 @@ class CPPCHECKLIB Check { virtual void runChecks(const Tokenizer &, ErrorLogger *) = 0; /** get error messages */ - virtual void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const = 0; + virtual void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const = 0; /** class name, used to generate documentation */ const std::string& name() const { diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index e1e6f086ff3..6c45c68aaeb 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -36,12 +36,12 @@ // CWE ids used static const CWE CWE758(758U); // Reliance on Undefined, Unspecified, or Implementation-Defined Behavior -static bool is32BitIntegerReturn(const Function* func, const Settings* settings) +static bool is32BitIntegerReturn(const Function* func, const Settings& settings) { - if (settings->platform.sizeof_pointer != 8) + if (settings.platform.sizeof_pointer != 8) return false; const ValueType* vt = func->arg->valueType(); - return vt && vt->pointer == 0 && vt->isIntegral() && vt->getSizeOf(*settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer) == 4; + return vt && vt->pointer == 0 && vt->isIntegral() && vt->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer) == 4; } static bool isFunctionPointer(const Token* tok) @@ -53,7 +53,7 @@ static bool isFunctionPointer(const Token* tok) void Check64BitPortabilityImpl::pointerassignment() { - if (!mSettings->severity.isEnabled(Severity::portability)) + if (!mSettings.severity.isEnabled(Severity::portability)) return; logChecker("Check64BitPortability::pointerassignment"); // portability @@ -185,11 +185,11 @@ void Check64BitPortabilityImpl::returnIntegerError(const Token *tok) void Check64BitPortability::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - Check64BitPortabilityImpl check64BitPortability(&tokenizer, &tokenizer.getSettings(), errorLogger); + Check64BitPortabilityImpl check64BitPortability(&tokenizer, tokenizer.getSettings(), errorLogger); check64BitPortability.pointerassignment(); } -void Check64BitPortability::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void Check64BitPortability::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { Check64BitPortabilityImpl c(nullptr, settings, errorLogger); c.assignmentAddressToIntegerError(nullptr); diff --git a/lib/check64bit.h b/lib/check64bit.h index 1996d91ee23..160df94b990 100644 --- a/lib/check64bit.h +++ b/lib/check64bit.h @@ -51,7 +51,7 @@ class CPPCHECKLIB Check64BitPortability : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check if there is 64-bit portability issues:\n" @@ -63,7 +63,7 @@ class CPPCHECKLIB Check64BitPortability : public Check { class CPPCHECKLIB Check64BitPortabilityImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - Check64BitPortabilityImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + Check64BitPortabilityImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Check for pointer assignment */ diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index 5242b595e67..3ae06984c7b 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -41,7 +41,7 @@ static const CWE CWE398(398U); // Indicator of Poor Code Quality void CheckAssertImpl::assertWithSideEffects() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckAssert::assertWithSideEffects"); // warning @@ -58,7 +58,7 @@ void CheckAssertImpl::assertWithSideEffects() checkVariableAssignment(tmp, tok->scope()); if (tmp->tokType() != Token::eFunction) { - if (const Library::Function* f = mSettings->library.getFunction(tmp)) { + if (const Library::Function* f = mSettings.library.getFunction(tmp)) { if (f->isconst || f->ispure) continue; if (Library::getContainerYield(tmp->next()) != Library::Container::Yield::NO_YIELD) // bailout, assume read access @@ -73,7 +73,7 @@ void CheckAssertImpl::assertWithSideEffects() f->containerYield == Library::Container::Yield::END_ITERATOR || f->containerYield == Library::Container::Yield::ITERATOR) continue; - sideEffectInAssertError(tmp, mSettings->library.getFunctionName(tmp)); + sideEffectInAssertError(tmp, mSettings.library.getFunctionName(tmp)); } continue; } @@ -180,11 +180,11 @@ bool CheckAssertImpl::inSameScope(const Token* returnTok, const Token* assignTok void CheckAssert::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckAssertImpl checkAssert(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckAssertImpl checkAssert(&tokenizer, tokenizer.getSettings(), errorLogger); checkAssert.assertWithSideEffects(); } -void CheckAssert::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckAssert::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckAssertImpl c(nullptr, settings, errorLogger); c.sideEffectInAssertError(nullptr, "function"); diff --git a/lib/checkassert.h b/lib/checkassert.h index 3fac8f5af83..6a4e1f45de2 100644 --- a/lib/checkassert.h +++ b/lib/checkassert.h @@ -48,7 +48,7 @@ class CPPCHECKLIB CheckAssert : public Check { private: /** run checks, the token list is not simplified */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).\n"; @@ -57,7 +57,7 @@ class CPPCHECKLIB CheckAssert : public Check { class CPPCHECKLIB CheckAssertImpl : public CheckImpl { public: - CheckAssertImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckAssertImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} void assertWithSideEffects(); diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 0d3cae1c2fa..48ca74253a5 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -204,9 +204,9 @@ static bool variableIsUsedInScope(const Token* start, nonneg int varId, const Sc void CheckAutoVariablesImpl::assignFunctionArg() { - const bool printStyle = mSettings->severity.isEnabled(Severity::style); - const bool printWarning = mSettings->severity.isEnabled(Severity::warning); - if (!printStyle && !printWarning && !mSettings->isPremiumEnabled("uselessAssignmentPtrArg")) + const bool printStyle = mSettings.severity.isEnabled(Severity::style); + const bool printWarning = mSettings.severity.isEnabled(Severity::warning); + if (!printStyle && !printWarning && !mSettings.isPremiumEnabled("uselessAssignmentPtrArg")) return; logChecker("CheckAutoVariables::assignFunctionArg"); // style,warning @@ -284,7 +284,7 @@ void CheckAutoVariablesImpl::autoVariables() { logChecker("CheckAutoVariables::autoVariables"); - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) { @@ -295,27 +295,27 @@ void CheckAutoVariablesImpl::autoVariables() } // Critical assignment const Token* rhs{}; - if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2(), *mSettings)) { + if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2(), mSettings)) { checkAutoVariableAssignment(tok->next(), false); - } else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2(), *mSettings)) { + } else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2(), mSettings)) { const Token* lhs = tok->tokAt(2); bool inconclusive = false; if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive)) checkAutoVariableAssignment(tok->next(), inconclusive); tok = tok->tokAt(4); - } else if (isMemberAssignment(tok, rhs, *mSettings)) { + } else if (isMemberAssignment(tok, rhs, mSettings)) { const Token* lhs = tok->tokAt(3); bool inconclusive = false; if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive)) checkAutoVariableAssignment(tok->next(), inconclusive); tok = rhs; } else if (Token::Match(tok, "[;{}] %var% [") && Token::simpleMatch(tok->linkAt(2), "] =") && - (isPtrArg(tok->next()) || isArrayArg(tok->next(), *mSettings)) && - isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2(), *mSettings)) { + (isPtrArg(tok->next()) || isArrayArg(tok->next(), mSettings)) && + isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2(), mSettings)) { errorAutoVariableAssignment(tok->next(), false); } // Invalid pointer deallocation - else if ((Token::Match(tok, "%name% ( %var%|%str% ) ;") && mSettings->library.getDeallocFuncInfo(tok)) || + else if ((Token::Match(tok, "%name% ( %var%|%str% ) ;") && mSettings.library.getDeallocFuncInfo(tok)) || (tok->isCpp() && Token::Match(tok, "delete [| ]| (| %var%|%str% !!["))) { tok = Token::findmatch(tok->next(), "%var%|%str%"); if (Token::simpleMatch(tok->astParent(), ".")) @@ -333,7 +333,7 @@ void CheckAutoVariablesImpl::autoVariables() } } } - } else if ((Token::Match(tok, "%name% ( & %var% ) ;") && mSettings->library.getDeallocFuncInfo(tok)) || + } else if ((Token::Match(tok, "%name% ( & %var% ) ;") && mSettings.library.getDeallocFuncInfo(tok)) || (tok->isCpp() && Token::Match(tok, "delete [| ]| (| & %var% !!["))) { tok = Token::findmatch(tok->next(), "%var%"); if (isAutoVar(tok)) @@ -564,7 +564,7 @@ static bool isAssignedToNonLocal(const Token* tok) void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const Token * end) { - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); if (!start) return; const Scope * scope = start->scope(); @@ -577,7 +577,7 @@ void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const To for (const Token *tok = start; tok && tok != end; tok = tok->next()) { // Return reference from function if (returnRef && Token::simpleMatch(tok->astParent(), "return")) { - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok, *mSettings, true)) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok, mSettings, true)) { if (!printInconclusive && lt.inconclusive) continue; const Variable* var = lt.token->variable(); @@ -586,7 +586,7 @@ void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const To errorReturnReference(tok, lt.errorPath, lt.inconclusive); break; } - if (isDeadTemporary(lt.token, nullptr, mSettings->library)) { + if (isDeadTemporary(lt.token, nullptr, mSettings.library)) { errorReturnTempReference(tok, lt.errorPath, lt.inconclusive); break; } @@ -597,18 +597,18 @@ void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const To tok->variable()->declarationId() == tok->varId() && tok->variable()->isStatic() && !tok->variable()->isArgument()) { ErrorPath errorPath; - const Variable *var = ValueFlow::getLifetimeVariable(tok, errorPath, *mSettings); + const Variable *var = ValueFlow::getLifetimeVariable(tok, errorPath, mSettings); if (var && isInScope(var->nameToken(), tok->scope())) { errorDanglingReference(tok, var, std::move(errorPath)); continue; } // Reference to temporary } else if (tok->variable() && (tok->variable()->isReference() || tok->variable()->isRValueReference())) { - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(getParentLifetime(tok), *mSettings)) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(getParentLifetime(tok), mSettings)) { if (!printInconclusive && lt.inconclusive) continue; const Token * tokvalue = lt.token; - if (isDeadTemporary(tokvalue, tok, mSettings->library)) { + if (isDeadTemporary(tokvalue, tok, mSettings.library)) { errorDanglingTempReference(tok, lt.errorPath, lt.inconclusive); break; } @@ -622,23 +622,23 @@ void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const To continue; if (!printInconclusive && val.isInconclusive()) continue; - const Token* parent = getParentLifetime(val.tokvalue, mSettings->library); + const Token* parent = getParentLifetime(val.tokvalue, mSettings.library); if (!exprs.insert(parent).second) continue; - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(parent, *mSettings, escape || isAssignedToNonLocal(tok))) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(parent, mSettings, escape || isAssignedToNonLocal(tok))) { const Token * tokvalue = lt.token; if (val.isLocalLifetimeValue()) { if (escape) { if (getPointerDepth(tok) < getPointerDepth(tokvalue)) continue; - if (!ValueFlow::isLifetimeBorrowed(tok, *mSettings)) + if (!ValueFlow::isLifetimeBorrowed(tok, mSettings)) continue; if (tokvalue->exprId() == tok->exprId() && !(tok->variable() && tok->variable()->isArray()) && !astIsContainerView(tok->astParent())) continue; if ((tokvalue->variable() && !isEscapedReference(tokvalue->variable()) && isInScope(tokvalue->variable()->nameToken(), scope)) || - isDeadTemporary(tokvalue, nullptr, mSettings->library)) { + isDeadTemporary(tokvalue, nullptr, mSettings.library)) { if (!diag(tokvalue)) errorReturnDanglingLifetime(tok, &val); break; @@ -647,7 +647,7 @@ void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const To errorInvalidLifetime(tok, &val); break; } else if (!tokvalue->variable() && - isDeadTemporary(tokvalue, tok, mSettings->library)) { + isDeadTemporary(tokvalue, tok, mSettings.library)) { if (!diag(tokvalue)) errorDanglingTemporaryLifetime(tok, &val, tokvalue); break; @@ -665,7 +665,7 @@ void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const To } else if (tok->variable() && tok->variable()->declarationId() == tok->varId()) { var = tok->variable(); } - if (!ValueFlow::isLifetimeBorrowed(tok, *mSettings)) + if (!ValueFlow::isLifetimeBorrowed(tok, mSettings)) continue; const Token* nextTok = nextAfterAstRightmostLeaf(tok->astTop()); if (!nextTok) @@ -677,7 +677,7 @@ void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const To var->valueType() ? var->valueType()->pointer : 0, var->declarationId(), var->isGlobal(), - *mSettings)) { + mSettings)) { if (!diag(tok2)) errorDanglngLifetime(tok2, &val, var->isLocal()); break; @@ -819,13 +819,13 @@ void CheckAutoVariablesImpl::errorInvalidDeallocation(const Token *tok, const Va void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckAutoVariablesImpl checkAutoVariables(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckAutoVariablesImpl checkAutoVariables(&tokenizer, tokenizer.getSettings(), errorLogger); checkAutoVariables.assignFunctionArg(); checkAutoVariables.autoVariables(); checkAutoVariables.checkVarLifetime(); } -void CheckAutoVariables::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckAutoVariables::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckAutoVariablesImpl c(nullptr,settings,errorLogger); c.errorAutoVariableAssignment(nullptr, false); diff --git a/lib/checkautovariables.h b/lib/checkautovariables.h index 39e6ceb10d5..77deef00113 100644 --- a/lib/checkautovariables.h +++ b/lib/checkautovariables.h @@ -54,7 +54,7 @@ class CPPCHECKLIB CheckAutoVariables : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "A pointer to a variable is only valid as long as the variable is in scope.\n" @@ -72,7 +72,7 @@ class CPPCHECKLIB CheckAutoVariablesImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckAutoVariablesImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckAutoVariablesImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** assign function argument */ diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index e4f55f26085..a216307ad2e 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -45,7 +45,7 @@ static bool isBool(const Variable* var) //--------------------------------------------------------------------------- void CheckBoolImpl::checkIncrementBoolean() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("incrementboolean")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("incrementboolean")) return; logChecker("CheckBool::checkIncrementBoolean"); // style @@ -85,11 +85,11 @@ static bool isConvertedToBool(const Token* tok) //--------------------------------------------------------------------------- void CheckBoolImpl::checkBitwiseOnBoolean() { - if (!mSettings->isPremiumEnabled("bitwiseOnBoolean") && - !mSettings->severity.isEnabled(Severity::style) && + if (!mSettings.isPremiumEnabled("bitwiseOnBoolean") && + !mSettings.severity.isEnabled(Severity::style) && // danmar: this is inconclusive because I don't like that there are // warnings for calculations. Example: set_flag(a & b); - !mSettings->certainty.isEnabled(Certainty::inconclusive)) + !mSettings.certainty.isEnabled(Certainty::inconclusive)) return; logChecker("CheckBool::checkBitwiseOnBoolean"); // style,inconclusive @@ -116,7 +116,7 @@ void CheckBoolImpl::checkBitwiseOnBoolean() if (tok->str() == "|" && !isConvertedToBool(tok) && !(isBoolOp1 && isBoolOp2)) continue; // first operand will always be evaluated - if (!isConstExpression(tok->astOperand2(), mSettings->library)) + if (!isConstExpression(tok->astOperand2(), mSettings.library)) continue; if (tok->astOperand2()->variable() && tok->astOperand2()->variable()->nameToken() == tok->astOperand2()) continue; @@ -146,7 +146,7 @@ void CheckBoolImpl::bitwiseOnBooleanError(const Token* tok, const std::string& e void CheckBoolImpl::checkComparisonOfBoolWithInt() { - if (!mSettings->severity.isEnabled(Severity::warning) || !mTokenizer->isCPP()) + if (!mSettings.severity.isEnabled(Severity::warning) || !mTokenizer->isCPP()) return; logChecker("CheckBool::checkComparisonOfBoolWithInt"); // warning,c++ @@ -197,7 +197,7 @@ static bool tokenIsFunctionReturningBool(const Token* tok) void CheckBoolImpl::checkComparisonOfFuncReturningBool() { - if (!mSettings->severity.isEnabled(Severity::style)) + if (!mSettings.severity.isEnabled(Severity::style)) return; if (!mTokenizer->isCPP()) @@ -263,7 +263,7 @@ void CheckBoolImpl::comparisonOfTwoFuncsReturningBoolError(const Token *tok, con void CheckBoolImpl::checkComparisonOfBoolWithBool() { - if (!mSettings->severity.isEnabled(Severity::style)) + if (!mSettings.severity.isEnabled(Severity::style)) return; if (!mTokenizer->isCPP()) @@ -335,7 +335,7 @@ void CheckBoolImpl::assignBoolToPointerError(const Token *tok) //----------------------------------------------------------------------------- void CheckBoolImpl::checkComparisonOfBoolExpressionWithInt() { - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("compareBoolExpressionWithInt")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("compareBoolExpressionWithInt")) return; logChecker("CheckBool::checkComparisonOfBoolExpressionWithInt"); // warning @@ -373,13 +373,13 @@ void CheckBoolImpl::checkComparisonOfBoolExpressionWithInt() if (astIsBool(numTok)) continue; - const ValueFlow::Value *minval = numTok->getValueLE(0, *mSettings); + const ValueFlow::Value *minval = numTok->getValueLE(0, mSettings); if (minval && minval->intvalue == 0 && (numInRhs ? Token::Match(tok, ">|==|!=") : Token::Match(tok, "<|==|!="))) minval = nullptr; - const ValueFlow::Value *maxval = numTok->getValueGE(1, *mSettings); + const ValueFlow::Value *maxval = numTok->getValueGE(1, mSettings); if (maxval && maxval->intvalue == 1 && (numInRhs ? Token::Match(tok, "<|==|!=") : Token::Match(tok, ">|==|!="))) @@ -460,7 +460,7 @@ void CheckBoolImpl::checkAssignBoolToFloat() { if (!mTokenizer->isCPP()) return; - if (!mSettings->severity.isEnabled(Severity::style)) + if (!mSettings.severity.isEnabled(Severity::style)) return; logChecker("CheckBool::checkAssignBoolToFloat"); // style,c++ const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -481,7 +481,7 @@ void CheckBoolImpl::assignBoolToFloatError(const Token *tok) void CheckBoolImpl::returnValueOfFunctionReturningBool() { - if (!mSettings->severity.isEnabled(Severity::style)) + if (!mSettings.severity.isEnabled(Severity::style)) return; logChecker("CheckBool::returnValueOfFunctionReturningBool"); // style @@ -500,7 +500,7 @@ void CheckBoolImpl::returnValueOfFunctionReturningBool() else if (tok->scope() && tok->scope()->isClassOrStruct()) tok = tok->scope()->bodyEnd; else if (Token::simpleMatch(tok, "return") && tok->astOperand1() && - (tok->astOperand1()->getValueGE(2, *mSettings) || tok->astOperand1()->getValueLE(-1, *mSettings)) && + (tok->astOperand1()->getValueGE(2, mSettings) || tok->astOperand1()->getValueLE(-1, mSettings)) && !(tok->astOperand1()->astOperand1() && Token::Match(tok->astOperand1(), "&|%or%"))) returnValueBoolError(tok); } @@ -514,7 +514,7 @@ void CheckBoolImpl::returnValueBoolError(const Token *tok) void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckBoolImpl checkBool(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckBoolImpl checkBool(&tokenizer, tokenizer.getSettings(), errorLogger); // Checks checkBool.checkComparisonOfBoolExpressionWithInt(); @@ -529,7 +529,7 @@ void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkBool.checkBitwiseOnBoolean(); } -void CheckBool::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckBool::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckBoolImpl c(nullptr, settings, errorLogger); c.assignBoolToPointerError(nullptr); diff --git a/lib/checkbool.h b/lib/checkbool.h index 607d9c4a4b7..2d523732682 100644 --- a/lib/checkbool.h +++ b/lib/checkbool.h @@ -48,7 +48,7 @@ class CPPCHECKLIB CheckBool : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Boolean type checks\n" @@ -67,7 +67,7 @@ class CPPCHECKLIB CheckBoolImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckBoolImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckBoolImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for comparison of function returning bool*/ diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 592e4268f58..7f0612963b9 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -323,7 +323,7 @@ void CheckBufferOverrunImpl::arrayIndex() ErrorPath errorPath; bool mightBeLarger = false; MathLib::bigint path = 0; - if (!getDimensionsEtc(tok->astOperand1(), *mSettings, dimensions, errorPath, mightBeLarger, path)) + if (!getDimensionsEtc(tok->astOperand1(), mSettings, dimensions, errorPath, mightBeLarger, path)) continue; const Variable* const var = array->variable(); @@ -331,7 +331,7 @@ void CheckBufferOverrunImpl::arrayIndex() const Token* changeTok = var->scope()->bodyStart; bool isChanged = false; while ((changeTok = findVariableChanged(changeTok->next(), var->scope()->bodyEnd, /*indirect*/ 0, var->declarationId(), - /*globalvar*/ false, *mSettings))) { + /*globalvar*/ false, mSettings))) { if (!Token::simpleMatch(changeTok->astParent(), "[")) { isChanged = true; break; @@ -353,7 +353,7 @@ void CheckBufferOverrunImpl::arrayIndex() bool neg = false; std::vector negativeIndexes; for (const Token * indexToken : indexTokens) { - const ValueFlow::Value *negativeValue = indexToken->getValueLE(-1, *mSettings); + const ValueFlow::Value *negativeValue = indexToken->getValueLE(-1, mSettings); if (negativeValue) { negativeIndexes.emplace_back(*negativeValue); neg = true; @@ -418,7 +418,7 @@ void CheckBufferOverrunImpl::arrayIndexError(const Token* tok, const Token *condition = nullptr; const ValueFlow::Value *index = nullptr; for (const ValueFlow::Value& indexValue : indexes) { - if (!indexValue.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning)) + if (!indexValue.errorSeverity() && !mSettings.severity.isEnabled(Severity::warning)) return; if (indexValue.condition) condition = indexValue.condition; @@ -446,7 +446,7 @@ void CheckBufferOverrunImpl::negativeIndexError(const Token* tok, const Token *condition = nullptr; const ValueFlow::Value *negativeValue = nullptr; for (const ValueFlow::Value& indexValue : indexes) { - if (!indexValue.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning)) + if (!indexValue.errorSeverity() && !mSettings.severity.isEnabled(Severity::warning)) return; if (indexValue.condition) condition = indexValue.condition; @@ -466,7 +466,7 @@ void CheckBufferOverrunImpl::negativeIndexError(const Token* tok, void CheckBufferOverrunImpl::pointerArithmetic() { - if (!mSettings->severity.isEnabled(Severity::portability) && !mSettings->isPremiumEnabled("pointerOutOfBounds")) + if (!mSettings.severity.isEnabled(Severity::portability) && !mSettings.isPremiumEnabled("pointerOutOfBounds")) return; logChecker("CheckBufferOverrun::pointerArithmetic"); // portability @@ -497,7 +497,7 @@ void CheckBufferOverrunImpl::pointerArithmetic() ErrorPath errorPath; bool mightBeLarger = false; MathLib::bigint path = 0; - if (!getDimensionsEtc(arrayToken, *mSettings, dimensions, errorPath, mightBeLarger, path)) + if (!getDimensionsEtc(arrayToken, mSettings, dimensions, errorPath, mightBeLarger, path)) continue; if (tok->str() == "+") { @@ -510,7 +510,7 @@ void CheckBufferOverrunImpl::pointerArithmetic() pointerArithmeticError(tok, indexToken, &indexValues.front()); } - if (const ValueFlow::Value *neg = indexToken->getValueLE(-1, *mSettings)) + if (const ValueFlow::Value *neg = indexToken->getValueLE(-1, mSettings)) pointerArithmeticError(tok, indexToken, neg); } else if (tok->str() == "-") { if (arrayToken->variable() && arrayToken->variable()->isArgument()) @@ -520,7 +520,7 @@ void CheckBufferOverrunImpl::pointerArithmetic() while (Token::Match(array, ".|::")) array = array->astOperand2(); if (array->variable() && array->variable()->isArray()) { - const ValueFlow::Value *v = indexToken->getValueGE(1, *mSettings); + const ValueFlow::Value *v = indexToken->getValueGE(1, mSettings); if (v) pointerArithmeticError(tok, indexToken, v); } @@ -578,9 +578,9 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons v.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE; if (var->isPointerArray()) - v.intvalue = dim * mSettings->platform.sizeof_pointer; + v.intvalue = dim * mSettings.platform.sizeof_pointer; else { - const size_t typeSize = bufTok->valueType()->getSizeOf(*mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee); + const size_t typeSize = bufTok->valueType()->getSizeOf(mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee); v.intvalue = dim * typeSize; } @@ -643,13 +643,13 @@ void CheckBufferOverrunImpl::bufferOverflow() for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { if (!Token::Match(tok, "%name% (") || Token::simpleMatch(tok, ") {")) continue; - if (!mSettings->library.hasminsize(tok)) + if (!mSettings.library.hasminsize(tok)) continue; const std::vector args = getArguments(tok); for (int argnr = 0; argnr < args.size(); ++argnr) { if (!args[argnr]->valueType() || args[argnr]->valueType()->pointer == 0) continue; - const std::vector *minsizes = mSettings->library.argminsizes(tok, argnr + 1); + const std::vector *minsizes = mSettings.library.argminsizes(tok, argnr + 1); if (!minsizes || minsizes->empty()) continue; // Get buffer size.. @@ -682,7 +682,7 @@ void CheckBufferOverrunImpl::bufferOverflow() } } const bool error = std::none_of(minsizes->begin(), minsizes->end(), [&](const Library::ArgumentChecks::MinSize &minsize) { - return checkBufferSize(tok, minsize, args, bufferSize.intvalue, *mSettings, mTokenizer); + return checkBufferSize(tok, minsize, args, bufferSize.intvalue, mSettings, mTokenizer); }); if (error) bufferOverflowError(args[argnr], &bufferSize, Certainty::normal); @@ -700,7 +700,7 @@ void CheckBufferOverrunImpl::bufferOverflowError(const Token *tok, const ValueFl void CheckBufferOverrunImpl::arrayIndexThenCheck() { - if (!mSettings->severity.isEnabled(Severity::style)) + if (!mSettings.severity.isEnabled(Severity::style)) return; logChecker("CheckBufferOverrun::arrayIndexThenCheck"); // style @@ -758,7 +758,7 @@ void CheckBufferOverrunImpl::arrayIndexThenCheckError(const Token *tok, const st void CheckBufferOverrunImpl::stringNotZeroTerminated() { // this is currently 'inconclusive'. See TestBufferOverrun::terminateStrncpy3 - if (!mSettings->severity.isEnabled(Severity::warning) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (!mSettings.severity.isEnabled(Severity::warning) || !mSettings.certainty.isEnabled(Certainty::inconclusive)) return; logChecker("CheckBufferOverrun::stringNotZeroTerminated"); // warning,inconclusive @@ -797,7 +797,7 @@ void CheckBufferOverrunImpl::stringNotZeroTerminated() const Token *rhs = tok2->next()->astOperand2(); if (!rhs || !rhs->hasKnownIntValue() || rhs->getKnownIntValue() != 0) continue; - if (isSameExpression(false, args[0], tok2->link()->astOperand1(), *mSettings, false, false)) + if (isSameExpression(false, args[0], tok2->link()->astOperand1(), mSettings, false, false)) isZeroTerminated = true; } if (isZeroTerminated) @@ -824,7 +824,7 @@ void CheckBufferOverrunImpl::terminateStrncpyError(const Token *tok, const std:: void CheckBufferOverrunImpl::argumentSize() { // Check '%type% x[10]' arguments - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("argumentSize")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("argumentSize")) return; logChecker("CheckBufferOverrun::argumentSize"); // warning @@ -990,7 +990,7 @@ Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLEle /** @brief Analyse all file infos for all TU */ bool CheckBufferOverrun::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) { - CheckBufferOverrunImpl dummy(nullptr, &settings, &errorLogger); + CheckBufferOverrunImpl dummy(nullptr, settings, &errorLogger); dummy. logChecker("CheckBufferOverrun::analyseWholeProgram"); @@ -1096,7 +1096,7 @@ void CheckBufferOverrunImpl::objectIndex() continue; } if (obj->valueType() && var->valueType() && (obj->isCast() || (obj->isCpp() && isCPPCast(obj)) || obj->valueType()->pointer)) { // allow cast to a different type - const auto varSize = var->valueType()->getSizeOf(*mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee); + const auto varSize = var->valueType()->getSizeOf(mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee); if (varSize == 0) continue; if (obj->valueType()->type != var->valueType()->type) { @@ -1176,7 +1176,7 @@ void CheckBufferOverrunImpl::negativeArraySize() const Token* const nameToken = var->nameToken(); if (!Token::Match(nameToken, "%var% [") || !nameToken->next()->astOperand2()) continue; - const ValueFlow::Value* sz = nameToken->next()->astOperand2()->getValueLE(-1, *mSettings); + const ValueFlow::Value* sz = nameToken->next()->astOperand2()->getValueLE(-1, mSettings); // don't warn about constant negative index because that is a compiler error if (sz && isVLAIndex(nameToken->next()->astOperand2())) negativeArraySizeError(nameToken); @@ -1189,7 +1189,7 @@ void CheckBufferOverrunImpl::negativeArraySize() const Token* valOperand = tok->astOperand1()->astOperand2(); if (!valOperand) continue; - const ValueFlow::Value* sz = valOperand->getValueLE(-1, *mSettings); + const ValueFlow::Value* sz = valOperand->getValueLE(-1, mSettings); if (sz) negativeMemoryAllocationSizeError(tok, sz); } @@ -1216,7 +1216,7 @@ void CheckBufferOverrunImpl::negativeMemoryAllocationSizeError(const Token* tok, void CheckBufferOverrun::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckBufferOverrunImpl checkBufferOverrun(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckBufferOverrunImpl checkBufferOverrun(&tokenizer, tokenizer.getSettings(), errorLogger); checkBufferOverrun.arrayIndex(); checkBufferOverrun.pointerArithmetic(); checkBufferOverrun.bufferOverflow(); @@ -1227,7 +1227,7 @@ void CheckBufferOverrun::runChecks(const Tokenizer &tokenizer, ErrorLogger *erro checkBufferOverrun.negativeArraySize(); } -void CheckBufferOverrun::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckBufferOverrun::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckBufferOverrunImpl c(nullptr, settings, errorLogger); c.arrayIndexError(nullptr, std::vector(), std::vector()); diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index fdf47121bb8..2b43d575dec 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -72,7 +72,7 @@ class CPPCHECKLIB CheckBufferOverrun : public Check { /** @brief Analyse all file infos for all TU */ bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; @@ -96,7 +96,7 @@ class CPPCHECKLIB CheckBufferOverrunImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckBufferOverrunImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckBufferOverrunImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} void arrayIndex(); diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index c5b8507f301..d7eb9b43b35 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -106,7 +106,7 @@ static bool isVclTypeInit(const Type *type) } //--------------------------------------------------------------------------- -CheckClassImpl::CheckClassImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) +CheckClassImpl::CheckClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger), mSymbolDatabase(tokenizer?tokenizer->getSymbolDatabase():nullptr) {} @@ -140,7 +140,7 @@ bool CheckClassImpl::isInitialized(const Usage& usage, FunctionType funcType) co const Token* ctt = var.valueType()->containerTypeToken; if (!ctt->isStandardType() && (!ctt->type() || ctt->type()->needInitialization != Type::NeedInitialization::True) && - !mSettings->library.podtype(ctt->str())) // TODO: handle complex type expression + !mSettings.library.podtype(ctt->str())) // TODO: handle complex type expression return true; } else @@ -201,16 +201,16 @@ void CheckClassImpl::handleUnionMembers(std::vector& usageList) void CheckClassImpl::constructors() { - const bool printStyle = mSettings->severity.isEnabled(Severity::style); - const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); - if (!printStyle && !printWarnings && !mSettings->isPremiumEnabled("uninitMemberVar")) + const bool printStyle = mSettings.severity.isEnabled(Severity::style); + const bool printWarnings = mSettings.severity.isEnabled(Severity::warning); + if (!printStyle && !printWarnings && !mSettings.isPremiumEnabled("uninitMemberVar")) return; logChecker("CheckClass::checkConstructors"); // style,warning - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { - if (mSettings->hasLib("vcl") && isVclTypeInit(scope->definedType)) + if (mSettings.hasLib("vcl") && isVclTypeInit(scope->definedType)) continue; const bool unusedTemplate = Token::simpleMatch(scope->classDef->previous(), ">"); @@ -315,9 +315,9 @@ void CheckClassImpl::constructors() } } - if (classNameUsed && mSettings->library.getTypeCheck("operatorEqVarError", var.getTypeName()) != Library::TypeCheck::suppress) + if (classNameUsed && mSettings.library.getTypeCheck("operatorEqVarError", var.getTypeName()) != Library::TypeCheck::suppress) operatorEqVarError(func.token, scope->className, var.name(), missingCopy); - } else if (func.access != AccessControl::Private || mSettings->standards.cpp >= Standards::CPP11) { + } else if (func.access != AccessControl::Private || mSettings.standards.cpp >= Standards::CPP11) { // If constructor is not in scope then we maybe using a constructor from a different template specialization if (!precedes(scope->bodyStart, func.tokenDef)) continue; @@ -347,7 +347,7 @@ void CheckClassImpl::constructors() // Variables with default initializers bool hasAnyDefaultInit = false; bool hasAnySelfInit = false; - const bool cpp14OrLater = mSettings->standards.cpp >= Standards::CPP14; + const bool cpp14OrLater = mSettings.standards.cpp >= Standards::CPP14; for (Usage& usage : usageList) { const Variable& var = *usage.var; @@ -387,7 +387,7 @@ static bool isPermissibleConversion(const std::string& type) void CheckClassImpl::checkExplicitConstructors() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("noExplicitConstructor")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("noExplicitConstructor")) return; logChecker("CheckClass::checkExplicitConstructors"); // style @@ -405,7 +405,7 @@ void CheckClassImpl::checkExplicitConstructors() // Abstract classes can't be instantiated. But if there is C++11 // "misuse" by derived classes then these constructors must be explicit. - if (isAbstractClass && mSettings->standards.cpp >= Standards::CPP11) + if (isAbstractClass && mSettings.standards.cpp >= Standards::CPP11) continue; for (const Function &func : scope->functionList) { @@ -456,7 +456,7 @@ static bool hasNonCopyableBase(const Scope *scope, bool *unknown) void CheckClassImpl::copyconstructors() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckClass::checkCopyConstructors"); // warning @@ -471,7 +471,7 @@ void CheckClassImpl::copyconstructors() const Token* tok = func.token->linkAt(1); for (const Token* const end = func.functionScope->bodyStart; tok != end; tok = tok->next()) { if (Token::Match(tok, "%var% ( new") || - (Token::Match(tok, "%var% ( %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)))) { + (Token::Match(tok, "%var% ( %name% (") && mSettings.library.getAllocFuncInfo(tok->tokAt(2)))) { const Variable* var = tok->variable(); if (var && var->isPointer() && var->scope() == scope) allocatedVars[tok->varId()] = tok; @@ -479,7 +479,7 @@ void CheckClassImpl::copyconstructors() } for (const Token* const end = func.functionScope->bodyEnd; tok != end; tok = tok->next()) { if (Token::Match(tok, "%var% = new") || - (Token::Match(tok, "%var% = %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)))) { + (Token::Match(tok, "%var% = %name% (") && mSettings.library.getAllocFuncInfo(tok->tokAt(2)))) { const Variable* var = tok->variable(); if (var && var->isPointer() && var->scope() == scope && !var->isStatic()) allocatedVars[tok->varId()] = tok; @@ -490,7 +490,7 @@ void CheckClassImpl::copyconstructors() const Token* tok = func.functionScope->bodyStart; for (const Token* const end = func.functionScope->bodyEnd; tok != end; tok = tok->next()) { if (Token::Match(tok, "delete %var%") || - (Token::Match(tok, "%name% ( %var%") && mSettings->library.getDeallocFuncInfo(tok))) { + (Token::Match(tok, "%name% ( %var%") && mSettings.library.getDeallocFuncInfo(tok))) { const Token *vartok = tok->str() == "delete" ? tok->next() : tok->tokAt(2); const Variable* var = vartok->variable(); if (var && var->isPointer() && var->scope() == scope && !var->isStatic()) @@ -580,7 +580,7 @@ void CheckClassImpl::copyconstructors() } for (tok = func.functionScope->bodyStart; tok != func.functionScope->bodyEnd; tok = tok->next()) { if ((tok->isCpp() && Token::Match(tok, "%var% = new")) || - (Token::Match(tok, "%var% = %name% (") && (mSettings->library.getAllocFuncInfo(tok->tokAt(2)) || mSettings->library.getReallocFuncInfo(tok->tokAt(2))))) { + (Token::Match(tok, "%var% = %name% (") && (mSettings.library.getAllocFuncInfo(tok->tokAt(2)) || mSettings.library.getReallocFuncInfo(tok->tokAt(2))))) { allocatedVars.erase(tok->varId()); } else if (Token::Match(tok, "%var% = %name% . %name% ;") && allocatedVars.find(tok->varId()) != allocatedVars.end()) { copiedVars.insert(tok); @@ -1059,7 +1059,7 @@ void CheckClassImpl::initializeVarList(const Function &func, std::listnext(); if (tok2->str() == "&") tok2 = tok2->next(); - if (isVariableChangedByFunctionCall(tok2, tok2->strAt(-1) == "&", tok2->varId(), *mSettings, nullptr)) + if (isVariableChangedByFunctionCall(tok2, tok2->strAt(-1) == "&", tok2->varId(), mSettings, nullptr)) assignVar(usage, tok2->varId()); } } @@ -1218,7 +1218,7 @@ void CheckClassImpl::operatorEqVarError(const Token *tok, const std::string &cla void CheckClassImpl::initializationListUsage() { - if (!mSettings->severity.isEnabled(Severity::performance)) + if (!mSettings.severity.isEnabled(Severity::performance)) return; logChecker("CheckClass::initializationListUsage"); // performance @@ -1279,7 +1279,7 @@ void CheckClassImpl::initializationListUsage() allowed = false; return ChildrenToVisit::done; } - if (var2->isLocal() && isVariableChanged(var2->nameToken(), previousBeforeAstLeftmostLeaf(tok), var2->declarationId(), /*globalvar*/ false, *mSettings)) { + if (var2->isLocal() && isVariableChanged(var2->nameToken(), previousBeforeAstLeftmostLeaf(tok), var2->declarationId(), /*globalvar*/ false, mSettings)) { allowed = false; return ChildrenToVisit::done; } @@ -1364,7 +1364,7 @@ static bool checkFunctionUsage(const Function *privfunc, const Scope* scope) void CheckClassImpl::privateFunctions() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedPrivateFunction")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedPrivateFunction")) return; logChecker("CheckClass::privateFunctions"); // style @@ -1447,7 +1447,7 @@ static const Scope* findFunctionOf(const Scope* scope) void CheckClassImpl::checkMemset() { logChecker("CheckClass::checkMemset"); - const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); + const bool printWarnings = mSettings.severity.isEnabled(Severity::warning); for (const Scope *scope : mSymbolDatabase->functionScopes) { for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) { if (Token::Match(tok, "memset|memcpy|memmove (")) { @@ -1505,7 +1505,7 @@ void CheckClassImpl::checkMemset() type = var->typeScope(); if (!type && !var->isPointer() && !Token::simpleMatch(var->typeStartToken(), "std :: array") && - mSettings->library.detectContainerOrIterator(var->typeStartToken())) { + mSettings.library.detectContainerOrIterator(var->typeStartToken())) { memsetError(tok, tok->str(), var->getTypeName(), {}, /*isContainer*/ true); } } @@ -1525,9 +1525,9 @@ void CheckClassImpl::checkMemset() checkMemsetType(scope, tok, type, false, {}); } } else if (tok->variable() && tok->variable()->isPointer() && tok->variable()->typeScope() && Token::Match(tok, "%var% = %name% (")) { - const Library::AllocFunc* alloc = mSettings->library.getAllocFuncInfo(tok->tokAt(2)); + const Library::AllocFunc* alloc = mSettings.library.getAllocFuncInfo(tok->tokAt(2)); if (!alloc) - alloc = mSettings->library.getReallocFuncInfo(tok->tokAt(2)); + alloc = mSettings.library.getReallocFuncInfo(tok->tokAt(2)); if (!alloc || alloc->bufferSize == Library::AllocFunc::BufferSize::none) continue; std::set parsedTypes; @@ -1547,7 +1547,7 @@ void CheckClassImpl::checkMemsetType(const Scope *start, const Token *tok, const return; parsedTypes.insert(type); - const bool printPortability = mSettings->severity.isEnabled(Severity::portability); + const bool printPortability = mSettings.severity.isEnabled(Severity::portability); // recursively check all parent classes for (const Type::BaseInfo & i : type->definedType->derivedFrom) { @@ -1588,7 +1588,7 @@ void CheckClassImpl::checkMemsetType(const Scope *start, const Token *tok, const } // check for std:: type - if (var.isStlType() && typeName != "std::array" && !mSettings->library.podtype(typeName)) { + if (var.isStlType() && typeName != "std::array" && !mSettings.library.podtype(typeName)) { if (allocation) mallocOnClassError(tok, tok->str(), type->classDef, "'" + typeName + "'"); else @@ -1663,7 +1663,7 @@ void CheckClassImpl::memsetErrorFloat(const Token *tok, const std::string &type) void CheckClassImpl::operatorEqRetRefThis() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("operatorEqRetRefThis")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("operatorEqRetRefThis")) return; logChecker("CheckClass::operatorEqRetRefThis"); // style @@ -1762,7 +1762,7 @@ void CheckClassImpl::checkReturnPtrThis(const Scope *scope, const Function *func } return; } - if (mSettings->library.isScopeNoReturn(last, nullptr)) { + if (mSettings.library.isScopeNoReturn(last, nullptr)) { // Typical wrong way to prohibit default assignment operator // by always throwing an exception or calling a noreturn function operatorEqShouldBeLeftUnimplementedError(func->token); @@ -1807,7 +1807,7 @@ void CheckClassImpl::operatorEqMissingReturnStatementError(const Token *tok, boo void CheckClassImpl::operatorEqToSelf() { - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("operatorEqToSelf")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("operatorEqToSelf")) return; logChecker("CheckClass::operatorEqToSelf"); // warning @@ -1867,13 +1867,13 @@ bool CheckClassImpl::hasAllocation(const Function *func, const Scope* scope, con end = func->functionScope->bodyEnd; for (const Token *tok = start; tok && (tok != end); tok = tok->next()) { if (((tok->isCpp() && Token::Match(tok, "%var% = new")) || - (Token::Match(tok, "%var% = %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)))) && + (Token::Match(tok, "%var% = %name% (") && mSettings.library.getAllocFuncInfo(tok->tokAt(2)))) && isMemberVar(scope, tok)) return true; // check for deallocating memory const Token *var; - if (Token::Match(tok, "%name% ( %var%") && mSettings->library.getDeallocFuncInfo(tok)) + if (Token::Match(tok, "%name% ( %var%") && mSettings.library.getDeallocFuncInfo(tok)) var = tok->tokAt(2); else if (tok->isCpp() && Token::Match(tok, "delete [ ] %var%")) var = tok->tokAt(3); @@ -2006,7 +2006,7 @@ void CheckClassImpl::virtualDestructor() // * base class is deleted // unless inconclusive in which case: // * A class with any virtual functions should have a destructor that is either public and virtual or protected - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); std::list inconclusiveErrors; @@ -2029,7 +2029,7 @@ void CheckClassImpl::virtualDestructor() } // Check if destructor is empty and non-empty .. - if (mSettings->standards.cpp <= Standards::CPP03) { + if (mSettings.standards.cpp <= Standards::CPP03) { // Find the destructor const Function *destructor = scope->getDestructor(); @@ -2136,7 +2136,7 @@ void CheckClassImpl::virtualDestructor() void CheckClassImpl::virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived, bool inconclusive) { if (inconclusive) { - if (mSettings->severity.isEnabled(Severity::warning)) + if (mSettings.severity.isEnabled(Severity::warning)) reportError(tok, Severity::warning, "virtualDestructor", "$symbol:" + Base + "\nClass '$symbol' which has virtual members does not have a virtual destructor.", CWE404, Certainty::inconclusive); } else { reportError(tok, Severity::error, "virtualDestructor", @@ -2156,7 +2156,7 @@ void CheckClassImpl::virtualDestructorError(const Token *tok, const std::string void CheckClassImpl::thisSubtraction() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckClass::thisSubtraction"); // warning @@ -2185,9 +2185,9 @@ void CheckClassImpl::thisSubtractionError(const Token *tok) void CheckClassImpl::checkConst() { - if (!mSettings->severity.isEnabled(Severity::style) && - !mSettings->isPremiumEnabled("functionConst") && - !mSettings->isPremiumEnabled("functionStatic")) + if (!mSettings.severity.isEnabled(Severity::style) && + !mSettings.isPremiumEnabled("functionConst") && + !mSettings.isPremiumEnabled("functionStatic")) return; logChecker("CheckClass::checkConst"); // style,inconclusive @@ -2248,7 +2248,7 @@ void CheckClassImpl::checkConst() const std::string& opName = func.tokenDef->str(); if (opName.compare(8, 5, "const") != 0 && (endsWith(opName,'&') || endsWith(opName,'*'))) continue; - } else if (mSettings->library.isSmartPointer(func.retDef)) { + } else if (mSettings.library.isSmartPointer(func.retDef)) { // Don't warn if a std::shared_ptr etc is returned continue; } else { @@ -2271,7 +2271,7 @@ void CheckClassImpl::checkConst() const bool suggestStatic = memberAccessed != MemberAccess::MEMBER && !func.isOperator(); if ((returnsPtrOrRef || func.isConst() || func.hasLvalRefQualifier()) && !suggestStatic) continue; - if (!suggestStatic && !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (!suggestStatic && !mSettings.certainty.isEnabled(Certainty::inconclusive)) // functionConst is inconclusive. False positives: #3322. continue; if (suggestStatic && func.isConst()) { @@ -2535,7 +2535,7 @@ bool CheckClassImpl::checkConstFunc(const Scope *scope, const Function *func, Me return true; } - if (const Library::Function* fLib = mSettings->library.getFunction(funcTok)) + if (const Library::Function* fLib = mSettings.library.getFunction(funcTok)) if (fLib->isconst || fLib->ispure) return true; @@ -2696,12 +2696,12 @@ bool CheckClassImpl::checkConstFunc(const Scope *scope, const Function *func, Me } else if (var->smartPointerType() && var->smartPointerType()->classScope && isConstMemberFunc(var->smartPointerType()->classScope, end)) { // empty body - } else if (var->isSmartPointer() && Token::simpleMatch(tok1->next(), ".") && tok1->next()->originalName().empty() && mSettings->library.isFunctionConst(end)) { + } else if (var->isSmartPointer() && Token::simpleMatch(tok1->next(), ".") && tok1->next()->originalName().empty() && mSettings.library.isFunctionConst(end)) { // empty body } else if (hasOverloadedMemberAccess(end, var->typeScope())) { // empty body } else if (!var->typeScope() || (end->function() != func && !isConstMemberFunc(var->typeScope(), end))) { - if (!mSettings->library.isFunctionConst(end)) + if (!mSettings.library.isFunctionConst(end)) return false; } } @@ -2806,15 +2806,15 @@ namespace { // avoid one-definition-rule violation void CheckClassImpl::initializerListOrder() { - if (!mSettings->isPremiumEnabled("initializerList")) { - if (!mSettings->severity.isEnabled(Severity::style)) + if (!mSettings.isPremiumEnabled("initializerList")) { + if (!mSettings.severity.isEnabled(Severity::style)) return; // This check is not inconclusive. However it only determines if the initialization // order is incorrect. It does not determine if being out of order causes // a real error. Out of order is not necessarily an error but you can never // have an error if the list is in order so this enforces defensive programming. - if (!mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (!mSettings.certainty.isEnabled(Certainty::inconclusive)) return; } @@ -2945,7 +2945,7 @@ void CheckClassImpl::selfInitializationError(const Token* tok, const std::string void CheckClassImpl::checkVirtualFunctionCallInConstructor() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckClass::checkVirtualFunctionCallInConstructor"); // warning std::map> virtualFunctionCallsMap; @@ -3012,8 +3012,8 @@ const std::list & CheckClassImpl::getVirtualFunctionCalls(const F tok->strAt(-1) == "(") { const Token * prev = tok->previous(); if (prev->previous() && - (mSettings->library.ignorefunction(tok->str()) - || mSettings->library.ignorefunction(prev->strAt(-1)))) + (mSettings.library.ignorefunction(tok->str()) + || mSettings.library.ignorefunction(prev->strAt(-1)))) continue; } @@ -3056,7 +3056,7 @@ void CheckClassImpl::virtualFunctionCallInConstructorError( const std::list & tokStack, const std::string &funcname) { - if (scopeFunction && !mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("virtualCallInConstructor")) + if (scopeFunction && !mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("virtualCallInConstructor")) return; const char * scopeFunctionTypeName = scopeFunction ? getFunctionTypeName(scopeFunction->type) : "constructor"; @@ -3116,7 +3116,7 @@ void CheckClassImpl::pureVirtualFunctionCallInConstructorError( void CheckClassImpl::checkDuplInheritedMembers() { - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("duplInheritedMember")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("duplInheritedMember")) return; logChecker("CheckClass::checkDuplInheritedMembers"); // warning @@ -3254,7 +3254,7 @@ void CheckClassImpl::checkCopyCtorAndEqOperator() { // TODO: This is disabled because of #8388 // The message must be clarified. How is the behaviour different? - if ((true) || !mSettings->severity.isEnabled(Severity::warning)) // NOLINT(readability-simplify-boolean-expr,readability-redundant-parentheses) + if ((true) || !mSettings.severity.isEnabled(Severity::warning)) // NOLINT(readability-simplify-boolean-expr,readability-redundant-parentheses) return; // logChecker @@ -3314,9 +3314,9 @@ void CheckClassImpl::copyCtorAndEqOperatorError(const Token *tok, const std::str void CheckClassImpl::checkOverride() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("missingOverride")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("missingOverride")) return; - if (mSettings->standards.cpp < Standards::CPP11) + if (mSettings.standards.cpp < Standards::CPP11) return; logChecker("CheckClass::checkMissingOverride"); // style,c++03 for (const Scope * classScope : mSymbolDatabase->classAndStructScopes) { @@ -3420,7 +3420,7 @@ static bool compareTokenRanges(const Token* start1, const Token* end1, const Tok void CheckClassImpl::checkUselessOverride() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("uselessOverride")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("uselessOverride")) return; logChecker("CheckClass::checkUselessOverride"); // style @@ -3501,7 +3501,7 @@ static const Variable* getSingleReturnVar(const Scope* scope) { void CheckClassImpl::checkReturnByReference() { - if (!mSettings->severity.isEnabled(Severity::performance) && !mSettings->isPremiumEnabled("returnByReference")) + if (!mSettings.severity.isEnabled(Severity::performance) && !mSettings.isPremiumEnabled("returnByReference")) return; logChecker("CheckClass::checkReturnByReference"); // performance @@ -3516,7 +3516,7 @@ void CheckClassImpl::checkReturnByReference() continue; if (func.functionPointerUsage) continue; - if (const Library::Container* container = mSettings->library.detectContainer(func.retDef)) + if (const Library::Container* container = mSettings.library.detectContainer(func.retDef)) if (container->view) continue; if (!func.isConst() && func.hasRvalRefQualifier()) @@ -3531,8 +3531,8 @@ void CheckClassImpl::checkReturnByReference() const bool isView = isContainer && var->valueType()->container->view; bool warn = isContainer && !isView; if (!warn && !isView) { - const std::size_t size = var->valueType()->getSizeOf(*mSettings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer); - if (size > 2 * mSettings->platform.sizeof_pointer) + const std::size_t size = var->valueType()->getSizeOf(mSettings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer); + if (size > 2 * mSettings.platform.sizeof_pointer) warn = true; } if (warn) @@ -3551,7 +3551,7 @@ void CheckClassImpl::returnByReferenceError(const Function* func, const Variable void CheckClassImpl::checkThisUseAfterFree() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckClass::checkThisUseAfterFree"); // warning @@ -3561,7 +3561,7 @@ void CheckClassImpl::checkThisUseAfterFree() for (const Variable &var : classScope->varlist) { // Find possible "self pointer".. pointer/smartpointer member variable of "self" type. if (var.valueType() && var.valueType()->smartPointerType != classScope->definedType && var.valueType()->typeScope != classScope) { - const ValueType valueType = ValueType::parseDecl(var.typeStartToken(), *mSettings); + const ValueType valueType = ValueType::parseDecl(var.typeStartToken(), mSettings); if (valueType.smartPointerType != classScope->definedType) continue; } @@ -3651,7 +3651,7 @@ void CheckClassImpl::thisUseAfterFree(const Token *self, const Token *free, cons void CheckClassImpl::checkUnsafeClassRefMember() { - if (!mSettings->safeChecks.classes || !mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.safeChecks.classes || !mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckClass::checkUnsafeClassRefMember"); // warning,safeChecks for (const Scope * classScope : mSymbolDatabase->classAndStructScopes) { @@ -3833,7 +3833,7 @@ bool CheckClass::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check the code for each class.\n" @@ -100,7 +100,7 @@ class CPPCHECKLIB CheckClass : public Check { class CPPCHECKLIB CheckClassImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckClassImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger); + CheckClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger); /** @brief Set of the STL types whose operator[] is not const */ static const std::set stl_containers_not_const; diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 163b05cc445..365a677b5cb 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -91,7 +91,7 @@ bool CheckConditionImpl::isAliased(const std::set &vars) const void CheckConditionImpl::assignIf() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("assignIfError")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("assignIfError")) return; logChecker("CheckCondition::assignIf"); // style @@ -204,7 +204,7 @@ bool CheckConditionImpl::assignIfParseScope(const Token * const assignTok, // is variable changed in loop? const Token *bodyStart = tok2->linkAt(1)->next(); const Token *bodyEnd = bodyStart ? bodyStart->link() : nullptr; - if (!bodyEnd || bodyEnd->str() != "}" || isVariableChanged(bodyStart, bodyEnd, varid, !islocal, *mSettings)) + if (!bodyEnd || bodyEnd->str() != "}" || isVariableChanged(bodyStart, bodyEnd, varid, !islocal, mSettings)) continue; } @@ -310,7 +310,7 @@ static bool isOperandExpanded(const Token *tok) void CheckConditionImpl::checkBadBitmaskCheck() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("badBitmaskCheck")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("badBitmaskCheck")) return; logChecker("CheckCondition::checkBadBitmaskCheck"); // style @@ -358,7 +358,7 @@ void CheckConditionImpl::badBitmaskCheckError(const Token *tok, bool isNoOp) void CheckConditionImpl::comparison() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("comparisonError")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("comparisonError")) return; logChecker("CheckCondition::comparison"); // style @@ -441,7 +441,7 @@ bool CheckConditionImpl::isOverlappingCond(const Token * const cond1, const Toke return false; // same expressions - if (isSameExpression(true, cond1, cond2, *mSettings, pure, false)) + if (isSameExpression(true, cond1, cond2, mSettings, pure, false)) return true; // bitwise overlap for example 'x&7' and 'x==1' @@ -464,7 +464,7 @@ bool CheckConditionImpl::isOverlappingCond(const Token * const cond1, const Toke if (!num2->isNumber() || MathLib::isNegative(num2->str())) return false; - if (!isSameExpression(true, expr1, expr2, *mSettings, pure, false)) + if (!isSameExpression(true, expr1, expr2, mSettings, pure, false)) return false; const MathLib::bigint value1 = MathLib::toBigNumber(num1); @@ -478,7 +478,7 @@ bool CheckConditionImpl::isOverlappingCond(const Token * const cond1, const Toke void CheckConditionImpl::duplicateCondition() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("duplicateCondition")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("duplicateCondition")) return; logChecker("CheckCondition::duplicateCondition"); // style @@ -509,8 +509,8 @@ void CheckConditionImpl::duplicateCondition() continue; ErrorPath errorPath; - if (!findExpressionChanged(cond1, scope.classDef->next(), cond2, *mSettings) && - isSameExpression(true, cond1, cond2, *mSettings, true, true, &errorPath)) + if (!findExpressionChanged(cond1, scope.classDef->next(), cond2, mSettings) && + isSameExpression(true, cond1, cond2, mSettings, true, true, &errorPath)) duplicateConditionError(cond1, cond2, std::move(errorPath)); } } @@ -529,7 +529,7 @@ void CheckConditionImpl::duplicateConditionError(const Token *tok1, const Token void CheckConditionImpl::multiCondition() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("multiCondition")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("multiCondition")) return; logChecker("CheckCondition::multiCondition"); // style @@ -559,11 +559,11 @@ void CheckConditionImpl::multiCondition() if (tok2->astOperand2()) { ErrorPath errorPath; if (isOverlappingCond(cond1, tok2->astOperand2(), true) && - !findExpressionChanged(cond1, cond1, tok2->astOperand2(), *mSettings)) + !findExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings)) overlappingElseIfConditionError(tok2->astOperand2(), cond1->linenr()); else if (isOppositeCond( - true, cond1, tok2->astOperand2(), *mSettings, true, true, &errorPath) && - !findExpressionChanged(cond1, cond1, tok2->astOperand2(), *mSettings)) + true, cond1, tok2->astOperand2(), mSettings, true, true, &errorPath) && + !findExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings)) oppositeElseIfConditionError(cond1, tok2->astOperand2(), std::move(errorPath)); } } @@ -631,9 +631,9 @@ static bool isNestedInLambda(const Scope* inner, const Scope* outer) void CheckConditionImpl::multiCondition2() { - if (!mSettings->severity.isEnabled(Severity::warning) && - !mSettings->isPremiumEnabled("identicalConditionAfterEarlyExit") && - !mSettings->isPremiumEnabled("identicalInnerCondition")) + if (!mSettings.severity.isEnabled(Severity::warning) && + !mSettings.isPremiumEnabled("identicalConditionAfterEarlyExit") && + !mSettings.isPremiumEnabled("identicalInnerCondition")) return; logChecker("CheckCondition::multiCondition2"); // warning @@ -668,7 +668,7 @@ void CheckConditionImpl::multiCondition2() [&](const Token *cond) { if (Token::Match(cond, "%name% (")) { functionCall = true; - nonConstFunctionCall = isNonConstFunctionCall(cond, mSettings->library); + nonConstFunctionCall = isNonConstFunctionCall(cond, mSettings.library); if (nonConstFunctionCall) return ChildrenToVisit::done; } @@ -725,13 +725,13 @@ void CheckConditionImpl::multiCondition2() for (; tok && tok != endToken; tok = tok->next()) { if (isNestedInLambda(tok->scope(), cond1->scope())) continue; - if (isExpressionChangedAt(cond1, tok, 0, false, *mSettings)) + if (isExpressionChangedAt(cond1, tok, 0, false, mSettings)) break; if (Token::Match(tok, "if|return")) { const Token * condStartToken = tok->str() == "if" ? tok->next() : tok; const Token * condEndToken = tok->str() == "if" ? condStartToken->link() : Token::findsimplematch(condStartToken, ";"); // Does condition modify tracked variables? - if (findExpressionChanged(cond1, condStartToken, condEndToken, *mSettings)) + if (findExpressionChanged(cond1, condStartToken, condEndToken, mSettings)) break; // Condition.. @@ -745,14 +745,14 @@ void CheckConditionImpl::multiCondition2() if (!firstCondition) return ChildrenToVisit::none; if (firstCondition->str() == "&&") { - if (!isOppositeCond(false, firstCondition, cond2, *mSettings, true, true)) + if (!isOppositeCond(false, firstCondition, cond2, mSettings, true, true)) return ChildrenToVisit::op1_and_op2; } if (!firstCondition->hasKnownIntValue()) { - if (!isReturnVar && isOppositeCond(false, firstCondition, cond2, *mSettings, true, true, &errorPath)) { + if (!isReturnVar && isOppositeCond(false, firstCondition, cond2, mSettings, true, true, &errorPath)) { if (!isAliased(vars)) oppositeInnerConditionError(firstCondition, cond2, errorPath); - } else if (!isReturnVar && isSameExpression(true, firstCondition, cond2, *mSettings, true, true, &errorPath)) { + } else if (!isReturnVar && isSameExpression(true, firstCondition, cond2, mSettings, true, true, &errorPath)) { identicalInnerConditionError(firstCondition, cond2, errorPath); } else if (!isReturnVar && isOverlappingCond(cond2, firstCondition, true)) { overlappingInnerConditionError(firstCondition, cond2, errorPath); @@ -766,7 +766,7 @@ void CheckConditionImpl::multiCondition2() return ChildrenToVisit::op1_and_op2; if ((!cond1->hasKnownIntValue() || !secondCondition->hasKnownIntValue()) && - isSameExpression(true, cond1, secondCondition, *mSettings, true, true, &errorPath)) { + isSameExpression(true, cond1, secondCondition, mSettings, true, true, &errorPath)) { if (!isAliased(vars) && !mTokenizer->hasIfdef(cond1, secondCondition)) { identicalConditionAfterEarlyExitError(cond1, secondCondition, errorPath); return ChildrenToVisit::done; @@ -777,10 +777,10 @@ void CheckConditionImpl::multiCondition2() } } if (Token::Match(tok, "%name% (") && - isVariablesChanged(tok, tok->linkAt(1), 0, varsInCond, *mSettings)) { + isVariablesChanged(tok, tok->linkAt(1), 0, varsInCond, mSettings)) { break; } - if (Token::Match(tok, "%type% (") && nonlocal && isNonConstFunctionCall(tok, mSettings->library)) // non const function call -> bailout if there are nonlocal variables + if (Token::Match(tok, "%type% (") && nonlocal && isNonConstFunctionCall(tok, mSettings.library)) // non const function call -> bailout if there are nonlocal variables break; if (Token::Match(tok, "case|break|continue|return|throw") && tok->scope() == endToken->scope()) break; @@ -806,7 +806,7 @@ void CheckConditionImpl::multiCondition2() break; } const bool changed = std::any_of(vars.cbegin(), vars.cend(), [&](int varid) { - return isVariableChanged(tok1, tok2, varid, nonlocal, *mSettings); + return isVariableChanged(tok1, tok2, varid, nonlocal, mSettings); }); if (changed) break; @@ -1158,11 +1158,11 @@ static bool isIfConstexpr(const Token* tok) { void CheckConditionImpl::checkIncorrectLogicOperator() { - const bool printStyle = mSettings->severity.isEnabled(Severity::style); - const bool printWarning = mSettings->severity.isEnabled(Severity::warning); - if (!printWarning && !printStyle && !mSettings->isPremiumEnabled("incorrectLogicOperator")) + const bool printStyle = mSettings.severity.isEnabled(Severity::style); + const bool printWarning = mSettings.severity.isEnabled(Severity::warning); + if (!printWarning && !printStyle && !mSettings.isPremiumEnabled("incorrectLogicOperator")) return; - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); logChecker("CheckCondition::checkIncorrectLogicOperator"); // style,warning @@ -1182,7 +1182,7 @@ void CheckConditionImpl::checkIncorrectLogicOperator() ((tok->str() == "||" && tok->astOperand2()->str() == "&&") || (tok->str() == "&&" && tok->astOperand2()->str() == "||"))) { const Token* tok2 = tok->astOperand2()->astOperand1(); - if (isOppositeCond(true, tok->astOperand1(), tok2, *mSettings, true, false)) { + if (isOppositeCond(true, tok->astOperand1(), tok2, mSettings, true, false)) { std::string expr1(tok->astOperand1()->expressionString()); std::string expr2(tok->astOperand2()->astOperand1()->expressionString()); std::string expr3(tok->astOperand2()->astOperand2()->expressionString()); @@ -1214,7 +1214,7 @@ void CheckConditionImpl::checkIncorrectLogicOperator() redundantConditionError(tok, msg, false); continue; } - if (isSameExpression(false, tok->astOperand1(), tok2, *mSettings, true, true)) { + if (isSameExpression(false, tok->astOperand1(), tok2, mSettings, true, true)) { std::string expr1(tok->astOperand1()->expressionString()); std::string expr2(tok->astOperand2()->astOperand1()->expressionString()); std::string expr3(tok->astOperand2()->astOperand2()->expressionString()); @@ -1279,7 +1279,7 @@ void CheckConditionImpl::checkIncorrectLogicOperator() // Opposite comparisons around || or && => always true or always false const bool isLogicalOr(tok->str() == "||"); - if (!isfloat && isOppositeCond(isLogicalOr, tok->astOperand1(), tok->astOperand2(), *mSettings, true, true, &errorPath)) { + if (!isfloat && isOppositeCond(isLogicalOr, tok->astOperand1(), tok->astOperand2(), mSettings, true, true, &errorPath)) { if (!isIfConstexpr(tok)) { const bool alwaysTrue(isLogicalOr); incorrectLogicOperatorError(tok, conditionString(tok), alwaysTrue, inconclusive, std::move(errorPath)); @@ -1290,9 +1290,9 @@ void CheckConditionImpl::checkIncorrectLogicOperator() if (!parseable) continue; - if (isSameExpression(true, comp1, comp2, *mSettings, true, true)) + if (isSameExpression(true, comp1, comp2, mSettings, true, true)) continue; // same expressions => only report that there are same expressions - if (!isSameExpression(true, expr1, expr2, *mSettings, true, true)) + if (!isSameExpression(true, expr1, expr2, mSettings, true, true)) continue; @@ -1396,7 +1396,7 @@ void CheckConditionImpl::redundantConditionError(const Token *tok, const std::st //----------------------------------------------------------------------------- void CheckConditionImpl::checkModuloAlwaysTrueFalse() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckCondition::checkModuloAlwaysTrueFalse"); // warning @@ -1452,7 +1452,7 @@ static int countPar(const Token *tok1, const Token *tok2) //--------------------------------------------------------------------------- void CheckConditionImpl::clarifyCondition() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("clarifyCondition")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("clarifyCondition")) return; logChecker("CheckCondition::clarifyCondition"); // style @@ -1516,11 +1516,11 @@ void CheckConditionImpl::clarifyConditionError(const Token *tok, bool assign, bo void CheckConditionImpl::alwaysTrueFalse() { - const bool pedantic = mSettings->isPremiumEnabled("alwaysTrue") || - mSettings->isPremiumEnabled("alwaysFalse") || - mSettings->isPremiumEnabled("knownConditionTrueFalse"); + const bool pedantic = mSettings.isPremiumEnabled("alwaysTrue") || + mSettings.isPremiumEnabled("alwaysFalse") || + mSettings.isPremiumEnabled("knownConditionTrueFalse"); - if (!pedantic && !mSettings->severity.isEnabled(Severity::style)) + if (!pedantic && !mSettings.severity.isEnabled(Severity::style)) return; logChecker("CheckCondition::alwaysTrueFalse"); // style @@ -1569,7 +1569,7 @@ void CheckConditionImpl::alwaysTrueFalse() continue; if (condition->isConstexpr()) continue; - if (!isUsedAsBool(tok, *mSettings)) + if (!isUsedAsBool(tok, mSettings)) continue; if (Token::simpleMatch(condition, "return") && Token::Match(tok, "%assign%")) continue; @@ -1598,7 +1598,7 @@ void CheckConditionImpl::alwaysTrueFalse() isSameExpression(true, tok->astOperand1(), tok->astOperand2(), - *mSettings, + mSettings, true, true)) continue; @@ -1702,7 +1702,7 @@ void CheckConditionImpl::checkInvalidTestForOverflow() // x + y < x -> y < 0 - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckCondition::checkInvalidTestForOverflow"); // warning @@ -1736,7 +1736,7 @@ void CheckConditionImpl::checkInvalidTestForOverflow() if (!isSameExpression(true, expr, lhs->astSibling(), - *mSettings, + mSettings, true, false)) continue; @@ -1792,7 +1792,7 @@ void CheckConditionImpl::invalidTestForOverflow(const Token* tok, const ValueTyp void CheckConditionImpl::checkPointerAdditionResultNotNull() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckCondition::checkPointerAdditionResultNotNull"); // warning @@ -1839,7 +1839,7 @@ void CheckConditionImpl::pointerAdditionResultNotNullError(const Token *tok, con void CheckConditionImpl::checkDuplicateConditionalAssign() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("duplicateConditionalAssign")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("duplicateConditionalAssign")) return; logChecker("CheckCondition::checkDuplicateConditionalAssign"); // style @@ -1883,10 +1883,10 @@ void CheckConditionImpl::checkDuplicateConditionalAssign() isRedundant = (isNegation && val == 0) || (!isNegation && val == 1); } else { // comparison if (!isSameExpression( - true, condTok->astOperand1(), assignTok->astOperand1(), *mSettings, true, true)) + true, condTok->astOperand1(), assignTok->astOperand1(), mSettings, true, true)) continue; if (!isSameExpression( - true, condTok->astOperand2(), assignTok->astOperand2(), *mSettings, true, true)) + true, condTok->astOperand2(), assignTok->astOperand2(), mSettings, true, true)) continue; } duplicateConditionalAssignError(condTok, assignTok, isRedundant); @@ -1918,7 +1918,7 @@ void CheckConditionImpl::duplicateConditionalAssignError(const Token *condTok, c void CheckConditionImpl::checkAssignmentInCondition() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("assignmentInCondition")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("assignmentInCondition")) return; logChecker("CheckCondition::checkAssignmentInCondition"); // style @@ -1965,10 +1965,10 @@ void CheckConditionImpl::assignmentInCondition(const Token *eq) void CheckConditionImpl::checkCompareValueOutOfTypeRange() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("compareValueOutOfTypeRangeError")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("compareValueOutOfTypeRangeError")) return; - if (mSettings->platform.type == Platform::Type::Unspecified) + if (mSettings.platform.type == Platform::Type::Unspecified) return; logChecker("CheckCondition::checkCompareValueOutOfTypeRange"); // style,platform @@ -1994,19 +1994,19 @@ void CheckConditionImpl::checkCompareValueOutOfTypeRange() bits = 1; break; case ValueType::Type::CHAR: - bits = mSettings->platform.char_bit; + bits = mSettings.platform.char_bit; break; case ValueType::Type::SHORT: - bits = mSettings->platform.short_bit; + bits = mSettings.platform.short_bit; break; case ValueType::Type::INT: - bits = mSettings->platform.int_bit; + bits = mSettings.platform.int_bit; break; case ValueType::Type::LONG: - bits = mSettings->platform.long_bit; + bits = mSettings.platform.long_bit; break; case ValueType::Type::LONGLONG: - bits = mSettings->platform.long_long_bit; + bits = mSettings.platform.long_long_bit; break; default: break; @@ -2019,7 +2019,7 @@ void CheckConditionImpl::checkCompareValueOutOfTypeRange() long long typeMaxValue; if (typeTok->valueType()->sign != ValueType::Sign::SIGNED) typeMaxValue = unsignedTypeMaxValue; - else if (bits >= mSettings->platform.int_bit && (!valueTok->valueType() || valueTok->valueType()->sign != ValueType::Sign::SIGNED)) + else if (bits >= mSettings.platform.int_bit && (!valueTok->valueType() || valueTok->valueType()->sign != ValueType::Sign::SIGNED)) typeMaxValue = unsignedTypeMaxValue; else typeMaxValue = unsignedTypeMaxValue / 2; @@ -2097,7 +2097,7 @@ void CheckConditionImpl::compareValueOutOfTypeRangeError(const Token *comparison void CheckCondition::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckConditionImpl checkCondition(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckConditionImpl checkCondition(&tokenizer, tokenizer.getSettings(), errorLogger); checkCondition.multiCondition(); checkCondition.clarifyCondition(); // not simplified because ifAssign checkCondition.multiCondition2(); @@ -2115,7 +2115,7 @@ void CheckCondition::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLog checkCondition.alwaysTrueFalse(); } -void CheckCondition::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckCondition::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckConditionImpl c(nullptr, settings, errorLogger); diff --git a/lib/checkcondition.h b/lib/checkcondition.h index be06dfbbfd2..06ed12695bc 100644 --- a/lib/checkcondition.h +++ b/lib/checkcondition.h @@ -56,7 +56,7 @@ class CPPCHECKLIB CheckCondition : public Check { private: void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Match conditions with assignments and other conditions:\n" @@ -81,7 +81,7 @@ class CPPCHECKLIB CheckCondition : public Check { class CPPCHECKLIB CheckConditionImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckConditionImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckConditionImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** mismatching assignment / comparison */ diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index 463e47bea1c..b0c510ed80a 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -42,7 +42,7 @@ static const CWE CWE480(480U); // Use of Incorrect Operator void CheckExceptionSafetyImpl::destructors() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckExceptionSafety::destructors"); // warning @@ -90,12 +90,12 @@ void CheckExceptionSafetyImpl::destructorsError(const Token * const tok, const s void CheckExceptionSafetyImpl::deallocThrow() { - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("exceptDeallocThrow")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("exceptDeallocThrow")) return; logChecker("CheckExceptionSafety::deallocThrow"); // warning - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); // Deallocate a global/member pointer and then throw exception @@ -165,7 +165,7 @@ void CheckExceptionSafetyImpl::deallocThrowError(const Token * const tok, const //--------------------------------------------------------------------------- void CheckExceptionSafetyImpl::checkRethrowCopy() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("exceptRethrowCopy")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("exceptRethrowCopy")) return; logChecker("CheckExceptionSafety::checkRethrowCopy"); // style @@ -209,7 +209,7 @@ void CheckExceptionSafetyImpl::rethrowCopyError(const Token * const tok, const s //--------------------------------------------------------------------------- void CheckExceptionSafetyImpl::checkCatchExceptionByValue() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("catchExceptionByValue")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("catchExceptionByValue")) return; logChecker("CheckExceptionSafety::checkCatchExceptionByValue"); // style @@ -298,7 +298,7 @@ void CheckExceptionSafetyImpl::nothrowThrows() function->isAttributeNothrow()) { // __attribute__((nothrow)) or __declspec(nothrow) functions isNoExcept = true; } - else if (mSettings->library.isentrypoint(function->name())) { + else if (mSettings.library.isentrypoint(function->name())) { isEntryPoint = true; } if (!isNoExcept && !isEntryPoint) @@ -328,8 +328,8 @@ void CheckExceptionSafetyImpl::entryPointThrowError(const Token * const tok) //-------------------------------------------------------------------------- void CheckExceptionSafetyImpl::unhandledExceptionSpecification() { - if ((!mSettings->severity.isEnabled(Severity::style) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) && - !mSettings->isPremiumEnabled("unhandledExceptionSpecification")) + if ((!mSettings.severity.isEnabled(Severity::style) || !mSettings.certainty.isEnabled(Certainty::inconclusive)) && + !mSettings.isPremiumEnabled("unhandledExceptionSpecification")) return; logChecker("CheckExceptionSafety::unhandledExceptionSpecification"); // style,inconclusive @@ -338,7 +338,7 @@ void CheckExceptionSafetyImpl::unhandledExceptionSpecification() for (const Scope * scope : symbolDatabase->functionScopes) { // only check functions without exception specification - if (scope->function && !scope->function->isThrow() && !mSettings->library.isentrypoint(scope->className)) { + if (scope->function && !scope->function->isThrow() && !mSettings.library.isentrypoint(scope->className)) { for (const Token *tok = scope->function->functionScope->bodyStart->next(); tok != scope->function->functionScope->bodyEnd; tok = tok->next()) { if (tok->str() == "try") @@ -414,7 +414,7 @@ void CheckExceptionSafety::runChecks(const Tokenizer &tokenizer, ErrorLogger *er if (tokenizer.isC()) return; - CheckExceptionSafetyImpl checkExceptionSafety(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckExceptionSafetyImpl checkExceptionSafety(&tokenizer, tokenizer.getSettings(), errorLogger); checkExceptionSafety.destructors(); checkExceptionSafety.deallocThrow(); checkExceptionSafety.checkRethrowCopy(); @@ -424,7 +424,7 @@ void CheckExceptionSafety::runChecks(const Tokenizer &tokenizer, ErrorLogger *er checkExceptionSafety.rethrowNoCurrentException(); } -void CheckExceptionSafety::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckExceptionSafety::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckExceptionSafetyImpl c(nullptr, settings, errorLogger); c.destructorsError(nullptr, "Class"); diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index bd44a649b1e..d452dac2cf8 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -53,7 +53,7 @@ class CPPCHECKLIB CheckExceptionSafety : public Check { void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** Generate all possible errors (for --errorlist) */ - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; /** wiki formatted description of the class (for --doc) */ std::string classInfo() const override { @@ -71,7 +71,7 @@ class CPPCHECKLIB CheckExceptionSafety : public Check { class CPPCHECKLIB CheckExceptionSafetyImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckExceptionSafetyImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckExceptionSafetyImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Don't throw exceptions in destructors */ diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 47a3828de31..db50846b262 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -54,7 +54,7 @@ static const CWE CWE688(688U); // Function Call With Incorrect Variable or Refe void CheckFunctionsImpl::checkProhibitedFunctions() { - const bool checkAlloca = mSettings->severity.isEnabled(Severity::warning) && ((mTokenizer->isC() && mSettings->standards.c >= Standards::C99) || mSettings->standards.cpp >= Standards::CPP11); + const bool checkAlloca = mSettings.severity.isEnabled(Severity::warning) && ((mTokenizer->isC() && mSettings.standards.c >= Standards::C99) || mSettings.standards.cpp >= Standards::CPP11); logChecker("CheckFunctions::checkProhibitedFunctions"); @@ -66,7 +66,7 @@ void CheckFunctionsImpl::checkProhibitedFunctions() // alloca() is special as it depends on the code being C or C++, so it is not in Library if (checkAlloca && Token::simpleMatch(tok, "alloca (") && (!tok->function() || tok->function()->nestedIn->type == ScopeType::eGlobal)) { if (tok->isC()) { - if (mSettings->standards.c > Standards::C89) + if (mSettings.standards.c > Standards::C89) reportError(tok, Severity::warning, "allocaCalled", "$symbol:alloca\n" "Obsolete function 'alloca' called. In C99 and later it is recommended to use a variable length array instead.\n" @@ -84,10 +84,10 @@ void CheckFunctionsImpl::checkProhibitedFunctions() if (tok->function() && tok->function()->hasBody()) continue; - const Library::WarnInfo* wi = mSettings->library.getWarnInfo(tok); + const Library::WarnInfo* wi = mSettings.library.getWarnInfo(tok); if (wi) { - if (mSettings->severity.isEnabled(wi->severity) && ((tok->isC() && mSettings->standards.c >= wi->standards.c) || (tok->isCpp() && mSettings->standards.cpp >= wi->standards.cpp))) { - const std::string daca = mSettings->daca ? "prohibited" : ""; + if (mSettings.severity.isEnabled(wi->severity) && ((tok->isC() && mSettings.standards.c >= wi->standards.c) || (tok->isCpp() && mSettings.standards.cpp >= wi->standards.cpp))) { + const std::string daca = mSettings.daca ? "prohibited" : ""; const std::string prefix = daca + tok->str(); functionCalledError(tok, wi->severity, prefix, wi->message); } @@ -120,24 +120,24 @@ void CheckFunctionsImpl::invalidFunctionUsage() const Token * const argtok = arguments[argnr-1]; // check ... - const ValueFlow::Value *invalidValue = argtok->getInvalidValue(functionToken,argnr,*mSettings); + const ValueFlow::Value *invalidValue = argtok->getInvalidValue(functionToken,argnr,mSettings); if (invalidValue) { - invalidFunctionArgError(argtok, functionToken->next()->astOperand1()->expressionString(), argnr, invalidValue, mSettings->library.validarg(functionToken, argnr)); + invalidFunctionArgError(argtok, functionToken->next()->astOperand1()->expressionString(), argnr, invalidValue, mSettings.library.validarg(functionToken, argnr)); } if (astIsBool(argtok)) { // check - if (mSettings->library.isboolargbad(functionToken, argnr)) + if (mSettings.library.isboolargbad(functionToken, argnr)) invalidFunctionArgBoolError(argtok, functionToken->str(), argnr); // Are the values 0 and 1 valid? - else if (!mSettings->library.isIntArgValid(functionToken, argnr, 0, *mSettings)) - invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, mSettings->library.validarg(functionToken, argnr)); - else if (!mSettings->library.isIntArgValid(functionToken, argnr, 1, *mSettings)) - invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, mSettings->library.validarg(functionToken, argnr)); + else if (!mSettings.library.isIntArgValid(functionToken, argnr, 0, mSettings)) + invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, mSettings.library.validarg(functionToken, argnr)); + else if (!mSettings.library.isIntArgValid(functionToken, argnr, 1, mSettings)) + invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, mSettings.library.validarg(functionToken, argnr)); } // check - if (mSettings->library.isargstrz(functionToken, argnr)) { + if (mSettings.library.isargstrz(functionToken, argnr)) { if (Token::Match(argtok, "& %var% !![") && argtok->next() && argtok->next()->valueType()) { const ValueType * valueType = argtok->next()->valueType(); const Variable * variable = argtok->next()->variable(); @@ -153,7 +153,7 @@ void CheckFunctionsImpl::invalidFunctionUsage() // Is non-null terminated local variable of type char (e.g. char buf[] = {'x'};) ? if (variable && variable->isLocal() && valueType && (valueType->type == ValueType::Type::CHAR || valueType->type == ValueType::Type::WCHAR_T) - && !isVariablesChanged(variable->declEndToken(), functionToken, valueType->pointer, { variable }, *mSettings)) { + && !isVariablesChanged(variable->declEndToken(), functionToken, valueType->pointer, { variable }, mSettings)) { const Token* varTok = variable->declEndToken(); MathLib::bigint count = -1; // Find out explicitly set count, e.g.: char buf[3] = {...}. Variable 'count' is set to 3 then. if (varTok && Token::simpleMatch(varTok->astOperand1(), "[")) @@ -183,7 +183,7 @@ void CheckFunctionsImpl::invalidFunctionUsage() invalidFunctionArgStrError(argtok, functionToken->str(), argnr); } } else if (count > -1 && Token::Match(varTok, "= %str%")) { - const Token* strTok = varTok->getValueTokenMinStrSize(*mSettings); + const Token* strTok = varTok->getValueTokenMinStrSize(mSettings); if (strTok) { const int strSize = Token::getStrArraySize(strTok); if (strSize > count && strTok->str().find('\0') == std::string::npos) @@ -247,9 +247,9 @@ void CheckFunctionsImpl::invalidFunctionArgStrError(const Token *tok, const std: //--------------------------------------------------------------------------- void CheckFunctionsImpl::checkIgnoredReturnValue() { - if (!mSettings->severity.isEnabled(Severity::warning) && - !mSettings->severity.isEnabled(Severity::style) && - !mSettings->isPremiumEnabled("ignoredReturnValue")) + if (!mSettings.severity.isEnabled(Severity::warning) && + !mSettings.severity.isEnabled(Severity::style) && + !mSettings.isPremiumEnabled("ignoredReturnValue")) return; logChecker("CheckFunctions::checkIgnoredReturnValue"); // style,warning @@ -282,13 +282,13 @@ void CheckFunctionsImpl::checkIgnoredReturnValue() if ((!tok->function() || !Token::Match(tok->function()->retDef, "void %name%")) && tok->next()->astOperand1()) { - const Library::UseRetValType retvalTy = mSettings->library.getUseRetValType(tok); + const Library::UseRetValType retvalTy = mSettings.library.getUseRetValType(tok); const bool warn = (tok->function() && (tok->function()->isAttributeNodiscard() || tok->function()->isAttributePure() || tok->function()->isAttributeConst())) || // avoid duplicate warnings for resource-allocating functions - (retvalTy == Library::UseRetValType::DEFAULT && mSettings->library.getAllocFuncInfo(tok) == nullptr); - if (mSettings->severity.isEnabled(Severity::warning) && warn) + (retvalTy == Library::UseRetValType::DEFAULT && mSettings.library.getAllocFuncInfo(tok) == nullptr); + if (mSettings.severity.isEnabled(Severity::warning) && warn) ignoredReturnValueError(tok, tok->next()->astOperand1()->expressionString()); - else if (mSettings->severity.isEnabled(Severity::style) && + else if (mSettings.severity.isEnabled(Severity::style) && retvalTy == Library::UseRetValType::ERROR_CODE) ignoredReturnErrorCode(tok, tok->next()->astOperand1()->expressionString()); } @@ -321,7 +321,7 @@ void CheckFunctionsImpl::checkMissingReturn() const Function *function = scope->function; if (!function || !function->hasBody()) continue; - if (function->name() == "main" && !(mTokenizer->isC() && mSettings->standards.c < Standards::C99)) + if (function->name() == "main" && !(mTokenizer->isC() && mSettings.standards.c < Standards::C99)) continue; if (function->type != FunctionType::eFunction && function->type != FunctionType::eOperatorEqual) continue; @@ -329,7 +329,7 @@ void CheckFunctionsImpl::checkMissingReturn() continue; if (Function::returnsVoid(function, true)) continue; - const Token *errorToken = checkMissingReturnScope(scope->bodyEnd, mSettings->library); + const Token *errorToken = checkMissingReturnScope(scope->bodyEnd, mSettings.library); if (errorToken) missingReturnError(errorToken); } @@ -441,10 +441,10 @@ void CheckFunctionsImpl::missingReturnError(const Token* tok) //--------------------------------------------------------------------------- void CheckFunctionsImpl::checkMathFunctions() { - const bool styleC99 = mSettings->severity.isEnabled(Severity::style) && ((mTokenizer->isC() && mSettings->standards.c != Standards::C89) || (mTokenizer->isCPP() && mSettings->standards.cpp != Standards::CPP03)); - const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); + const bool styleC99 = mSettings.severity.isEnabled(Severity::style) && ((mTokenizer->isC() && mSettings.standards.c != Standards::C89) || (mTokenizer->isCPP() && mSettings.standards.cpp != Standards::CPP03)); + const bool printWarnings = mSettings.severity.isEnabled(Severity::warning); - if (!styleC99 && !printWarnings && !mSettings->isPremiumEnabled("wrongmathcall")) + if (!styleC99 && !printWarnings && !mSettings.isPremiumEnabled("wrongmathcall")) return; logChecker("CheckFunctions::checkMathFunctions"); // style,warning,c99,c++11 @@ -528,7 +528,7 @@ void CheckFunctionsImpl::memsetZeroBytes() // //
- if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckFunctions::memsetZeroBytes"); // warning @@ -567,8 +567,8 @@ void CheckFunctionsImpl::memsetInvalid2ndParam() // //
- const bool printPortability = mSettings->severity.isEnabled(Severity::portability); - const bool printWarning = mSettings->severity.isEnabled(Severity::warning); + const bool printPortability = mSettings.severity.isEnabled(Severity::portability); + const bool printWarning = mSettings.severity.isEnabled(Severity::warning); if (!printWarning && !printPortability) return; @@ -596,8 +596,8 @@ void CheckFunctionsImpl::memsetInvalid2ndParam() if (printWarning && secondParamTok->isNumber()) { // Check if the second parameter is a literal and is out of range const MathLib::bigint value = MathLib::toBigNumber(secondParamTok); - const long long sCharMin = mSettings->platform.signedCharMin(); - const long long uCharMax = mSettings->platform.unsignedCharMax(); + const long long sCharMin = mSettings.platform.signedCharMin(); + const long long uCharMax = mSettings.platform.unsignedCharMax(); if (value < sCharMin || value > uCharMax) memsetValueOutOfRangeError(secondParamTok, secondParamTok->str()); } @@ -627,7 +627,7 @@ void CheckFunctionsImpl::memsetValueOutOfRangeError(const Token *tok, const std: void CheckFunctionsImpl::checkLibraryMatchFunctions() { - if (!mSettings->checkLibrary) + if (!mSettings.checkLibrary) return; bool insideNew = false; @@ -665,32 +665,32 @@ void CheckFunctionsImpl::checkLibraryMatchFunctions() if (Token::simpleMatch(tok->astParent(), ".")) { const Token* contTok = tok->astParent()->astOperand1(); - if (astContainerAction(contTok, mSettings->library) != Library::Container::Action::NO_ACTION) + if (astContainerAction(contTok, mSettings.library) != Library::Container::Action::NO_ACTION) continue; - if (astContainerYield(contTok, mSettings->library) != Library::Container::Yield::NO_YIELD) + if (astContainerYield(contTok, mSettings.library) != Library::Container::Yield::NO_YIELD) continue; } - if (!mSettings->library.isNotLibraryFunction(tok)) + if (!mSettings.library.isNotLibraryFunction(tok)) continue; - const std::string &functionName = mSettings->library.getFunctionName(tok); + const std::string &functionName = mSettings.library.getFunctionName(tok); if (functionName.empty()) continue; - if (mSettings->library.functions().find(functionName) != mSettings->library.functions().end()) + if (mSettings.library.functions().find(functionName) != mSettings.library.functions().end()) continue; - if (mSettings->library.podtype(tok->expressionString())) + if (mSettings.library.podtype(tok->expressionString())) continue; - if (mSettings->library.getTypeCheck("unusedvar", functionName) != Library::TypeCheck::def) + if (mSettings.library.getTypeCheck("unusedvar", functionName) != Library::TypeCheck::def) continue; const Token* start = tok; while (Token::Match(start->tokAt(-2), "%name% ::") && !start->tokAt(-2)->isKeyword()) start = start->tokAt(-2); - if (mSettings->library.detectContainerOrIterator(start)) + if (mSettings.library.detectContainerOrIterator(start)) continue; reportError(tok, @@ -705,10 +705,10 @@ void CheckFunctionsImpl::checkLibraryMatchFunctions() // details: https://en.cppreference.com/w/cpp/language/copy_elision void CheckFunctionsImpl::returnLocalStdMove() { - if (!mTokenizer->isCPP() || mSettings->standards.cpp < Standards::CPP11) + if (!mTokenizer->isCPP() || mSettings.standards.cpp < Standards::CPP11) return; - if (!mSettings->severity.isEnabled(Severity::performance)) + if (!mSettings.severity.isEnabled(Severity::performance)) return; logChecker("CheckFunctions::returnLocalStdMove"); // performance,c++11 @@ -744,7 +744,7 @@ void CheckFunctionsImpl::copyElisionError(const Token *tok) void CheckFunctionsImpl::useStandardLibrary() { - if (!mSettings->severity.isEnabled(Severity::style)) + if (!mSettings.severity.isEnabled(Severity::style)) return; logChecker("CheckFunctions::useStandardLibrary"); // style @@ -780,10 +780,10 @@ void CheckFunctionsImpl::useStandardLibrary() const auto& secondOp = condToken->str(); const bool isLess = "<" == secondOp && - isConstExpression(condToken->astOperand2(), mSettings->library) && + isConstExpression(condToken->astOperand2(), mSettings.library) && condToken->astOperand1()->varId() == idxVarId; const bool isMore = ">" == secondOp && - isConstExpression(condToken->astOperand1(), mSettings->library) && + isConstExpression(condToken->astOperand1(), mSettings.library) && condToken->astOperand2()->varId() == idxVarId; if (!(isLess || isMore)) @@ -855,7 +855,7 @@ void CheckFunctionsImpl::useStandardLibraryError(const Token *tok, const std::st void CheckFunctions::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckFunctionsImpl checkFunctions(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckFunctionsImpl checkFunctions(&tokenizer, tokenizer.getSettings(), errorLogger); checkFunctions.checkIgnoredReturnValue(); checkFunctions.checkMissingReturn(); // Missing "return" in exit path @@ -872,11 +872,11 @@ void CheckFunctions::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLog checkFunctions.useStandardLibrary(); } -void CheckFunctions::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckFunctions::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckFunctionsImpl c(nullptr, settings, errorLogger); - for (auto i = settings->library.functionwarn().cbegin(); i != settings->library.functionwarn().cend(); ++i) { + for (auto i = settings.library.functionwarn().cbegin(); i != settings.library.functionwarn().cend(); ++i) { c.functionCalledError(nullptr, Severity::style, i->first, i->second.message); } diff --git a/lib/checkfunctions.h b/lib/checkfunctions.h index 7ea9e2833a2..b6939ffb17f 100644 --- a/lib/checkfunctions.h +++ b/lib/checkfunctions.h @@ -54,7 +54,7 @@ class CPPCHECKLIB CheckFunctions : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check function usage:\n" @@ -73,7 +73,7 @@ class CPPCHECKLIB CheckFunctions : public Check { class CPPCHECKLIB CheckFunctionsImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckFunctionsImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckFunctionsImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Check for functions that should not be used */ diff --git a/lib/checkimpl.cpp b/lib/checkimpl.cpp index 43e56cfa360..2b28b829277 100644 --- a/lib/checkimpl.cpp +++ b/lib/checkimpl.cpp @@ -47,7 +47,7 @@ void CheckImpl::reportError(ErrorPath errorPath, Severity severity, const char i bool CheckImpl::wrongData(const Token *tok, const char *str) { - if (mSettings->daca) + if (mSettings.daca) reportError(tok, Severity::debug, "DacaWrongData", "Wrong data detected by condition " + std::string(str)); return true; } @@ -57,7 +57,7 @@ ErrorPath CheckImpl::getErrorPath(const Token* errtok, const ValueFlow::Value* v ErrorPath errorPath; if (!value) { errorPath.emplace_back(errtok, std::move(bug)); - } else if (mSettings->verbose || mSettings->outputFormat == Settings::OutputFormat::xml || !mSettings->templateLocation.empty()) { + } else if (mSettings.verbose || mSettings.outputFormat == Settings::OutputFormat::xml || !mSettings.templateLocation.empty()) { errorPath = value->errorPath; errorPath.emplace_back(errtok, std::move(bug)); } else { @@ -72,6 +72,6 @@ ErrorPath CheckImpl::getErrorPath(const Token* errtok, const ValueFlow::Value* v void CheckImpl::logChecker(const char id[]) { - if (!mSettings->buildDir.empty() || mSettings->collectLogCheckers()) + if (!mSettings.buildDir.empty() || mSettings.collectLogCheckers()) reportError(nullptr, Severity::internal, "logChecker", id); } diff --git a/lib/checkimpl.h b/lib/checkimpl.h index 35e70bbaae5..36f04a23d1f 100644 --- a/lib/checkimpl.h +++ b/lib/checkimpl.h @@ -37,7 +37,7 @@ class CPPCHECKLIB CheckImpl { protected: /** This constructor is used when running checks. */ - CheckImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger) {} public: @@ -46,7 +46,7 @@ class CPPCHECKLIB CheckImpl protected: const Tokenizer* const mTokenizer{}; - const Settings* const mSettings{}; + const Settings& mSettings; ErrorLogger* const mErrorLogger{}; /** report an error */ diff --git a/lib/checkinternal.cpp b/lib/checkinternal.cpp index 10af0543cec..f84203e5d0d 100644 --- a/lib/checkinternal.cpp +++ b/lib/checkinternal.cpp @@ -382,7 +382,7 @@ void CheckInternal::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogg if (!tokenizer.getSettings().checks.isEnabled(Checks::internalCheck)) return; - CheckInternalImpl checkInternal(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckInternalImpl checkInternal(&tokenizer, tokenizer.getSettings(), errorLogger); checkInternal.checkTokenMatchPatterns(); checkInternal.checkTokenSimpleMatchPatterns(); @@ -393,7 +393,7 @@ void CheckInternal::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogg checkInternal.checkRedundantTokCheck(); } -void CheckInternal::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckInternal::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckInternalImpl c(nullptr, settings, errorLogger); c.simplePatternError(nullptr, "class {", "Match"); diff --git a/lib/checkinternal.h b/lib/checkinternal.h index 2d95e3ed7e4..2b6267b4550 100644 --- a/lib/checkinternal.h +++ b/lib/checkinternal.h @@ -48,7 +48,7 @@ class CPPCHECKLIB CheckInternal : public Check { private: void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { // Don't include these checks on the WIKI where people can read what @@ -60,7 +60,7 @@ class CPPCHECKLIB CheckInternal : public Check { class CPPCHECKLIB CheckInternalImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckInternalImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckInternalImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check if a simple pattern is used inside Token::Match or Token::findmatch */ diff --git a/lib/checkio.cpp b/lib/checkio.cpp index f1cb4670c50..a62955d3017 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -121,9 +121,9 @@ namespace { void CheckIOImpl::checkFileUsage() { - const bool windows = mSettings->platform.isWindows(); - const bool printPortability = mSettings->severity.isEnabled(Severity::portability); - const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); + const bool windows = mSettings.platform.isWindows(); + const bool printPortability = mSettings.severity.isEnabled(Severity::portability); + const bool printWarnings = mSettings.severity.isEnabled(Severity::warning); std::map filepointers; @@ -166,7 +166,7 @@ void CheckIOImpl::checkFileUsage() filepointer.second.lastOperation = Filepointer::Operation::UNKNOWN_OP; } } - } else if (tok->str() == "return" || tok->str() == "continue" || tok->str() == "break" || mSettings->library.isnoreturn(tok)) { // Reset upon return, continue or break + } else if (tok->str() == "return" || tok->str() == "continue" || tok->str() == "break" || mSettings.library.isnoreturn(tok)) { // Reset upon return, continue or break for (std::pair& filepointer : filepointers) { filepointer.second.mode_indent = 0; filepointer.second.mode = OpenMode::UNKNOWN_OM; @@ -258,7 +258,7 @@ void CheckIOImpl::checkFileUsage() } // Do not trigger a warning if the loop always exits or if the file is opened again in the loop. - if (!isReturnScope(bodyEnd, mSettings->library) && Token::findmatch(bodyStart, "%var% =", bodyEnd, fileTok->varId()) == nullptr) + if (!isReturnScope(bodyEnd, mSettings.library) && Token::findmatch(bodyStart, "%var% =", bodyEnd, fileTok->varId()) == nullptr) fcloseInLoopConditionError(tok, fileTok->str()); } } @@ -267,7 +267,7 @@ void CheckIOImpl::checkFileUsage() if ((tok->str() == "ungetc" || tok->str() == "ungetwc") && fileTok) fileTok = fileTok->nextArgument(); operation = Filepointer::Operation::UNIMPORTANT; - } else if (!Token::Match(tok, "if|for|while|catch|switch") && !mSettings->library.isFunctionConst(tok->str(), true)) { + } else if (!Token::Match(tok, "if|for|while|catch|switch") && !mSettings.library.isFunctionConst(tok->str(), true)) { const Token* const end2 = tok->linkAt(1); if (scope->functionOf && scope->functionOf->isClassOrStruct() && !scope->function->isStatic() && ((tok->strAt(-1) != "::" && tok->strAt(-1) != ".") || tok->strAt(-2) == "this")) { if (!tok->function() || (tok->function()->nestedIn && tok->function()->nestedIn->isClassOrStruct())) { @@ -436,7 +436,7 @@ void CheckIOImpl::incompatibleFileOpenError(const Token *tok, const std::string //--------------------------------------------------------------------------- void CheckIOImpl::invalidScanf() { - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("invalidscanf")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("invalidscanf")) return; logChecker("CheckIO::invalidScanf"); @@ -556,7 +556,7 @@ static inline bool typesMatch(const std::string& iToTest, const std::string& iTy void CheckIOImpl::checkWrongPrintfScanfArguments() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); - const bool isWindows = mSettings->platform.isWindows(); + const bool isWindows = mSettings.platform.isWindows(); logChecker("CheckIO::checkWrongPrintfScanfArguments"); @@ -571,10 +571,10 @@ void CheckIOImpl::checkWrongPrintfScanfArguments() bool scanf_s = false; int formatStringArgNo = -1; - if (tok->strAt(1) == "(" && mSettings->library.formatstr_function(tok)) { - formatStringArgNo = mSettings->library.formatstr_argno(tok); - scan = mSettings->library.formatstr_scan(tok); - scanf_s = mSettings->library.formatstr_secure(tok); + if (tok->strAt(1) == "(" && mSettings.library.formatstr_function(tok)) { + formatStringArgNo = mSettings.library.formatstr_argno(tok); + scan = mSettings.library.formatstr_scan(tok); + scanf_s = mSettings.library.formatstr_secure(tok); } if (formatStringArgNo >= 0) { @@ -631,8 +631,8 @@ void CheckIOImpl::checkFormatString(const Token * const tok, const bool scan, const bool scanf_s) { - const bool isWindows = mSettings->platform.isWindows(); - const bool printWarning = mSettings->severity.isEnabled(Severity::warning); + const bool isWindows = mSettings.platform.isWindows(); + const bool printWarning = mSettings.severity.isEnabled(Severity::warning); const std::string &formatString = formatStringTok->str(); // Count format string parameters.. @@ -722,9 +722,9 @@ void CheckIOImpl::checkFormatString(const Token * const tok, } // Perform type checks - ArgumentInfo argInfo(argListTok, *mSettings, mTokenizer->isCPP()); + ArgumentInfo argInfo(argListTok, mSettings, mTokenizer->isCPP()); - if ((argInfo.typeToken && !argInfo.isLibraryType(*mSettings)) || *i == ']') { + if ((argInfo.typeToken && !argInfo.isLibraryType(mSettings)) || *i == ']') { if (scan) { std::string specifier; bool done = false; @@ -1737,7 +1737,7 @@ void CheckIOImpl::wrongPrintfScanfArgumentsError(const Token* tok, nonneg int numFunction) { const Severity severity = numFormat > numFunction ? Severity::error : Severity::warning; - if (severity != Severity::error && !mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("wrongPrintfScanfArgNum")) + if (severity != Severity::error && !mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("wrongPrintfScanfArgNum")) return; std::ostringstream errmsg; @@ -1756,7 +1756,7 @@ void CheckIOImpl::wrongPrintfScanfArgumentsError(const Token* tok, void CheckIOImpl::wrongPrintfScanfPosixParameterPositionError(const Token* tok, const std::string& functionName, nonneg int index, nonneg int numFunction) { - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("wrongPrintfScanfParameterPositionError")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("wrongPrintfScanfParameterPositionError")) return; std::ostringstream errmsg; errmsg << functionName << ": "; @@ -1771,7 +1771,7 @@ void CheckIOImpl::wrongPrintfScanfPosixParameterPositionError(const Token* tok, void CheckIOImpl::invalidScanfArgTypeError_s(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a \'"; @@ -1787,7 +1787,7 @@ void CheckIOImpl::invalidScanfArgTypeError_s(const Token* tok, nonneg int numFor void CheckIOImpl::invalidScanfArgTypeError_int(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; @@ -1832,7 +1832,7 @@ void CheckIOImpl::invalidScanfArgTypeError_int(const Token* tok, nonneg int numF void CheckIOImpl::invalidScanfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; @@ -1851,7 +1851,7 @@ void CheckIOImpl::invalidScanfArgTypeError_float(const Token* tok, nonneg int nu void CheckIOImpl::invalidPrintfArgTypeError_s(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%s in format string (no. " << numFormat << ") requires \'char *\' but the argument type is "; @@ -1862,7 +1862,7 @@ void CheckIOImpl::invalidPrintfArgTypeError_s(const Token* tok, nonneg int numFo void CheckIOImpl::invalidPrintfArgTypeError_n(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%n in format string (no. " << numFormat << ") requires \'int *\' but the argument type is "; @@ -1873,7 +1873,7 @@ void CheckIOImpl::invalidPrintfArgTypeError_n(const Token* tok, nonneg int numFo void CheckIOImpl::invalidPrintfArgTypeError_p(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%p in format string (no. " << numFormat << ") requires an address but the argument type is "; @@ -1923,7 +1923,7 @@ static void printfFormatType(std::ostream& os, const std::string& specifier, boo void CheckIOImpl::invalidPrintfArgTypeError_uint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires "; @@ -1937,7 +1937,7 @@ void CheckIOImpl::invalidPrintfArgTypeError_uint(const Token* tok, nonneg int nu void CheckIOImpl::invalidPrintfArgTypeError_sint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires "; @@ -1950,7 +1950,7 @@ void CheckIOImpl::invalidPrintfArgTypeError_sint(const Token* tok, nonneg int nu void CheckIOImpl::invalidPrintfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) { const Severity severity = getSeverity(argInfo); - if (!mSettings->severity.isEnabled(severity)) + if (!mSettings.severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; @@ -2019,7 +2019,7 @@ void CheckIOImpl::argumentType(std::ostream& os, const ArgumentInfo * argInfo) void CheckIOImpl::invalidLengthModifierError(const Token* tok, nonneg int numFormat, const std::string& modifier) { - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("invalidLengthModifierError")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("invalidLengthModifierError")) return; std::ostringstream errmsg; errmsg << "'" << modifier << "' in format string (no. " << numFormat << ") is a length modifier and cannot be used without a conversion specifier."; @@ -2038,7 +2038,7 @@ void CheckIOImpl::invalidScanfFormatWidthError(const Token* tok, nonneg int numF std::ostringstream errmsg; if (arrlen > width) { - if (tok != nullptr && (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning))) + if (tok != nullptr && (!mSettings.certainty.isEnabled(Certainty::inconclusive) || !mSettings.severity.isEnabled(Severity::warning))) return; errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is smaller than destination buffer" << " '" << varname << "[" << arrlen << "]'."; @@ -2052,7 +2052,7 @@ void CheckIOImpl::invalidScanfFormatWidthError(const Token* tok, nonneg int numF void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckIOImpl checkIO(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckIOImpl checkIO(&tokenizer, tokenizer.getSettings(), errorLogger); checkIO.checkWrongPrintfScanfArguments(); checkIO.checkCoutCerrMisusage(); @@ -2060,7 +2060,7 @@ void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkIO.invalidScanf(); } -void CheckIO::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckIO::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckIOImpl c(nullptr, settings, errorLogger); c.coutCerrMisusageError(nullptr, "cout"); diff --git a/lib/checkio.h b/lib/checkio.h index acad40de136..4642feac511 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -52,7 +52,7 @@ class CPPCHECKLIB CheckIO : public Check { /** @brief Run checks on the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check format string input/output operations.\n" @@ -72,7 +72,7 @@ class CPPCHECKLIB CheckIO : public Check { class CPPCHECKLIB CheckIOImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckIOImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckIOImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for missusage of std::cout */ diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 7e12872c3d4..11d1086ee5d 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -137,9 +137,9 @@ void CheckLeakAutoVarImpl::deallocReturnError(const Token *tok, const Token *dea void CheckLeakAutoVarImpl::configurationInfo(const Token* tok, const std::pair& functionUsage) { - if (mSettings->checkLibrary && functionUsage.second == VarInfo::USED && + if (mSettings.checkLibrary && functionUsage.second == VarInfo::USED && (!functionUsage.first || !functionUsage.first->function() || !functionUsage.first->function()->hasBody())) { - std::string funcStr = functionUsage.first ? mSettings->library.getFunctionName(functionUsage.first) : "f"; + std::string funcStr = functionUsage.first ? mSettings.library.getFunctionName(functionUsage.first) : "f"; if (funcStr.empty()) funcStr = "unknown::" + functionUsage.first->str(); reportError(tok, @@ -162,7 +162,7 @@ void CheckLeakAutoVarImpl::doubleFreeError(const Token *tok, const Token *prevFr void CheckLeakAutoVarImpl::check() { - if (mSettings->clang) + if (mSettings.clang) return; logChecker("CheckLeakAutoVar::check"); // notclang @@ -381,7 +381,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, ftok = ftok->tokAt(2); // bailout for variable passed to library function with out parameter - if (const Library::Function *libFunc = mSettings->library.getFunction(ftok)) { + if (const Library::Function *libFunc = mSettings.library.getFunction(ftok)) { using ArgumentChecks = Library::ArgumentChecks; using Direction = ArgumentChecks::Direction; const std::vector args = getArguments(ftok); @@ -479,7 +479,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, // allocation? const Token *const fTok = tokRightAstOperand ? tokRightAstOperand->previous() : nullptr; if (Token::Match(fTok, "%type% (")) { - const Library::AllocFunc* f = mSettings->library.getAllocFuncInfo(fTok); + const Library::AllocFunc* f = mSettings.library.getAllocFuncInfo(fTok); if (f && f->arg == -1) { VarInfo::AllocInfo& varAlloc = alloctype[varTok->varId()]; varAlloc.type = f->groupId; @@ -545,7 +545,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, tokRightAstOperand = tokRightAstOperand->astOperand2() ? tokRightAstOperand->astOperand2() : tokRightAstOperand->astOperand1(); if (tokRightAstOperand && Token::Match(tokRightAstOperand->previous(), "%type% (")) { const Token * fTok = tokRightAstOperand->previous(); - const Library::AllocFunc* f = mSettings->library.getAllocFuncInfo(fTok); + const Library::AllocFunc* f = mSettings.library.getAllocFuncInfo(fTok); if (f && f->arg == -1) { VarInfo::AllocInfo& varAlloc = alloctype[innerTok->varId()]; varAlloc.type = f->groupId; @@ -568,7 +568,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, // check for function call if (openingPar) { - const Library::AllocFunc* allocFunc = mSettings->library.getDeallocFuncInfo(innerTok); + const Library::AllocFunc* allocFunc = mSettings.library.getDeallocFuncInfo(innerTok); // innerTok is a function name const VarInfo::AllocInfo allocation(0, VarInfo::NOALLOC); functionCall(innerTok, openingPar, varInfo, allocation, allocFunc); @@ -623,7 +623,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, if (std::any_of(varInfo1.alloctype.begin(), varInfo1.alloctype.end(), [&](const std::pair& info) { if (info.second.status != VarInfo::ALLOC) return false; - const Token* ret = getReturnValueFromOutparamAlloc(info.second.allocTok, *mSettings); + const Token* ret = getReturnValueFromOutparamAlloc(info.second.allocTok, mSettings); return ret && vartok && ret->varId() && ret->varId() == vartok->varId(); })) { varInfo1.clear(); @@ -755,7 +755,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, // Function call.. else if (const Token* openingPar = isFunctionCall(ftok)) { - const Library::AllocFunc* af = mSettings->library.getDeallocFuncInfo(ftok); + const Library::AllocFunc* af = mSettings.library.getDeallocFuncInfo(ftok); VarInfo::AllocInfo allocation(af ? af->groupId : 0, VarInfo::DEALLOC, ftok); if (allocation.type == 0) allocation.status = VarInfo::NOALLOC; @@ -776,8 +776,8 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, if (ftok->function() && !ftok->function()->isAttributeNoreturn() && !(ftok->function()->functionScope && mTokenizer->isScopeNoReturn(ftok->function()->functionScope->bodyEnd))) // check function scope continue; - const std::string functionName(mSettings->library.getFunctionName(ftok)); - if (!mSettings->library.isLeakIgnore(functionName) && !mSettings->library.isUse(functionName)) { + const std::string functionName(mSettings.library.getFunctionName(ftok)); + if (!mSettings.library.isLeakIgnore(functionName) && !mSettings.library.isUse(functionName)) { const VarInfo::Usage usage = Token::simpleMatch(openingPar, "( )") ? VarInfo::NORET : VarInfo::USED; // TODO: check parameters passed to function varInfo.possibleUsageAll({ ftok, usage }); } @@ -800,7 +800,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, } // Check smart pointer - else if (Token::Match(ftok, "%name% <") && mSettings->library.isSmartPointer(tok)) { + else if (Token::Match(ftok, "%name% <") && mSettings.library.isSmartPointer(tok)) { const Token * typeEndTok = ftok->linkAt(1); if (!Token::Match(typeEndTok, "> %var% {|( %var% ,|)|}")) continue; @@ -835,7 +835,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, const Token * dtok = Token::findmatch(deleterToken, "& %name%", endDeleterToken); if (dtok) { dtok = dtok->next(); - af = mSettings->library.getDeallocFuncInfo(dtok); + af = mSettings.library.getDeallocFuncInfo(dtok); } if (!dtok || !af) { const Token * tscopeStart = nullptr; @@ -865,7 +865,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, if (tscopeStart && tscopeEnd) { for (const Token *tok2 = tscopeStart; tok2 != tscopeEnd; tok2 = tok2->next()) { - af = mSettings->library.getDeallocFuncInfo(tok2); + af = mSettings.library.getDeallocFuncInfo(tok2); if (af) break; } @@ -896,7 +896,7 @@ const Token * CheckLeakAutoVarImpl::checkTokenInsideExpression(const Token * con if (var != varInfo.alloctype.end()) { bool unknown = false; if (var->second.status == VarInfo::DEALLOC && tok->valueType() && tok->valueType()->pointer && - CheckNullPointerImpl::isPointerDeRef(tok, unknown, *mSettings, /*checkNullArg*/ false) && !unknown) { + CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings, /*checkNullArg*/ false) && !unknown) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { varInfo.erase(tok->varId()); @@ -917,9 +917,9 @@ const Token * CheckLeakAutoVarImpl::checkTokenInsideExpression(const Token * con if ((rhs->str() == "." || rhs->varId() == tok->varId()) && isAssignment) { // simple assignment varInfo.erase(tok->varId()); - } else if (rhs->astParent() && rhs->str() == "(" && !mSettings->library.returnValue(rhs->astOperand1()).empty()) { + } else if (rhs->astParent() && rhs->str() == "(" && !mSettings.library.returnValue(rhs->astOperand1()).empty()) { // #9298, assignment through return value of a function - const std::string &returnValue = mSettings->library.returnValue(rhs->astOperand1()); + const std::string &returnValue = mSettings.library.returnValue(rhs->astOperand1()); if (startsWith(returnValue, "arg")) { int argn; const Token *func = getTokenArgumentFunction(tok, argn); @@ -940,12 +940,12 @@ const Token * CheckLeakAutoVarImpl::checkTokenInsideExpression(const Token * con // check for function call const Token * const openingPar = inFuncCall ? nullptr : isFunctionCall(tok); if (openingPar) { - const Library::AllocFunc* allocFunc = mSettings->library.getDeallocFuncInfo(tok); + const Library::AllocFunc* allocFunc = mSettings.library.getDeallocFuncInfo(tok); VarInfo::AllocInfo alloc(allocFunc ? allocFunc->groupId : 0, VarInfo::DEALLOC, tok); if (alloc.type == 0) alloc.status = VarInfo::NOALLOC; functionCall(tok, openingPar, varInfo, alloc, nullptr); - const std::string &returnValue = mSettings->library.returnValue(tok); + const std::string &returnValue = mSettings.library.returnValue(tok); if (startsWith(returnValue, "arg")) // the function returns one of its argument, we need to process a potential assignment return openingPar; @@ -958,7 +958,7 @@ const Token * CheckLeakAutoVarImpl::checkTokenInsideExpression(const Token * con void CheckLeakAutoVarImpl::changeAllocStatusIfRealloc(std::map &alloctype, const Token *fTok, const Token *retTok) const { - const Library::AllocFunc* f = mSettings->library.getReallocFuncInfo(fTok); + const Library::AllocFunc* f = mSettings.library.getReallocFuncInfo(fTok); if (f && f->arg == -1 && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(fTok)) { const Token* argTok = getArguments(fTok).at(f->reallocArg - 1); if (alloctype.find(argTok->varId()) != alloctype.end()) { @@ -984,7 +984,7 @@ void CheckLeakAutoVarImpl::changeAllocStatus(VarInfo &varInfo, const VarInfo::Al if (var != alloctype.end()) { // bailout if function is also allocating, since the argument might be moved // to the return value, such as in fdopen - if (allocation.allocTok && mSettings->library.getAllocFuncInfo(allocation.allocTok)) { + if (allocation.allocTok && mSettings.library.getAllocFuncInfo(allocation.allocTok)) { varInfo.erase(arg->varId()); return; } @@ -1017,8 +1017,8 @@ void CheckLeakAutoVarImpl::changeAllocStatus(VarInfo &varInfo, const VarInfo::Al void CheckLeakAutoVarImpl::functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af) { // Ignore function call? - const bool isLeakIgnore = mSettings->library.isLeakIgnore(mSettings->library.getFunctionName(tokName)); - if (mSettings->library.getReallocFuncInfo(tokName)) + const bool isLeakIgnore = mSettings.library.isLeakIgnore(mSettings.library.getFunctionName(tokName)); + if (mSettings.library.getReallocFuncInfo(tokName)) return; if (tokName->next()->valueType() && tokName->next()->valueType()->container && tokName->next()->valueType()->container->stdStringLike) return; @@ -1069,10 +1069,10 @@ void CheckLeakAutoVarImpl::functionCall(const Token *tokName, const Token *tokOp // Is variable allocated? if (!isnull && (!af || af->arg == argNr)) { - const Library::AllocFunc* deallocFunc = mSettings->library.getDeallocFuncInfo(tokName); + const Library::AllocFunc* deallocFunc = mSettings.library.getDeallocFuncInfo(tokName); VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName); - if (const Library::AllocFunc* allocFunc = mSettings->library.getAllocFuncInfo(tokName)) { - if (mSettings->library.getDeallocFuncInfo(tokName)) { + if (const Library::AllocFunc* allocFunc = mSettings.library.getAllocFuncInfo(tokName)) { + if (mSettings.library.getDeallocFuncInfo(tokName)) { changeAllocStatus(varInfo, dealloc.type == 0 ? allocation : dealloc, tokName, arg); } if (allocFunc->arg == argNr && @@ -1092,7 +1092,7 @@ void CheckLeakAutoVarImpl::functionCall(const Token *tokName, const Token *tokOp } } // Check smart pointer - else if (Token::Match(arg, "%name% < %type%") && mSettings->library.isSmartPointer(argTypeStartTok)) { + else if (Token::Match(arg, "%name% < %type%") && mSettings.library.isSmartPointer(argTypeStartTok)) { const Token * typeEndTok = arg->linkAt(1); const Token * allocTok = nullptr; if (!Token::Match(typeEndTok, "> {|( %var% ,|)|}")) @@ -1117,14 +1117,14 @@ void CheckLeakAutoVarImpl::functionCall(const Token *tokName, const Token *tokOp // Check if its a pointer to a function const Token * dtok = Token::findmatch(deleterToken, "& %name%", endDeleterToken); if (dtok) { - sp_af = mSettings->library.getDeallocFuncInfo(dtok->tokAt(1)); + sp_af = mSettings.library.getDeallocFuncInfo(dtok->tokAt(1)); } else { // If the deleter is a class, check if class calls the dealloc function dtok = Token::findmatch(deleterToken, "%type%", endDeleterToken); if (dtok && dtok->type()) { const Scope * tscope = dtok->type()->classScope; for (const Token *tok2 = tscope->bodyStart; tok2 != tscope->bodyEnd; tok2 = tok2->next()) { - sp_af = mSettings->library.getDeallocFuncInfo(tok2); + sp_af = mSettings.library.getDeallocFuncInfo(tok2); if (sp_af) { allocTok = tok2; break; @@ -1209,7 +1209,7 @@ void CheckLeakAutoVarImpl::ret(const Token *tok, VarInfo &varInfo, const bool is while (tok3 && tok3->isCast() && (!tok3->valueType() || tok3->valueType()->pointer || - isSafeCast(tok3->valueType(), *mSettings))) + isSafeCast(tok3->valueType(), mSettings))) tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1(); if (tok3 && tok3->varId() == varid) tok2 = tok3->next(); @@ -1232,7 +1232,7 @@ void CheckLeakAutoVarImpl::ret(const Token *tok, VarInfo &varInfo, const bool is // don't warn when returning after checking return value of outparam allocation const Token* outparamFunc{}; if ((tok->scope()->type == ScopeType::eIf || tok->scope()->type== ScopeType::eElse) && - (outparamFunc = getOutparamAllocation(it->second.allocTok, *mSettings))) { + (outparamFunc = getOutparamAllocation(it->second.allocTok, mSettings))) { const Scope* scope = tok->scope(); if (scope->type == ScopeType::eElse) { scope = scope->bodyStart->tokAt(-2)->scope(); @@ -1280,11 +1280,11 @@ void CheckLeakAutoVarImpl::ret(const Token *tok, VarInfo &varInfo, const bool is void CheckLeakAutoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckLeakAutoVarImpl checkLeakAutoVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckLeakAutoVarImpl checkLeakAutoVar(&tokenizer, tokenizer.getSettings(), errorLogger); checkLeakAutoVar.check(); } -void CheckLeakAutoVar::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckLeakAutoVar::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckLeakAutoVarImpl c(nullptr, settings, errorLogger); c.deallocReturnError(nullptr, nullptr, "p"); diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index ce7e1ddbd8b..c12c03b6a09 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -113,7 +113,7 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check { private: void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Detect when a auto variable is allocated but not deallocated or deallocated twice.\n"; @@ -123,7 +123,7 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check { class CPPCHECKLIB CheckLeakAutoVarImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckLeakAutoVarImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckLeakAutoVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** check for leaks in all scopes */ diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index cef03b1a538..0286884ab16 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -95,7 +95,7 @@ CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getAllocationType(const Toke return New; } - if (mSettings->hasLib("posix")) { + if (mSettings.hasLib("posix")) { if (Token::Match(tok2, "open|openat|creat|mkstemp|mkostemp|socket (")) { // simple sanity check of function parameters.. // TODO: Make such check for all these functions @@ -114,11 +114,11 @@ CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getAllocationType(const Toke } // Does tok2 point on a Library allocation function? - const int alloctype = mSettings->library.getAllocId(tok2, -1); + const int alloctype = mSettings.library.getAllocId(tok2, -1); if (alloctype > 0) { - if (alloctype == mSettings->library.deallocId("free")) + if (alloctype == mSettings.library.deallocId("free")) return Malloc; - if (alloctype == mSettings->library.deallocId("fclose")) + if (alloctype == mSettings.library.deallocId("fclose")) return File; return Library::ismemory(alloctype) ? OtherMem : OtherRes; } @@ -159,7 +159,7 @@ CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getReallocationType(const To if (!Token::Match(tok2, "%name% (")) return No; - const Library::AllocFunc *f = mSettings->library.getReallocFuncInfo(tok2); + const Library::AllocFunc *f = mSettings.library.getReallocFuncInfo(tok2); if (!(f && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(tok2))) return No; const auto args = getArguments(tok2); @@ -173,11 +173,11 @@ CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getReallocationType(const To if (varid > 0 && !Token::Match(arg, "%varid% [,)]", varid)) return No; - const int realloctype = mSettings->library.getReallocId(tok2, -1); + const int realloctype = mSettings.library.getReallocId(tok2, -1); if (realloctype > 0) { - if (realloctype == mSettings->library.deallocId("free")) + if (realloctype == mSettings.library.deallocId("free")) return Malloc; - if (realloctype == mSettings->library.deallocId("fclose")) + if (realloctype == mSettings.library.deallocId("fclose")) return File; return Library::ismemory(realloctype) ? OtherMem : OtherRes; } @@ -216,7 +216,7 @@ CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getDeallocationType(const To if (tok->str() == "realloc" && Token::simpleMatch(vartok->next(), ", 0 )")) return Malloc; - if (mSettings->hasLib("posix")) { + if (mSettings.hasLib("posix")) { if (tok->str() == "close") return Fd; if (tok->str() == "pclose") @@ -224,11 +224,11 @@ CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getDeallocationType(const To } // Does tok point on a Library deallocation function? - const int dealloctype = mSettings->library.getDeallocId(tok, argNr); + const int dealloctype = mSettings.library.getDeallocId(tok, argNr); if (dealloctype > 0) { - if (dealloctype == mSettings->library.deallocId("free")) + if (dealloctype == mSettings.library.deallocId("free")) return Malloc; - if (dealloctype == mSettings->library.deallocId("fclose")) + if (dealloctype == mSettings.library.deallocId("fclose")) return File; return Library::ismemory(dealloctype) ? OtherMem : OtherRes; } @@ -243,7 +243,7 @@ CheckMemoryLeakImpl::AllocType CheckMemoryLeakImpl::getDeallocationType(const To bool CheckMemoryLeakImpl::isReopenStandardStream(const Token *tok) const { if (getReallocationType(tok, 0) == File) { - const Library::AllocFunc *f = mSettings->library.getReallocFuncInfo(tok); + const Library::AllocFunc *f = mSettings.library.getReallocFuncInfo(tok); if (f && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(tok)) { const Token* arg = getArguments(tok).at(f->reallocArg - 1); if (Token::Match(arg, "stdin|stdout|stderr")) @@ -255,7 +255,7 @@ bool CheckMemoryLeakImpl::isReopenStandardStream(const Token *tok) const bool CheckMemoryLeakImpl::isOpenDevNull(const Token *tok) const { - if (mSettings->hasLib("posix") && tok->str() == "open" && numberOfArguments(tok) == 2) { + if (mSettings.hasLib("posix") && tok->str() == "open" && numberOfArguments(tok) == 2) { const Token* arg = getArguments(tok).at(0); if (Token::simpleMatch(arg, "\"/dev/null\"")) return true; @@ -440,8 +440,8 @@ void CheckMemoryLeakInFunctionImpl::checkReallocUsage() const Token *const reallocTok = parTok->astOperand1(); if (!reallocTok) continue; - const Library::AllocFunc* f = mSettings->library.getReallocFuncInfo(reallocTok); - if (!(f && f->arg == -1 && mSettings->library.isnotnoreturn(reallocTok))) + const Library::AllocFunc* f = mSettings.library.getReallocFuncInfo(reallocTok); + if (!(f && f->arg == -1 && mSettings.library.isnotnoreturn(reallocTok))) continue; const AllocType allocType = getReallocationType(reallocTok, tok->varId()); @@ -467,7 +467,7 @@ void CheckMemoryLeakInFunctionImpl::checkReallocUsage() Token::findmatch(scope->bodyStart, "[{};] %varid% = *| %var%", tok, tok->varId())) continue; if (const Token* storeTok = Token::findmatch(scope->bodyStart, "[{};] %varid% = %name% (", tok, tok->varId())) - if (storeTok->tokAt(3) != reallocTok && !mSettings->library.getAllocFuncInfo(storeTok->tokAt(3))) + if (storeTok->tokAt(3) != reallocTok && !mSettings.library.getAllocFuncInfo(storeTok->tokAt(3))) continue; // Check if the argument is known to be null, which means it is not a memory leak @@ -492,11 +492,11 @@ void CheckMemoryLeakInFunctionImpl::checkReallocUsage() void CheckMemoryLeakInFunction::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, tokenizer.getSettings(), errorLogger); checkMemoryLeak.checkReallocUsage(); } -void CheckMemoryLeakInFunction::getErrorMessages(ErrorLogger *e, const Settings *settings) const +void CheckMemoryLeakInFunction::getErrorMessages(ErrorLogger *e, const Settings &settings) const { CheckMemoryLeakInFunctionImpl c(nullptr, settings, e); c.memleakError(nullptr, "varname"); @@ -629,7 +629,7 @@ void CheckMemoryLeakInClassImpl::variable(const Scope *scope, const Token *tokVa } // Function call .. possible deallocation - else if (Token::Match(tok->previous(), "[{};] %name% (") && !tok->isKeyword() && !mSettings->library.isLeakIgnore(tok->str())) { + else if (Token::Match(tok->previous(), "[{};] %name% (") && !tok->isKeyword() && !mSettings.library.isLeakIgnore(tok->str())) { return; } } @@ -645,7 +645,7 @@ void CheckMemoryLeakInClassImpl::variable(const Scope *scope, const Token *tokVa void CheckMemoryLeakInClassImpl::unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname) { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unsafeClassCanLeak")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unsafeClassCanLeak")) return; reportError(tok, Severity::style, "unsafeClassCanLeak", @@ -661,7 +661,7 @@ void CheckMemoryLeakInClassImpl::checkPublicFunctions(const Scope *scope, const // Check that public functions deallocate the pointers that they allocate. // There is no checking how these functions are used and therefore it // isn't established if there is real leaks or not. - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; const int varid = classtok->varId(); @@ -696,11 +696,11 @@ void CheckMemoryLeakInClass::runChecks(const Tokenizer &tokenizer, ErrorLogger * if (!tokenizer.isCPP()) return; - CheckMemoryLeakInClassImpl checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckMemoryLeakInClassImpl checkMemoryLeak(&tokenizer, tokenizer.getSettings(), errorLogger); checkMemoryLeak.check(); } -void CheckMemoryLeakInClass::getErrorMessages(ErrorLogger *e, const Settings *settings) const +void CheckMemoryLeakInClass::getErrorMessages(ErrorLogger *e, const Settings &settings) const { CheckMemoryLeakInClassImpl c(nullptr, settings, e); c.publicAllocationError(nullptr, "varname"); @@ -709,7 +709,7 @@ void CheckMemoryLeakInClass::getErrorMessages(ErrorLogger *e, const Settings *se void CheckMemoryLeakStructMemberImpl::check() { - if (mSettings->clang) + if (mSettings.clang) return; logChecker("CheckMemoryLeakStructMember::check"); @@ -739,7 +739,7 @@ bool CheckMemoryLeakStructMemberImpl::isMalloc(const Variable *variable) const const Token* tok3 = tok2->tokAt(1)->astOperand2(); while (tok3 && tok3->isCast()) tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1(); - if ((tok3 && Token::Match(tok3->tokAt(-1), "%name% (") && mSettings->library.getAllocFuncInfo(tok3->tokAt(-1))) || + if ((tok3 && Token::Match(tok3->tokAt(-1), "%name% (") && mSettings.library.getAllocFuncInfo(tok3->tokAt(-1))) || (Token::simpleMatch(tok3, "new") && tok3->isCpp())) { alloc = true; } @@ -767,7 +767,7 @@ void CheckMemoryLeakStructMemberImpl::checkStructVariable(const Variable* const auto deallocInFunction = [this](const Token* tok, int structid) -> bool { // Calling non-function / function that doesn't deallocate? - if (tok->isKeyword() || mSettings->library.isLeakIgnore(tok->str())) + if (tok->isKeyword() || mSettings.library.isLeakIgnore(tok->str())) return false; // Check if the struct is used.. @@ -889,7 +889,7 @@ void CheckMemoryLeakStructMemberImpl::checkStructVariable(const Variable* const } // Deallocating the struct.. - else if (Token::Match(tok3, "%name% ( %varid% )", structid) && mSettings->library.getDeallocFuncInfo(tok3)) { + else if (Token::Match(tok3, "%name% ( %varid% )", structid) && mSettings.library.getDeallocFuncInfo(tok3)) { if (indentlevel2 == 0) memoryLeak(tok3, variable->name() + "." + tok2->strAt(2), allocType); break; @@ -923,7 +923,7 @@ void CheckMemoryLeakStructMemberImpl::checkStructVariable(const Variable* const --indentlevel4; if (indentlevel4 == 0) break; - } else if (Token::Match(tok4, "%name% ( %var% . %varid% )", structmemberid) && mSettings->library.getDeallocFuncInfo(tok4)) { + } else if (Token::Match(tok4, "%name% ( %var% . %varid% )", structmemberid) && mSettings.library.getDeallocFuncInfo(tok4)) { break; } } @@ -968,11 +968,11 @@ void CheckMemoryLeakStructMemberImpl::checkStructVariable(const Variable* const void CheckMemoryLeakStructMember::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckMemoryLeakStructMemberImpl checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckMemoryLeakStructMemberImpl checkMemoryLeak(&tokenizer, tokenizer.getSettings(), errorLogger); checkMemoryLeak.check(); } -void CheckMemoryLeakStructMember::getErrorMessages(ErrorLogger * errorLogger, const Settings * settings) const +void CheckMemoryLeakStructMember::getErrorMessages(ErrorLogger * errorLogger, const Settings & settings) const { (void)errorLogger; (void)settings; @@ -1028,7 +1028,7 @@ void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scop if (Token::simpleMatch(tok->next()->astParent(), "(")) // passed to another function continue; - if (!tok->isKeyword() && !tok->function() && !mSettings->library.isLeakIgnore(functionName)) + if (!tok->isKeyword() && !tok->function() && !mSettings.library.isLeakIgnore(functionName)) continue; const std::vector args = getArguments(tok); @@ -1048,8 +1048,8 @@ void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scop if (alloc == New || alloc == NewArray) { const Token* typeTok = arg->next(); bool bail = !typeTok->isStandardType() && - !mSettings->library.detectContainerOrIterator(typeTok) && - !mSettings->library.podtype(typeTok->expressionString()); + !mSettings.library.detectContainerOrIterator(typeTok) && + !mSettings.library.podtype(typeTok->expressionString()); if (bail && typeTok->type() && typeTok->type()->classScope && typeTok->type()->classScope->numConstructors == 0 && typeTok->type()->classScope->getDestructor() == nullptr) { @@ -1064,8 +1064,8 @@ void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scop const Variable* argvar = tok->function()->getArgumentVar(argnr); if (!argvar || !argvar->valueType()) continue; - const size_t argSize = argvar->valueType()->getSizeOf(*mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); - if (argSize == 0 || argSize >= mSettings->platform.sizeof_pointer) + const size_t argSize = argvar->valueType()->getSizeOf(mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); + if (argSize == 0 || argSize >= mSettings.platform.sizeof_pointer) continue; } functionCallLeak(arg, arg->str(), functionName); @@ -1110,7 +1110,7 @@ void CheckMemoryLeakNoVarImpl::checkForUnusedReturnValue(const Scope *scope) bool warn = true; if (isNew) { const Token* typeTok = tok->next(); - warn = typeTok && (typeTok->isStandardType() || mSettings->library.detectContainer(typeTok)); + warn = typeTok && (typeTok->isStandardType() || mSettings.library.detectContainer(typeTok)); } if (!parent && warn) { @@ -1150,7 +1150,7 @@ void CheckMemoryLeakNoVarImpl::checkForUnsafeArgAlloc(const Scope *scope) if (!mTokenizer->isCPP()) return; - if (!mSettings->isPremiumEnabled("leakUnsafeArgAlloc") && (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning))) + if (!mSettings.isPremiumEnabled("leakUnsafeArgAlloc") && (!mSettings.certainty.isEnabled(Certainty::inconclusive) || !mSettings.severity.isEnabled(Severity::warning))) return; logChecker("CheckMemoryLeakNoVar::checkForUnsafeArgAlloc"); @@ -1216,11 +1216,11 @@ void CheckMemoryLeakNoVarImpl::unsafeArgAllocError(const Token *tok, const std:: void CheckMemoryLeakNoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckMemoryLeakNoVarImpl checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckMemoryLeakNoVarImpl checkMemoryLeak(&tokenizer, tokenizer.getSettings(), errorLogger); checkMemoryLeak.check(); } -void CheckMemoryLeakNoVar::getErrorMessages(ErrorLogger *e, const Settings *settings) const +void CheckMemoryLeakNoVar::getErrorMessages(ErrorLogger *e, const Settings &settings) const { CheckMemoryLeakNoVarImpl c(nullptr, settings, e); c.functionCallLeak(nullptr, "funcName", "funcName"); diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 047cf3295ae..6c867749fa4 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -75,7 +75,7 @@ class CPPCHECKLIB CheckMemoryLeakInFunction : public Check { void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** Report all possible errors (for the --errorlist) */ - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *e, const Settings &settings) const override; /** * Get class information (--doc) @@ -100,7 +100,7 @@ class CPPCHECKLIB CheckMemoryLeakInClass : public Check { private: void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *e, const Settings &settings) const override; std::string classInfo() const override { return "If the constructor allocate memory then the destructor must deallocate it.\n"; @@ -120,7 +120,7 @@ class CPPCHECKLIB CheckMemoryLeakStructMember : public Check { private: void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger * errorLogger, const Settings * settings) const override; + void getErrorMessages(ErrorLogger * errorLogger, const Settings & settings) const override; std::string classInfo() const override { return "Don't forget to deallocate struct members\n"; @@ -140,7 +140,7 @@ class CPPCHECKLIB CheckMemoryLeakNoVar : public Check { private: void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *e, const Settings &settings) const override; std::string classInfo() const override { return "Not taking the address to allocated memory\n"; @@ -175,7 +175,7 @@ class CPPCHECKLIB CheckMemoryLeakImpl : public CheckImpl { CheckMemoryLeakImpl(const CheckMemoryLeakImpl &) = delete; CheckMemoryLeakImpl& operator=(const CheckMemoryLeakImpl &) = delete; - CheckMemoryLeakImpl(const Tokenizer *t, const Settings *s, ErrorLogger *e) + CheckMemoryLeakImpl(const Tokenizer *t, const Settings &s, ErrorLogger *e) : CheckImpl(t, s, e) {} /** @brief What type of allocation are used.. the "Many" means that several types of allocation and deallocation are used */ @@ -254,7 +254,7 @@ class CPPCHECKLIB CheckMemoryLeakImpl : public CheckImpl { class CPPCHECKLIB CheckMemoryLeakInFunctionImpl : public CheckMemoryLeakImpl { public: /** @brief This constructor is used when running checks */ - CheckMemoryLeakInFunctionImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckMemoryLeakInFunctionImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} /** @@ -271,7 +271,7 @@ class CPPCHECKLIB CheckMemoryLeakInFunctionImpl : public CheckMemoryLeakImpl { class CPPCHECKLIB CheckMemoryLeakInClassImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakInClassImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckMemoryLeakInClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); @@ -292,7 +292,7 @@ class CPPCHECKLIB CheckMemoryLeakInClassImpl : private CheckMemoryLeakImpl { class CPPCHECKLIB CheckMemoryLeakStructMemberImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakStructMemberImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckMemoryLeakStructMemberImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); @@ -309,7 +309,7 @@ class CPPCHECKLIB CheckMemoryLeakStructMemberImpl : private CheckMemoryLeakImpl class CPPCHECKLIB CheckMemoryLeakNoVarImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakNoVarImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckMemoryLeakNoVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 2dbff296cf0..92938b4a60f 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -130,7 +130,7 @@ namespace { bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown) const { - return isPointerDeRef(tok, unknown, *mSettings); + return isPointerDeRef(tok, unknown, mSettings); } bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings, bool checkNullArg) @@ -266,7 +266,7 @@ static bool isNullablePointer(const Token* tok) void CheckNullPointerImpl::nullPointerByDeRefAndCheck() { - const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive)); + const bool printInconclusive = (mSettings.certainty.isEnabled(Certainty::inconclusive)); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { @@ -292,13 +292,13 @@ void CheckNullPointerImpl::nullPointerByDeRefAndCheck() return true; }; const Token* const start = (scope->function && scope->function->isConstructor()) ? scope->function->token : scope->bodyStart; // Check initialization list - std::vector tokens = findTokensSkipDeadAndUnevaluatedCode(mSettings->library, start, scope->bodyEnd, pred); + std::vector tokens = findTokensSkipDeadAndUnevaluatedCode(mSettings.library, start, scope->bodyEnd, pred); for (const Token *tok : tokens) { const ValueFlow::Value *value = tok->getValue(0); // Pointer dereference. bool unknown = false; - if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, *mSettings)) { + if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings)) { if (unknown) nullPointerError(tok, tok->expressionString(), value, true); continue; @@ -357,7 +357,7 @@ void CheckNullPointerImpl::nullConstantDereference() if (var && !var->isPointer() && !var->isArray() && var->isStlStringType()) nullPointerError(tok); } else { // function call - const std::list var = parseFunctionCall(*tok, mSettings->library); + const std::list var = parseFunctionCall(*tok, mSettings.library); // is one of the var items a NULL pointer? for (const Token *vartok : var) { @@ -376,7 +376,7 @@ void CheckNullPointerImpl::nullConstantDereference() continue; if (argtok->getKnownIntValue() != 0) continue; - if (mSettings->library.isnullargbad(tok, argnr+1)) + if (mSettings.library.isnullargbad(tok, argnr+1)) nullPointerError(argtok); } } @@ -444,7 +444,7 @@ void CheckNullPointerImpl::nullPointerError(const Token *tok, const std::string return; } - if (!mSettings->isEnabled(value, inconclusive) && !mSettings->isPremiumEnabled("nullPointer")) + if (!mSettings.isEnabled(value, inconclusive) && !mSettings.isPremiumEnabled("nullPointer")) return; ErrorPath errorPath = getErrorPath(tok, value, "Null pointer dereference"); @@ -503,9 +503,9 @@ void CheckNullPointerImpl::arithmetic() const ValueFlow::Value* value = pointerOperand->getValue(0); if (!value) continue; - if (!mSettings->certainty.isEnabled(Certainty::inconclusive) && value->isInconclusive()) + if (!mSettings.certainty.isEnabled(Certainty::inconclusive) && value->isInconclusive()) continue; - if (value->condition && !mSettings->severity.isEnabled(Severity::warning)) + if (value->condition && !mSettings.severity.isEnabled(Severity::warning)) continue; if (value->condition) redundantConditionWarning(tok, value, value->condition, value->isInconclusive()); @@ -632,7 +632,7 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo &ctu, const std:: { (void)settings; - CheckNullPointerImpl dummy(nullptr, &settings, &errorLogger); + CheckNullPointerImpl dummy(nullptr, settings, &errorLogger); dummy. logChecker("CheckNullPointer::analyseWholeProgram"); @@ -694,13 +694,13 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo &ctu, const std:: void CheckNullPointer::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckNullPointerImpl checkNullPointer(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckNullPointerImpl checkNullPointer(&tokenizer, tokenizer.getSettings(), errorLogger); checkNullPointer.nullPointer(); checkNullPointer.arithmetic(); checkNullPointer.nullConstantDereference(); } -void CheckNullPointer::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckNullPointer::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckNullPointerImpl c(nullptr, settings, errorLogger); c.nullPointerError(nullptr, "pointer", nullptr, false); diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index f9f78280fea..4da9fe8abc7 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -67,7 +67,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; /** Get error messages. Used by --errorlist */ - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; /** class info in WIKI format. Used by --doc */ std::string classInfo() const override { @@ -80,7 +80,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { class CPPCHECKLIB CheckNullPointerImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckNullPointerImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckNullPointerImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6edbef63c0e..1adcaeb9c3a 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -82,7 +82,7 @@ static const CWE CWE783(783U); // Operator Precedence Logic Error //---------------------------------------------------------------------------------- void CheckOtherImpl::checkCastIntToCharAndBack() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckOther::checkCastIntToCharAndBack"); // warning @@ -152,7 +152,7 @@ void CheckOtherImpl::checkCastIntToCharAndBackError(const Token *tok, const std: //--------------------------------------------------------------------------- void CheckOtherImpl::clarifyCalculation() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("clarifyCalculation")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("clarifyCalculation")) return; logChecker("CheckOther::clarifyCalculation"); // style @@ -223,7 +223,7 @@ void CheckOtherImpl::clarifyCalculationError(const Token *tok, const std::string //--------------------------------------------------------------------------- void CheckOtherImpl::clarifyStatement() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckOther::clarifyStatement"); // warning @@ -259,7 +259,7 @@ void CheckOtherImpl::clarifyStatementError(const Token *tok) //--------------------------------------------------------------------------- void CheckOtherImpl::checkSuspiciousSemicolon() { - if (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.certainty.isEnabled(Certainty::inconclusive) || !mSettings.severity.isEnabled(Severity::warning)) return; const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -335,7 +335,7 @@ void CheckOtherImpl::warningOldStylePointerCast() if (!mTokenizer->isCPP()) return; - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("cstyleCast")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("cstyleCast")) return; logChecker("CheckOther::warningOldStylePointerCast"); // style,c++ @@ -410,7 +410,7 @@ void CheckOtherImpl::warningDangerousTypeCast() // Only valid on C++ code if (!mTokenizer->isCPP()) return; - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("dangerousTypeCast")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("dangerousTypeCast")) return; logChecker("CheckOther::warningDangerousTypeCast"); // warning,c++ @@ -444,7 +444,7 @@ void CheckOtherImpl::dangerousTypeCastError(const Token *tok, bool isPtr) void CheckOtherImpl::warningIntToPointerCast() { - if (!mSettings->severity.isEnabled(Severity::portability) && !mSettings->isPremiumEnabled("cstyleCast")) + if (!mSettings.severity.isEnabled(Severity::portability) && !mSettings.isPremiumEnabled("cstyleCast")) return; logChecker("CheckOther::warningIntToPointerCast"); // portability @@ -480,7 +480,7 @@ void CheckOtherImpl::intToPointerCastError(const Token *tok, const std::string& void CheckOtherImpl::suspiciousFloatingPointCast() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("suspiciousFloatingPointCast")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("suspiciousFloatingPointCast")) return; logChecker("CheckOther::suspiciousFloatingPointCast"); // style @@ -541,12 +541,12 @@ void CheckOtherImpl::suspiciousFloatingPointCastError(const Token* tok) void CheckOtherImpl::invalidPointerCast() { - if (!mSettings->severity.isEnabled(Severity::portability)) + if (!mSettings.severity.isEnabled(Severity::portability)) return; logChecker("CheckOther::invalidPointerCast"); // portability - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { @@ -594,9 +594,9 @@ void CheckOtherImpl::invalidPointerCastError(const Token* tok, const std::string void CheckOtherImpl::checkRedundantAssignment() { - if (!mSettings->severity.isEnabled(Severity::style) && - !mSettings->isPremiumEnabled("redundantAssignment") && - !mSettings->isPremiumEnabled("redundantAssignInSwitch")) + if (!mSettings.severity.isEnabled(Severity::style) && + !mSettings.isPremiumEnabled("redundantAssignment") && + !mSettings.isPremiumEnabled("redundantAssignInSwitch")) return; logChecker("CheckOther::checkRedundantAssignment"); // style @@ -666,10 +666,10 @@ void CheckOtherImpl::checkRedundantAssignment() if (tok->astOperand1()->valueType()->type == ValueType::SMART_POINTER) break; } - if (inconclusive && !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (inconclusive && !mSettings.certainty.isEnabled(Certainty::inconclusive)) continue; - FwdAnalysis fwdAnalysis(*mSettings); + FwdAnalysis fwdAnalysis(mSettings); if (fwdAnalysis.hasOperand(tok->astOperand2(), tok->astOperand1())) continue; @@ -794,7 +794,7 @@ static inline bool isFunctionOrBreakPattern(const Token *tok) void CheckOtherImpl::redundantBitwiseOperationInSwitchError() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckOther::redundantBitwiseOperationInSwitch"); // warning @@ -923,7 +923,7 @@ void CheckOtherImpl::redundantBitwiseOperationInSwitchError(const Token *tok, co //--------------------------------------------------------------------------- void CheckOtherImpl::checkSuspiciousCaseInSwitch() { - if (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.certainty.isEnabled(Certainty::inconclusive) || !mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckOther::checkSuspiciousCaseInSwitch"); // warning,inconclusive @@ -1011,12 +1011,12 @@ void CheckOtherImpl::checkUnreachableCode() // misra-c-2023-2.1 // misra-cpp-2008-0-1-1 // autosar - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("duplicateBreak") && !mSettings->isPremiumEnabled("unreachableCode")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("duplicateBreak") && !mSettings.isPremiumEnabled("unreachableCode")) return; logChecker("CheckOther::checkUnreachableCode"); // style - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { if (scope->hasInlineOrLambdaFunction(nullptr, /*onlyInline*/ true)) @@ -1043,7 +1043,7 @@ void CheckOtherImpl::checkUnreachableCode() } else if (Token::Match(tok, "goto %any% ;")) { secondBreak = tok->tokAt(3); labelName = tok->next(); - } else if (Token::Match(tok, "%name% (") && mSettings->library.isnoreturn(tok) && !Token::Match(tok->next()->astParent(), "?|:")) { + } else if (Token::Match(tok, "%name% (") && mSettings.library.isnoreturn(tok) && !Token::Match(tok->next()->astParent(), "?|:")) { if ((!tok->function() || (tok->function()->token != tok && tok->function()->tokenDef != tok)) && tok->linkAt(1)->strAt(1) != "{") secondBreak = tok->linkAt(1)->tokAt(2); if (Token::simpleMatch(secondBreak, "return")) { @@ -1136,7 +1136,7 @@ void CheckOtherImpl::duplicateBreakError(const Token *tok, bool inconclusive) void CheckOtherImpl::unreachableCodeError(const Token *tok, const Token* noreturn, bool inconclusive) { std::string msg = "Statements following "; - if (noreturn && (noreturn->function() || mSettings->library.isnoreturn(noreturn))) + if (noreturn && (noreturn->function() || mSettings.library.isnoreturn(noreturn))) msg += "noreturn function '" + noreturn->str() + "()'"; else if (noreturn && noreturn->isKeyword()) msg += "'" + noreturn->str() + "'"; @@ -1185,17 +1185,17 @@ static bool isSimpleExpr(const Token* tok, const Variable* var, const Settings& //--------------------------------------------------------------------------- void CheckOtherImpl::checkVariableScope() { - if (mSettings->clang) + if (mSettings.clang) return; - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("variableScope")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("variableScope")) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); // In C it is common practice to declare local variables at the // start of functions. - if (mSettings->daca && mTokenizer->isC()) + if (mSettings.daca && mTokenizer->isC()) return; logChecker("CheckOther::checkVariableScope"); // style,notclang @@ -1244,7 +1244,7 @@ void CheckOtherImpl::checkVariableScope() bool isConstructor = false; if (Token::Match(tok, "; %varid% =", var->declarationId())) { // bailout for assignment tok = tok->tokAt(2)->astOperand2(); - if (!isSimpleExpr(tok, var, *mSettings)) + if (!isSimpleExpr(tok, var, mSettings)) continue; } else if (Token::Match(tok, "{|(")) { // bailout for constructor @@ -1253,11 +1253,11 @@ void CheckOtherImpl::checkVariableScope() bool bail = false; while (argTok) { if (Token::simpleMatch(argTok, ",")) { - if (!isSimpleExpr(argTok->astOperand2(), var, *mSettings)) { + if (!isSimpleExpr(argTok->astOperand2(), var, mSettings)) { bail = true; break; } - } else if (argTok->str() != "." && !isSimpleExpr(argTok, var, *mSettings)) { + } else if (argTok->str() != "." && !isSimpleExpr(argTok, var, mSettings)) { bail = true; break; } @@ -1422,7 +1422,7 @@ bool CheckOtherImpl::checkInnerScope(const Token *tok, const Variable* var, bool if (ftok->next()->astParent()) { // return value used? if (ftok->function() && Function::returnsPointer(ftok->function())) return false; - const std::string ret = mSettings->library.returnValueType(ftok); // assume that var is returned + const std::string ret = mSettings.library.returnValueType(ftok); // assume that var is returned if (!ret.empty() && ret.back() == '*') return false; } @@ -1437,7 +1437,7 @@ bool CheckOtherImpl::checkInnerScope(const Token *tok, const Variable* var, bool } } } - const auto yield = astContainerYield(tok, mSettings->library); + const auto yield = astContainerYield(tok, mSettings.library); if (yield == Library::Container::Yield::BUFFER || yield == Library::Container::Yield::BUFFER_NT) return false; } @@ -1476,7 +1476,7 @@ void CheckOtherImpl::variableScopeError(const Token *tok, const std::string &var void CheckOtherImpl::checkCommaSeparatedReturn() { // TODO: This is experimental for now. See #5076 - if ((true) || !mSettings->severity.isEnabled(Severity::style)) // NOLINT(readability-simplify-boolean-expr,readability-redundant-parentheses) + if ((true) || !mSettings.severity.isEnabled(Severity::style)) // NOLINT(readability-simplify-boolean-expr,readability-redundant-parentheses) return; // logChecker @@ -1540,7 +1540,7 @@ static bool isLargeContainer(const Variable* var, const Settings& settings) void CheckOtherImpl::checkPassByReference() { - if (!mSettings->severity.isEnabled(Severity::performance) || mTokenizer->isC()) + if (!mSettings.severity.isEnabled(Severity::performance) || mTokenizer->isC()) return; logChecker("CheckOther::checkPassByReference"); // performance,c++ @@ -1566,21 +1566,21 @@ void CheckOtherImpl::checkPassByReference() bool inconclusive = false; const bool isContainer = var->valueType() && var->valueType()->type == ValueType::Type::CONTAINER && var->valueType()->container && !var->valueType()->container->view; - if (isContainer && !isLargeContainer(var, *mSettings)) + if (isContainer && !isLargeContainer(var, mSettings)) continue; if (!isContainer) { if (var->type() && !var->type()->isEnumType()) { // Check if type is a struct or class. // Ensure that it is a large object. if (!var->type()->classScope) inconclusive = true; - else if (!var->valueType() || var->valueType()->getSizeOf(*mSettings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer) <= 2 * mSettings->platform.sizeof_pointer) + else if (!var->valueType() || var->valueType()->getSizeOf(mSettings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer) <= 2 * mSettings.platform.sizeof_pointer) continue; } else continue; } - if (inconclusive && !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (inconclusive && !mSettings.certainty.isEnabled(Certainty::inconclusive)) continue; if (var->isArray() && (!var->isStlType() || Token::simpleMatch(var->nameToken()->next(), "["))) @@ -1611,7 +1611,7 @@ void CheckOtherImpl::checkPassByReference() if (!isRangeBasedFor && (!var->scope() || var->scope()->function->isImplicitlyVirtual())) continue; - if (!isVariableChanged(var, *mSettings)) { + if (!isVariableChanged(var, mSettings)) { passedByValueError(var, inconclusive, isRangeBasedFor); } } @@ -1684,7 +1684,7 @@ static bool isCastToVoid(const Variable* var) void CheckOtherImpl::checkConstVariable() { - if ((!mSettings->severity.isEnabled(Severity::style) || mTokenizer->isC()) && !mSettings->isPremiumEnabled("constVariable")) + if ((!mSettings.severity.isEnabled(Severity::style) || mTokenizer->isC()) && !mSettings.isPremiumEnabled("constVariable")) return; logChecker("CheckOther::checkConstVariable"); // style,c++ @@ -1732,7 +1732,7 @@ void CheckOtherImpl::checkConstVariable() continue; if (isCastToVoid(var)) continue; - if (isVariableChanged(var, *mSettings)) + if (isVariableChanged(var, mSettings)) continue; const bool hasFunction = function != nullptr; if (!hasFunction) { @@ -1755,7 +1755,7 @@ void CheckOtherImpl::checkConstVariable() ValueFlow::Value ltVal = ValueFlow::getLifetimeObjValue(retTok); if (ltVal.isLifetimeValue() && ltVal.tokvalue->varId() == var->declarationId()) return true; - return ValueFlow::hasLifetimeToken(getParentLifetime(retTok), var->nameToken(), *mSettings); + return ValueFlow::hasLifetimeToken(getParentLifetime(retTok), var->nameToken(), mSettings); })) continue; } @@ -1791,7 +1791,7 @@ void CheckOtherImpl::checkConstVariable() continue; } else if (const Token* ftok = getTokenArgumentFunction(tok, argn)) { bool inconclusive{}; - if (var->valueType() && !isVariableChangedByFunctionCall(ftok, var->valueType()->pointer, var->declarationId(), *mSettings, &inconclusive) && !inconclusive) + if (var->valueType() && !isVariableChangedByFunctionCall(ftok, var->valueType()->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) continue; } usedInAssignment = true; @@ -1877,11 +1877,11 @@ static const Function* getEnclosingFunction(const Variable* var) void CheckOtherImpl::checkConstPointer() { - if (!mSettings->severity.isEnabled(Severity::style) && - !mSettings->isPremiumEnabled("constParameter") && - !mSettings->isPremiumEnabled("constParameterPointer") && - !mSettings->isPremiumEnabled("constParameterReference") && - !mSettings->isPremiumEnabled("constVariablePointer")) + if (!mSettings.severity.isEnabled(Severity::style) && + !mSettings.isPremiumEnabled("constParameter") && + !mSettings.isPremiumEnabled("constParameterPointer") && + !mSettings.isPremiumEnabled("constParameterReference") && + !mSettings.isPremiumEnabled("constVariablePointer")) return; logChecker("CheckOther::checkConstPointer"); // style @@ -1946,7 +1946,7 @@ void CheckOtherImpl::checkConstPointer() if (parent->astOperand2()) { if (parent->astOperand2()->function() && parent->astOperand2()->function()->isConst()) continue; - if (mSettings->library.isFunctionConst(parent->astOperand2())) + if (mSettings.library.isFunctionConst(parent->astOperand2())) continue; if (parent->astOperand2()->varId()) { if (gparent->str() == "?" && astIsLHS(parent)) @@ -1984,7 +1984,7 @@ void CheckOtherImpl::checkConstPointer() continue; else if (const Token* ftok = getTokenArgumentFunction(parent, argn)) { bool inconclusive{}; - if (!isVariableChangedByFunctionCall(ftok->next(), vt->pointer, var->declarationId(), *mSettings, &inconclusive) && !inconclusive) + if (!isVariableChangedByFunctionCall(ftok->next(), vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) continue; } } else { @@ -2009,12 +2009,12 @@ void CheckOtherImpl::checkConstPointer() const Variable* argVar = ftok->function()->getArgumentVar(argn); if (argVar && argVar->valueType() && argVar->valueType()->isConst(vt->pointer)) { bool inconclusive{}; - if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), *mSettings, &inconclusive) && !inconclusive) + if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) continue; } } } else { - const auto dir = mSettings->library.getArgDirection(ftok, argn + 1); + const auto dir = mSettings.library.getArgDirection(ftok, argn + 1); if (dir == Library::ArgumentChecks::Direction::DIR_IN) continue; } @@ -2042,7 +2042,7 @@ void CheckOtherImpl::checkConstPointer() // const int indirect = p->isArray() ? p->dimensions().size() : 1; // if (isVariableChanged(start, p->scope()->bodyEnd, indirect, p->declarationId(), false, *mSettings)) // continue; - if (!isConstPointerVariable(p, *mSettings)) + if (!isConstPointerVariable(p, mSettings)) continue; if (p->typeStartToken() && p->typeStartToken()->isSimplifiedTypedef() && !(Token::simpleMatch(p->typeEndToken(), "*") && !p->typeEndToken()->isSimplifiedTypedef())) continue; @@ -2091,8 +2091,8 @@ void CheckOtherImpl::constVariableError(const Variable *var, const Function *fun void CheckOtherImpl::checkCharVariable() { - const bool warning = mSettings->severity.isEnabled(Severity::warning); - const bool portability = mSettings->severity.isEnabled(Severity::portability); + const bool warning = mSettings.severity.isEnabled(Severity::warning); + const bool portability = mSettings.severity.isEnabled(Severity::portability); if (!warning && !portability) return; @@ -2107,24 +2107,24 @@ void CheckOtherImpl::checkCharVariable() if (!tok->variable()->isArray() && !tok->variable()->isPointer()) continue; const Token *index = tok->next()->astOperand2(); - if (warning && tok->variable()->isArray() && astIsSignedChar(index) && index->getValueGE(0x80, *mSettings)) + if (warning && tok->variable()->isArray() && astIsSignedChar(index) && index->getValueGE(0x80, mSettings)) signedCharArrayIndexError(tok); - if (portability && astIsUnknownSignChar(index) && index->getValueGE(0x80, *mSettings)) + if (portability && astIsUnknownSignChar(index) && index->getValueGE(0x80, mSettings)) unknownSignCharArrayIndexError(tok); } else if (warning && Token::Match(tok, "[&|^]") && tok->isBinaryOp()) { bool warn = false; if (astIsSignedChar(tok->astOperand1())) { - const ValueFlow::Value *v1 = tok->astOperand1()->getValueLE(-1, *mSettings); + const ValueFlow::Value *v1 = tok->astOperand1()->getValueLE(-1, mSettings); const ValueFlow::Value *v2 = tok->astOperand2()->getMaxValue(false); if (!v1) - v1 = tok->astOperand1()->getValueGE(0x80, *mSettings); + v1 = tok->astOperand1()->getValueGE(0x80, mSettings); if (v1 && !(tok->str() == "&" && v2 && v2->isKnown() && v2->intvalue >= 0 && v2->intvalue < 0x100)) warn = true; } else if (astIsSignedChar(tok->astOperand2())) { - const ValueFlow::Value *v1 = tok->astOperand2()->getValueLE(-1, *mSettings); + const ValueFlow::Value *v1 = tok->astOperand2()->getValueLE(-1, mSettings); const ValueFlow::Value *v2 = tok->astOperand1()->getMaxValue(false); if (!v1) - v1 = tok->astOperand2()->getValueGE(0x80, *mSettings); + v1 = tok->astOperand2()->getValueGE(0x80, mSettings); if (v1 && !(tok->str() == "&" && v2 && v2->isKnown() && v2->intvalue >= 0 && v2->intvalue < 0x100)) warn = true; } @@ -2350,8 +2350,8 @@ static bool isConstTop(const Token *tok) void CheckOtherImpl::checkIncompleteStatement() { - if (!mSettings->severity.isEnabled(Severity::warning) && - !mSettings->isPremiumEnabled("constStatement")) + if (!mSettings.severity.isEnabled(Severity::warning) && + !mSettings.isPremiumEnabled("constStatement")) return; logChecker("CheckOther::checkIncompleteStatement"); // warning @@ -2397,15 +2397,15 @@ void CheckOtherImpl::checkIncompleteStatement() // Skip statement expressions if (Token::simpleMatch(rtok, "; } )")) continue; - if (!isConstStatement(tok, mSettings->library, false)) + if (!isConstStatement(tok, mSettings.library, false)) continue; if (isVoidStmt(tok)) continue; if (tok->isCpp() && tok->str() == "&" && !(tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral())) // Possible archive continue; - const bool inconclusive = tok->isConstOp() && !mSettings->isPremiumEnabled("constStatement"); - if (mSettings->certainty.isEnabled(Certainty::inconclusive) || !inconclusive) + const bool inconclusive = tok->isConstOp() && !mSettings.isPremiumEnabled("constStatement"); + if (mSettings.certainty.isEnabled(Certainty::inconclusive) || !inconclusive) constStatementError(tok, tok->isNumber() ? "numeric" : "string", inconclusive); } } @@ -2455,7 +2455,7 @@ void CheckOtherImpl::constStatementError(const Token *tok, const std::string &ty msg = "Redundant code: Found unused function."; else if (Token::Match(tok->previous(), "%name% (")) msg = "Redundant code: Found unused '" + tok->strAt(-1) + "' expression."; - else if (mSettings->debugwarnings) { + else if (mSettings.debugwarnings) { reportError(tok, Severity::debug, "debug", "constStatementError not handled."); return; } @@ -2481,7 +2481,7 @@ void CheckOtherImpl::checkZeroDivision() // Value flow.. const ValueFlow::Value *value = tok->astOperand2()->getValue(0LL); - if (value && mSettings->isEnabled(value, false)) + if (value && mSettings.isEnabled(value, false)) zerodivError(tok, value); } } @@ -2517,7 +2517,7 @@ void CheckOtherImpl::zerodivError(const Token *tok, const ValueFlow::Value *valu void CheckOtherImpl::checkNanInArithmeticExpression() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("nanInArithmeticExpression")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("nanInArithmeticExpression")) return; logChecker("CheckOther::checkNanInArithmeticExpression"); // style for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { @@ -2547,7 +2547,7 @@ void CheckOtherImpl::checkMisusedScopedObject() if (mTokenizer->isC()) return; - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedScopedObject")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedScopedObject")) return; logChecker("CheckOther::checkMisusedScopedObject"); // style,c++ @@ -2574,10 +2574,10 @@ void CheckOtherImpl::checkMisusedScopedObject() }; auto isLibraryConstructor = [&](const Token* tok, const std::string& typeStr) -> bool { - const Library::TypeCheck typeCheck = mSettings->library.getTypeCheck("unusedvar", typeStr); + 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); + return mSettings.library.detectContainerOrIterator(tok); }; const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -2592,7 +2592,7 @@ void CheckOtherImpl::checkMisusedScopedObject() if (Token::simpleMatch(parTok, "<") && parTok->link()) parTok = parTok->link()->next(); if (const Token* arg = parTok->astOperand2()) { - if (!isConstStatement(arg, mSettings->library, false)) + if (!isConstStatement(arg, mSettings.library, false)) continue; if (parTok->str() == "(") { if (arg->varId() && !(arg->variable() && arg->variable()->nameToken() != arg)) @@ -2651,7 +2651,7 @@ void CheckOtherImpl::checkDuplicateBranch() // and their conditional code is a duplicate of the condition that // is always true just in case it would be false. See for instance // abiword. - if (!mSettings->severity.isEnabled(Severity::style) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (!mSettings.severity.isEnabled(Severity::style) || !mSettings.certainty.isEnabled(Certainty::inconclusive)) return; logChecker("CheckOther::checkDuplicateBranch"); // style,inconclusive @@ -2713,8 +2713,8 @@ void CheckOtherImpl::checkDuplicateBranch() if (branchTop1->str() != branchTop2->str()) continue; ErrorPath errorPath; - if (isSameExpression(false, branchTop1->astOperand1(), branchTop2->astOperand1(), *mSettings, true, true, &errorPath) && - isSameExpression(false, branchTop1->astOperand2(), branchTop2->astOperand2(), *mSettings, true, true, &errorPath)) + if (isSameExpression(false, branchTop1->astOperand1(), branchTop2->astOperand1(), mSettings, true, true, &errorPath) && + isSameExpression(false, branchTop1->astOperand2(), branchTop2->astOperand2(), mSettings, true, true, &errorPath)) duplicateBranchError(scope.classDef, scope.bodyEnd->next(), std::move(errorPath)); } } @@ -2744,14 +2744,14 @@ void CheckOtherImpl::checkInvalidFree() logChecker("CheckOther::checkInvalidFree"); - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { for (const Token* tok = scope->bodyStart->next(); tok && tok != scope->bodyEnd; tok = tok->next()) { // Keep track of which variables were assigned addresses to newly-allocated memory if ((tok->isCpp() && Token::Match(tok, "%var% = new")) || - (Token::Match(tok, "%var% = %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)))) { + (Token::Match(tok, "%var% = %name% (") && mSettings.library.getAllocFuncInfo(tok->tokAt(2)))) { allocation.emplace(tok->varId(), tok->strAt(2)); inconclusive.emplace(tok->varId(), false); } @@ -2779,7 +2779,7 @@ void CheckOtherImpl::checkInvalidFree() // If a variable that was previously assigned a newly-allocated memory location is // added or subtracted from when used to free the memory, report an error. - else if ((Token::Match(tok, "%name% ( %any% +|-") && mSettings->library.getDeallocFuncInfo(tok)) || + else if ((Token::Match(tok, "%name% ( %any% +|-") && mSettings.library.getDeallocFuncInfo(tok)) || Token::Match(tok, "delete [ ] ( %any% +|-") || Token::Match(tok, "delete %any% +|- %any%")) { @@ -2799,7 +2799,7 @@ void CheckOtherImpl::checkInvalidFree() // If the previously-allocated variable is passed in to another function // as a parameter, it might be modified, so we shouldn't report an error // if it is later used to free memory - else if (Token::Match(tok, "%name% (") && !mSettings->library.isFunctionConst(tok->str(), true)) { + else if (Token::Match(tok, "%name% (") && !mSettings.library.isFunctionConst(tok->str(), true)) { const Token* tok2 = Token::findmatch(tok->next(), "%var%", tok->linkAt(1)); while (tok2 != nullptr) { allocation.erase(tok->varId()); @@ -2873,14 +2873,14 @@ isStaticAssert(const Settings &settings, const Token *tok) void CheckOtherImpl::checkDuplicateExpression() { { - const bool styleEnabled = mSettings->severity.isEnabled(Severity::style); - const bool premiumEnabled = mSettings->isPremiumEnabled("oppositeExpression") || - mSettings->isPremiumEnabled("duplicateExpression") || - mSettings->isPremiumEnabled("duplicateAssignExpression") || - mSettings->isPremiumEnabled("duplicateExpressionTernary") || - mSettings->isPremiumEnabled("duplicateValueTernary") || - mSettings->isPremiumEnabled("selfAssignment") || - mSettings->isPremiumEnabled("knownConditionTrueFalse"); + const bool styleEnabled = mSettings.severity.isEnabled(Severity::style); + const bool premiumEnabled = mSettings.isPremiumEnabled("oppositeExpression") || + mSettings.isPremiumEnabled("duplicateExpression") || + mSettings.isPremiumEnabled("duplicateAssignExpression") || + mSettings.isPremiumEnabled("duplicateExpressionTernary") || + mSettings.isPremiumEnabled("duplicateValueTernary") || + mSettings.isPremiumEnabled("selfAssignment") || + mSettings.isPremiumEnabled("knownConditionTrueFalse"); if (!styleEnabled && !premiumEnabled) return; @@ -2918,8 +2918,8 @@ void CheckOtherImpl::checkDuplicateExpression() Token::Match(tok->astOperand2()->previous(), "%name% (") ) && tok->next()->tokType() != Token::eType && - isSameExpression(true, tok->next(), nextAssign->next(), *mSettings, true, false) && - isSameExpression(true, tok->astOperand2(), nextAssign->astOperand2(), *mSettings, true, false) && + isSameExpression(true, tok->next(), nextAssign->next(), mSettings, true, false) && + isSameExpression(true, tok->astOperand2(), nextAssign->astOperand2(), mSettings, true, false) && tok->astOperand2()->expressionString() == nextAssign->astOperand2()->expressionString()) { bool differentDomain = false; const Scope * varScope = var1->scope() ? var1->scope() : scope; @@ -2937,7 +2937,7 @@ void CheckOtherImpl::checkDuplicateExpression() !isSameExpression(true, tok->astOperand2(), assignTok->astOperand1(), - *mSettings, + mSettings, true, true)) continue; @@ -2946,7 +2946,7 @@ void CheckOtherImpl::checkDuplicateExpression() !isSameExpression(true, tok->astOperand2(), assignTok->astOperand2(), - *mSettings, + mSettings, true, true)) continue; @@ -2955,7 +2955,7 @@ void CheckOtherImpl::checkDuplicateExpression() } if (!differentDomain && !isUniqueExpression(tok->astOperand2())) duplicateAssignExpressionError(var1, var2, false); - else if (mSettings->certainty.isEnabled(Certainty::inconclusive)) { + else if (mSettings.certainty.isEnabled(Certainty::inconclusive)) { diag(assignTok); duplicateAssignExpressionError(var1, var2, true); } @@ -2981,14 +2981,14 @@ void CheckOtherImpl::checkDuplicateExpression() if (isSameExpression(true, tok->astOperand1(), tok->astOperand2(), - *mSettings, + mSettings, true, followVar, &errorPath)) { if (isWithoutSideEffects(tok->astOperand1())) { const Token* loopTok = isInLoopCondition(tok); if (!loopTok || - !findExpressionChanged(tok, tok, loopTok->link()->linkAt(1), *mSettings)) { + !findExpressionChanged(tok, tok, loopTok->link()->linkAt(1), mSettings)) { const bool isEnum = tok->scope()->type == ScopeType::eEnum; const bool assignment = !isEnum && tok->str() == "="; if (assignment) @@ -3000,7 +3000,7 @@ void CheckOtherImpl::checkDuplicateExpression() parent = parent->astParent(); } if (parent && parent->previous() && - (isStaticAssert(*mSettings, parent->previous()) || + (isStaticAssert(mSettings, parent->previous()) || Token::simpleMatch(parent->previous(), "assert"))) { continue; } @@ -3013,7 +3013,7 @@ void CheckOtherImpl::checkDuplicateExpression() isSameExpression(false, tok->astOperand1(), tok->astOperand2()->astOperand1(), - *mSettings, + mSettings, true, false)) { if (isWithoutSideEffects(tok->astOperand1())) { @@ -3021,7 +3021,7 @@ void CheckOtherImpl::checkDuplicateExpression() } } else if (isOppositeExpression(tok->astOperand1(), tok->astOperand2(), - *mSettings, + mSettings, false, true, &errorPath) && @@ -3033,15 +3033,15 @@ void CheckOtherImpl::checkDuplicateExpression() isSameExpression(true, tok->astOperand2(), tok->astOperand1()->astOperand2(), - *mSettings, + mSettings, true, followVar, &errorPath) && isWithoutSideEffects(tok->astOperand2())) duplicateExpressionError(tok->astOperand2(), tok->astOperand1()->astOperand2(), tok, std::move(errorPath)); - else if (tok->astOperand2() && isConstExpression(tok->astOperand1(), mSettings->library)) { + else if (tok->astOperand2() && isConstExpression(tok->astOperand1(), mSettings.library)) { auto checkDuplicate = [&](const Token* exp1, const Token* exp2, const Token* ast1) { - if (isSameExpression(true, exp1, exp2, *mSettings, true, true, &errorPath) && + if (isSameExpression(true, exp1, exp2, mSettings, true, true, &errorPath) && isWithoutSideEffects(exp1) && isWithoutSideEffects(ast1->astOperand2())) duplicateExpressionError(exp1, exp2, tok, errorPath, /*hasMultipleExpr*/ true); @@ -3056,12 +3056,12 @@ void CheckOtherImpl::checkDuplicateExpression() } } } else if (tok->astOperand1() && tok->astOperand2() && tok->str() == ":" && tok->astParent() && tok->astParent()->str() == "?") { - if (isSameExpression(true, tok->astOperand1(), tok->astOperand2(), *mSettings, false, true, &errorPath)) + if (isSameExpression(true, tok->astOperand1(), tok->astOperand2(), mSettings, false, true, &errorPath)) duplicateExpressionTernaryError(tok, std::move(errorPath)); else if (!tok->astOperand1()->values().empty() && !tok->astOperand2()->values().empty() && isEqualKnownValue(tok->astOperand1(), tok->astOperand2()) && - !isVariableChanged(tok->astParent(), /*indirect*/ 0, *mSettings) && - isConstStatement(tok->astOperand1(), mSettings->library, true) && isConstStatement(tok->astOperand2(), mSettings->library, true)) + !isVariableChanged(tok->astParent(), /*indirect*/ 0, mSettings) && + isConstStatement(tok->astOperand1(), mSettings.library, true) && isConstStatement(tok->astOperand2(), mSettings.library, true)) duplicateValueTernaryError(tok); } } @@ -3156,7 +3156,7 @@ void CheckOtherImpl::selfAssignmentError(const Token *tok, const std::string &va //----------------------------------------------------------------------------- void CheckOtherImpl::checkComparisonFunctionIsAlwaysTrueOrFalse() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse"); // warning @@ -3201,7 +3201,7 @@ void CheckOtherImpl::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token //--------------------------------------------------------------------------- void CheckOtherImpl::checkSignOfUnsignedVariable() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unsignedLessThanZero")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unsignedLessThanZero")) return; logChecker("CheckOther::checkSignOfUnsignedVariable"); // style @@ -3385,7 +3385,7 @@ static bool checkVariableAssignment(const Token* tok, const ValueType* vtLhs, co void CheckOtherImpl::checkRedundantCopy() { - if (!mSettings->severity.isEnabled(Severity::performance) || mTokenizer->isC() || !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (!mSettings.severity.isEnabled(Severity::performance) || mTokenizer->isC() || !mSettings.certainty.isEnabled(Certainty::inconclusive)) return; logChecker("CheckOther::checkRedundantCopy"); // c++,performance,inconclusive @@ -3395,7 +3395,7 @@ void CheckOtherImpl::checkRedundantCopy() for (const Variable* var : symbolDatabase->variableList()) { if (!var || var->isReference() || var->isPointer() || (!var->type() && !var->isStlType() && !(var->valueType() && var->valueType()->container)) || // bailout if var is of standard type, if it is a pointer or non-const - (!var->isConst() && isVariableChanged(var, *mSettings))) + (!var->isConst() && isVariableChanged(var, mSettings))) continue; const Token* startTok = var->nameToken(); @@ -3415,7 +3415,7 @@ void CheckOtherImpl::checkRedundantCopy() const Token* tok = startTok->next()->astOperand2(); if (!tok) continue; - if (!checkFunctionReturnsRef(tok, *mSettings) && !checkVariableAssignment(tok, var->valueType(), *mSettings)) + if (!checkFunctionReturnsRef(tok, mSettings) && !checkVariableAssignment(tok, var->valueType(), mSettings)) continue; redundantCopyError(startTok, startTok->str()); } @@ -3443,7 +3443,7 @@ static bool isNegative(const Token *tok, const Settings &settings) void CheckOtherImpl::checkNegativeBitwiseShift() { - const bool portability = mSettings->severity.isEnabled(Severity::portability); + const bool portability = mSettings.severity.isEnabled(Severity::portability); logChecker("CheckOther::checkNegativeBitwiseShift"); @@ -3475,9 +3475,9 @@ void CheckOtherImpl::checkNegativeBitwiseShift() continue; // Get negative rhs value. preferably a value which doesn't have 'condition'. - if (portability && isNegative(tok->astOperand1(), *mSettings)) + if (portability && isNegative(tok->astOperand1(), mSettings)) negativeBitwiseShiftError(tok, 1); - else if (isNegative(tok->astOperand2(), *mSettings)) + else if (isNegative(tok->astOperand2(), mSettings)) negativeBitwiseShiftError(tok, 2); } } @@ -3499,10 +3499,10 @@ void CheckOtherImpl::negativeBitwiseShiftError(const Token *tok, int op) //--------------------------------------------------------------------------- void CheckOtherImpl::checkIncompleteArrayFill() { - if (!mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (!mSettings.certainty.isEnabled(Certainty::inconclusive)) return; - const bool printWarning = mSettings->severity.isEnabled(Severity::warning); - const bool printPortability = mSettings->severity.isEnabled(Severity::portability); + const bool printWarning = mSettings.severity.isEnabled(Severity::warning); + const bool printPortability = mSettings.severity.isEnabled(Severity::portability); if (!printPortability && !printWarning) return; @@ -3532,9 +3532,9 @@ void CheckOtherImpl::checkIncompleteArrayFill() continue; int size = mTokenizer->sizeOfType(var->typeStartToken()); if (size == 0 && var->valueType()->pointer) - size = mSettings->platform.sizeof_pointer; + size = mSettings.platform.sizeof_pointer; else if (size == 0 && var->valueType()) - size = var->valueType()->getSizeOf(*mSettings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer); + size = var->valueType()->getSizeOf(mSettings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer); const Token* tok3 = tok->next()->astOperand2()->astOperand1()->astOperand1(); if ((size != 1 && size != 100 && size != 0) || var->isPointer()) { if (printWarning) @@ -3568,7 +3568,7 @@ void CheckOtherImpl::incompleteArrayFillError(const Token* tok, const std::strin void CheckOtherImpl::checkVarFuncNullUB() { - if (!mSettings->severity.isEnabled(Severity::portability)) + if (!mSettings.severity.isEnabled(Severity::portability)) return; logChecker("CheckOther::checkVarFuncNullUB"); // portability @@ -3653,7 +3653,7 @@ void CheckOtherImpl::varFuncNullUBError(const Token *tok) void CheckOtherImpl::checkRedundantPointerOp() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("redundantPointerOp")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("redundantPointerOp")) return; logChecker("CheckOther::checkRedundantPointerOp"); // style @@ -3699,7 +3699,7 @@ void CheckOtherImpl::redundantPointerOpError(const Token* tok, const std::string void CheckOtherImpl::checkInterlockedDecrement() { - if (!mSettings->platform.isWindows()) { + if (!mSettings.platform.isWindows()) { return; } @@ -3745,7 +3745,7 @@ void CheckOtherImpl::raceAfterInterlockedDecrementError(const Token* tok) void CheckOtherImpl::checkUnusedLabel() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("unusedLabel")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("unusedLabel")) return; logChecker("CheckOther::checkUnusedLabel"); // style,warning @@ -3768,7 +3768,7 @@ void CheckOtherImpl::checkUnusedLabel() void CheckOtherImpl::unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef) { - if (tok && !mSettings->severity.isEnabled(inSwitch ? Severity::warning : Severity::style) && !mSettings->isPremiumEnabled("unusedLabel")) + if (tok && !mSettings.severity.isEnabled(inSwitch ? Severity::warning : Severity::style) && !mSettings.isPremiumEnabled("unusedLabel")) return; std::string id = "unusedLabel"; @@ -3900,14 +3900,14 @@ void CheckOtherImpl::checkEvaluationOrder() break; bool foundError{false}, foundUnspecified{false}, bSelfAssignmentError{false}; - if (mTokenizer->isCPP() && mSettings->standards.cpp >= Standards::CPP11) { - if (mSettings->standards.cpp >= Standards::CPP17) - foundError = checkEvaluationOrderCpp17(tok, tok2, parent, *mSettings, foundUnspecified); + if (mTokenizer->isCPP() && mSettings.standards.cpp >= Standards::CPP11) { + if (mSettings.standards.cpp >= Standards::CPP17) + foundError = checkEvaluationOrderCpp17(tok, tok2, parent, mSettings, foundUnspecified); else - foundError = checkEvaluationOrderCpp11(tok, tok2, parent, *mSettings); + foundError = checkEvaluationOrderCpp11(tok, tok2, parent, mSettings); } else - foundError = checkEvaluationOrderC(tok, tok2, parent, *mSettings, bSelfAssignmentError); + foundError = checkEvaluationOrderC(tok, tok2, parent, mSettings, bSelfAssignmentError); if (foundError) { unknownEvaluationOrder(parent, foundUnspecified); @@ -3933,12 +3933,12 @@ void CheckOtherImpl::unknownEvaluationOrder(const Token* tok, bool isUnspecified void CheckOtherImpl::checkAccessOfMovedVariable() { - if (!mTokenizer->isCPP() || mSettings->standards.cpp < Standards::CPP11) + if (!mTokenizer->isCPP() || mSettings.standards.cpp < Standards::CPP11) return; - if (!mSettings->isPremiumEnabled("accessMoved") && !mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.isPremiumEnabled("accessMoved") && !mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckOther::checkAccessOfMovedVariable"); // c++11,warning - const bool reportInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool reportInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { const Token * scopeStart = scope->bodyStart; @@ -3964,11 +3964,11 @@ void CheckOtherImpl::checkAccessOfMovedVariable() else inconclusive = true; } else { - const ExprUsage usage = getExprUsage(tok, 0, *mSettings); + const ExprUsage usage = getExprUsage(tok, 0, mSettings); if (usage == ExprUsage::Used) accessOfMoved = true; if (usage == ExprUsage::PassedByReference) - accessOfMoved = !isVariableChangedByFunctionCall(tok, 0, *mSettings, &inconclusive); + accessOfMoved = !isVariableChangedByFunctionCall(tok, 0, mSettings, &inconclusive); else if (usage == ExprUsage::Inconclusive) inconclusive = true; } @@ -4009,11 +4009,11 @@ void CheckOtherImpl::accessMovedError(const Token *tok, const std::string &varna void CheckOtherImpl::checkFuncArgNamesDifferent() { - const bool style = mSettings->severity.isEnabled(Severity::style); - const bool inconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); - const bool warning = mSettings->severity.isEnabled(Severity::warning); + const bool style = mSettings.severity.isEnabled(Severity::style); + const bool inconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); + const bool warning = mSettings.severity.isEnabled(Severity::warning); - if (!(warning || (style && inconclusive)) && !mSettings->isPremiumEnabled("funcArgNamesDifferent")) + if (!(warning || (style && inconclusive)) && !mSettings.isPremiumEnabled("funcArgNamesDifferent")) return; logChecker("CheckOther::checkFuncArgNamesDifferent"); // style,warning,inconclusive @@ -4155,7 +4155,7 @@ static const Token *findShadowed(const Scope *scope, const Variable& var, int li void CheckOtherImpl::checkShadowVariables() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("shadowVariable")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("shadowVariable")) return; logChecker("CheckOther::checkShadowVariables"); // style const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -4256,7 +4256,7 @@ static bool isVariableExprHidden(const Token* tok) void CheckOtherImpl::checkKnownArgument() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("knownArgument")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("knownArgument")) return; logChecker("CheckOther::checkKnownArgument"); // style const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -4291,7 +4291,7 @@ void CheckOtherImpl::checkKnownArgument() continue; if (tok->isComparisonOp() && isSameExpression( - true, tok->astOperand1(), tok->astOperand2(), *mSettings, true, true)) + true, tok->astOperand1(), tok->astOperand2(), mSettings, true, true)) continue; // ensure that there is a integer variable in expression with unknown value const Token* vartok = nullptr; @@ -4357,7 +4357,7 @@ void CheckOtherImpl::knownArgumentError(const Token *tok, const Token *ftok, con void CheckOtherImpl::checkKnownPointerToBool() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("knownPointerToBool")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("knownPointerToBool")) return; logChecker("CheckOther::checkKnownPointerToBool"); // style const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -4377,7 +4377,7 @@ void CheckOtherImpl::checkKnownPointerToBool() return parent->isExpandedMacro(); })) continue; - if (!isUsedAsBool(tok, *mSettings)) + if (!isUsedAsBool(tok, mSettings)) continue; const ValueFlow::Value& value = tok->values().front(); knownPointerToBoolError(tok, &value); @@ -4428,10 +4428,10 @@ void CheckOtherImpl::checkComparePointers() continue; if (var1->isRValueReference() || var2->isRValueReference()) continue; - if (const Token* parent2 = getParentLifetime(v2.tokvalue, mSettings->library)) + if (const Token* parent2 = getParentLifetime(v2.tokvalue, mSettings.library)) if (var1 == parent2->variable()) continue; - if (const Token* parent1 = getParentLifetime(v1.tokvalue, mSettings->library)) + if (const Token* parent1 = getParentLifetime(v1.tokvalue, mSettings.library)) if (var2 == parent1->variable()) continue; comparePointersError(tok, &v1, &v2); @@ -4461,7 +4461,7 @@ void CheckOtherImpl::comparePointersError(const Token *tok, const ValueFlow::Val void CheckOtherImpl::checkModuloOfOne() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("moduloofone")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("moduloofone")) return; logChecker("CheckOther::checkModuloOfOne"); // style @@ -4571,7 +4571,7 @@ static bool isZeroInitializer(const Token *tok) void CheckOtherImpl::checkUnionZeroInit() { - if (!mSettings->severity.isEnabled(Severity::portability)) + if (!mSettings.severity.isEnabled(Severity::portability)) return; logChecker("CheckOther::checkUnionZeroInit"); // portability @@ -4579,7 +4579,7 @@ void CheckOtherImpl::checkUnionZeroInit() const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); std::unordered_map unionsByScopeId; - const std::vector unions = parseUnions(*symbolDatabase, *mSettings); + const std::vector unions = parseUnions(*symbolDatabase, mSettings); for (const Union &u : unions) { unionsByScopeId.emplace(u.scope, u); } @@ -4718,7 +4718,7 @@ void CheckOtherImpl::checkOverlappingWrite() if (errorToken) overlappingWriteUnion(tok); } else if (Token::Match(tok, "%name% (")) { - const Library::NonOverlappingData *nonOverlappingData = mSettings->library.getNonOverlappingData(tok); + const Library::NonOverlappingData *nonOverlappingData = mSettings.library.getNonOverlappingData(tok); if (!nonOverlappingData) continue; const std::vector args = getArguments(tok); @@ -4743,7 +4743,7 @@ void CheckOtherImpl::checkOverlappingWrite() constexpr bool macro = true; constexpr bool pure = true; constexpr bool follow = true; - if (!isSameExpression(macro, ptr1, ptr2, *mSettings, pure, follow, &errorPath)) + if (!isSameExpression(macro, ptr1, ptr2, mSettings, pure, follow, &errorPath)) continue; overlappingWriteFunction(tok, tok->str()); } @@ -4755,9 +4755,9 @@ void CheckOtherImpl::checkOverlappingWrite() MathLib::bigint sizeValue = args[sizeArg-1]->getKnownIntValue(); const Token *buf1, *buf2; MathLib::bigint offset1, offset2; - if (!getBufAndOffset(ptr1, buf1, &offset1, *mSettings, isCountArg ? &sizeValue : nullptr)) + if (!getBufAndOffset(ptr1, buf1, &offset1, mSettings, isCountArg ? &sizeValue : nullptr)) continue; - if (!getBufAndOffset(ptr2, buf2, &offset2, *mSettings)) + if (!getBufAndOffset(ptr2, buf2, &offset2, mSettings)) continue; if (offset1 < offset2 && offset1 + sizeValue <= offset2) @@ -4769,7 +4769,7 @@ void CheckOtherImpl::checkOverlappingWrite() constexpr bool macro = true; constexpr bool pure = true; constexpr bool follow = true; - if (!isSameExpression(macro, buf1, buf2, *mSettings, pure, follow, &errorPath)) + if (!isSameExpression(macro, buf1, buf2, mSettings, pure, follow, &errorPath)) continue; overlappingWriteFunction(tok, tok->str()); } @@ -4789,7 +4789,7 @@ void CheckOtherImpl::overlappingWriteFunction(const Token *tok, const std::strin void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckOtherImpl checkOther(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckOtherImpl checkOther(&tokenizer, tokenizer.getSettings(), errorLogger); // Checks checkOther.warningOldStylePointerCast(); @@ -4839,7 +4839,7 @@ void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkOther.checkUnionZeroInit(); } -void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckOtherImpl c(nullptr, settings, errorLogger); diff --git a/lib/checkother.h b/lib/checkother.h index 6f6460bdfde..c3c045653c8 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -62,7 +62,7 @@ class CPPCHECKLIB CheckOther : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Other checks\n" @@ -127,7 +127,7 @@ class CPPCHECKLIB CheckOther : public Check { class CPPCHECKLIB CheckOtherImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckOtherImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckOtherImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is less than zero? */ diff --git a/lib/checkpostfixoperator.cpp b/lib/checkpostfixoperator.cpp index 0b02313b672..e0026e1d70c 100644 --- a/lib/checkpostfixoperator.cpp +++ b/lib/checkpostfixoperator.cpp @@ -39,7 +39,7 @@ static const CWE CWE398(398U); // Indicator of Poor Code Quality void CheckPostfixOperatorImpl::postfixOperator() { - if (!mSettings->severity.isEnabled(Severity::performance)) + if (!mSettings.severity.isEnabled(Severity::performance)) return; logChecker("CheckPostfixOperator::postfixOperator"); // performance @@ -99,11 +99,11 @@ void CheckPostfixOperator::runChecks(const Tokenizer &tokenizer, ErrorLogger *er if (tokenizer.isC()) return; - CheckPostfixOperatorImpl checkPostfixOperator(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckPostfixOperatorImpl checkPostfixOperator(&tokenizer, tokenizer.getSettings(), errorLogger); checkPostfixOperator.postfixOperator(); } -void CheckPostfixOperator::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckPostfixOperator::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckPostfixOperatorImpl c(nullptr, settings, errorLogger); c.postfixOperatorError(nullptr); diff --git a/lib/checkpostfixoperator.h b/lib/checkpostfixoperator.h index 03ab54eed11..27d833a992e 100644 --- a/lib/checkpostfixoperator.h +++ b/lib/checkpostfixoperator.h @@ -50,7 +50,7 @@ class CPPCHECKLIB CheckPostfixOperator : public Check { private: void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Warn if using postfix operators ++ or -- rather than prefix operator\n"; } @@ -59,7 +59,7 @@ class CPPCHECKLIB CheckPostfixOperator : public Check { class CPPCHECKLIB CheckPostfixOperatorImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckPostfixOperatorImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckPostfixOperatorImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Check postfix operators */ diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index ab398dda570..694f73eeff6 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -41,7 +41,7 @@ static const CWE CWE682(682U); // Incorrect Calculation //--------------------------------------------------------------------------- void CheckSizeofImpl::checkSizeofForNumericParameter() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckSizeof::checkSizeofForNumericParameter"); // warning @@ -71,7 +71,7 @@ void CheckSizeofImpl::sizeofForNumericParameterError(const Token *tok) //--------------------------------------------------------------------------- void CheckSizeofImpl::checkSizeofForArrayParameter() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckSizeof::checkSizeofForArrayParameter"); // warning @@ -112,7 +112,7 @@ void CheckSizeofImpl::sizeofForArrayParameterError(const Token *tok) void CheckSizeofImpl::checkSizeofForPointerSize() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckSizeof::checkSizeofForPointerSize"); // warning @@ -129,7 +129,7 @@ void CheckSizeofImpl::checkSizeofForPointerSize() // Once leaving those tests, it is mandatory to have: // - variable matching the used pointer // - tokVar pointing on the argument where sizeof may be used - if (Token::Match(tok->tokAt(2), "%name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2))) { + if (Token::Match(tok->tokAt(2), "%name% (") && mSettings.library.getAllocFuncInfo(tok->tokAt(2))) { if (Token::Match(tok, "%var% =")) variable = tok; else if (tok->strAt(1) == ")" && Token::Match(tok->linkAt(1)->tokAt(-2), "%var% =")) @@ -282,7 +282,7 @@ void CheckSizeofImpl::divideBySizeofError(const Token *tok, const std::string &m //----------------------------------------------------------------------------- void CheckSizeofImpl::sizeofsizeof() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckSizeof::sizeofsizeof"); // warning @@ -308,12 +308,12 @@ void CheckSizeofImpl::sizeofsizeofError(const Token *tok) void CheckSizeofImpl::sizeofCalculation() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckSizeof::sizeofCalculation"); // warning - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { if (!Token::simpleMatch(tok, "sizeof (")) @@ -354,7 +354,7 @@ void CheckSizeofImpl::sizeofCalculationError(const Token *tok, bool inconclusive void CheckSizeofImpl::sizeofFunction() { - if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->isPremiumEnabled("sizeofFunctionCall")) + if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("sizeofFunctionCall")) return; logChecker("CheckSizeof::sizeofFunction"); // warning @@ -397,7 +397,7 @@ void CheckSizeofImpl::sizeofFunctionError(const Token *tok) //----------------------------------------------------------------------------- void CheckSizeofImpl::suspiciousSizeofCalculation() { - if (!mSettings->severity.isEnabled(Severity::warning) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (!mSettings.severity.isEnabled(Severity::warning) || !mSettings.certainty.isEnabled(Certainty::inconclusive)) return; logChecker("CheckSizeof::suspiciousSizeofCalculation"); // warning,inconclusive @@ -441,7 +441,7 @@ void CheckSizeofImpl::divideSizeofError(const Token *tok) void CheckSizeofImpl::sizeofVoid() { - if (!mSettings->severity.isEnabled(Severity::portability)) + if (!mSettings.severity.isEnabled(Severity::portability)) return; logChecker("CheckSizeof::sizeofVoid"); // portability @@ -500,7 +500,7 @@ void CheckSizeofImpl::arithOperationsOnVoidPointerError(const Token* tok, const void CheckSizeof::runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) { - CheckSizeofImpl checkSizeof(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckSizeofImpl checkSizeof(&tokenizer, tokenizer.getSettings(), errorLogger); // Checks checkSizeof.sizeofsizeof(); @@ -513,7 +513,7 @@ void CheckSizeof::runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger checkSizeof.sizeofVoid(); } -void CheckSizeof::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const +void CheckSizeof::getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const { CheckSizeofImpl c(nullptr, settings, errorLogger); c.sizeofForArrayParameterError(nullptr); diff --git a/lib/checksizeof.h b/lib/checksizeof.h index 0ec4b298de5..90d55e69506 100644 --- a/lib/checksizeof.h +++ b/lib/checksizeof.h @@ -48,7 +48,7 @@ class CPPCHECKLIB CheckSizeof : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) override; - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; + void getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const override; std::string classInfo() const override { return "sizeof() usage checks\n" @@ -66,7 +66,7 @@ class CPPCHECKLIB CheckSizeof : public Check { class CPPCHECKLIB CheckSizeofImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckSizeofImpl(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) + CheckSizeofImpl(const Tokenizer* tokenizer, const Settings& settings, ErrorLogger* errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for 'sizeof sizeof ..' */ diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 2980fe2d86e..887f7001ef2 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -150,9 +150,9 @@ void CheckStlImpl::outOfBounds() continue; if (value.isImpossible()) continue; - if (value.isInconclusive() && !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (value.isInconclusive() && !mSettings.certainty.isEnabled(Certainty::inconclusive)) continue; - if (!value.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning)) + if (!value.errorSeverity() && !mSettings.severity.isEnabled(Severity::warning)) continue; if (value.intvalue == 0 && (indexTok || (containerYieldsElement(container, parent) && !containerAppendsElement(container, parent)) || @@ -165,7 +165,7 @@ void CheckStlImpl::outOfBounds() } if (indexTok) { std::vector indexValues = - ValueFlow::isOutOfBounds(value, indexTok, mSettings->severity.isEnabled(Severity::warning)); + ValueFlow::isOutOfBounds(value, indexTok, mSettings.severity.isEnabled(Severity::warning)); if (!indexValues.empty()) { outOfBoundsError( accessTok, tok->expressionString(), &value, indexTok->expressionString(), &indexValues.front()); @@ -175,7 +175,7 @@ void CheckStlImpl::outOfBounds() } if (indexTok && !indexTok->hasKnownIntValue()) { const ValueFlow::Value* value = - ValueFlow::findValue(indexTok->values(), *mSettings, [&](const ValueFlow::Value& v) { + ValueFlow::findValue(indexTok->values(), mSettings, [&](const ValueFlow::Value& v) { if (!v.isSymbolicValue()) return false; if (v.isImpossible()) @@ -280,7 +280,7 @@ bool CheckStlImpl::isContainerSize(const Token *containerToken, const Token *exp return false; if (!Token::Match(expr->astOperand1(), ". %name% (")) return false; - if (!isSameExpression(false, containerToken, expr->astOperand1()->astOperand1(), *mSettings, false, false)) + if (!isSameExpression(false, containerToken, expr->astOperand1()->astOperand1(), mSettings, false, false)) return false; return containerToken->valueType()->container->getYield(expr->strAt(-1)) == Library::Container::Yield::SIZE; } @@ -309,7 +309,7 @@ bool CheckStlImpl::isContainerSizeGE(const Token * containerToken, const Token * op = expr->astOperand1(); else return false; - return op && op->getValueGE(0, *mSettings); + return op && op->getValueGE(0, mSettings); } return false; } @@ -470,7 +470,7 @@ void CheckStlImpl::iterators() bool inconclusiveType=false; if (!isIterator(var, inconclusiveType)) continue; - if (inconclusiveType && !mSettings->certainty.isEnabled(Certainty::inconclusive)) + if (inconclusiveType && !mSettings.certainty.isEnabled(Certainty::inconclusive)) continue; const int iteratorId = var->declarationId(); @@ -772,7 +772,7 @@ bool CheckStlImpl::checkIteratorPair(const Token* tok1, const Token* tok2) (!astIsContainer(val1.tokvalue) || !astIsContainer(val2.tokvalue))) return false; } - if (isSameIteratorContainerExpression(val1.tokvalue, val2.tokvalue, *mSettings, val1.lifetimeKind)) + if (isSameIteratorContainerExpression(val1.tokvalue, val2.tokvalue, mSettings, val1.lifetimeKind)) return false; if (val1.tokvalue->expressionString() == val2.tokvalue->expressionString()) iteratorsError(tok1, val1.tokvalue, val1.tokvalue->expressionString()); @@ -792,7 +792,7 @@ bool CheckStlImpl::checkIteratorPair(const Token* tok1, const Token* tok2) const Token* iter2 = getIteratorExpression(tok2); if (!iter2) return false; - if (!isSameIteratorContainerExpression(iter1, iter2, *mSettings)) { + if (!isSameIteratorContainerExpression(iter1, iter2, mSettings)) { mismatchingContainerExpressionError(iter1, iter2); return true; } @@ -829,7 +829,7 @@ void CheckStlImpl::mismatchingContainers() // Group args together by container std::map> containers; for (int argnr = 1; argnr <= args.size(); ++argnr) { - const Library::ArgumentChecks::IteratorInfo *i = mSettings->library.getArgIteratorInfo(ftok, argnr); + const Library::ArgumentChecks::IteratorInfo *i = mSettings.library.getArgIteratorInfo(ftok, argnr); if (!i) continue; const Token * const argTok = args[argnr - 1]; @@ -846,7 +846,7 @@ void CheckStlImpl::mismatchingContainers() if (iter1.tok == iter2.tok) continue; if (iter1.info->first && iter2.info->last && - isSameExpression(false, iter1.tok, iter2.tok, *mSettings, false, false)) + isSameExpression(false, iter1.tok, iter2.tok, mSettings, false, false)) sameIteratorExpressionError(iter1.tok); if (checkIteratorPair(iter1.tok, iter2.tok)) return; @@ -910,7 +910,7 @@ void CheckStlImpl::mismatchingContainerIterator() continue; if (iterTok->str() == "*" && iterTok->astOperand1()->valueType() && iterTok->astOperand1()->valueType()->type == ValueType::ITERATOR) continue; - if (isSameIteratorContainerExpression(tok, val.tokvalue, *mSettings)) + if (isSameIteratorContainerExpression(tok, val.tokvalue, mSettings)) continue; mismatchingContainerIteratorError(tok, iterTok, val.tokvalue); } @@ -1143,7 +1143,7 @@ void CheckStlImpl::invalidContainer() const Scope* s = tok2->scope(); if (!s) continue; - if (isReturnScope(s->bodyEnd, mSettings->library)) + if (isReturnScope(s->bodyEnd, mSettings.library)) continue; invalidContainerLoopError(r.ftok, tok, r.errorPath); bail = true; @@ -1194,7 +1194,7 @@ void CheckStlImpl::invalidContainer() ErrorPath ep; bool addressOf = false; - const Variable* var = ValueFlow::getLifetimeVariable(info.tok, ep, *mSettings, &addressOf); + const Variable* var = ValueFlow::getLifetimeVariable(info.tok, ep, mSettings, &addressOf); // Check the reference is created before the change if (var && var->declarationId() == r.tok->varId() && !addressOf) { // An argument always reaches @@ -1371,10 +1371,10 @@ void CheckStlImpl::negativeIndex() const Variable * const var = tok->variable(); if (!var || tok == var->nameToken()) continue; - const Library::Container * const container = mSettings->library.detectContainer(var->typeStartToken()); + const Library::Container * const container = mSettings.library.detectContainer(var->typeStartToken()); if (!container || !container->arrayLike_indexOp) continue; - const ValueFlow::Value *index = tok->next()->astOperand2()->getValueLE(-1, *mSettings); + const ValueFlow::Value *index = tok->next()->astOperand2()->getValueLE(-1, mSettings); if (!index) continue; negativeIndexError(tok, *index); @@ -1470,7 +1470,7 @@ void CheckStlImpl::stlBoundaries() if (!var || !var->scope() || !var->scope()->isExecutable()) continue; - const Library::Container* container = mSettings->library.detectIterator(var->typeStartToken()); + const Library::Container* container = mSettings.library.detectIterator(var->typeStartToken()); if (!container || container->opLessAllowed) continue; @@ -1517,8 +1517,8 @@ static bool if_findCompare(const Token * const tokBack, bool stdStringLike) void CheckStlImpl::if_find() { - const bool printWarning = mSettings->severity.isEnabled(Severity::warning); - const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); + const bool printWarning = mSettings.severity.isEnabled(Severity::warning); + const bool printPerformance = mSettings.severity.isEnabled(Severity::performance); if (!printWarning && !printPerformance) return; @@ -1542,7 +1542,7 @@ void CheckStlImpl::if_find() tok = tok->linkAt(1); else if (tok->variable() && Token::Match(tok, "%var% . %name% (")) { - container = mSettings->library.detectContainer(tok->variable()->typeStartToken()); + container = mSettings.library.detectContainer(tok->variable()->typeStartToken()); funcTok = tok->tokAt(2); } @@ -1556,16 +1556,16 @@ void CheckStlImpl::if_find() funcTok = tok2->astParent()->next(); if (tok->variable()->isArrayOrPointer()) - container = mSettings->library.detectContainer(tok->variable()->typeStartToken()); + container = mSettings.library.detectContainer(tok->variable()->typeStartToken()); else { // Container of container - find the inner container - container = mSettings->library.detectContainer(tok->variable()->typeStartToken()); // outer container + container = mSettings.library.detectContainer(tok->variable()->typeStartToken()); // outer container tok2 = Token::findsimplematch(tok->variable()->typeStartToken(), "<", tok->variable()->typeEndToken()); if (container && container->type_templateArgNo >= 0 && tok2) { tok2 = tok2->next(); for (int j = 0; j < container->type_templateArgNo; j++) tok2 = tok2->nextTemplateArgument(); - container = mSettings->library.detectContainer(tok2); // inner container + container = mSettings.library.detectContainer(tok2); // inner container } else container = nullptr; } @@ -1594,7 +1594,7 @@ void CheckStlImpl::if_find() void CheckStlImpl::if_findError(const Token *tok, bool str) { - if (str && mSettings->standards.cpp >= Standards::CPP20) + if (str && mSettings.standards.cpp >= Standards::CPP20) reportError(tok, Severity::performance, "stlIfStrFind", "Inefficient usage of string::find() in condition; string::starts_with() could be faster.\n" "Either inefficient or wrong usage of string::find(). string::starts_with() will be faster if " @@ -1685,7 +1685,7 @@ static const Token *findInsertValue(const Token *tok, const Token *containerTok, void CheckStlImpl::checkFindInsert() { - if (!mSettings->severity.isEnabled(Severity::performance)) + if (!mSettings.severity.isEnabled(Severity::performance)) return; logChecker("CheckStl::checkFindInsert"); // performance @@ -1706,20 +1706,20 @@ void CheckStlImpl::checkFindInsert() if (!containerTok) continue; // In < C++17 we only warn for small simple types - if (mSettings->standards.cpp < Standards::CPP17 && !(keyTok && keyTok->valueType() && (keyTok->valueType()->isIntegral() || keyTok->valueType()->pointer > 0))) + if (mSettings.standards.cpp < Standards::CPP17 && !(keyTok && keyTok->valueType() && (keyTok->valueType()->isIntegral() || keyTok->valueType()->pointer > 0))) continue; const Token *thenTok = tok->linkAt(1)->next(); - const Token *valueTok = findInsertValue(thenTok, containerTok, keyTok, *mSettings); + const Token *valueTok = findInsertValue(thenTok, containerTok, keyTok, mSettings); if (!valueTok) continue; if (Token::simpleMatch(thenTok->link(), "} else {")) { const Token *valueTok2 = - findInsertValue(thenTok->link()->tokAt(2), containerTok, keyTok, *mSettings); + findInsertValue(thenTok->link()->tokAt(2), containerTok, keyTok, mSettings); if (!valueTok2) continue; - if (isSameExpression(true, valueTok, valueTok2, *mSettings, true, true)) { + if (isSameExpression(true, valueTok, valueTok2, mSettings, true, true)) { checkFindInsertError(valueTok); } } else { @@ -1733,10 +1733,10 @@ void CheckStlImpl::checkFindInsertError(const Token *tok) { std::string replaceExpr; if (tok && Token::simpleMatch(tok->astParent(), "=") && tok == tok->astParent()->astOperand2() && Token::simpleMatch(tok->astParent()->astOperand1(), "[")) { - if (mSettings->standards.cpp < Standards::CPP11) + if (mSettings.standards.cpp < Standards::CPP11) // We will recommend using emplace/try_emplace instead return; - const std::string f = (mSettings->standards.cpp < Standards::CPP17) ? "emplace" : "try_emplace"; + const std::string f = (mSettings.standards.cpp < Standards::CPP17) ? "emplace" : "try_emplace"; replaceExpr = " Instead of '" + tok->astParent()->expressionString() + "' consider using '" + tok->astParent()->astOperand1()->astOperand1()->expressionString() + "." + f + "(" + @@ -1763,10 +1763,10 @@ static bool isCpp03ContainerSizeSlow(const Token *tok) void CheckStlImpl::size() { - if (!mSettings->severity.isEnabled(Severity::performance)) + if (!mSettings.severity.isEnabled(Severity::performance)) return; - if (mSettings->standards.cpp >= Standards::CPP11) + if (mSettings.standards.cpp >= Standards::CPP11) return; logChecker("CheckStl::size"); // performance,c++03 @@ -1824,7 +1824,7 @@ void CheckStlImpl::sizeError(const Token *tok) void CheckStlImpl::redundantCondition() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("redundantIfRemove")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("redundantIfRemove")) return; logChecker("CheckStl::redundantCondition"); // style @@ -1865,7 +1865,7 @@ void CheckStlImpl::redundantIfRemoveError(const Token *tok) void CheckStlImpl::missingComparison() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckStl::missingComparison"); // warning @@ -2025,8 +2025,8 @@ namespace { void CheckStlImpl::string_c_str() { - const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); - const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); + const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); + const bool printPerformance = mSettings.severity.isEnabled(Severity::performance); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -2289,8 +2289,8 @@ namespace { void CheckStlImpl::uselessCalls() { - const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); - const bool printWarning = mSettings->severity.isEnabled(Severity::warning); + const bool printPerformance = mSettings.severity.isEnabled(Severity::performance); + const bool printWarning = mSettings.severity.isEnabled(Severity::warning); if (!printPerformance && !printWarning) return; @@ -2416,7 +2416,7 @@ void CheckStlImpl::uselessCallsRemoveError(const Token *tok, const std::string& // E.g. if (*i && i != str.end()) { } void CheckStlImpl::checkDereferenceInvalidIterator() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckStl::checkDereferenceInvalidIterator"); // warning @@ -2480,7 +2480,7 @@ void CheckStlImpl::checkDereferenceInvalidIterator() void CheckStlImpl::checkDereferenceInvalidIterator2() { - const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive)); + const bool printInconclusive = (mSettings.certainty.isEnabled(Certainty::inconclusive)); logChecker("CheckStl::checkDereferenceInvalidIterator2"); @@ -2550,7 +2550,7 @@ void CheckStlImpl::checkDereferenceInvalidIterator2() emptyAdvance = tok->astParent(); } } - if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, *mSettings) && !isInvalidIterator && !emptyAdvance) { + if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings) && !isInvalidIterator && !emptyAdvance) { if (!unknown) continue; inconclusive = true; @@ -2583,7 +2583,7 @@ void CheckStlImpl::dereferenceInvalidIteratorError(const Token* tok, const Value reportError(tok, Severity::warning, "derefInvalidIteratorRedundantCheck", errmsgcond, CWE825, Certainty::normal); return; } - if (!mSettings->isEnabled(value, inconclusive)) + if (!mSettings.isEnabled(value, inconclusive)) return; ErrorPath errorPath = getErrorPath(tok, value, "Dereference of an invalid iterator"); @@ -3002,7 +3002,7 @@ namespace { void CheckStlImpl::useStlAlgorithm() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("useStlAlgorithm")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("useStlAlgorithm")) return; logChecker("CheckStl::useStlAlgorithm"); // style @@ -3018,7 +3018,7 @@ void CheckStlImpl::useStlAlgorithm() if (!Token::simpleMatch(tok, "{") || !Token::simpleMatch(tok->previous(), ")")) return false; const Token* condTok = tok->linkAt(-1)->astOperand2(); - if (isConstExpression(condTok, mSettings->library)) { + if (isConstExpression(condTok, mSettings.library)) { if (condTok->str() == "<") type = ConditionOpType::MIN; else if (condTok->str() == ">") @@ -3044,7 +3044,7 @@ void CheckStlImpl::useStlAlgorithm() continue; if (!Token::simpleMatch(tok->linkAt(1), ") {")) continue; - LoopAnalyzer a{tok, mSettings}; + LoopAnalyzer a{tok, &mSettings}; std::string algoName = a.findAlgo(); if (!algoName.empty()) { useStlAlgorithmError(tok, algoName); @@ -3082,7 +3082,7 @@ void CheckStlImpl::useStlAlgorithm() // Check for single assignment bool useLoopVarInAssign{}, hasBreak{}; - const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign, hasBreak, loopType, *mSettings); + const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign, hasBreak, loopType, mSettings); if (assignTok) { if (!checkAssignee(assignTok->astOperand1())) continue; @@ -3114,7 +3114,7 @@ void CheckStlImpl::useStlAlgorithm() } // Check for container calls bool useLoopVarInMemCall; - const Token *memberAccessTok = singleMemberCallInScope(bodyTok, loopVar->varId(), useLoopVarInMemCall, *mSettings); + const Token *memberAccessTok = singleMemberCallInScope(bodyTok, loopVar->varId(), useLoopVarInMemCall, mSettings); if (memberAccessTok && loopType == LoopType::RANGE) { const Token *memberCallTok = memberAccessTok->astOperand2(); const int contVarId = memberAccessTok->astOperand1()->varId(); @@ -3147,10 +3147,10 @@ void CheckStlImpl::useStlAlgorithm() } // Check for conditionals - const Token *condBodyTok = singleConditionalInScope(bodyTok, loopVar->varId(), loopType, *mSettings); + const Token *condBodyTok = singleConditionalInScope(bodyTok, loopVar->varId(), loopType, mSettings); if (condBodyTok) { // Check for single assign - assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign, hasBreak, loopType, *mSettings); + assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign, hasBreak, loopType, mSettings); if (assignTok) { if (!checkAssignee(assignTok->astOperand1())) continue; @@ -3191,7 +3191,7 @@ void CheckStlImpl::useStlAlgorithm() } // Check for container call - memberAccessTok = singleMemberCallInScope(condBodyTok, loopVar->varId(), useLoopVarInMemCall, *mSettings); + memberAccessTok = singleMemberCallInScope(condBodyTok, loopVar->varId(), useLoopVarInMemCall, mSettings); if (memberAccessTok) { const Token *memberCallTok = memberAccessTok->astOperand2(); const int contVarId = memberAccessTok->astOperand1()->varId(); @@ -3269,7 +3269,7 @@ static bool isKnownEmptyContainer(const Token* tok) void CheckStlImpl::knownEmptyContainer() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("knownEmptyContainer")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("knownEmptyContainer")) return; logChecker("CheckStl::knownEmptyContainer"); // style for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { @@ -3295,7 +3295,7 @@ void CheckStlImpl::knownEmptyContainer() continue; for (int argnr = 1; argnr <= args.size(); ++argnr) { - const Library::ArgumentChecks::IteratorInfo *i = mSettings->library.getArgIteratorInfo(tok, argnr); + const Library::ArgumentChecks::IteratorInfo *i = mSettings.library.getArgIteratorInfo(tok, argnr); if (!i) continue; const Token * const argTok = args[argnr - 1]; @@ -3418,7 +3418,7 @@ void CheckStlImpl::localMutexError(const Token* tok) void CheckStlImpl::checkMutexes() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckStl::checkMutexes"); // warning for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { @@ -3459,7 +3459,7 @@ void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) return; } - CheckStlImpl checkStl(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckStlImpl checkStl(&tokenizer, tokenizer.getSettings(), errorLogger); checkStl.erase(); checkStl.if_find(); checkStl.checkFindInsert(); @@ -3490,7 +3490,7 @@ void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkStl.size(); } -void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const +void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const { CheckStlImpl c(nullptr, settings, errorLogger); c.outOfBoundsError(nullptr, "container", nullptr, "x", nullptr); diff --git a/lib/checkstl.h b/lib/checkstl.h index 626e39f4276..e23d6b54fb4 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -55,7 +55,7 @@ class CPPCHECKLIB CheckStl : public Check { /** run checks, the token list is not simplified */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; + void getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const override; std::string classInfo() const override { return "Check for invalid usage of STL:\n" @@ -83,7 +83,7 @@ class CPPCHECKLIB CheckStl : public Check { class CPPCHECKLIB CheckStlImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckStlImpl(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) + CheckStlImpl(const Tokenizer* tokenizer, const Settings& settings, ErrorLogger* errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Accessing container out of bounds using ValueFlow */ diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 916885e094a..db4a3eca113 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -55,7 +55,7 @@ void CheckStringImpl::stringLiteralWrite() for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { if (!tok->variable() || !tok->variable()->isPointer()) continue; - const Token *str = tok->getValueTokenMinStrSize(*mSettings); + const Token *str = tok->getValueTokenMinStrSize(mSettings); if (!str) continue; if (Token::Match(tok, "%var% [") && Token::simpleMatch(tok->linkAt(1), "] =")) @@ -91,7 +91,7 @@ void CheckStringImpl::stringLiteralWriteError(const Token *tok, const Token *str //--------------------------------------------------------------------------- void CheckStringImpl::checkAlwaysTrueOrFalseStringCompare() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckString::checkAlwaysTrueOrFalseStringCompare"); // warning @@ -160,7 +160,7 @@ void CheckStringImpl::alwaysTrueStringVariableCompareError(const Token *tok, con //----------------------------------------------------------------------------- void CheckStringImpl::checkSuspiciousStringCompare() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckString::checkSuspiciousStringCompare"); // warning @@ -274,7 +274,7 @@ static bool isMacroUsage(const Token* tok) //--------------------------------------------------------------------------- void CheckStringImpl::checkIncorrectStringCompare() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckString::checkIncorrectStringCompare"); // warning @@ -314,7 +314,7 @@ void CheckStringImpl::checkIncorrectStringCompare() } } else if (Token::Match(tok, "%str%|%char%") && !Token::Match(tok->next(), "%name%") && - isUsedAsBool(tok, *mSettings) && + isUsedAsBool(tok, mSettings) && !isMacroUsage(tok)) incorrectStringBooleanError(tok, tok->str()); } @@ -343,7 +343,7 @@ void CheckStringImpl::incorrectStringBooleanError(const Token *tok, const std::s //--------------------------------------------------------------------------- void CheckStringImpl::overlappingStrcmp() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckString::overlappingStrcmp"); // warning @@ -395,7 +395,7 @@ void CheckStringImpl::overlappingStrcmp() if (args1[1]->isLiteral() && args2[1]->isLiteral() && args1[1]->str() != args2[1]->str() && - isSameExpression(true, args1[0], args2[0], *mSettings, true, false)) + isSameExpression(true, args1[0], args2[0], mSettings, true, false)) overlappingStrcmpError(eq0, ne0); } } @@ -446,7 +446,7 @@ void CheckStringImpl::sprintfOverlappingData() const bool same = isSameExpression(false, dest, arg, - *mSettings, + mSettings, true, false); if (same) { @@ -473,7 +473,7 @@ void CheckStringImpl::sprintfOverlappingDataError(const Token *funcTok, const To void CheckString::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckStringImpl checkString(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckStringImpl checkString(&tokenizer, tokenizer.getSettings(), errorLogger); // Checks checkString.strPlusChar(); @@ -485,7 +485,7 @@ void CheckString::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger checkString.checkAlwaysTrueOrFalseStringCompare(); } -void CheckString::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckString::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckStringImpl c(nullptr, settings, errorLogger); c.stringLiteralWriteError(nullptr, nullptr); diff --git a/lib/checkstring.h b/lib/checkstring.h index 9edefc3f8b0..054c4208a18 100644 --- a/lib/checkstring.h +++ b/lib/checkstring.h @@ -48,7 +48,7 @@ class CPPCHECKLIB CheckString : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Detect misusage of C-style strings:\n" @@ -65,7 +65,7 @@ class CPPCHECKLIB CheckString : public Check { class CPPCHECKLIB CheckStringImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckStringImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckStringImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief undefined behaviour, writing string literal */ diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 1679d98e80f..262cb37a612 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -59,7 +59,7 @@ static const CWE CWE190(190U); // Integer Overflow or Wraparound void CheckTypeImpl::checkTooBigBitwiseShift() { // unknown sizeof(int) => can't run this checker - if (mSettings->platform.type == Platform::Type::Unspecified) + if (mSettings.platform.type == Platform::Type::Unspecified) return; logChecker("CheckType::checkTooBigBitwiseShift"); // platform @@ -90,21 +90,21 @@ void CheckTypeImpl::checkTooBigBitwiseShift() (lhstype->type == ValueType::Type::WCHAR_T) || (lhstype->type == ValueType::Type::BOOL) || (lhstype->type == ValueType::Type::INT)) - lhsbits = mSettings->platform.int_bit; + lhsbits = mSettings.platform.int_bit; else if (lhstype->type == ValueType::Type::LONG) - lhsbits = mSettings->platform.long_bit; + lhsbits = mSettings.platform.long_bit; else if (lhstype->type == ValueType::Type::LONGLONG) - lhsbits = mSettings->platform.long_long_bit; + lhsbits = mSettings.platform.long_long_bit; else continue; // Get biggest rhs value. preferably a value which doesn't have 'condition'. - const ValueFlow::Value * value = tok->astOperand2()->getValueGE(lhsbits, *mSettings); - if (value && mSettings->isEnabled(value, false)) + const ValueFlow::Value * value = tok->astOperand2()->getValueGE(lhsbits, mSettings); + if (value && mSettings.isEnabled(value, false)) tooBigBitwiseShiftError(tok, lhsbits, *value); else if (lhstype->sign == ValueType::Sign::SIGNED) { - value = tok->astOperand2()->getValueGE(lhsbits-1, *mSettings); - if (value && mSettings->isEnabled(value, false)) + value = tok->astOperand2()->getValueGE(lhsbits-1, mSettings); + if (value && mSettings.isEnabled(value, false)) tooBigSignedBitwiseShiftError(tok, lhsbits, *value); } } @@ -133,7 +133,7 @@ void CheckTypeImpl::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, { constexpr char id[] = "shiftTooManyBitsSigned"; - const bool cpp14 = ((tok && tok->isCpp()) || (mTokenizer && mTokenizer->isCPP())) && (mSettings->standards.cpp >= Standards::CPP14); + const bool cpp14 = ((tok && tok->isCpp()) || (mTokenizer && mTokenizer->isCPP())) && (mSettings.standards.cpp >= Standards::CPP14); std::string behaviour = "undefined"; if (cpp14) @@ -148,7 +148,7 @@ void CheckTypeImpl::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, if (cpp14) severity = Severity::portability; - if ((severity == Severity::portability) && !mSettings->severity.isEnabled(Severity::portability)) + if ((severity == Severity::portability) && !mSettings.severity.isEnabled(Severity::portability)) return; ErrorPath errorPath = getErrorPath(tok, &rhsbits, "Shift"); @@ -167,7 +167,7 @@ void CheckTypeImpl::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, void CheckTypeImpl::checkIntegerOverflow() { // unknown sizeof(int) => can't run this checker - if (mSettings->platform.type == Platform::Type::Unspecified || mSettings->platform.int_bit >= MathLib::bigint_bits) + if (mSettings.platform.type == Platform::Type::Unspecified || mSettings.platform.int_bit >= MathLib::bigint_bits) return; logChecker("CheckType::checkIntegerOverflow"); // platform @@ -183,11 +183,11 @@ void CheckTypeImpl::checkIntegerOverflow() unsigned int bits; if (vt->type == ValueType::Type::INT) - bits = mSettings->platform.int_bit; + bits = mSettings.platform.int_bit; else if (vt->type == ValueType::Type::LONG) - bits = mSettings->platform.long_bit; + bits = mSettings.platform.long_bit; else if (vt->type == ValueType::Type::LONGLONG) - bits = mSettings->platform.long_long_bit; + bits = mSettings.platform.long_long_bit; else continue; @@ -199,12 +199,12 @@ void CheckTypeImpl::checkIntegerOverflow() // is there a overflow result value bool isOverflow = true; - const ValueFlow::Value *value = tok->getValueGE(maxvalue + 1, *mSettings); + const ValueFlow::Value *value = tok->getValueGE(maxvalue + 1, mSettings); if (!value) { - value = tok->getValueLE(-maxvalue - 2, *mSettings); + value = tok->getValueLE(-maxvalue - 2, mSettings); isOverflow = false; } - if (!value || !mSettings->isEnabled(value,false)) + if (!value || !mSettings.isEnabled(value,false)) continue; // For left shift, it's common practice to shift into the sign bit @@ -253,7 +253,7 @@ void CheckTypeImpl::integerOverflowError(const Token *tok, const ValueFlow::Valu void CheckTypeImpl::checkSignConversion() { - if (!mSettings->severity.isEnabled(Severity::warning)) + if (!mSettings.severity.isEnabled(Severity::warning)) return; logChecker("CheckType::checkSignConversion"); // warning @@ -272,7 +272,7 @@ void CheckTypeImpl::checkSignConversion() if (!tok1) continue; const ValueFlow::Value* negativeValue = - ValueFlow::findValue(tok1->values(), *mSettings, [&](const ValueFlow::Value& v) { + ValueFlow::findValue(tok1->values(), mSettings, [&](const ValueFlow::Value& v) { return !v.isImpossible() && v.isIntValue() && (v.intvalue <= -1 || v.wideintvalue <= -1); }); if (!negativeValue) @@ -338,7 +338,7 @@ static bool checkTypeCombination(ValueType src, ValueType tgt, const Settings& s void CheckTypeImpl::checkLongCast() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("truncLongCastAssignment")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("truncLongCastAssignment")) return; logChecker("CheckType::checkLongCast"); // style @@ -349,7 +349,7 @@ void CheckTypeImpl::checkLongCast() continue; if (const ValueFlow::Value* v = tok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { - if (mSettings->platform.isIntValue(v->intvalue)) + if (mSettings.platform.isIntValue(v->intvalue)) continue; } @@ -358,7 +358,7 @@ void CheckTypeImpl::checkLongCast() if (!lhstype || !rhstype) continue; - if (!checkTypeCombination(*rhstype, *lhstype, *mSettings)) + if (!checkTypeCombination(*rhstype, *lhstype, mSettings)) continue; // assign int result to long/longlong const nonpointer? @@ -385,12 +385,12 @@ void CheckTypeImpl::checkLongCast() if (tok->str() == "return") { if (Token::Match(tok->astOperand1(), "<<|*")) { const ValueType *type = tok->astOperand1()->valueType(); - if (type && checkTypeCombination(*type, *retVt, *mSettings) && + if (type && checkTypeCombination(*type, *retVt, mSettings) && type->pointer == 0U && type->originalTypeName.empty()) { if (!tok->astOperand1()->hasKnownIntValue()) { ret = tok; - } else if (!mSettings->platform.isIntValue(tok->astOperand1()->getKnownIntValue())) + } else if (!mSettings.platform.isIntValue(tok->astOperand1()->getKnownIntValue())) ret = tok; } } @@ -476,7 +476,7 @@ void CheckTypeImpl::checkFloatToIntegerOverflow() while (scope && scope->type != ScopeType::eLambda && scope->type != ScopeType::eFunction) scope = scope->nestedIn; if (scope && scope->type == ScopeType::eFunction && scope->function && scope->function->retDef) { - const ValueType &valueType = ValueType::parseDecl(scope->function->retDef, *mSettings); + const ValueType &valueType = ValueType::parseDecl(scope->function->retDef, mSettings); vtfloat = tok->astOperand1()->valueType(); checkFloatToIntegerOverflow(tok, &valueType, vtfloat, tok->astOperand1()->values()); } @@ -495,24 +495,24 @@ void CheckTypeImpl::checkFloatToIntegerOverflow(const Token *tok, const ValueTyp for (const ValueFlow::Value &f : floatValues) { if (f.valueType != ValueFlow::Value::ValueType::FLOAT) continue; - if (!mSettings->isEnabled(&f, false)) + if (!mSettings.isEnabled(&f, false)) continue; - if (f.floatValue >= std::exp2(mSettings->platform.long_long_bit)) + if (f.floatValue >= std::exp2(mSettings.platform.long_long_bit)) floatToIntegerOverflowError(tok, f); - else if ((-f.floatValue) > std::exp2(mSettings->platform.long_long_bit - 1)) + else if ((-f.floatValue) > std::exp2(mSettings.platform.long_long_bit - 1)) floatToIntegerOverflowError(tok, f); - else if (mSettings->platform.type != Platform::Type::Unspecified) { + else if (mSettings.platform.type != Platform::Type::Unspecified) { int bits = 0; if (vtint->type == ValueType::Type::CHAR) - bits = mSettings->platform.char_bit; + bits = mSettings.platform.char_bit; else if (vtint->type == ValueType::Type::SHORT) - bits = mSettings->platform.short_bit; + bits = mSettings.platform.short_bit; else if (vtint->type == ValueType::Type::INT) - bits = mSettings->platform.int_bit; + bits = mSettings.platform.int_bit; else if (vtint->type == ValueType::Type::LONG) - bits = mSettings->platform.long_bit; + bits = mSettings.platform.long_bit; else if (vtint->type == ValueType::Type::LONGLONG) - bits = mSettings->platform.long_long_bit; + bits = mSettings.platform.long_long_bit; else continue; if (bits < MathLib::bigint_bits && f.floatValue >= (1ULL << bits)) @@ -534,7 +534,7 @@ void CheckTypeImpl::floatToIntegerOverflowError(const Token *tok, const ValueFlo void CheckType::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { // These are not "simplified" because casts can't be ignored - CheckTypeImpl checkType(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckTypeImpl checkType(&tokenizer, tokenizer.getSettings(), errorLogger); checkType.checkTooBigBitwiseShift(); checkType.checkIntegerOverflow(); checkType.checkSignConversion(); @@ -542,7 +542,7 @@ void CheckType::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkType.checkFloatToIntegerOverflow(); } -void CheckType::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckType::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckTypeImpl c(nullptr, settings, errorLogger); c.tooBigBitwiseShiftError(nullptr, 32, ValueFlow::Value(64)); diff --git a/lib/checktype.h b/lib/checktype.h index a65ed7ea084..0030e3622be 100644 --- a/lib/checktype.h +++ b/lib/checktype.h @@ -54,7 +54,7 @@ class CPPCHECKLIB CheckType : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Type checks\n" @@ -70,7 +70,7 @@ class CPPCHECKLIB CheckType : public Check { class CPPCHECKLIB CheckTypeImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckTypeImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckTypeImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for bitwise shift with too big right operand */ diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 819bfa9d85a..bdfc07a8d47 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -212,10 +212,10 @@ void CheckUninitVarImpl::checkScope(const Scope* scope, const std::setbodyStart; tok != scope->bodyEnd; tok = tok->next()) { if (!Token::Match(tok, "[;{}] %varid% =", arg.declarationId())) continue; - const Token *allocFuncCallToken = findAllocFuncCallToken(tok->tokAt(2)->astOperand2(), mSettings->library); + const Token *allocFuncCallToken = findAllocFuncCallToken(tok->tokAt(2)->astOperand2(), mSettings.library); if (!allocFuncCallToken) continue; - const Library::AllocFunc *allocFunc = mSettings->library.getAllocFuncInfo(allocFuncCallToken); + const Library::AllocFunc *allocFunc = mSettings.library.getAllocFuncInfo(allocFuncCallToken); if (!allocFunc || allocFunc->initData) continue; @@ -396,7 +396,7 @@ static bool isVariableUsed(const Token *tok, const Variable& var) bool CheckUninitVarImpl::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, Alloc* const alloc, const std::string &membervar, std::map& variableValue) { const bool suppressErrors(possibleInit && *possibleInit); // Assume that this is a variable declaration, rather than a fundef - const bool printDebug = mSettings->debugwarnings; + const bool printDebug = mSettings.debugwarnings; if (possibleInit) *possibleInit = false; @@ -763,7 +763,7 @@ bool CheckUninitVarImpl::checkScopeForVariable(const Token *tok, const Variable& while (rhs && rhs->isCast()) rhs = rhs->astOperand2() ? rhs->astOperand2() : rhs->astOperand1(); if (rhs && Token::Match(rhs->previous(), "%name% (")) { - const Library::AllocFunc *allocFunc = mSettings->library.getAllocFuncInfo(rhs->astOperand1()); + const Library::AllocFunc *allocFunc = mSettings.library.getAllocFuncInfo(rhs->astOperand1()); if (allocFunc && !allocFunc->initData) { *alloc = NO_CTOR_CALL; continue; @@ -1355,7 +1355,7 @@ const Token* CheckUninitVarImpl::isVariableUsage(const Token *vartok, const Libr const Token* CheckUninitVarImpl::isVariableUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect) const { - return isVariableUsage(vartok, mSettings->library, pointer, alloc, indirect); + return isVariableUsage(vartok, mSettings.library, pointer, alloc, indirect); } /*** @@ -1436,7 +1436,7 @@ int CheckUninitVarImpl::isFunctionParUsage(const Token *vartok, const Library& l int CheckUninitVarImpl::isFunctionParUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect) const { - return isFunctionParUsage(vartok, mSettings->library, pointer, alloc, indirect); + return isFunctionParUsage(vartok, mSettings.library, pointer, alloc, indirect); } bool CheckUninitVarImpl::isMemberVariableAssignment(const Token *tok, const std::string &membervar) const @@ -1483,9 +1483,9 @@ bool CheckUninitVarImpl::isMemberVariableAssignment(const Token *tok, const std: // check how function handle uninitialized data arguments.. const Function *function = ftok->function(); - if (!function && mSettings) { + if (!function) { // Function definition not seen, check if direction is specified in the library configuration - const Library::ArgumentChecks::Direction argDirection = mSettings->library.getArgDirection(ftok, 1 + argumentNumber); + const Library::ArgumentChecks::Direction argDirection = mSettings.library.getArgDirection(ftok, 1 + argumentNumber); if (argDirection == Library::ArgumentChecks::Direction::DIR_IN) return false; if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT) @@ -1570,7 +1570,7 @@ void CheckUninitVarImpl::uninitvarError(const Token *tok, const std::string &var void CheckUninitVarImpl::uninitvarError(const Token* tok, const ValueFlow::Value& v) { - if (!mSettings->isEnabled(&v)) + if (!mSettings.isEnabled(&v)) return; if (diag(tok)) return; @@ -1660,28 +1660,28 @@ void CheckUninitVarImpl::valueFlowUninit() if (isarray && tok->variable()->isMember()) continue; // Todo: this is a bailout if (isarray && tok->variable()->isStlType() && Token::simpleMatch(tok->astParent(), ".")) { - const auto yield = astContainerYield(tok, mSettings->library); + const auto yield = astContainerYield(tok, mSettings.library); if (yield != Library::Container::Yield::AT_INDEX && yield != Library::Container::Yield::ITEM) continue; } - const bool deref = CheckNullPointerImpl::isPointerDeRef(tok, unknown, *mSettings); + const bool deref = CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings); uninitderef = deref && v->indirect == 0; const bool isleaf = isLeafDot(tok) || uninitderef; if (!isleaf && Token::Match(tok->astParent(), ". %name%") && (tok->astParent()->next()->variable() || tok->astParent()->next()->isEnumerator())) continue; } - const ExprUsage usage = getExprUsage(tok, v->indirect, *mSettings); + const ExprUsage usage = getExprUsage(tok, v->indirect, mSettings); if (usage == ExprUsage::NotUsed || usage == ExprUsage::Inconclusive) continue; if (!v->subexpressions.empty() && usage == ExprUsage::PassedByReference) continue; if (usage != ExprUsage::Used) { if (!(Token::Match(tok->astParent(), ". %name% (|[") && uninitderef) && - isVariableChanged(tok, v->indirect, *mSettings)) + isVariableChanged(tok, v->indirect, mSettings)) continue; bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, v->indirect, *mSettings, &inconclusive) || inconclusive) + if (isVariableChangedByFunctionCall(tok, v->indirect, mSettings, &inconclusive) || inconclusive) continue; } uninitvarError(tok, *v); @@ -1753,7 +1753,7 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo &ctu, const std::li { (void)settings; - CheckUninitVarImpl dummy(nullptr, &settings, &errorLogger); + CheckUninitVarImpl dummy(nullptr, settings, &errorLogger); dummy. logChecker("CheckUninitVar::analyseWholeProgram"); @@ -1799,12 +1799,12 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo &ctu, const std::li void CheckUninitVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckUninitVarImpl checkUninitVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckUninitVarImpl checkUninitVar(&tokenizer, tokenizer.getSettings(), errorLogger); checkUninitVar.valueFlowUninit(); checkUninitVar.check(); } -void CheckUninitVar::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const +void CheckUninitVar::getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const { CheckUninitVarImpl c(nullptr, settings, errorLogger); diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index f484c13e55c..e7af8f85e50 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -76,7 +76,7 @@ class CPPCHECKLIB CheckUninitVar : public Check { /** @brief Analyse all file infos for all TU */ bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; + void getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const override; std::string classInfo() const override { return "Uninitialized variables\n" @@ -88,7 +88,7 @@ class CPPCHECKLIB CheckUninitVar : public Check { class CPPCHECKLIB CheckUninitVarImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckUninitVarImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckUninitVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} enum Alloc : std::uint8_t { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY }; diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 4c5f8175f66..b5b863badc5 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -726,8 +726,8 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage_iterateScopes(const Scope* c i->typeEndToken()->isStandardType() || i->isStlType() || mTokenizer->getSymbolDatabase()->isRecordTypeWithoutSideEffects(i->type()) || - mSettings->library.detectContainer(i->typeStartToken()) || - mSettings->library.getTypeCheck("unusedvar", i->typeStartToken()->str()) == Library::TypeCheck::check) + mSettings.library.detectContainer(i->typeStartToken()) || + mSettings.library.getTypeCheck("unusedvar", i->typeStartToken()->str()) == Library::TypeCheck::check) type = Variables::standard; if (type == Variables::none || isPartOfClassStructUnion(i->typeStartToken())) @@ -852,7 +852,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage_iterateScopes(const Scope* c } } // Freeing memory (not considered "using" the pointer if it was also allocated in this function) - if ((Token::Match(tok, "%name% ( %var% )") && mSettings->library.getDeallocFuncInfo(tok)) || + if ((Token::Match(tok, "%name% ( %var% )") && mSettings.library.getDeallocFuncInfo(tok)) || (tok->isCpp() && (Token::Match(tok, "delete %var% ;") || Token::Match(tok, "delete [ ] %var% ;")))) { nonneg int varid = 0; if (tok->str() != "delete") { @@ -958,10 +958,10 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage_iterateScopes(const Scope* c // Consider allocating memory separately because allocating/freeing alone does not constitute using the variable else if (var && var->mType == Variables::pointer && Token::Match(start, "%name% =") && - findAllocFuncCallToken(start->next()->astOperand2(), mSettings->library)) { + findAllocFuncCallToken(start->next()->astOperand2(), mSettings.library)) { - const Token *allocFuncCallToken = findAllocFuncCallToken(start->next()->astOperand2(), mSettings->library); - const Library::AllocFunc *allocFunc = mSettings->library.getAllocFuncInfo(allocFuncCallToken); + const Token *allocFuncCallToken = findAllocFuncCallToken(start->next()->astOperand2(), mSettings.library); + const Library::AllocFunc *allocFunc = mSettings.library.getAllocFuncInfo(allocFuncCallToken); bool allocateMemory = !allocFunc || Library::ismemory(allocFunc->groupId); @@ -1043,7 +1043,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage_iterateScopes(const Scope* c // Consider allocating memory separately because allocating/freeing alone does not constitute using the variable if (var->mType == Variables::pointer && ((tok->isCpp() && Token::simpleMatch(skipBrackets(tok->next()), "= new")) || - (Token::Match(skipBrackets(tok->next()), "= %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2))))) { + (Token::Match(skipBrackets(tok->next()), "= %name% (") && mSettings.library.getAllocFuncInfo(tok->tokAt(2))))) { variables.allocateMemory(varid, tok); } else if (var->mType == Variables::pointer || var->mType == Variables::reference) { variables.read(varid, tok); @@ -1175,7 +1175,7 @@ static bool isReturnedByRef(const Variable* var, const Function* func) void CheckUnusedVarImpl::checkFunctionVariableUsage() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->checkLibrary && !mSettings->isPremiumEnabled("unusedVariable")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.checkLibrary && !mSettings.isPremiumEnabled("unusedVariable")) return; logChecker("CheckUnusedVar::checkFunctionVariableUsage"); // style @@ -1184,7 +1184,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage() const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); auto reportLibraryCfgError = [this](const Token* tok, const std::string& typeName) { - if (mSettings->checkLibrary) { + if (mSettings.checkLibrary) { reportError(tok, Severity::information, "checkLibraryCheckType", @@ -1331,7 +1331,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage() std::string typeName = op1Var->getTypeName(); if (startsWith(typeName, "::")) typeName.erase(typeName.begin(), typeName.begin() + 2); - switch (mSettings->library.getTypeCheck("unusedvar", typeName)) { + switch (mSettings.library.getTypeCheck("unusedvar", typeName)) { case Library::TypeCheck::def: bailoutTypeName = std::move(typeName); break; @@ -1370,7 +1370,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage() continue; } - FwdAnalysis fwdAnalysis(*mSettings); + FwdAnalysis fwdAnalysis(mSettings); const Token* scopeEnd = ValueFlow::getEndOfExprScope(expr, scope, /*smallest*/ false); if (fwdAnalysis.unusedValue(expr, start, scopeEnd)) { if (!bailoutTypeName.empty()) { @@ -1378,7 +1378,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage() reportLibraryCfgError(tok, bailoutTypeName); continue; } - if (isTrivialInit && findExpressionChanged(expr, start, scopeEnd, *mSettings)) + if (isTrivialInit && findExpressionChanged(expr, start, scopeEnd, mSettings)) continue; // warn @@ -1460,7 +1460,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage() if (mTokenizer->isCPP() && var->isClass() && (!var->valueType() || var->valueType()->type == ValueType::Type::UNKNOWN_TYPE)) { const std::string typeName = var->getTypeName(); - switch (mSettings->library.getTypeCheck("unusedvar", typeName)) { + switch (mSettings.library.getTypeCheck("unusedvar", typeName)) { case Library::TypeCheck::def: reportLibraryCfgError(vnt, typeName); break; @@ -1481,7 +1481,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage() void CheckUnusedVarImpl::unusedVariableError(const Token *tok, const std::string &varname) { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedVariable")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedVariable")) return; reportError(tok, Severity::style, "unusedVariable", "$symbol:" + varname + "\nUnused variable: $symbol", CWE563, Certainty::normal); @@ -1489,7 +1489,7 @@ void CheckUnusedVarImpl::unusedVariableError(const Token *tok, const std::string void CheckUnusedVarImpl::allocatedButUnusedVariableError(const Token *tok, const std::string &varname) { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedVariable")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedVariable")) return; reportError(tok, Severity::style, "unusedAllocatedMemory", "$symbol:" + varname + "\nVariable '$symbol' is allocated memory that is never used.", CWE563, Certainty::normal); @@ -1497,7 +1497,7 @@ void CheckUnusedVarImpl::allocatedButUnusedVariableError(const Token *tok, const void CheckUnusedVarImpl::unreadVariableError(const Token *tok, const std::string &varname, bool modified) { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedVariable")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedVariable")) return; if (modified) @@ -1508,7 +1508,7 @@ void CheckUnusedVarImpl::unreadVariableError(const Token *tok, const std::string void CheckUnusedVarImpl::unassignedVariableError(const Token *tok, const std::string &varname) { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedVariable")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedVariable")) return; reportError(tok, Severity::style, "unassignedVariable", "$symbol:" + varname + "\nVariable '$symbol' is not assigned a value.", CWE665, Certainty::normal); @@ -1519,7 +1519,7 @@ void CheckUnusedVarImpl::unassignedVariableError(const Token *tok, const std::st //--------------------------------------------------------------------------- void CheckUnusedVarImpl::checkStructMemberUsage() { - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("unusedStructMember") && !mSettings->isPremiumEnabled("unusedVariable")) + if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("unusedStructMember") && !mSettings.isPremiumEnabled("unusedVariable")) return; logChecker("CheckUnusedVar::checkStructMemberUsage"); // style @@ -1726,14 +1726,14 @@ bool CheckUnusedVarImpl::isEmptyType(const Type* type) void CheckUnusedVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckUnusedVarImpl checkUnusedVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, tokenizer.getSettings(), errorLogger); // Coding style checks checkUnusedVar.checkStructMemberUsage(); checkUnusedVar.checkFunctionVariableUsage(); } -void CheckUnusedVar::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckUnusedVar::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckUnusedVarImpl c(nullptr, settings, errorLogger); c.unusedVariableError(nullptr, "varname"); diff --git a/lib/checkunusedvar.h b/lib/checkunusedvar.h index 1d2227c15bf..49ef59bee92 100644 --- a/lib/checkunusedvar.h +++ b/lib/checkunusedvar.h @@ -53,7 +53,7 @@ class CPPCHECKLIB CheckUnusedVar : public Check { /** @brief Run checks against the normal token list */ void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "UnusedVar checks\n" @@ -70,7 +70,7 @@ class CPPCHECKLIB CheckUnusedVar : public Check { class CPPCHECKLIB CheckUnusedVarImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckUnusedVarImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckUnusedVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for unused function variables */ diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index 18eb246e0e7..42cd6852788 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -43,7 +43,7 @@ void CheckVaargImpl::va_start_argument() { const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const std::size_t functions = symbolDatabase->functionScopes.size(); - const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); + const bool printWarnings = mSettings.severity.isEnabled(Severity::warning); logChecker("CheckVaarg::va_start_argument"); @@ -92,7 +92,7 @@ void CheckVaargImpl::referenceAs_va_start_error(const Token *tok, const std::str void CheckVaargImpl::va_list_usage() { - if (mSettings->clang) + if (mSettings.clang) return; logChecker("CheckVaarg::va_list_usage"); // notclang @@ -175,12 +175,12 @@ void CheckVaargImpl::va_start_subsequentCallsError(const Token *tok, const std:: void CheckVaarg::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) { - CheckVaargImpl check(&tokenizer, &tokenizer.getSettings(), errorLogger); + CheckVaargImpl check(&tokenizer, tokenizer.getSettings(), errorLogger); check.va_start_argument(); check.va_list_usage(); } -void CheckVaarg::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +void CheckVaarg::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const { CheckVaargImpl c(nullptr, settings, errorLogger); c.wrongParameterTo_va_start_error(nullptr, "arg1", "arg2"); diff --git a/lib/checkvaarg.h b/lib/checkvaarg.h index e07d653456a..4be92045427 100644 --- a/lib/checkvaarg.h +++ b/lib/checkvaarg.h @@ -47,7 +47,7 @@ class CPPCHECKLIB CheckVaarg : public Check { void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; private: - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; + void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check for misusage of variable argument lists:\n" @@ -62,7 +62,7 @@ class CPPCHECKLIB CheckVaarg : public Check { class CPPCHECKLIB CheckVaargImpl : public CheckImpl { public: - CheckVaargImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + CheckVaargImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} void va_start_argument(); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index f39e64a938f..471a1a8ff1e 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1714,7 +1714,7 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) // call all "getErrorMessages" in all registered Check classes for (const Check * const c : CheckInstances::get()) - c->getErrorMessages(&errorlogger, &s); + c->getErrorMessages(&errorlogger, s); CheckUnusedFunctions::getErrorMessages(errorlogger); Preprocessor::getErrorMessages(errorlogger, s); diff --git a/test/test64bit.cpp b/test/test64bit.cpp index da837fd9a96..8439b5aa787 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -49,7 +49,7 @@ class Test64BitPortability : public TestFixture { SimpleTokenizer tokenizer(settings, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - Check64BitPortabilityImpl check64BitPortability(&tokenizer, &settings, this); + Check64BitPortabilityImpl check64BitPortability(&tokenizer, settings, this); check64BitPortability.pointerassignment(); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 5d545606387..29d8fa13d17 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -5171,7 +5171,7 @@ class TestBufferOverrun : public TestFixture { // Ticket #2292: segmentation fault when using --errorlist CheckBufferOverrun check; const Check& c = getCheck(check); - c.getErrorMessages(this, nullptr); + c.getErrorMessages(this, settingsDefault); // we are not interested in the output - just consume it ignore_errout(); } diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index bb98dfad48d..ecbf6bf4dc1 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -47,7 +47,7 @@ class TestCharVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check char variable usage.. - CheckOtherImpl checkOther(&tokenizer, &settings, this); + CheckOtherImpl checkOther(&tokenizer, settings, this); checkOther.checkCharVariable(); } diff --git a/test/testclass.cpp b/test/testclass.cpp index 35994e98cf4..8fba8d4a340 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -270,7 +270,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); (checkClass.checkCopyCtorAndEqOperator)(); } @@ -371,7 +371,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings0, this); + CheckClassImpl checkClass(&tokenizer, settings0, this); (checkClass.checkExplicitConstructors)(); } @@ -528,7 +528,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, this); (checkClass.checkDuplInheritedMembers)(); } @@ -752,7 +752,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings3, this); + CheckClassImpl checkClass(&tokenizer, settings3, this); checkClass.copyconstructors(); } @@ -1223,7 +1223,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings0, this); + CheckClassImpl checkClass(&tokenizer, settings0, this); checkClass.operatorEqRetRefThis(); } @@ -1694,7 +1694,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, this); checkClass.operatorEqToSelf(); } @@ -2657,7 +2657,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &s, this); + CheckClassImpl checkClass(&tokenizer, s, this); checkClass.virtualDestructor(); } @@ -2994,7 +2994,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); checkClass.checkMemset(); } @@ -3640,7 +3640,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, this); checkClass.thisSubtraction(); } @@ -3680,7 +3680,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); (checkClass.checkConst)(); } @@ -7863,7 +7863,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings2, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, &settings2, this); + CheckClassImpl checkClass(&tokenizer, settings2, this); checkClass.initializerListOrder(); } @@ -8017,7 +8017,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); checkClass.initializationListUsage(); } @@ -8241,7 +8241,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings0, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, &settings0, this); + CheckClassImpl checkClass(&tokenizer, settings0, this); (checkClass.checkSelfInitialization)(); } @@ -8351,7 +8351,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); checkClass.checkVirtualFunctionCallInConstructor(); } @@ -8696,7 +8696,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); (checkClass.checkOverride)(); } @@ -8908,7 +8908,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); (checkClass.checkUselessOverride)(); } @@ -9098,7 +9098,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); (checkClass.checkUnsafeClassRefMember)(); } @@ -9116,7 +9116,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, this); (checkClass.checkThisUseAfterFree)(); } @@ -9353,7 +9353,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, &settings, this); + CheckClassImpl checkClass(&tokenizer, settings, this); (checkClass.checkReturnByReference)(); } diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 8bec74529b6..155c921de80 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -52,7 +52,7 @@ class TestConstructors : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check class constructors.. - CheckClassImpl checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, this); checkClass.constructors(); } diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index bd94b52af0e..23c6f667797 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -50,7 +50,7 @@ class TestIncompleteStatement : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for incomplete statements.. - CheckOtherImpl checkOther(&tokenizer, &settings1, this); + CheckOtherImpl checkOther(&tokenizer, settings1, this); checkOther.checkIncompleteStatement(); } diff --git a/test/testio.cpp b/test/testio.cpp index bc6e40034f6..6d9b55ddda9 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -109,7 +109,7 @@ class TestIO : public TestFixture { // Check.. if (options.onlyFormatStr) { - CheckIOImpl checkIO(&tokenizer, &settings1, this); + CheckIOImpl checkIO(&tokenizer, settings1, this); checkIO.checkWrongPrintfScanfArguments(); return; } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 8982215d8e3..8ac0b2484ad 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -44,7 +44,7 @@ class TestMemleak : public TestFixture { SimpleTokenizer tokenizer(settingsDefault, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - const CheckMemoryLeakImpl c(&tokenizer, &settingsDefault, this); + const CheckMemoryLeakImpl c(&tokenizer, settingsDefault, this); return (c.functionReturnType)(&tokenizer.getSymbolDatabase()->scopeList.front().functionList.front()); } @@ -93,7 +93,7 @@ class TestMemleak : public TestFixture { // there is no allocation const Token *tok = Token::findsimplematch(tokenizer.tokens(), "ret ="); - const CheckMemoryLeakImpl check(&tokenizer, &settingsDefault, nullptr); + const CheckMemoryLeakImpl check(&tokenizer, settingsDefault, nullptr); ASSERT_EQUALS(CheckMemoryLeakImpl::No, check.getAllocationType(tok->tokAt(2), 1)); } }; @@ -119,7 +119,7 @@ class TestMemleakInFunction : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, &settings, this); + CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, settings, this); checkMemoryLeak.checkReallocUsage(); } @@ -501,7 +501,7 @@ class TestMemleakInClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakInClassImpl checkMemoryLeak(&tokenizer, &settings, this); + CheckMemoryLeakInClassImpl checkMemoryLeak(&tokenizer, settings, this); (checkMemoryLeak.check)(); } @@ -1706,7 +1706,7 @@ class TestMemleakStructMember : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakStructMemberImpl checkMemoryLeakStructMember(&tokenizer, &settings, this); + CheckMemoryLeakStructMemberImpl checkMemoryLeakStructMember(&tokenizer, settings, this); (checkMemoryLeakStructMember.check)(); } @@ -2388,7 +2388,7 @@ class TestMemleakNoVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakNoVarImpl checkMemoryLeakNoVar(&tokenizer, &settings, this); + CheckMemoryLeakNoVarImpl checkMemoryLeakNoVar(&tokenizer, settings, this); (checkMemoryLeakNoVar.check)(); } diff --git a/test/testother.cpp b/test/testother.cpp index 321657c668f..2394cfefe7c 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2055,7 +2055,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizerCpp(settings, *this); ASSERT_LOC(tokenizerCpp.tokenize(code), file, line); - CheckOtherImpl checkOtherCpp(&tokenizerCpp, &settings, this); + CheckOtherImpl checkOtherCpp(&tokenizerCpp, settings, this); checkOtherCpp.warningOldStylePointerCast(); checkOtherCpp.warningDangerousTypeCast(); } @@ -2341,7 +2341,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizerCpp(settings, *this); ASSERT_LOC(tokenizerCpp.tokenize(code), file, line); - CheckOtherImpl checkOtherCpp(&tokenizerCpp, &settings, this); + CheckOtherImpl checkOtherCpp(&tokenizerCpp, settings, this); checkOtherCpp.warningIntToPointerCast(); } @@ -2380,7 +2380,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckOtherImpl checkOtherCpp(&tokenizer, &settings, this); + CheckOtherImpl checkOtherCpp(&tokenizer, settings, this); checkOtherCpp.invalidPointerCast(); } diff --git a/test/testpostfixoperator.cpp b/test/testpostfixoperator.cpp index 1d01217231a..73c864f10bc 100644 --- a/test/testpostfixoperator.cpp +++ b/test/testpostfixoperator.cpp @@ -38,7 +38,7 @@ class TestPostfixOperator : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckPostfixOperatorImpl checkPostfixOperator(&tokenizer, &settings, this); + CheckPostfixOperatorImpl checkPostfixOperator(&tokenizer, settings, this); checkPostfixOperator.postfixOperator(); } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 6ad2047ddd7..0d71efbc897 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -127,7 +127,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVarImpl checkuninitvar(&tokenizer, &settings1, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, settings1, this); checkuninitvar.check(); } @@ -137,7 +137,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVarImpl checkuninitvar(&tokenizer, &settings, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, settings, this); checkuninitvar.check(); } @@ -3673,7 +3673,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVarImpl checkuninitvar(&tokenizer, &settings, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, settings, this); (checkuninitvar.valueFlowUninit)(); } diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 3b419814dca..60916133f8c 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -104,7 +104,7 @@ class TestUnusedPrivateFunction : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused private functions.. - CheckClassImpl checkClass(&tokenizer, &settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, this); checkClass.privateFunctions(); } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index d0ad22b004d..6419ee78c08 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -290,7 +290,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for unused variables.. - CheckUnusedVarImpl checkUnusedVar(&tokenizer, &settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, this); checkUnusedVar.checkFunctionVariableUsage(); } @@ -310,7 +310,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for unused variables.. - CheckUnusedVarImpl checkUnusedVar(&tokenizer, &settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, this); (checkUnusedVar.checkStructMemberUsage)(); } @@ -323,7 +323,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused variables.. - CheckUnusedVarImpl checkUnusedVar(&tokenizer, &settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, this); (checkUnusedVar.checkStructMemberUsage)(); } @@ -336,7 +336,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused variables.. - CheckUnusedVarImpl checkUnusedVar(&tokenizer, &settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, this); (checkUnusedVar.checkFunctionVariableUsage)(); } From d152dd696dab022390d5617d4879db62471d11cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 29 May 2026 10:29:08 +0200 Subject: [PATCH 133/493] added test for #13690 (#8584) --- .../fuzz-crash/crash-6d019f821f348d758d8d88bd7de692af6f9b07f4 | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/cli/fuzz-crash/crash-6d019f821f348d758d8d88bd7de692af6f9b07f4 diff --git a/test/cli/fuzz-crash/crash-6d019f821f348d758d8d88bd7de692af6f9b07f4 b/test/cli/fuzz-crash/crash-6d019f821f348d758d8d88bd7de692af6f9b07f4 new file mode 100644 index 00000000000..cd0cc97f0fb --- /dev/null +++ b/test/cli/fuzz-crash/crash-6d019f821f348d758d8d88bd7de692af6f9b07f4 @@ -0,0 +1 @@ +#error\ \ No newline at end of file From e0ee4f2c91feb23d17ac18a7fa1d7014227bab19 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 29 May 2026 10:30:50 +0200 Subject: [PATCH 134/493] Fix #11775 cppcheckError with array typedef (#8581) --- lib/tokenize.cpp | 7 +++++++ test/testsimplifytypedef.cpp | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6f9cf90a852..6305e0f021a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2295,6 +2295,13 @@ void Tokenizer::simplifyTypedefCpp() tok2 = tok2->tokAt(2); else tok2 = tok2->tokAt(3); + while (tok2->link()) { + tok2 = tok2->link()->next(); + if (Token::simpleMatch(tok2, ";")) { + tok2 = tok2->previous(); + break; + } + } if (!tok2) syntaxError(nullptr); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 342cda59dc8..022412139f1 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -231,6 +231,7 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedef158); TEST_CASE(simplifyTypedef159); TEST_CASE(simplifyTypedef160); + TEST_CASE(simplifyTypedef161); TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -3842,6 +3843,22 @@ class TestSimplifyTypedef : public TestFixture { ASSERT_EQUALS(exp2, simplifyTypedefC(code2)); } + void simplifyTypedef161() { + const char code[] = "namespace N {\n" // #11775 + " typedef int A[3];\n" + " p = new A*[n];\n" + "}\n"; + const char cur[] = "namespace N { p = new int ( * [ n ] ) [ 3 ] ; }"; + const char exp[] = "namespace N { p = new ( int ( * [ n ] ) [ 3 ] ) ; }"; + TODO_ASSERT_EQUALS(exp, cur, tok(code)); + + const char code2[] = "typedef int A[3];\n" + "p = new A*[n];\n"; + const char cur2[] = "p = new int ( * ) [ n ] [ 3 ] ;"; + const char exp2[] = "p = new ( int ( * [ n ] ) [ 3 ] ) ;"; + TODO_ASSERT_EQUALS(exp2, cur2, tok(code2)); + } + void simplifyTypedefFunction1() { { const char code[] = "typedef void (*my_func)();\n" From 7f1eba2e1ececd83a8415641be83353a9438a704 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 29 May 2026 10:32:46 +0200 Subject: [PATCH 135/493] Fix #11184 FN leakNoVarFunctionCall with assignment (#8567) --- lib/checkmemoryleak.cpp | 12 ++++++++---- test/testmemleak.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 0286884ab16..d396d20c7a2 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -1016,10 +1016,8 @@ void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scop const Token* tok2 = tok->next()->astParent(); while (tok2 && (tok2->isCast() || Token::Match(tok2, "?|:"))) tok2 = tok2->astParent(); - if (Token::Match(tok2, "%assign%")) // TODO: check if function returns allocated resource - continue; - if (Token::simpleMatch(tok->astTop(), "return")) - continue; + const bool hasAssign = Token::Match(tok2, "%assign%"); + const bool hasReturn = Token::simpleMatch(tok->astTop(), "return"); const std::string& functionName = tok->str(); if ((tok->isCpp() && functionName == "delete") || @@ -1031,6 +1029,12 @@ void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scop if (!tok->isKeyword() && !tok->function() && !mSettings.library.isLeakIgnore(functionName)) continue; + if ((hasAssign || hasReturn) && !tok->function()) { + const std::string& ret = mSettings->library.returnValueType(tok); + if (ret.empty() || endsWith(ret, "*")) + continue; + } + const std::vector args = getArguments(tok); int argnr = -1; for (const Token* arg : args) { diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 8ac0b2484ad..6e3d28010a1 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2602,6 +2602,17 @@ class TestMemleakNoVar : public TestFixture { " a.g(new int);\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("int f() {\n" // #11184 + " return strlen(new char[4]{});\n" + "}\n" + "int g() {\n" + " int i = strlen(new char[4]{});\n" + " return i;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:19]: (error) Allocation with new, strlen doesn't release it. [leakNoVarFunctionCall]\n" + "[test.cpp:5:20]: (error) Allocation with new, strlen doesn't release it. [leakNoVarFunctionCall]\n", + errout_str()); } void missingAssignment() { From fe41d367067c6ab195e1564bafccf31029b657a6 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 29 May 2026 12:29:35 +0200 Subject: [PATCH 136/493] Fix build: checkmemoryleak.cpp (#8596) --- lib/checkmemoryleak.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index d396d20c7a2..d02bb607b33 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -1030,7 +1030,7 @@ void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scop continue; if ((hasAssign || hasReturn) && !tok->function()) { - const std::string& ret = mSettings->library.returnValueType(tok); + const std::string& ret = mSettings.library.returnValueType(tok); if (ret.empty() || endsWith(ret, "*")) continue; } From 15a41911a87d1ab244179bf9186bb9c3d3586bf9 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 29 May 2026 12:31:39 +0200 Subject: [PATCH 137/493] Fix #14785/14786 FN unusedStructMember (scoped standard type, smart pointer) (#8576) Co-authored-by: chrchr-github --- lib/checkunusedvar.cpp | 3 ++- test/testunusedvar.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index b5b863badc5..dd30f65db58 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1641,7 +1641,8 @@ void CheckUnusedVarImpl::checkStructMemberUsage() for (const Variable &var : scope.varlist) { // only warn for variables without side effects - if (!var.typeStartToken()->isStandardType() && !var.isPointer() && !astIsContainer(var.nameToken()) && !mTokenizer->getSymbolDatabase()->isRecordTypeWithoutSideEffects(var.type())) + if (!(var.valueType() && var.valueType()->type >= ValueType::VOID) && !var.isPointer() && !astIsContainer(var.nameToken()) && + !astIsSmartPointer(var.nameToken()) && !mTokenizer->getSymbolDatabase()->isRecordTypeWithoutSideEffects(var.type())) continue; if (isInherited && !var.isPrivate()) continue; diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 6419ee78c08..ae44305ef6a 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -79,6 +79,7 @@ class TestUnusedVar : public TestFixture { TEST_CASE(structmember31); // #14130 TEST_CASE(structmember32); // #14483 TEST_CASE(structmember33); + TEST_CASE(structmember34); TEST_CASE(structmember_macro); TEST_CASE(structmember_template_argument); // #13887 - do not report that member used in template argument is unused TEST_CASE(classmember); @@ -2088,6 +2089,18 @@ class TestUnusedVar : public TestFixture { ASSERT_EQUALS("[test.cpp:2:23]: (style) struct member 'S::mp' is never used. [unusedStructMember]\n", errout_str()); } + void structmember34() { + checkStructMemberUsage("struct S {\n" // #14785 + " std::int32_t i;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:2:16]: (style) struct member 'S::i' is never used. [unusedStructMember]\n", errout_str()); + + checkStructMemberUsage("struct S {\n" // #14786 + " std::unique_ptr p;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:2:24]: (style) struct member 'S::p' is never used. [unusedStructMember]\n", errout_str()); + } + void structmember_macro() { checkStructMemberUsageP("#define S(n) struct n { int a, b, c; };\n" "S(unused);\n"); From f034ad3663e509465486b946cc71704337c38ae4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 29 May 2026 12:40:10 +0200 Subject: [PATCH 138/493] Fix #14762 FN knownConditionTrueFalse (default constructed container) (#8575) Co-authored-by: chrchr-github --- lib/vf_settokenvalue.cpp | 4 ++-- test/testvalueflow.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index c5fe519b720..fe94225083b 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -291,9 +291,9 @@ namespace ValueFlow combineValueProperties(value1, value2, result); - if (Token::simpleMatch(parent, "==") && result.intvalue) + if (Token::simpleMatch(parent, "==") && result.intvalue && !(value1.intvalue == 0 && value2.intvalue == 0)) continue; - if (Token::simpleMatch(parent, "!=") && !result.intvalue) + if (Token::simpleMatch(parent, "!=") && !result.intvalue && !(value1.intvalue == 0 && value2.intvalue == 0)) continue; setTokenValue(parent, std::move(result), settings); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 1f4879b7cca..65f198dcbab 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -9249,6 +9249,19 @@ class TestValueFlow : public TestFixture { "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 5U, 1)); ASSERT_EQUALS(false, testValueOfX(code, 5U, 0)); + + code = "bool f() {\n" + " std::string s1, s2;\n" + " bool x = (s1 == s2);\n" + " return x;\n" + "}\n" + "bool g() {\n" + " std::string s1, s2;\n" + " bool x = (s1 != s2);\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXKnown(code, 4U, 1)); + ASSERT_EQUALS(true, testValueOfXKnown(code, 9U, 0)); } void valueFlowBailoutIncompleteVar() { From 97b642f1f04589319882c0fc2e29c42f7464113e Mon Sep 17 00:00:00 2001 From: Wija <50847546+wjakobsson@users.noreply.github.com> Date: Fri, 29 May 2026 16:26:07 +0200 Subject: [PATCH 139/493] Release 2.21: Update copyright year (#8594) --- cli/filelister.cpp | 2 +- gui/cppchecklibrarydata.h | 2 +- gui/helpdialog.cpp | 2 +- gui/librarydialog.h | 2 +- gui/main.cpp | 2 +- gui/projectfiledialog.h | 2 +- gui/statsdialog.cpp | 2 +- gui/test/projectfile/testprojectfile.cpp | 2 +- gui/test/projectfile/testprojectfile.h | 2 +- lib/check.h | 2 +- lib/check64bit.h | 2 +- lib/checkassert.cpp | 2 +- lib/checkassert.h | 2 +- lib/checkautovariables.h | 2 +- lib/checkbool.cpp | 2 +- lib/checkbool.h | 2 +- lib/checkbufferoverrun.h | 2 +- lib/checkcondition.h | 2 +- lib/checkexceptionsafety.h | 2 +- lib/checkfunctions.h | 2 +- lib/checkinternal.cpp | 2 +- lib/checkinternal.h | 2 +- lib/checkio.h | 2 +- lib/checkleakautovar.h | 2 +- lib/checkmemoryleak.h | 2 +- lib/checknullpointer.h | 2 +- lib/checkother.h | 2 +- lib/checkpostfixoperator.cpp | 2 +- lib/checkpostfixoperator.h | 2 +- lib/checksizeof.h | 2 +- lib/checkstl.cpp | 2 +- lib/checkstl.h | 2 +- lib/checkstring.cpp | 2 +- lib/checkstring.h | 2 +- lib/checktype.h | 2 +- lib/checkuninitvar.h | 2 +- lib/checkunusedfunctions.h | 2 +- lib/checkunusedvar.h | 2 +- lib/checkvaarg.cpp | 2 +- lib/checkvaarg.h | 2 +- lib/mathlib.h | 2 +- lib/path.cpp | 2 +- lib/path.h | 2 +- lib/preprocessor.h | 2 +- lib/programmemory.cpp | 2 +- lib/programmemory.h | 2 +- lib/regex.cpp | 2 +- lib/regex.h | 2 +- lib/valueptr.h | 2 +- lib/vf_common.h | 2 +- test/options.cpp | 2 +- test/options.h | 2 +- test/test64bit.cpp | 2 +- test/testassert.cpp | 2 +- test/testastutils.cpp | 2 +- test/testbool.cpp | 2 +- test/testcharvar.cpp | 2 +- test/testcheck.cpp | 2 +- test/testcheckersreport.cpp | 2 +- test/testconstructors.cpp | 2 +- test/testerrorlogger.cpp | 2 +- test/testincompletestatement.cpp | 2 +- test/testinternal.cpp | 2 +- test/testio.cpp | 2 +- test/testoptions.cpp | 2 +- test/testpostfixoperator.cpp | 2 +- test/testregex.cpp | 2 +- test/testsimplifytokens.cpp | 2 +- test/testsizeof.cpp | 2 +- test/teststring.cpp | 2 +- test/testunusedfunctions.cpp | 2 +- test/testunusedprivfunc.cpp | 2 +- test/testvaarg.cpp | 2 +- tools/dmake/dmake.cpp | 2 +- tools/triage/mainwindow.cpp | 2 +- tools/triage/mainwindow.h | 2 +- 76 files changed, 76 insertions(+), 76 deletions(-) diff --git a/cli/filelister.cpp b/cli/filelister.cpp index 65a77ea6306..9b95689679c 100644 --- a/cli/filelister.cpp +++ b/cli/filelister.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/cppchecklibrarydata.h b/gui/cppchecklibrarydata.h index ddccf3b6534..71d8382ef34 100644 --- a/gui/cppchecklibrarydata.h +++ b/gui/cppchecklibrarydata.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/helpdialog.cpp b/gui/helpdialog.cpp index 0768318531c..78ac1e0e635 100644 --- a/gui/helpdialog.cpp +++ b/gui/helpdialog.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/librarydialog.h b/gui/librarydialog.h index 6737da638c8..c8e522b10d4 100644 --- a/gui/librarydialog.h +++ b/gui/librarydialog.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/main.cpp b/gui/main.cpp index efdb2a33c72..c855b2529f6 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/projectfiledialog.h b/gui/projectfiledialog.h index af21685b675..a93d12dc2e2 100644 --- a/gui/projectfiledialog.h +++ b/gui/projectfiledialog.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/statsdialog.cpp b/gui/statsdialog.cpp index d3e15d87ad5..bf46abcb2d4 100644 --- a/gui/statsdialog.cpp +++ b/gui/statsdialog.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/test/projectfile/testprojectfile.cpp b/gui/test/projectfile/testprojectfile.cpp index dbc4cb51659..1eb43f7d72f 100644 --- a/gui/test/projectfile/testprojectfile.cpp +++ b/gui/test/projectfile/testprojectfile.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2021 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/test/projectfile/testprojectfile.h b/gui/test/projectfile/testprojectfile.h index 18f38d0eb39..ceda2ff6b96 100644 --- a/gui/test/projectfile/testprojectfile.h +++ b/gui/test/projectfile/testprojectfile.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2021 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/check.h b/lib/check.h index 019b77e148e..7deab9e52e7 100644 --- a/lib/check.h +++ b/lib/check.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/check64bit.h b/lib/check64bit.h index 160df94b990..bafb5646aaa 100644 --- a/lib/check64bit.h +++ b/lib/check64bit.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index 3ae06984c7b..8240304d83f 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkassert.h b/lib/checkassert.h index 6a4e1f45de2..f6190bb8d25 100644 --- a/lib/checkassert.h +++ b/lib/checkassert.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkautovariables.h b/lib/checkautovariables.h index 77deef00113..4bdbfc4c730 100644 --- a/lib/checkautovariables.h +++ b/lib/checkautovariables.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index a216307ad2e..0d7516a9418 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkbool.h b/lib/checkbool.h index 2d523732682..5eafc4d692d 100644 --- a/lib/checkbool.h +++ b/lib/checkbool.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 2b43d575dec..b71f4520d48 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkcondition.h b/lib/checkcondition.h index 06ed12695bc..56d2c6f25e0 100644 --- a/lib/checkcondition.h +++ b/lib/checkcondition.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index d452dac2cf8..7de91ba812c 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkfunctions.h b/lib/checkfunctions.h index b6939ffb17f..42281774482 100644 --- a/lib/checkfunctions.h +++ b/lib/checkfunctions.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkinternal.cpp b/lib/checkinternal.cpp index f84203e5d0d..727df306e63 100644 --- a/lib/checkinternal.cpp +++ b/lib/checkinternal.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkinternal.h b/lib/checkinternal.h index 2b6267b4550..c1e5addc4da 100644 --- a/lib/checkinternal.h +++ b/lib/checkinternal.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkio.h b/lib/checkio.h index 4642feac511..e881e22cbf3 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index c12c03b6a09..5d4fa07ec06 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 6c867749fa4..4fa69742277 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index 4da9fe8abc7..8e35fd7565a 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkother.h b/lib/checkother.h index c3c045653c8..97291b53769 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkpostfixoperator.cpp b/lib/checkpostfixoperator.cpp index e0026e1d70c..0d72b8e3860 100644 --- a/lib/checkpostfixoperator.cpp +++ b/lib/checkpostfixoperator.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkpostfixoperator.h b/lib/checkpostfixoperator.h index 27d833a992e..de51a34fe42 100644 --- a/lib/checkpostfixoperator.h +++ b/lib/checkpostfixoperator.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checksizeof.h b/lib/checksizeof.h index 90d55e69506..6fa7908eb92 100644 --- a/lib/checksizeof.h +++ b/lib/checksizeof.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 887f7001ef2..08ac141610a 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkstl.h b/lib/checkstl.h index e23d6b54fb4..b67632fbfed 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index db4a3eca113..00fa80998c1 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkstring.h b/lib/checkstring.h index 054c4208a18..2c19d64332c 100644 --- a/lib/checkstring.h +++ b/lib/checkstring.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checktype.h b/lib/checktype.h index 0030e3622be..8ebfb0fb5b2 100644 --- a/lib/checktype.h +++ b/lib/checktype.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index e7af8f85e50..f558fe84709 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 20e1788cf64..5c5b369c194 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkunusedvar.h b/lib/checkunusedvar.h index 49ef59bee92..cddc36bb7e3 100644 --- a/lib/checkunusedvar.h +++ b/lib/checkunusedvar.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index 42cd6852788..60a27b897b5 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkvaarg.h b/lib/checkvaarg.h index 4be92045427..6d50bd94d0d 100644 --- a/lib/checkvaarg.h +++ b/lib/checkvaarg.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/mathlib.h b/lib/mathlib.h index 9b6b304501c..84338b5ce70 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/path.cpp b/lib/path.cpp index caa45898f99..c4758dfeae9 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/path.h b/lib/path.h index 22bfcf667f3..863e74580f8 100644 --- a/lib/path.h +++ b/lib/path.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 9daabbf6ca8..ba4d55a1e60 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 92952152ca5..e1f40de277e 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/programmemory.h b/lib/programmemory.h index 21350d86d36..ec24c0df59f 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/regex.cpp b/lib/regex.cpp index 0c8b0c9f188..df92982204a 100644 --- a/lib/regex.cpp +++ b/lib/regex.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/regex.h b/lib/regex.h index afe92d92d40..9717ff6f05d 100644 --- a/lib/regex.h +++ b/lib/regex.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/valueptr.h b/lib/valueptr.h index 270b5f58fc6..b6f02ef1186 100644 --- a/lib/valueptr.h +++ b/lib/valueptr.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/vf_common.h b/lib/vf_common.h index 64e394b2979..9859955cbfe 100644 --- a/lib/vf_common.h +++ b/lib/vf_common.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/options.cpp b/test/options.cpp index 54527b26ecd..757b6cdff86 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -1,5 +1,5 @@ // Cppcheck - A tool for static C/C++ code analysis -// Copyright (C) 2007-2025 Cppcheck team. +// Copyright (C) 2007-2026 Cppcheck team. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/test/options.h b/test/options.h index b327721351c..0bd83cef78b 100644 --- a/test/options.h +++ b/test/options.h @@ -1,5 +1,5 @@ // Cppcheck - A tool for static C/C++ code analysis -// Copyright (C) 2007-2024 Cppcheck team. +// Copyright (C) 2007-2026 Cppcheck team. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/test/test64bit.cpp b/test/test64bit.cpp index 8439b5aa787..ca2654b12f1 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testassert.cpp b/test/testassert.cpp index e14825e46b2..651897af057 100644 --- a/test/testassert.cpp +++ b/test/testassert.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testastutils.cpp b/test/testastutils.cpp index eb9559ed39d..904ea92b466 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testbool.cpp b/test/testbool.cpp index ccf4d7860c4..6156e089aee 100644 --- a/test/testbool.cpp +++ b/test/testbool.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index ecbf6bf4dc1..347557bd051 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testcheck.cpp b/test/testcheck.cpp index 3ae2cad3d8f..254519da2eb 100644 --- a/test/testcheck.cpp +++ b/test/testcheck.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testcheckersreport.cpp b/test/testcheckersreport.cpp index eafe7b8848f..39a6f2a9997 100644 --- a/test/testcheckersreport.cpp +++ b/test/testcheckersreport.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 155c921de80..b4f17cd25b8 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testerrorlogger.cpp b/test/testerrorlogger.cpp index 23b3233995c..014ac3a0a8f 100644 --- a/test/testerrorlogger.cpp +++ b/test/testerrorlogger.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 23c6f667797..be0b3e7ad3d 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testinternal.cpp b/test/testinternal.cpp index 10431adcd38..b724c860fae 100644 --- a/test/testinternal.cpp +++ b/test/testinternal.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testio.cpp b/test/testio.cpp index 6d9b55ddda9..c622bc5936d 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testoptions.cpp b/test/testoptions.cpp index 0dec04927e4..af164fb43cc 100644 --- a/test/testoptions.cpp +++ b/test/testoptions.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testpostfixoperator.cpp b/test/testpostfixoperator.cpp index 73c864f10bc..07b7c03ca00 100644 --- a/test/testpostfixoperator.cpp +++ b/test/testpostfixoperator.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testregex.cpp b/test/testregex.cpp index 4b6b2781cc8..85ab8007478 100644 --- a/test/testregex.cpp +++ b/test/testregex.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 88d1a4b2725..6077438a9cf 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index fca8cb7ed7a..ee9416a65bc 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/teststring.cpp b/test/teststring.cpp index e0e401256e2..7f28f58c80a 100644 --- a/test/teststring.cpp +++ b/test/teststring.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index b3b8a298650..3e78b119012 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 60916133f8c..06c41bbb9c2 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testvaarg.cpp b/test/testvaarg.cpp index 33fb6c11389..3f44b687ff3 100644 --- a/test/testvaarg.cpp +++ b/test/testvaarg.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2025 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index 3d08943f5ba..d2147efa8c6 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2023 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tools/triage/mainwindow.cpp b/tools/triage/mainwindow.cpp index e8a15f87f3b..18b6bb09533 100644 --- a/tools/triage/mainwindow.cpp +++ b/tools/triage/mainwindow.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2021 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tools/triage/mainwindow.h b/tools/triage/mainwindow.h index 38afcaf9553..263d9953e60 100644 --- a/tools/triage/mainwindow.h +++ b/tools/triage/mainwindow.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2021 Cppcheck team. + * Copyright (C) 2007-2026 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From bc2b84dd40d779bd0ab6fe62d32a3bf74dcc9883 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 29 May 2026 17:18:27 +0200 Subject: [PATCH 140/493] F'up to #14654: Fix Boost test macro definitions (#8590) CI failure is unrelated. --- cfg/boost.cfg | 8 ++++---- test/cfg/boost.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/cfg/boost.cfg b/cfg/boost.cfg index 722c4c83cd7..b09d9ccd9e5 100644 --- a/cfg/boost.cfg +++ b/cfg/boost.cfg @@ -83,12 +83,12 @@ - + - + - - + + diff --git a/test/cfg/boost.cpp b/test/cfg/boost.cpp index 7e724a8b472..2cc4b288cce 100644 --- a/test/cfg/boost.cpp +++ b/test/cfg/boost.cpp @@ -22,6 +22,8 @@ #include // IWYU pragma: keep #include #include // IWYU pragma: keep +#include +#include #include #include @@ -199,3 +201,46 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(my_tuple_test, T, test_types_w_tuples) } BOOST_AUTO_TEST_SUITE_END() + +// https://www.boost.org/doc/libs/latest/libs/test/doc/html/boost_test/tests_organization/test_cases/test_case_generation/datasets.html +namespace bdata = boost::unit_test::data; + +// Dataset generating a Fibonacci sequence +struct fibonacci_dataset { + // the type of the samples is deduced + // cppcheck-suppress unusedStructMember // FP #14795, used in template is_dataset + static const int arity = 1; + + struct iterator { + int operator*() const { return b; } + void operator++() { + a = a + b; + std::swap(a, b); + } + private: + int a = 1; + int b = 1; // b is the output + }; + + // size is infinite + bdata::size_t size() const { return bdata::BOOST_TEST_DS_INFINITE_SIZE; } + + // iterator + static iterator begin() { return iterator(); } +}; + +namespace boost { namespace unit_test { namespace data { namespace monomorphic { + // registering fibonacci_dataset as a proper dataset + template <> + struct is_dataset : boost::mpl::true_ {}; +}}}} + +// Creating a test-driven dataset, the zip is for checking +BOOST_DATA_TEST_CASE( + test1, + fibonacci_dataset() ^ bdata::make( { 1, 2, 3, 5, 8, 13, 21, 35, 56 } ), + fib_sample, exp) +{ + // cppcheck-suppress valueFlowBailoutIncompleteVar // TODO: fib_sample declared in test case + BOOST_TEST(fib_sample == exp); +} From 8c14fc78e5dd9f0696b1facde4bd867dddd951a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 31 May 2026 09:56:45 +0200 Subject: [PATCH 141/493] cleaned up includes based on `include-what-you-use` (#8579) --- .github/workflows/selfcheck.yml | 2 +- Makefile | 4 ++-- cli/cmdlineparser.cpp | 3 ++- cli/processexecutor.cpp | 3 ++- cli/singleexecutor.cpp | 1 - cli/threadexecutor.cpp | 1 - gui/mainwindow.cpp | 3 --- gui/projectfiledialog.cpp | 1 - gui/test/resultstree/testresultstree.cpp | 1 - lib/checks.cpp | 2 ++ lib/cppcheck.h | 2 ++ lib/importproject.cpp | 1 + lib/settings.cpp | 1 + lib/settings.h | 10 +++++++--- lib/suppressions.cpp | 1 + lib/utils.h | 1 + lib/vf_common.cpp | 1 + test/testsuppressions.cpp | 1 + 18 files changed, 24 insertions(+), 15 deletions(-) diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index cfd1107e92d..dcdf8bfbdd3 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -121,7 +121,7 @@ jobs: - name: Self check (unusedFunction / no test / no gui) run: | - supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1665 --suppress=unusedFunction:lib/importproject.cpp:1689" + supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1666 --suppress=unusedFunction:lib/importproject.cpp:1690" ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs env: DISABLE_VALUEFLOW: 1 diff --git a/Makefile b/Makefile index 684e79179cf..dd739e8e6de 100644 --- a/Makefile +++ b/Makefile @@ -723,13 +723,13 @@ cli/sehwrapper.o: cli/sehwrapper.cpp cli/sehwrapper.h lib/config.h lib/utils.h cli/signalhandler.o: cli/signalhandler.cpp cli/signalhandler.h cli/stacktrace.h lib/config.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/signalhandler.cpp -cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h +cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/singleexecutor.cpp cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/stacktrace.cpp -cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 27cfe08d871..5f735c4ec56 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -61,6 +60,8 @@ // xml is used for rules #include "xml.h" + +#include #endif static bool addFilesToList(const std::string& fileList, std::vector& pathNames) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index e77a75ba39e..959d16d37ec 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -44,9 +45,9 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/cli/singleexecutor.cpp b/cli/singleexecutor.cpp index d710a4d4c57..e25fc804490 100644 --- a/cli/singleexecutor.cpp +++ b/cli/singleexecutor.cpp @@ -21,7 +21,6 @@ #include "cppcheck.h" #include "filesettings.h" #include "settings.h" -#include "timer.h" #include #include diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index b8581d7e772..5d723366574 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -26,7 +26,6 @@ #include "filesettings.h" #include "settings.h" #include "suppressions.h" -#include "timer.h" #include #include diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index ce1b3ef1508..15f3e8e0665 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -23,7 +23,6 @@ #include "aboutdialog.h" #include "analyzerinfo.h" #include "checkers.h" -#include "checkstatistics.h" #include "checkthread.h" #include "common.h" #include "cppcheck.h" @@ -60,7 +59,6 @@ #include #include -#include #include #include #include @@ -101,7 +99,6 @@ #include #include #include -#include #include #include #include diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index 4e75696484b..e156f3dfe3b 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -23,7 +23,6 @@ #include "importproject.h" #include "library.h" #include "newsuppressiondialog.h" -#include "path.h" #include "platform.h" #include "platforms.h" #include "projectfile.h" diff --git a/gui/test/resultstree/testresultstree.cpp b/gui/test/resultstree/testresultstree.cpp index afda38e0075..921abd69ff0 100644 --- a/gui/test/resultstree/testresultstree.cpp +++ b/gui/test/resultstree/testresultstree.cpp @@ -22,7 +22,6 @@ // headers that declare mocked functions/variables #include "applicationlist.h" -#include "common.h" #include "filesettings.h" #include "projectfile.h" #include "threadhandler.h" diff --git a/lib/checks.cpp b/lib/checks.cpp index 169832c2745..ef4b9fef3da 100644 --- a/lib/checks.cpp +++ b/lib/checks.cpp @@ -42,6 +42,8 @@ #include "checkunusedvar.h" #include "checkvaarg.h" +#include + class CheckInstancesImpl { private: diff --git a/lib/cppcheck.h b/lib/cppcheck.h index 94f2b721037..d72e65ebb34 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -31,7 +31,9 @@ #include #include +#ifdef HAVE_RULES class TokenList; +#endif struct FileSettings; class CheckUnusedFunctions; class Tokenizer; diff --git a/lib/importproject.cpp b/lib/importproject.cpp index ac19db922ed..96e8b98f2e8 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/lib/settings.cpp b/lib/settings.cpp index 080946e07bc..0df9907b3ab 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -17,6 +17,7 @@ */ #include "config.h" +#include "errortypes.h" #include "settings.h" #include "path.h" #include "summaries.h" diff --git a/lib/settings.h b/lib/settings.h index 6c12c509701..25dee019739 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -23,7 +23,6 @@ #include "addoninfo.h" #include "config.h" -#include "errortypes.h" #include "library.h" #include "platform.h" #include "standards.h" @@ -40,22 +39,27 @@ #include #include -#include "regex.h" - #if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING) #include #endif #ifdef HAVE_RULES +#include "errortypes.h" +#include "regex.h" + #include class Regex; +#else +enum class Severity : std::uint8_t; #endif struct Suppressions; namespace ValueFlow { class Value; } +enum class Certainty : std::uint8_t; +enum class Checks : std::uint8_t; /// @addtogroup Core /// @{ diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index 70b689e2cdb..fe483e347fe 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -31,6 +31,7 @@ #include #include // std::isdigit, std::isalnum, etc #include +#include #include // std::bind, std::placeholders #include #include diff --git a/lib/utils.h b/lib/utils.h index 3f9c4ab949f..410bd7c6040 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index 282e0b9fddb..56f928bcbd8 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -19,6 +19,7 @@ #include "vf_common.h" #include "astutils.h" +#include "library.h" #include "mathlib.h" #include "path.h" #include "platform.h" diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 49d46149c90..90c64eb809e 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include From 59a6654120b2953976fe2be5a0f6bf2e1cf6ae5b Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Mon, 1 Jun 2026 17:27:24 +0200 Subject: [PATCH 142/493] AUTHORS: Add Alvin Che-Chia Chang, Andreas Wilhelm, Piotr Idzik, William Jakobsson [skip ci] (#8608) Co-authored-by: William Jakobsson --- AUTHORS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AUTHORS b/AUTHORS index 04cff0891a9..874ff59748b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -22,6 +22,7 @@ Alexey Eryomenko Alexey Zhikhartsev Alfi Maulana Ali Can Demiralp +Alvin Che-Chia Chang Allen Winter Alon Alexander Alon Liberman @@ -33,6 +34,7 @@ Andreas Lutsch Andreas Pokorny Andreas Rönnquist Andreas Vollenweider +Andreas Wilhelm Andrei Karas Andrew C Aitchison Andrew C. Martin @@ -328,6 +330,7 @@ Philip Chimento Philipp Kloke Pierre Schweitzer Pieter Duchi +Piotr Idzik Pino Toscano Pranav Khanna Radek Jarecki @@ -435,6 +438,7 @@ Vladimir Petrigo Wang Haoyu Wang Yang WenChung Chiu +William Jakobsson Wolfgang Stöggl x29a XhmikosR From fd039589fc55d2412dca34ca2735f1d530993c0f Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:25:19 +0200 Subject: [PATCH 143/493] 2.21 updated gui translations (#8597) --- gui/cppcheck_de.ts | 784 ++++++++++++++++++++-------------------- gui/cppcheck_es.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_fi.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_fr.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_it.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_ja.ts | 774 ++++++++++++++++++++-------------------- gui/cppcheck_ka.ts | 782 ++++++++++++++++++++-------------------- gui/cppcheck_ko.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_nl.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_ru.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_sr.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_sv.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_zh_CN.ts | 811 ++++++++++++++++++++---------------------- gui/cppcheck_zh_TW.ts | 802 ++++++++++++++++++++--------------------- 14 files changed, 5334 insertions(+), 5918 deletions(-) diff --git a/gui/cppcheck_de.ts b/gui/cppcheck_de.ts index c0d68ed6d8a..3f9d9ed53d7 100644 --- a/gui/cppcheck_de.ts +++ b/gui/cppcheck_de.ts @@ -120,65 +120,52 @@ Parameter: -l(line) (file) ComplianceReportDialog - Compliance Report - Compliance-Report + Compliance-Report - Project name - Projektname + Projektname - Project version - Projekt-Version + Projekt-Version - Coding Standard - Programmierstandards + Programmierstandards - Misra C - Misra C + Misra C - Cert C - Cert C + Cert C - Cert C++ - Cert C++ + Cert C++ - List of files with md5 checksums - Datei-Listen mit MD5-Prüfsummen + Datei-Listen mit MD5-Prüfsummen - Compliance report - Compliance-Report + Compliance-Report - HTML files (*.html) - HTML-Dateien (*.html) + HTML-Dateien (*.html) - - Save compliance report - Compliance-Report speichern + Compliance-Report speichern - Failed to import '%1' (%2), can not show files in compliance report - Import von '%1' (%2) fehlgeschlagen, Compliance-Report kann nicht angezeigt werden + Import von '%1' (%2) fehlgeschlagen, Compliance-Report kann nicht angezeigt werden @@ -218,12 +205,12 @@ Parameter: -l(line) (file) Index - + Helpfile '%1' was not found Hilfedatei '%1' nicht gefunden - + Cppcheck Cppcheck @@ -496,25 +483,25 @@ Parameter: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck - + Standard Standard @@ -524,246 +511,246 @@ Parameter: -l(line) (file) &Datei - + &View &Ansicht - + &Toolbars &Symbolleisten - + A&nalyze A&nalysieren - + C++ standard C++-Standard - + &C standard &C-Standard - + &Edit &Bearbeiten - + &License... &Lizenz... - + A&uthors... &Autoren... - + &About... Ü&ber... - + &Files... &Dateien... - - + + Analyze files Analysiere Dateien - + Ctrl+F Strg+F - + &Directory... &Verzeichnis... - - + + Analyze directory Analysiere Verzeichnis - + Ctrl+D Strg+D - + Ctrl+R Strg+R - + &Stop &Stoppen - - + + Stop analysis Analyse abbrechen - + Esc Esc - + &Save results to file... &Ergebnisse in Datei speichern... - + Ctrl+S Strg+S - + &Quit &Beenden - + &Clear results Ergebnisse &löschen - + &Preferences &Einstellungen - - - + + + Show errors Zeige Fehler - - - + + + Show warnings Zeige Warnungen - - + + Show performance warnings Zeige Performance-Warnungen - + Show &hidden Zeige &versteckte - - + + Information Information - + Show information messages Zeige Informationsmeldungen - + Show portability warnings Zeige Portabilitätswarnungen - + Show Cppcheck results Zeige Cppcheck-Ergebnisse - + Clang Clang - + Show Clang results Zeige Clang-Ergebnisse - + &Filter &Filter - + Filter results Gefilterte Ergebnisse - + Windows 32-bit ANSI Windows 32-bit, ANSI - + Windows 32-bit Unicode Windows 32-bit, Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - + &Print... Drucken... - + Print the Current Report Aktuellen Bericht ausdrucken - + Print Pre&view... Druckvorschau - + Open a Print Preview Dialog for the Current Results Druckvorschaudialog für aktuelle Ergebnisse öffnen - + Open library editor Bibliothekseditor öffnen - + &Check all Alle &auswählen @@ -778,335 +765,335 @@ Parameter: -l(line) (file) Verstecken - - + + Report - + Filter Filter - + &Reanalyze modified files Veränderte Dateien neu analysieren - + Reanal&yze all files Alle Dateien erneut anal&ysieren - + Ctrl+Q - + Style war&nings Stilwar&nungen - + E&rrors F&ehler - + &Uncheck all Alle a&bwählen - + Collapse &all Alle &reduzieren - + &Expand all Alle &erweitern - + &Standard &Standard - + Standard items Standardeinträge - + Toolbar Symbolleiste - + &Categories &Kategorien - + Error categories Fehler-Kategorien - + &Open XML... Öffne &XML... - + Open P&roject File... Pr&ojektdatei öffnen... - + Ctrl+Shift+O - + Sh&ow Scratchpad... &Zeige Schmierzettel... - + &New Project File... &Neue Projektdatei... - + Ctrl+Shift+N - + &Log View &Loganzeige - + Log View Loganzeige - + C&lose Project File Projektdatei &schließen - + &Edit Project File... Projektdatei &bearbeiten... - + &Statistics &Statistik - + &Warnings &Warnungen - + Per&formance warnings Per&formance-Warnungen - + &Information &Information - + &Portability &Portabilität - + P&latforms P&lattformen - + C++&11 C++&11 - + C&99 C&99 - + &Posix Posix - + C&11 C&11 - + &C89 &C89 - + &C++03 &C++03 - + &Library Editor... &Bibliothekseditor - + &Auto-detect language Sprache &automatisch erkennen - + &Enforce C++ C++ &erzwingen - + E&nforce C C e&rzwingen - + C++14 C++14 - + Reanalyze and check library Neu analysieren und Bibliothek prüfen - + Check configuration (defines, includes) Prüfe Konfiguration (Definitionen, Includes) - + C++17 C++17 - + C++20 C++20 - + Compliance report... - + Normal - + Misra C Misra C - + Misra C++ 2008 - + Cert C Cert C - + Cert C++ Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + &Contents &Inhalte - + Categories Kategorien - - + + Show style warnings Zeige Stilwarnungen - + Open the help contents Öffnet die Hilfe-Inhalte - + F1 F1 - + &Help &Hilfe - - + + Quick Filter: Schnellfilter: - + Select configuration Konfiguration wählen - + Found project file: %1 Do you want to load this project file instead? @@ -1115,102 +1102,102 @@ Do you want to load this project file instead? Möchten Sie stattdessen diese öffnen? - + File not found Datei nicht gefunden - + Bad XML Fehlerhaftes XML - + Missing attribute Fehlendes Attribut - + Bad attribute value Falscher Attributwert - + Duplicate platform type Plattformtyp doppelt - + Platform type redefined Plattformtyp neu definiert - + Duplicate define - + Failed to load the selected library '%1'. %2 Laden der ausgewählten Bibliothek '%1' schlug fehl. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Lizenz - + Authors Autoren - + Save the report file Speichert die Berichtdatei - - + + XML files (*.xml) XML-Dateien (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1219,38 +1206,32 @@ This is probably because the settings were changed between the Cppcheck versions Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bitte prüfen (und korrigieren) Sie die Einstellungen, andernfalls könnte die Editor-Anwendung nicht korrekt starten. - + You must close the project file before selecting new files or directories! Sie müssen die Projektdatei schließen, bevor Sie neue Dateien oder Verzeichnisse auswählen! - + The library '%1' contains unknown elements: %2 Die Bibliothek '%1' enthält unbekannte Elemente: %2 - + Unsupported format Nicht unterstütztes Format - + Unknown element Unbekanntes Element - - Unknown element - Unknown issue - Unbekannter Fehler - - - - - - + + + + Error Fehler @@ -1259,80 +1240,80 @@ Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bi Laden von %1 fehlgeschlagen. Ihre Cppcheck-Installation ist defekt. Sie können --data-dir=<Verzeichnis> als Kommandozeilenparameter verwenden, um anzugeben, wo die Datei sich befindet. Bitte beachten Sie, dass --data-dir in Installationsroutinen genutzt werden soll, und die GUI bei dessen Nutzung nicht startet, sondern die Einstellungen konfiguriert. - + Open the report file Berichtdatei öffnen - + Text files (*.txt) Textdateien (*.txt) - + CSV files (*.csv) CSV-Dateien (*.csv) - + Project files (*.cppcheck);;All files(*.*) Projektdateien (*.cppcheck);;Alle Dateien(*.*) - + Select Project File Projektdatei auswählen - - - - + + + + Project: Projekt: - + No suitable files found to analyze! Keine passenden Dateien für Analyse gefunden! - + C/C++ Source C/C++-Quellcode - + Compile database Compilerdatenbank - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++-Builder 6 - + Select files to analyze Dateien für Analyse auswählen - + Select directory to analyze Verzeichnis für Analyse auswählen - + Select the configuration that will be analyzed Zu analysierende Konfiguration auswählen - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1341,7 +1322,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1352,7 +1333,7 @@ Eine neue XML-Datei zu öffnen wird die aktuellen Ergebnisse löschen Möchten sie fortfahren? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1361,109 +1342,104 @@ Do you want to stop the analysis and exit Cppcheck? Wollen sie die Analyse abbrechen und Cppcheck beenden? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML-Dateien (*.xml);;Textdateien (*.txt);;CSV-Dateien (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Build dir '%1' does not exist, create it? Erstellungsverzeichnis '%1' existiert nicht. Erstellen? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1472,22 +1448,22 @@ Analysis is stopped. Import von '%1' fehlgeschlagen; Analyse wurde abgebrochen. - + Project files (*.cppcheck) Projektdateien (*.cppcheck) - + Select Project Filename Projektnamen auswählen - + No project file loaded Keine Projektdatei geladen - + The project file %1 @@ -1504,12 +1480,12 @@ Do you want to remove the file from the recently used projects -list? Möchten Sie die Datei von der Liste der zuletzt benutzten Projekte entfernen? - + Install - + New version available: %1. %2 @@ -1639,7 +1615,7 @@ Options: Definitionen müssen mit einem Semikolon getrennt werden. Beispiel: DEF1;DEF2=5;DEF3=int - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Hinweis: Legen Sie eigene .cfg-Dateien in den Ordner der Projektdatei. Dann sollten sie oben sichtbar werden. @@ -1648,17 +1624,17 @@ Options: MISRA C 2012 - + MISRA rule texts MISRA-Regeltexte - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Text aus Anhang A &quot;Summary of guidelines&quot; aus der MISRA-C-2012-PDF in eine Textdatei einfügen.</p></body></html> - + ... ... @@ -1669,8 +1645,7 @@ Options: - - + Browse... Durchsuchen... @@ -1698,15 +1673,15 @@ Options: - + Edit Bearbeiten - - + + Remove Entfernen @@ -1736,271 +1711,281 @@ Options: Ab - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Platform Plattform - - + + Analysis Analyse - + This is a workfolder that Cppcheck will use for various purposes. - + Clang (experimental) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) Prüfe Code in ungenutzten Templates (normalerweise AN, theoretisch können Warnungen in ungenutzten Templates gefahrlos ignoriert werden) - + Max CTU depth Maximale CTU-Tiefe - + Max recursion in template instantiation - - Premium License - - - - + Warning options Warnoptionen - + Root path: Wurzelverzeichnis: - + Filepaths in warnings will be relative to this path - + Warning tags (separated by semicolon) Warnungs-Tags (Semikolon-getrennt) - + Enable inline suppressions Inline-Fehlerunterdrückung aktivieren - + 2025 - + Misra C++ - + 2008 - + Cert C Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting - + External tools Externe Werkzeuge - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck-Arbeitsverzeichnis (Vollständige Programmanalyse, inkrementelle Analyse, Statistiken, etc.) - + Types and Functions - + Libraries Bibliotheken - + Parser - + Cppcheck (built in) - + Check that each class has a safe public interface - + Limit analysis - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Suppressions Fehlerunterdrückungen - + Add Hinzufügen - - + + Addons Add-Ons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 Y2038 - + Thread safety Threadsicherheit - + Coding standards Programmierstandards - + Misra C Misra C - + 2012 - - + + 2023 - + Cert C++ Cert C++ - + Bug hunting (Premium) - + Clang analyzer Clang-Analyzer - + Clang-tidy Clang-Tidy @@ -2013,82 +1998,93 @@ Options: ProjectFileDialog - + Project file: %1 Projektdatei: %1 - + Select Cppcheck build dir Wähle Cppcheck-Erstellungsverzeichnis - + Select include directory Wähle Include-Verzeichnisse - + Select a directory to check Wähle zu prüfendes Verzeichnis - + Note: Open source Cppcheck does not fully implement Misra C 2012 Hinweis: Open-Source Cppcheck implementiert Misra C 2012 nicht vollständig - + Clang-tidy (not found) Clang-tidy (nicht gefunden) - + Visual Studio Visual Studio - + Compile database Compilerdatenbank - + Borland C++ Builder 6 Borland C++-Builder 6 - + Import Project Projekt importieren - + + C/C++ header + + + + + Include file + + + + Select directory to ignore Wähle zu ignorierendes Verzeichnis - + Source files Quelltext-Dateien - + + All files Alle Dateien - + Exclude file Datei ausschließen - + Select MISRA rule texts file Wähle MISRA-Regeltext-Datei - + MISRA rule texts file (%1) MISRA-Regeltext-Datei (%1) @@ -2121,7 +2117,7 @@ Options: - + (Not found) (nicht gefunden) @@ -2523,102 +2519,102 @@ Bitte überprüfen Sie ob der Pfad und die Parameter der Anwendung richtig einge ResultsView - + Print Report Bericht drucken - + No errors found, nothing to print. Keine Funde, nichts zu drucken. - + %p% (%1 of %2 files checked) %p% (%1 von %2 Dateien geprüft) - - + + Cppcheck Cppcheck - + No errors found. Keine Fehler gefunden. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Es wurden Fehler gefunden, aber sie sind so konfiguriert, ausgeblendet zu werden. Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werden sollen. - - + + Failed to read the report. Lesen des Berichts fehlgeschlagen. - + XML format version 1 is no longer supported. XML-Format-Version 1 wird nicht länger unterstützt. - + First included by Zuerst inkludiert von - + Id Id - + Clear Log Protokoll leeren - + Copy this Log entry Diesen Protokolleintrag kopieren - + Copy complete Log Gesamtes Protokoll kopieren - + Analysis was stopped Analyse wurde gestoppt - + There was a critical error with id '%1' Kritischer Fehler mit ID '%1' aufgetreten - + when checking %1 beim Prüfen von %1 - + when checking a file beim Prüfen einer Datei - + Analysis was aborted. Analyse abgebrochen. - - + + Failed to save the report. Der Bericht konnte nicht speichern werden. @@ -2923,14 +2919,14 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde - - + + Statistics Statistik - + Project Projekt @@ -2961,7 +2957,7 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde - + Previous Scan Vorherige Prüfung @@ -3041,103 +3037,103 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde PDF-Export - + 1 day 1 Tag - + %1 days %1 Tage - + 1 hour 1 Stunde - + %1 hours %1 Stunden - + 1 minute 1 Minute - + %1 minutes %1 Minuten - + 1 second 1 Sekunde - + %1 seconds %1 Sekunden - + 0.%1 seconds 0,%1 Sekunden - + and und - + Export PDF Exportiere PDF - + Project Settings Projekteinstellungen - + Paths Pfade - + Include paths Include-Pfade - + Defines Definitionen - + Undefines Un-Definitionen - + Path selected Gewählte Pfade - + Number of files scanned Anzahl geprüfter Dateien - + Scan duration Prüfungsdauer - - + + Errors Fehler @@ -3152,32 +3148,32 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde Kein Cppcheck-Analyseverzeichnis - - + + Warnings Warnungen - - + + Style warnings Stilwarnungen - - + + Portability warnings Portabilitätswarnungen - - + + Performance warnings Performance-Warnungen - - + + Information messages Informationsmeldungen diff --git a/gui/cppcheck_es.ts b/gui/cppcheck_es.ts index 927a56e05e5..32485d556f3 100644 --- a/gui/cppcheck_es.ts +++ b/gui/cppcheck_es.ts @@ -105,70 +105,6 @@ Parameters: -l(line) (file) ¡Debes especificar el nombre, la ruta y opcionalmente los parámetros para la aplicación! - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -206,12 +142,12 @@ Parameters: -l(line) (file) - + Helpfile '%1' was not found - + Cppcheck Cppcheck @@ -476,20 +412,20 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck @@ -499,248 +435,248 @@ Parameters: -l(line) (file) &Archivo - + &View &Ver - + &Toolbars &Herramientas - + &Help &Ayuda - + C++ standard C++ estándar - + &C standard C standard C estándar - + &Edit &Editar - + Standard Estándar - + Categories Categorías - + &License... &Licencia... - + A&uthors... A&utores... - + &About... &Acerca de... - + &Files... &Ficheros... - - + + Analyze files Check files Comprobar archivos - + Ctrl+F Ctrl+F - + &Directory... &Carpeta... - - + + Analyze directory Check directory Comprobar carpeta - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop &Detener - - + + Stop analysis Stop checking Detener comprobación - + Esc Esc - + &Save results to file... &Guardar los resultados en el fichero... - + Ctrl+S Ctrl+S - + &Quit &Salir - + &Clear results &Limpiar resultados - + &Preferences &Preferencias - - + + Show style warnings Mostrar advertencias de estilo - - - + + + Show errors Mostrar errores - - + + Information Información - + Show information messages Mostrar mensajes de información - + Show portability warnings Mostrar advertencias de portabilidad - + Show Cppcheck results - + Clang - + Show Clang results - + &Filter &Filtro - + Filter results Resultados del filtro - + Windows 32-bit ANSI Windows 32-bit ANSI - + Windows 32-bit Unicode Windows 32-bit Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - + &Print... Im&primir... - + Print the Current Report Imprimir el informe actual - + Print Pre&view... Pre&visualización de impresión... - + Open a Print Preview Dialog for the Current Results Abre el diálogo de previsualización de impresión para el informe actual - + Open library editor Abrir el editor de bibliotecas - + &Check all &Seleccionar todo @@ -755,449 +691,449 @@ Parameters: -l(line) (file) Ocultar - - + + Report - + A&nalyze - + Filter Filtro - + &Reanalyze modified files &Recheck modified files - + Reanal&yze all files - + Ctrl+Q - + Style war&nings - + E&rrors - + &Uncheck all &Deseleccionar todo - + Collapse &all Contraer &todo - + &Expand all &Expandir todo - + &Standard &Estándar - + Standard items Elementos estándar - + &Contents &Contenidos - + Open the help contents Abrir la ayuda de contenidos - + F1 F1 - + Toolbar Barra de herramientas - + &Categories &Categorías - + Error categories Categorías de error - + &Open XML... &Abrir XML... - + Open P&roject File... Abrir P&royecto... - + Ctrl+Shift+O - + Sh&ow Scratchpad... - + &New Project File... &Nuevo Proyecto... - + Ctrl+Shift+N - + &Log View &Visor del log - + Log View Visor del log - + C&lose Project File C&errar Proyecto - + &Edit Project File... &Editar Proyecto... - + &Statistics &Estadísticas - + &Warnings - + Per&formance warnings - + &Information - + &Portability - + P&latforms - + C++&11 - + C&99 - + &Posix - + C&11 - + &C89 - + &C++03 - + &Library Editor... - + &Auto-detect language - + &Enforce C++ - + E&nforce C - + C++14 C++14 - + Reanalyze and check library - + Check configuration (defines, includes) - + C++17 C++17 - + C++20 C++20 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - - - + + + Show warnings Mostrar advertencias - - + + Show performance warnings Mostrar advertencias de rendimiento - + Show &hidden Mostrar &ocultos - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! ¡Tienes que cerrar el proyecto antes de seleccionar nuevos ficheros o carpetas! - + Select configuration - + File not found Archivo no encontrado - + Bad XML XML malformado - + Missing attribute Falta el atributo - + Bad attribute value - + Unsupported format Formato no soportado - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - - + + XML files (*.xml) Archivos XML (*.xml) - + Open the report file Abrir informe - + License Licencia - + Authors Autores - + Save the report file Guardar informe - - + + Quick Filter: Filtro rápido: - + Found project file: %1 Do you want to load this project file instead? @@ -1206,118 +1142,112 @@ Do you want to load this project file instead? ¿Quiere cargar este fichero de proyecto en su lugar? - + The library '%1' contains unknown elements: %2 La biblioteca '%1' contiene elementos deconocidos: %2 - + Duplicate platform type - + Platform type redefined - - Unknown element - - - - + Unknown element - Unknown issue - - - - + + + + Error Error - + Text files (*.txt) Ficheros de texto (*.txt) - + CSV files (*.csv) Ficheros CVS (*.cvs) - + Project files (*.cppcheck);;All files(*.*) Ficheros de proyecto (*.cppcheck;;Todos los ficheros (*.*) - + Select Project File Selecciona el archivo de proyecto - - - - + + + + Project: Proyecto: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1325,81 +1255,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Selecciona el nombre del proyecto - + No project file loaded No hay ningún proyecto cargado - + The project file %1 @@ -1416,67 +1341,67 @@ Do you want to remove the file from the recently used projects -list? ¿Quiere eliminar el fichero de la lista de proyectos recientes? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1607,58 +1532,58 @@ Options: - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Nota: Ponga sus propios archivos .cfg en la misma carpeta que el proyecto. Debería verlos arriba. - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Misra C - + 2012 - - + + 2023 - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + ... @@ -1669,8 +1594,7 @@ Options: - - + Browse... @@ -1698,15 +1622,15 @@ Options: - + Edit Editar - - + + Remove Eliminar @@ -1726,124 +1650,134 @@ Options: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions - - + + Analysis - + This is a workfolder that Cppcheck will use for various purposes. - + Parser - + Cppcheck (built in) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + Check that each class has a safe public interface - + Limit analysis - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth - - Premium License - - - - + Enable inline suppressions Habilitar supresiones inline - + 2025 - + Misra C++ - + 2008 - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting - + External tools @@ -1858,113 +1792,113 @@ Options: Bajar - + Platform - + Clang (experimental) - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + Max recursion in template instantiation - + Warning options - + Root path: - + Filepaths in warnings will be relative to this path - + Warning tags (separated by semicolon) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) - + Libraries - + Suppressions Supresiones - + Add Añadir - - + + Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 - + Thread safety - + Coding standards - + Cert C++ - + Bug hunting (Premium) - + Clang analyzer - + Clang-tidy @@ -1977,82 +1911,93 @@ Options: ProjectFileDialog - + Project file: %1 Archivo de proyecto: %1 - + Select Cppcheck build dir - + Select include directory Selecciona una carpeta para incluir - + Select a directory to check Selecciona la carpeta a comprobar - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) - + Visual Studio - + Compile database - + Borland C++ Builder 6 - + Import Project - + + C/C++ header + + + + + Include file + + + + Select directory to ignore Selecciona la carpeta a ignorar - + Source files - + + All files - + Exclude file - + Select MISRA rule texts file - + MISRA rule texts file (%1) @@ -2085,7 +2030,7 @@ Options: - + (Not found) @@ -2517,102 +2462,102 @@ Por favor comprueba que la ruta a la aplicación y los parámetros son correctos - - + + Failed to save the report. Error al guardar el informe. - + Print Report Imprimir informe - + No errors found, nothing to print. No se encontraron errores, nada que imprimir. - + %p% (%1 of %2 files checked) %p% (%1 of %2 archivos comprobados) - - + + Cppcheck Cppcheck - + No errors found. No se han encontrado errores. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Se han encontrado errores, pero están configurados para que no se muestren. Para cambiar el tipo de comportamiento, abra el menú Ver. - - + + Failed to read the report. Error al leer el informe. - + XML format version 1 is no longer supported. - + First included by - + Id Id - + Clear Log - + Copy this Log entry - + Copy complete Log - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. @@ -2897,14 +2842,14 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. - - + + Statistics Estadísticas - + Project Proyecto @@ -2935,7 +2880,7 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. - + Previous Scan Análisis anterior @@ -3015,103 +2960,103 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. - + 1 day 1 día - + %1 days %1 días - + 1 hour 1 hora - + %1 hours %1 horas - + 1 minute 1 minuto - + %1 minutes %1 minutos - + 1 second 1 segundo - + %1 seconds %1 segundos - + 0.%1 seconds 0.%1 segundos - + and y - + Export PDF - + Project Settings Preferencias del proyecto - + Paths Rutas - + Include paths Incluye las rutas - + Defines Definiciones - + Undefines - + Path selected Ruta seleccionada - + Number of files scanned Número de archivos analizados - + Scan duration Duración del análisis - - + + Errors Errores @@ -3126,32 +3071,32 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. - - + + Warnings Advertencias - - + + Style warnings Advertencias de estilo - - + + Portability warnings Advertencias de portabilidad - - + + Performance warnings Advertencias de rendimiento - - + + Information messages Mensajes de información diff --git a/gui/cppcheck_fi.ts b/gui/cppcheck_fi.ts index f6c959aa099..5a41a1cb41d 100644 --- a/gui/cppcheck_fi.ts +++ b/gui/cppcheck_fi.ts @@ -106,70 +106,6 @@ Parameters: -l(line) (file) - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -209,12 +145,12 @@ Parameters: -l(line) (file) - + Helpfile '%1' was not found - + Cppcheck Cppcheck @@ -479,30 +415,30 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck - + A&nalyze - + Standard Vakio @@ -512,245 +448,245 @@ Parameters: -l(line) (file) &Tiedosto - + &View &Näytä - + &Toolbars - + C++ standard - + &C standard C standard - + &Edit &Muokkaa - + &License... &Lisenssi... - + A&uthors... &Tekijät... - + &About... &Tietoa ohjelmasta Cppcheck... - + &Files... &Tiedostot... - - + + Analyze files Check files - + Ctrl+F Ctrl+F - + &Directory... &Hakemisto... - - + + Analyze directory Check directory - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop &Pysäytä - - + + Stop analysis Stop checking - + Esc Esc - + &Save results to file... &Tallenna tulokset tiedostoon... - + Ctrl+S Ctrl+S - + &Quit &Lopeta - + &Clear results &Tyhjennä tulokset - + &Preferences &Asetukset - - - + + + Show errors - - - + + + Show warnings - - + + Show performance warnings - + Show &hidden - - + + Information - + Show information messages - + Show portability warnings - + Show Cppcheck results - + Clang - + Show Clang results - + &Filter - + Filter results - + Windows 32-bit ANSI - + Windows 32-bit Unicode - + Unix 32-bit - + Unix 64-bit - + Windows 64-bit - + &Print... - + Print the Current Report - + Print Pre&view... - + Open a Print Preview Dialog for the Current Results - + Open library editor - + &Check all &Valitse kaikki @@ -765,559 +701,553 @@ Parameters: -l(line) (file) - - + + Report - + Filter - + &Reanalyze modified files &Recheck modified files - + Reanal&yze all files - + Ctrl+Q - + Style war&nings - + E&rrors - + &Uncheck all &Poista kaikista valinta - + Collapse &all &Pienennä kaikki - + &Expand all &Laajenna kaikki - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... - + Open P&roject File... - + Ctrl+Shift+O - + Sh&ow Scratchpad... - + &New Project File... - + Ctrl+Shift+N - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Warnings - + Per&formance warnings - + &Information - + &Portability - + P&latforms - + C++&11 - + C&99 - + &Posix - + C&11 - + &C89 - + &C++03 - + &Library Editor... - + &Auto-detect language - + &Enforce C++ - + E&nforce C - + C++14 - + Reanalyze and check library - + Check configuration (defines, includes) - + C++17 - + C++20 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + &Contents - + Categories - - + + Show style warnings - + Open the help contents - + F1 - + &Help &Ohje - - + + Quick Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Lisenssi - + Authors Tekijät - + Save the report file Tallenna raportti - - + + XML files (*.xml) XML-tiedostot (*xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - - Unknown element - - - - + Unknown element - Unknown issue - - - - + + + + Error - + Open the report file - + Text files (*.txt) Tekstitiedostot (*.txt) - + CSV files (*.csv) - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - - - - + + + + Project: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1325,81 +1255,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename - + No project file loaded - + The project file %1 @@ -1410,67 +1335,67 @@ Do you want to remove the file from the recently used projects -list? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1601,22 +1526,22 @@ Options: - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + ... @@ -1627,8 +1552,7 @@ Options: - - + Browse... @@ -1656,15 +1580,15 @@ Options: - + Edit - - + + Remove @@ -1694,271 +1618,281 @@ Options: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Platform - - + + Analysis - + This is a workfolder that Cppcheck will use for various purposes. - + Clang (experimental) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth - + Max recursion in template instantiation - - Premium License - - - - + Warning options - + Root path: - + Filepaths in warnings will be relative to this path - + Warning tags (separated by semicolon) - + Enable inline suppressions - + 2025 - + Misra C++ - + 2008 - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting - + External tools - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) - + Types and Functions - + Libraries - + Parser - + Cppcheck (built in) - + Check that each class has a safe public interface - + Limit analysis - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Suppressions - + Add - - + + Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 - + Thread safety - + Coding standards - + Misra C - + 2012 - - + + 2023 - + Cert C++ - + Bug hunting (Premium) - + Clang analyzer - + Clang-tidy @@ -1971,82 +1905,93 @@ Options: ProjectFileDialog - + Project file: %1 - + Select Cppcheck build dir - + Select include directory - + Select a directory to check - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) - + Visual Studio - + Compile database - + Borland C++ Builder 6 - + Import Project - + + C/C++ header + + + + + Include file + + + + Select directory to ignore - + Source files - + + All files - + Exclude file - + Select MISRA rule texts file - + MISRA rule texts file (%1) @@ -2081,7 +2026,7 @@ Options: - + (Not found) @@ -2477,102 +2422,102 @@ Tarkista että ohjelman polku ja parametrit ovat oikeat. ResultsView - + Print Report - + No errors found, nothing to print. - + %p% (%1 of %2 files checked) - - + + Cppcheck Cppcheck - + No errors found. Virheitä ei löytynyt. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Virheitä löytyi, mutta asetuksissa kyseiset virheet on määritelty piilotettavaksi. Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valikko. - - + + Failed to read the report. - + XML format version 1 is no longer supported. - + First included by - + Id - + Clear Log - + Copy this Log entry - + Copy complete Log - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. - - + + Failed to save the report. Raportin tallentaminen epäonnistui. @@ -2870,14 +2815,14 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik - - + + Statistics - + Project @@ -2908,7 +2853,7 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik - + Previous Scan @@ -2988,103 +2933,103 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik - + 1 day - + %1 days - + 1 hour - + %1 hours - + 1 minute - + %1 minutes - + 1 second - + %1 seconds - + 0.%1 seconds - + and - + Export PDF - + Project Settings - + Paths - + Include paths - + Defines - + Undefines - + Path selected - + Number of files scanned - + Scan duration - - + + Errors @@ -3099,32 +3044,32 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik - - + + Warnings - - + + Style warnings - - + + Portability warnings - - + + Performance warnings - - + + Information messages diff --git a/gui/cppcheck_fr.ts b/gui/cppcheck_fr.ts index 82e0ea2bf74..828dffa7ad2 100644 --- a/gui/cppcheck_fr.ts +++ b/gui/cppcheck_fr.ts @@ -116,70 +116,6 @@ Paramètres : -l(ligne) (fichier) Vous devez spécifier un nom, un chemin, et eventuellement des paramètres en option à l'application ! - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -217,12 +153,12 @@ Paramètres : -l(ligne) (fichier) - + Helpfile '%1' was not found - + Cppcheck @@ -485,20 +421,20 @@ Paramètres : -l(ligne) (fichier) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck @@ -518,526 +454,521 @@ Paramètres : -l(ligne) (fichier) &Fichier - + &View &Affichage - - + + Report - + &Help &Aide - + &Edit &Édition - + Standard Standard - + &License... &Licence... - + A&uthors... A&uteurs... - + &About... À &Propos... - + &Files... &Fichiers... - + Ctrl+F - + &Directory... &Répertoires... - + Ctrl+D - + Ctrl+R - + &Stop &Arrêter - + Esc - + &Save results to file... &Sauvegarder les résultats dans un fichier... - + Ctrl+S - + &Quit &Quitter - + &Clear results &Effacer les résultats - + &Preferences &Préférences - + &Check all &Tout cocher - + &Uncheck all &Tout décocher - + Collapse &all &Tout réduire - + &Expand all &Tout dérouler - + &Contents &Contenus - + Open the help contents Ouvir l'aide - + F1 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + License Licence - + Authors Auteurs - + Save the report file Sauvegarder le rapport - - + + XML files (*.xml) Fichiers XML (*.xml) - + About - + Text files (*.txt) Fichiers Texte (*.txt) - + CSV files (*.csv) Fichiers CSV (*.csv) - + &Toolbars &Boite à outils - + Categories Catégories - - + + Show style warnings Afficher les avertissements de style - - - + + + Show errors Afficher les erreurs - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... &Ouvrir un fichier XML... - + Open P&roject File... Ouvrir un P&rojet... - + &New Project File... &Nouveau Projet... - + &Log View &Journal - + Log View Journal - + C&lose Project File F&ermer le projet - + &Edit Project File... &Editer le projet - + &Statistics Statistiques - - - + + + Show warnings Afficher les avertissements - - + + Show performance warnings Afficher les avertissements de performance - + Show &hidden - - + + Information Information - + Show information messages Afficher les messages d'information - + Show portability warnings Afficher les problèmes de portabilité - + You must close the project file before selecting new files or directories! Vous devez d'abord fermer le projet avant de choisir des fichiers/répertoires - + Open the report file Ouvrir le rapport - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Select Project Filename - + No project file loaded - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + &Filter &Filtre - + Filter results - - + + Quick Filter: Filtre rapide : - + Found project file: %1 Do you want to load this project file instead? - - - - + + + + Project: Projet : - + The project file %1 @@ -1048,32 +979,32 @@ Do you want to remove the file from the recently used projects -list? - + Filter Filtre - + Windows 32-bit ANSI - + Windows 32-bit Unicode - + Unix 32-bit - + Unix 64-bit - + Windows 64-bit @@ -1083,105 +1014,99 @@ Do you want to remove the file from the recently used projects -list? - + C++ standard - - - - + + + + Error Erreur - + File not found Fichier introuvable - + Bad XML Mauvais fichier XML - + Missing attribute Attribut manquant - + Bad attribute value Mauvaise valeur d'attribut - + Failed to load the selected library '%1'. %2 Echec lors du chargement de la bibliothèque '%1'. %2 - + Unsupported format Format non supporté - + The library '%1' contains unknown elements: %2 La bibliothèque '%1' contient des éléments inconnus: %2 - + Duplicate platform type - + Platform type redefined - + &Print... &Imprimer... - + Print the Current Report Imprimer le rapport - + Print Pre&view... Apercu d'impression... - + Open a Print Preview Dialog for the Current Results - + Open library editor - - Unknown element - - - - + Unknown element - Unknown issue - + Select configuration @@ -1204,296 +1129,296 @@ Options: - + Build dir '%1' does not exist, create it? - - + + Analyze files - - + + Analyze directory - + &Reanalyze modified files - - + + Stop analysis - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + No suitable files found to analyze! - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + A&nalyze - + &C standard - + Reanal&yze all files - + Ctrl+Q - + Style war&nings - + E&rrors - + Ctrl+Shift+O - + Sh&ow Scratchpad... - + Ctrl+Shift+N - + &Warnings - + Per&formance warnings - + &Information - + &Portability - + Show Cppcheck results - + Clang - + Show Clang results - + P&latforms - + C++&11 - + C&99 - + &Posix - + C&11 - + &C89 - + &C++03 - + &Library Editor... - + &Auto-detect language - + &Enforce C++ - + E&nforce C - + C++14 - + Project files (*.cppcheck) - + Reanalyze and check library - + Check configuration (defines, includes) - + C++17 - + C++20 - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1593,15 +1518,15 @@ Do you want to proceed? - + Edit Editer - - + + Remove Supprimer @@ -1616,22 +1541,22 @@ Do you want to proceed? Descendre - + Suppressions Suppressions - + Add Ajouter - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. - + ... @@ -1656,17 +1581,17 @@ Do you want to proceed? - + Root path: - + Warning tags (separated by semicolon) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) @@ -1676,95 +1601,109 @@ Do you want to proceed? - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions - + Libraries - + Parser - + Cppcheck (built in) - + Check that each class has a safe public interface - + Limit analysis - - + + Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 - + Thread safety - + Coding standards - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Bug hunting - + Clang analyzer - + Clang-tidy - - + Browse... @@ -1774,153 +1713,148 @@ Do you want to proceed? - + Platform - + This is a workfolder that Cppcheck will use for various purposes. - + Clang (experimental) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + Max recursion in template instantiation - - Premium License - - - - + Warning options - + Filepaths in warnings will be relative to this path - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Enable inline suppressions - + Misra C - + 2012 - - + + 2023 - + 2025 - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + Misra C++ - + 2008 - + Cert C++ - + Safety profiles (defined in C++ core guidelines) - + Bug hunting (Premium) - + External tools @@ -1940,19 +1874,19 @@ Do you want to proceed? - - + + Analysis - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth @@ -1960,82 +1894,93 @@ Do you want to proceed? ProjectFileDialog - + Project file: %1 Fichier projet : %1 - + Select include directory Selectionner un répertoire à inclure - + Select directory to ignore Selectionner un répertoire à ignorer - + Select a directory to check Selectionner un répertoire à vérifier - + Select Cppcheck build dir - + Import Project - + Clang-tidy (not found) - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Source files - + + All files - + + C/C++ header + + + + + Include file + + + + Exclude file - + Select MISRA rule texts file - + MISRA rule texts file (%1) - + Visual Studio - + Compile database - + Borland C++ Builder 6 @@ -2068,7 +2013,7 @@ Do you want to proceed? - + (Not found) @@ -2483,87 +2428,87 @@ Please select the default editor application in preferences/Applications.Résultats - - + + Cppcheck - + No errors found. Pas d'erreurs trouvées. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Des erreurs ont été trouvées mais sont configurées pour rester cachées. Pour configurer les erreurs affichées, ouvrez le menu d'affichage. - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. - - + + Failed to save the report. Erreur lors de la sauvegarde du rapport. - - + + Failed to read the report. Erreur lors de la lecture du rapport - + %p% (%1 of %2 files checked) %p% (%1 fichiers sur %2 vérifiés) - + Id Id - + Print Report Imprimer le rapport - + No errors found, nothing to print. Aucune erreur trouvée. Il n'y a rien à imprimer - + First included by - + XML format version 1 is no longer supported. @@ -2583,17 +2528,17 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. - + Clear Log - + Copy this Log entry - + Copy complete Log @@ -2870,14 +2815,14 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. - - + + Statistics Statistiques - + Project Projet @@ -2903,7 +2848,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. - + Previous Scan Analyse précédente @@ -2968,123 +2913,123 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage.Copier vers le presse-papier - + 1 day - + %1 days - + 1 hour - + %1 hours - + 1 minute - + %1 minutes - + 1 second - + %1 seconds - + 0.%1 seconds - + and - + Project Settings - + Paths Chemins - + Include paths - + Defines - + Path selected - + Number of files scanned - + Scan duration - - + + Errors Erreurs - - + + Warnings Avertissements - - + + Style warnings Avertissement de style - - + + Portability warnings - - + + Performance warnings Avertissements de performance - - + + Information messages @@ -3094,7 +3039,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. - + Export PDF @@ -3124,7 +3069,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. - + Undefines diff --git a/gui/cppcheck_it.ts b/gui/cppcheck_it.ts index 1c8829bb198..46ec9cb51d8 100644 --- a/gui/cppcheck_it.ts +++ b/gui/cppcheck_it.ts @@ -117,70 +117,6 @@ Parametri: -l(line) (file) Devi specificare un nome, un percorso ed, opzionalmente, i parametri per l'applicazione! - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -218,12 +154,12 @@ Parametri: -l(line) (file) - + Helpfile '%1' was not found - + Cppcheck Cppcheck @@ -488,30 +424,30 @@ Parametri: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck - + A&nalyze - + Standard Standard @@ -521,245 +457,245 @@ Parametri: -l(line) (file) &File - + &View &Visualizza - + &Toolbars &Barre degli strumenti - + C++ standard - + &C standard C standard - + &Edit &Modifica - + &License... &Licenza... - + A&uthors... A&utori... - + &About... I&nformazioni su... - + &Files... &File... - - + + Analyze files Check files Scansiona i file - + Ctrl+F Ctrl+F - + &Directory... &Cartella... - - + + Analyze directory Check directory Scansiona la cartella - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop &Ferma - - + + Stop analysis Stop checking Ferma la scansione - + Esc Esc - + &Save results to file... &Salva i risultati nel file... - + Ctrl+S Ctrl+S - + &Quit &Esci - + &Clear results &Cancella i risultati - + &Preferences &Preferenze - - - + + + Show errors Mostra gli errori - - - + + + Show warnings Mostra gli avvisi - - + + Show performance warnings Mostra gli avvisi sulle prestazioni - + Show &hidden Mostra &i nascosti - - + + Information Informazione - + Show information messages Mostra messaggi di informazione - + Show portability warnings Mostra gli avvisi sulla portabilità - + Show Cppcheck results - + Clang - + Show Clang results - + &Filter &Filtro - + Filter results Filtra i risultati - + Windows 32-bit ANSI Windows 32-bit, ANSI - + Windows 32-bit Unicode Windows 32-bit, Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - + &Print... - + Print the Current Report - + Print Pre&view... - + Open a Print Preview Dialog for the Current Results - + Open library editor - + &Check all &Seleziona tutto @@ -774,336 +710,336 @@ Parametri: -l(line) (file) Nascondi - - + + Report - + Filter Filtro - + &Reanalyze modified files &Recheck modified files - + Reanal&yze all files - + Ctrl+Q - + Style war&nings - + E&rrors - + &Uncheck all &Deseleziona tutto - + Collapse &all Riduci &tutto - + &Expand all &Espandi tutto - + &Standard &Standard - + Standard items Oggetti standard - + Toolbar Barra degli strumenti - + &Categories &Categorie - + Error categories Categorie di errore - + &Open XML... &Apri XML... - + Open P&roject File... Apri file di p&rogetto... - + Ctrl+Shift+O - + Sh&ow Scratchpad... - + &New Project File... &Nuovo file di progetto... - + Ctrl+Shift+N - + &Log View &Visualizza il rapporto - + Log View Visualizza il rapporto - + C&lose Project File C&hiudi il file di progetto - + &Edit Project File... &Modifica il file di progetto... - + &Statistics &Statistiche - + &Warnings - + Per&formance warnings - + &Information - + &Portability - + P&latforms - + C++&11 - + C&99 - + &Posix - + C&11 - + &C89 - + &C++03 - + &Library Editor... - + &Auto-detect language - + &Enforce C++ - + E&nforce C - + C++14 C++14 - + Reanalyze and check library - + Check configuration (defines, includes) - + C++17 C++17 - + C++20 C++20 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + &Contents &Contenuti - + Categories Categorie - - + + Show style warnings Mostra gli avvisi sullo stile - + Open the help contents Apri i contenuti di aiuto - + F1 F1 - + &Help &Aiuto - - + + Quick Filter: Rapido filtro: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? @@ -1112,96 +1048,96 @@ Do you want to load this project file instead? Vuoi piuttosto caricare questo file di progetto? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Unsupported format - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licenza - + Authors Autori - + Save the report file Salva il file di rapporto - - + + XML files (*.xml) File XML (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1210,127 +1146,121 @@ This is probably because the settings were changed between the Cppcheck versions Probabilmente ciò è avvenuto perché le impostazioni sono state modificate tra le versioni di Cppcheck. Per favore controlla (e sistema) le impostazioni delle applicazioni editor, altrimenti il programma editor può non partire correttamente. - + You must close the project file before selecting new files or directories! Devi chiudere il file di progetto prima di selezionare nuovi file o cartelle! - + The library '%1' contains unknown elements: %2 - + Duplicate platform type - + Platform type redefined - - Unknown element - - - - + Unknown element - Unknown issue - - - - + + + + Error - + Open the report file Apri il file di rapporto - + Text files (*.txt) File di testo (*.txt) - + CSV files (*.csv) Files CSV (*.csv) - + Project files (*.cppcheck);;All files(*.*) Files di progetto (*.cppcheck);;Tutti i files(*.*) - + Select Project File Seleziona il file di progetto - - - - + + + + Project: Progetto: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1338,81 +1268,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Seleziona il nome del file di progetto - + No project file loaded Nessun file di progetto caricato - + The project file %1 @@ -1429,67 +1354,67 @@ Do you want to remove the file from the recently used projects -list? Vuoi rimuovere il file dalla lista dei progetti recentemente usati? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1620,58 +1545,58 @@ Options: - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Misra C - + 2012 - - + + 2023 - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + ... @@ -1682,8 +1607,7 @@ Options: - - + Browse... @@ -1711,15 +1635,15 @@ Options: - + Edit Modifica - - + + Remove Rimuovi @@ -1739,124 +1663,134 @@ Options: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions - - + + Analysis - + This is a workfolder that Cppcheck will use for various purposes. - + Parser - + Cppcheck (built in) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + Check that each class has a safe public interface - + Limit analysis - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth - - Premium License - - - - + Enable inline suppressions Abilita le soppressioni - + 2025 - + Misra C++ - + 2008 - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting - + External tools @@ -1871,113 +1805,113 @@ Options: Giù - + Platform - + Clang (experimental) - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + Max recursion in template instantiation - + Warning options - + Root path: - + Filepaths in warnings will be relative to this path - + Warning tags (separated by semicolon) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) - + Libraries - + Suppressions - + Add - - + + Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 - + Thread safety - + Coding standards - + Cert C++ - + Bug hunting (Premium) - + Clang analyzer - + Clang-tidy @@ -1990,82 +1924,93 @@ Options: ProjectFileDialog - + Project file: %1 File di progetto: %1 - + Select Cppcheck build dir - + Select include directory Seleziona la cartella da includere - + Select a directory to check Seleziona una cartella da scansionare - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) - + Visual Studio - + Compile database - + Borland C++ Builder 6 - + Import Project - + + C/C++ header + + + + + Include file + + + + Select directory to ignore Seleziona la cartella da ignorare - + Source files - + + All files - + Exclude file - + Select MISRA rule texts file - + MISRA rule texts file (%1) @@ -2098,7 +2043,7 @@ Options: - + (Not found) @@ -2509,102 +2454,102 @@ Per favore verifica che il percorso dell'applicazione e i parametri siano c ResultsView - + Print Report - + No errors found, nothing to print. - + %p% (%1 of %2 files checked) %p% (%1 su %2 file scansionati) - - + + Cppcheck Cppcheck - + No errors found. Nessun errore trovato. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Sono stati trovati errori, ma sono stati configurati per essere nascosti. Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. - - + + Failed to read the report. Apertura del report fallito. - + XML format version 1 is no longer supported. - + First included by - + Id Id - + Clear Log - + Copy this Log entry - + Copy complete Log - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. - - + + Failed to save the report. Salvataggio del report fallito. @@ -2909,14 +2854,14 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. - - + + Statistics Statistiche - + Project Progetto @@ -2947,7 +2892,7 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. - + Previous Scan Precedente Scansione @@ -3027,103 +2972,103 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. - + 1 day 1 giorno - + %1 days %1 giorni - + 1 hour 1 ora - + %1 hours %1 ore - + 1 minute 1 minuto - + %1 minutes %1 minuti - + 1 second 1 secondo - + %1 seconds %1 secondi - + 0.%1 seconds 0,%1 secondi - + and e - + Export PDF - + Project Settings Impostazioni progetto - + Paths Percorsi - + Include paths Percorsi di inclusione - + Defines Definizioni - + Undefines - + Path selected Selezionato percorso - + Number of files scanned Numero di file scansionati - + Scan duration Durata della scansione - - + + Errors Errori @@ -3138,32 +3083,32 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. - - + + Warnings Avvisi - - + + Style warnings Stilwarnungen - - + + Portability warnings Avvisi sulla portabilità - - + + Performance warnings Avvisi sulle performance - - + + Information messages Messaggi di informazione diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index 3e486f416dd..b3252ec769d 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -119,65 +119,52 @@ Parameters: -l(line) (file) ComplianceReportDialog - Compliance Report - コンプライアンスレポート + コンプライアンスレポート - Project name - プロジェクト名 + プロジェクト名 - Project version - プロジェクトバージョン + プロジェクトバージョン - Coding Standard - コーディング標準 + コーディング標準 - Misra C - MISRA C + MISRA C - Cert C - CERT C + CERT C - Cert C++ - Cert C++ + Cert C++ - List of files with md5 checksums - md5チェックサムつきファイルリスト + md5チェックサムつきファイルリスト - Compliance report - コンプライアンスレポート + コンプライアンスレポート - HTML files (*.html) - HTMLファイル(*.html) + HTMLファイル(*.html) - - Save compliance report - コンプライアンスレポートの保存 + コンプライアンスレポートの保存 - Failed to import '%1' (%2), can not show files in compliance report - '%1' (%2)のインポートに失敗しました。コンプライアンスレポートに表示できません + '%1' (%2)のインポートに失敗しました。コンプライアンスレポートに表示できません Failed to import '%1', can not show files in compliance report @@ -221,12 +208,12 @@ Parameters: -l(line) (file) インデックス - + Helpfile '%1' was not found ヘルプファイル '%1' が見つかりません - + Cppcheck Cppcheck @@ -502,20 +489,20 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck @@ -525,281 +512,281 @@ Parameters: -l(line) (file) ファイル(&F) - + &View 表示(&V) - + &Toolbars ツールバー(&T) - + &Help ヘルプ(&H) - + C++ standard C++標準 - + &C standard C standard &C標準 - + &Edit 編集(&E) - + Standard 言語規格 - + Categories カテゴリ - + &License... ライセンス(&L)... - + A&uthors... 作者(&u)... - + &About... Cppcheckについて(&A)... - + &Files... ファイル選択(&F)... - - + + Analyze files Check files ファイルをチェックする - + Ctrl+F Ctrl+F - + &Directory... ディレクトリ選択(&D)... - - + + Analyze directory Check directory ディレクトリをチェックする - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop 停止(&S) - - + + Stop analysis Stop checking チェックを停止する - + Esc Esc - + &Save results to file... 結果をファイルに保存(&S)... - + Ctrl+S Ctrl+S - + &Quit 終了(&Q) - + &Clear results 結果をクリア(&C) - + &Preferences 設定(&P) - - + + Show style warnings スタイル警告を表示 - - - + + + Show errors エラーを表示 - - + + Information 情報 - + Show information messages 情報メッセージを表示 - + Show portability warnings 移植可能性の問題を表示 - + Show Cppcheck results Cppcheck結果を表示する - + Clang Clang - + Show Clang results Clangの結果を表示 - + &Filter フィルター(&F) - + Filter results フィルタ結果 - + Windows 32-bit ANSI Windows 32-bit ANSIエンコード - + Windows 32-bit Unicode Windows 32-bit Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - + &Print... 印刷(&P)... - + Print the Current Report 現在のレポートを印刷 - + Print Pre&view... 印刷プレビュー(&v)... - + Open a Print Preview Dialog for the Current Results 現在のレポートをプレビュー表示 - + Open library editor ライブラリエディタを開く - + C&lose Project File プロジェクトを閉じる(&l) - + &Edit Project File... プロジェクトの編集(&E)... - + &Statistics 統計情報(&S) - - - + + + Show warnings 警告を表示 - - + + Show performance warnings パフォーマンス警告を表示 - + Show &hidden 非表示を表示(&h) - + &Check all すべてのエラーを表示(&C) @@ -814,299 +801,299 @@ Parameters: -l(line) (file) 非表示 - - + + Report レポート - + A&nalyze チェック(&n) - + Filter フィルター - + &Reanalyze modified files &Recheck modified files 変更ありファイルを再解析(&R) - + Reanal&yze all files 全ファイル再解析(&y) - + Ctrl+Q Ctrl+Q - + Style war&nings スタイル警告(&n) - + E&rrors エラー(&r) - + &Uncheck all すべてのエラーを非表示(&U) - + Collapse &all ツリーを折り畳む(&a) - + &Expand all ツリーを展開(&E) - + &Standard 言語規格(&S) - + Standard items 標準項目 - + &Contents コンテンツ(&C) - + Open the help contents ヘルプファイルを開く - + F1 F1 - + Toolbar ツールバー - + &Categories カテゴリ(&C) - + Error categories エラーカテゴリ - + &Open XML... XMLを開く(&O)... - + Open P&roject File... プロジェクトを開く(&R)... - + Ctrl+Shift+O Ctrl+Shift+O - + Sh&ow Scratchpad... スクラッチパッドを表示(&o)... - + &New Project File... 新規プロジェクト(&N)... - + Ctrl+Shift+N Ctrl+Shift+N - + &Log View ログを表示(&L) - + Log View ログ表示 - + &Warnings 警告(&W) - + Per&formance warnings パフォーマンス警告(&f) - + &Information 情報(&I) - + &Portability 移植可能性(&P) - + P&latforms プラットフォーム(&l) - + C++&11 C++11(&1) - + C&99 C99(&9) - + &Posix Posix(&P) - + C&11 C11(&1) - + &C89 C89(&C) - + &C++03 C++03(&C) - + &Library Editor... ライブラリエディタ(&L)... - + &Auto-detect language 自動言語検出(&A) - + &Enforce C++ C++ 強制(&E) - + E&nforce C C 強制(&n) - + C++14 C++14 - + Reanalyze and check library ライブラリを再チェックする - + Check configuration (defines, includes) チェックの設定(define、インクルード) - + C++17 C++17 - + C++20 C++20 - + Compliance report... コンプライアンスレポート... - + Normal ノーマル - + Misra C MISRA C - + Misra C++ 2008 MISRA C++ 2008 - + Cert C CERT C - + Cert C++ Cert C++ - + Misra C++ 2023 MISRA C++ 2023 - + Autosar AUTOSAR - + EULA... EULA... - + Thread Details スレッド詳細 - + Show thread details スレッド詳細を表示 - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1115,23 +1102,23 @@ This is probably because the settings were changed between the Cppcheck versions Cppcheckの古いバージョンの設定には互換性がありません。エディタアプリケーションの設定を確認して修正してください、そうしないと正しく起動できないかもしれません。 - + You must close the project file before selecting new files or directories! 新しいファイル/ディレクトリをチェックするには現在のプロジェクトを閉じてください! - - + + Quick Filter: クイックフィルタ: - + Select configuration コンフィグレーションの選択 - + Found project file: %1 Do you want to load this project file instead? @@ -1140,64 +1127,64 @@ Do you want to load this project file instead? 現在のプロジェクトの代わりにこのプロジェクトファイルを読み込んでもかまいませんか? - + The library '%1' contains unknown elements: %2 このライブラリ '%1' には次の不明な要素が含まれています。 %2 - + File not found ファイルがありません - + Bad XML 不正なXML - + Missing attribute 属性がありません - + Bad attribute value 不正な属性があります - + Unsupported format サポートされていないフォーマット - + Duplicate platform type プラットフォームの種類が重複しています - + Platform type redefined プラットフォームの種類が再定義されました - + Unknown element 不明な要素 - + Failed to load the selected library '%1'. %2 選択したライブラリの読み込みに失敗しました '%1' %2 - - - - + + + + Error エラー @@ -1210,73 +1197,72 @@ Do you want to load this project file instead? %1 - %2 の読み込みに失敗 - - + + XML files (*.xml) XML ファイル (*.xml) - + Open the report file レポートを開く - + License ライセンス - + Authors 作者 - + Save the report file レポートを保存 - + Text files (*.txt) テキストファイル (*.txt) - + CSV files (*.csv) CSV形式ファイル (*.csv) - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - コンプライアンスレポートをすぐに生成できません。解析が完了し成功していなければなりません。コードを再解析して、致命的なエラーがないことを確認してください。 + コンプライアンスレポートをすぐに生成できません。解析が完了し成功していなければなりません。コードを再解析して、致命的なエラーがないことを確認してください。 - + Project files (*.cppcheck);;All files(*.*) プロジェクトファイル (*.cppcheck);;すべてのファイル(*.*) - + Select Project File プロジェクトファイルを選択 - + Failed to open file ファイルを開くのに失敗しました - + Unknown project file format プロジェクトファイルの形式が不明です - + Failed to import project file プロジェクトファイルのインポートに失敗しました - + Failed to import '%1': %2 Analysis is stopped. @@ -1285,70 +1271,70 @@ Analysis is stopped. 解析を停止しました。 - + Failed to import '%1' (%2), analysis is stopped '%1' (%2) のインポートに失敗しました。解析は停止 - + Install インストール - + New version available: %1. %2 新しいバージョンが利用可能です。: %1. %2 - - - - + + + + Project: プロジェクト: - + No suitable files found to analyze! チェック対象のファイルがみつかりません! - + C/C++ Source C/C++のソースコード - + Compile database コンパイルデータベース - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze チェック対象のファイルを選択 - + Select directory to analyze チェックするディレクトリを選択してください - + Select the configuration that will be analyzed チェックの設定を選択 - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1357,37 +1343,37 @@ Do you want to proceed analysis without using any of these project files? - + Duplicate define 重複した定義 - + File not found: '%1' ファイルがありません: '%1' - + Failed to load/setup addon %1: %2 アドオンの読み込みまたは設定に失敗 %1 - %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. %1のロードに失敗しました。あなたの Cppcheck は正しくインストールされていません。あなたは --data-dir=<directory> コマンドラインオプションを使ってこのファイルの場所を指定できます。ただし、この --data-dir はインストールスクリプトによって使用されていなければなりません。またGUI版はこれを使用しません。さらに、全ての設定は調整済みでなければなりません。 - + Failed to load %1 - %2 Analysis is aborted. 読み込みに失敗 %1 - %2 - - + + %1 Analysis is aborted. @@ -1396,7 +1382,7 @@ Analysis is aborted. 解析は中止した。 - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1406,7 +1392,7 @@ Do you want to proceed? 新しくXMLファイルを開くと現在の結果が削除されます。実行しますか? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1415,77 +1401,77 @@ Do you want to stop the analysis and exit Cppcheck? チェックを中断して、Cppcheckを終了しますか? - + About CppCheckについて - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ファイル (*.xml);;テキストファイル (*.txt);;CSVファイル (*.csv) - + Build dir '%1' does not exist, create it? ビルドディレクトリ'%1'がありません。作成しますか? - + To check the project using addons, you need a build directory. アドオンを使用してプロジェクトをチェックするためには、ビルドディレクトリが必要です。 - + Show Mandatory 必須を表示 - + Show Required 要求を表示 - + Show Advisory 推奨を表示 - + Show Document ドキュメントを表示 - + Show L1 L1を表示 - + Show L2 L2を表示 - + Show L3 L3を表示 - + Show style スタイルを表示 - + Show portability 移植可能性を表示 - + Show performance パフォーマンスを表示 - + Show information 情報を表示 @@ -1494,22 +1480,22 @@ Do you want to stop the analysis and exit Cppcheck? '%1'のインポートに失敗しました。(チェック中断) - + Project files (*.cppcheck) プロジェクトファイル (*.cppcheck) - + Select Project Filename プロジェクトファイル名を選択 - + No project file loaded プロジェクトファイルが読み込まれていません - + The project file %1 @@ -1658,7 +1644,7 @@ Options: 定義(Define)はセミコロン';'で区切る必要があります。 例: DEF1;DEF2=5;DEF3=int - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. カスタマイズした cfgファイルを同じフォルダにプロジェクトファイルとして保存してください。ここに表示できるようになります。 @@ -1667,17 +1653,17 @@ Options: MISRA C 2012 - + MISRA rule texts MISRA ルールテキスト - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>MISRA C 2012 pdfのAppendix A &quot;Summary of guidelines&quot; からテキストをコピーペーストしてください。</p></body></html> - + ... ... @@ -1688,8 +1674,7 @@ Options: - - + Browse... 参照... @@ -1717,15 +1702,15 @@ Options: - + Edit 編集 - - + + Remove 取り除く @@ -1745,155 +1730,169 @@ Options: インクルードパス: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions 型と関数 - - + + Analysis チェック - + This is a workfolder that Cppcheck will use for various purposes. Cppcheckがさまざまな目的で使用するワークディレクトリ。 - + Parser パーサー - + Cppcheck (built in) Cppcheckビルトイン - + Check level チェックレベル - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. #R 限定的 -- 開発者が直接的に結果を得るための解析を意味します。解析は限定的で高速ですがより少ない結果になります。 - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. #N 通常 -- CIでの通常の解析を意味します。解析が合理的な時間内に完了すべきです。 - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). #E 徹底的 -- ナイトリービルド等を意味します。解析時間はより長くなることがあります (コンパイルの10倍以上時間がかかってもよい)。 - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) ヘッダファイルのコードもチェック (通常はONにしてください、制限するときのみOFF) - Premium License - プレミアムライセンス + プレミアムライセンス - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. タグが追加された場合、警告上で右クリックしてそれらのタグの中の一つを設定できます。警告を分類できます。 - + Exclude source files 除外するソースファイル - + Exclude folder... フォルダで除外... - + Exclude file... ファイルで除外... - + Check that each class has a safe public interface クラスが安全で公開されたインターフェースをもっているか確認 - + Limit analysis 解析の制限 - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) 未使用テンプレートのコードもチェック (解析に時間がかかり、また正確性は低い) - + Max CTU depth CTUの最大深さ - + Enable inline suppressions inline抑制を有効にする - + Misra C MISRA C - + 2012 2012 - - + + 2023 2023 - + 2025 2025 - + Misra C++ MISRA C++ - + 2008 2008 - + Cert C++ Cert C++ - + Safety profiles (defined in C++ core guidelines) 安全性プロファイル(C++コアガイドラインで定義) - + Bug hunting (Premium) バグハンティング(プレミアム) - + External tools 外部ツール @@ -1908,88 +1907,88 @@ Options: 下 - + Platform プラットフォーム - + Clang (experimental) Clang (実験的) - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. 可能な限りクラスが柔軟であり堅牢であることを望む場合、公開されたインターフェースが非常に堅牢です。Cppcheckは引数があらゆる値をとりうると仮定します。 - + Max recursion in template instantiation テンプレートインスタンス化の最大再帰回数 - + Warning options 警告オプション - + Root path: ルートパス: - + Filepaths in warnings will be relative to this path 警告中のファイルパスはこのパスからの相対パスになります - + Warning tags (separated by semicolon) 警告タグ(セミコロン区切り) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck ビルドディレクトリ (全プログラムチェック, 差分チェック, 統計等) - + Libraries ライブラリ - + Suppressions 指摘の抑制 - + Add 追加 - - + + Addons アドオン - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. 注意: アドオンには<a href="https://www.python.org/">Python</a>が必要です。 - + Y2038 Y2038 - + Thread safety スレッドセーフ - + Coding standards コーディング標準 @@ -1998,12 +1997,12 @@ Options: MISRA C 2012 - + Cert C CERT C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) CERT-INT35-C: int型の精度 (もしサイズが精度と一致する場合空のままにしてください) @@ -2012,22 +2011,22 @@ Options: MISRA C++ 2008 - + Autosar AUTOSAR - + Bug hunting バグハント - + Clang analyzer Clang Analyzer - + Clang-tidy Clang-tidy @@ -2040,82 +2039,93 @@ Options: ProjectFileDialog - + Project file: %1 プロジェクトファイル:%1 - + Select Cppcheck build dir Cppcheckビルドディレクトリ - + Select include directory includeディレクトリを選択 - + Select a directory to check チェックするディレクトリを選択してください - + Note: Open source Cppcheck does not fully implement Misra C 2012 注意: オープンソースのCppcheckはMisra C 2012を完全にサポートしていません。 - + Clang-tidy (not found) Clang-tidy (みつかりません) - + Visual Studio Visual Studio - + Compile database コンパイルデータベース - + Borland C++ Builder 6 Borland C++ Builder 6 - + Import Project プロジェクトのインポート - + + C/C++ header + + + + + Include file + + + + Select directory to ignore 除外するディレクトリを選択してください - + Source files ソースファイル - + + All files 全ファイル - + Exclude file 除外ファイル - + Select MISRA rule texts file MISRAルールテキストファイルを選択 - + MISRA rule texts file (%1) MISRAルールテキストファイル (%1) @@ -2156,7 +2166,7 @@ Options: 行 %1: 必須の属性 '%2' が '%3'にない - + (Not found) (見つかりません) @@ -2600,61 +2610,61 @@ Please check the application path and parameters are correct. 警告の詳細 - - + + Failed to save the report. レポートの保存に失敗しました。 - + Print Report レポートの印刷 - + No errors found, nothing to print. 指摘がないため、印刷するものがありません。 - + %p% (%1 of %2 files checked) %p% (%1 / %2 :ファイル数) - - + + Cppcheck Cppcheck - + No errors found. 警告/エラーは見つかりませんでした。 - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. 警告/エラーが見つかりましたが、非表示設定になっています。 - - + + Failed to read the report. レポートの読み込みに失敗. - + XML format version 1 is no longer supported. XML フォーマットバージョン 1 はもうサポートされていません。 - + First included by は次のものが最初にインクルードしました - + Id ID @@ -2663,42 +2673,42 @@ To toggle what kind of errors are shown, open view menu. バグハントの解析は不完全です - + Clear Log ログの消去 - + Copy this Log entry このログ項目をコピー - + Copy complete Log ログ全体をコピー - + Analysis was stopped 解析は停止しした - + There was a critical error with id '%1' id '%1'の致命的なエラーがあります - + when checking %1 %1 をチェックするとき - + when checking a file ファイルをチェックするとき - + Analysis was aborted. 解析は中止した。 @@ -2984,14 +2994,14 @@ To toggle what kind of errors are shown, open view menu. - - + + Statistics 統計情報 - + Project プロジェクト @@ -3022,7 +3032,7 @@ To toggle what kind of errors are shown, open view menu. - + Previous Scan 前回の解析 @@ -3102,103 +3112,103 @@ To toggle what kind of errors are shown, open view menu. PDF エクスポート - + 1 day 一日 - + %1 days %1日 - + 1 hour 一時間 - + %1 hours %1時間 - + 1 minute 一分 - + %1 minutes %1分 - + 1 second 一秒 - + %1 seconds %1秒 - + 0.%1 seconds 0.%1秒 - + and と - + Export PDF PDF エクスポート - + Project Settings プロジェクトの設定 - + Paths パス - + Include paths インクルードパス - + Defines 定義(define) - + Undefines 定義取り消し(Undef) - + Path selected 選択されたパス - + Number of files scanned スキャンしたファイルの数 - + Scan duration スキャン期間 - - + + Errors エラー @@ -3213,32 +3223,32 @@ To toggle what kind of errors are shown, open view menu. cppcheckビルドディレクトリがありません - - + + Warnings 警告 - - + + Style warnings スタイル警告 - - + + Portability warnings 移植可能性警告 - - + + Performance warnings パフォーマンス警告 - - + + Information messages 情報メッセージ diff --git a/gui/cppcheck_ka.ts b/gui/cppcheck_ka.ts index ecc47d7d090..f6d571ab3f5 100644 --- a/gui/cppcheck_ka.ts +++ b/gui/cppcheck_ka.ts @@ -109,65 +109,52 @@ Parameters: -l(line) (file) ComplianceReportDialog - Compliance Report - შესაბამისობის ანგარიში + შესაბამისობის ანგარიში - Project name - პროექტის სახელი + პროექტის სახელი - Project version - პროექტის ვერსია + პროექტის ვერსია - Coding Standard - კოდირების სტანდარტი + კოდირების სტანდარტი - Misra C - Misra C + Misra C - Cert C - Cert C + Cert C - Cert C++ - Cert C++ + Cert C++ - List of files with md5 checksums - MD5 საკონტროლო ჯამების მქონე ფაილების სია + MD5 საკონტროლო ჯამების მქონე ფაილების სია - Compliance report - შესაბამისობის ანგარიში + შესაბამისობის ანგარიში - HTML files (*.html) - HTML ფაილები (*.html) + HTML ფაილები (*.html) - - Save compliance report - შესაბამისობის ანგარიშის შენახვა + შესაბამისობის ანგარიშის შენახვა - Failed to import '%1' (%2), can not show files in compliance report - '%1'-ის (%2) შემოტანა ჩავარდა. შესაბამისობის ანგარიშში ფაილებს ვერ ვაჩვენებ + '%1'-ის (%2) შემოტანა ჩავარდა. შესაბამისობის ანგარიშში ფაილებს ვერ ვაჩვენებ @@ -209,12 +196,12 @@ Parameters: -l(line) (file) ინდექსი - + Helpfile '%1' was not found დახმარების ფაილი '%1' ვერ ვიპოვე - + Cppcheck Cppcheck @@ -478,30 +465,30 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck - + A&nalyze ა&ნალიზი - + Standard სტანდარტული @@ -511,245 +498,245 @@ Parameters: -l(line) (file) &ფაილი - + &View &ხედი - + &Toolbars &ხელსაწყოთა ზოლები - + C++ standard C++-ის სტანდარტი - + &C standard C standard &C-ის სტანდარტი - + &Edit &ჩასწორება - + &License... &ლიცენზია... - + A&uthors... &ავტორები... - + &About... &შესახებ... - + &Files... ფაილ&ები... - - + + Analyze files Check files ფაილების ანალიზი - + Ctrl+F Ctrl+F - + &Directory... &საქაღალდე.... - - + + Analyze directory Check directory საქაღალდის ანალიზი - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop &გაჩერება - - + + Stop analysis Stop checking ანალიზის გაჩერება - + Esc Esc - + &Save results to file... შედეგები&ს შენახვა ფაილში.... - + Ctrl+S Ctrl+S - + &Quit გამოსვლა - + &Clear results შედეგების &გასუფთავება - + &Preferences &გამართვა - - - + + + Show errors შეცდომების ჩვენება - - - + + + Show warnings გაფრთხილების ჩვენება - - + + Show performance warnings წარმადობის გაფრთხილებების ჩვენება - + Show &hidden დამალულის &ჩვენება - - + + Information ინფორმაცია - + Show information messages ინფორმაციის შეტყობინებების ჩვენება - + Show portability warnings გადატანადობის გაფრთხილებების ჩვენება - + Show Cppcheck results Cppcheck-ის შედეგები ჩვენება - + Clang Clang - + Show Clang results Clang-ის შედეგები ჩვენება - + &Filter &ფილტრი - + Filter results შედეგების გაფილტვრა - + Windows 32-bit ANSI Windows 32-bit ANSI - + Windows 32-bit Unicode Windows 32-bit Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - + &Print... &ბეჭდვა… - + Print the Current Report მიმდინარე ანგარიშის დაბეჭდვა - + Print Pre&view... საბეჭდის &გადახედვა... - + Open a Print Preview Dialog for the Current Results მიმდინარე შედეგების დაბეჭდვის მინიატურის დიალოგის ჩვენება - + Open library editor ბიბლიოთეკის რედაქტორის გახსნა - + &Check all &ყველას ჩართვა @@ -764,336 +751,336 @@ Parameters: -l(line) (file) დამალვა - - + + Report - + Filter ფილტრი - + &Reanalyze modified files &Recheck modified files ყველა შეცვლილი ფაილის თავიდან ანალი&ზი - + Reanal&yze all files &ყველა ფაილის თავიდან ანალიზი - + Ctrl+Q Ctrl+Q - + Style war&nings ს&ტილის გაფრთხილებები - + E&rrors &შეცდომები - + &Uncheck all ყველას ჩამოყ&რა - + Collapse &all ყველას ჩაკეცვ&ა - + &Expand all &ყველას ამოკეცვა - + &Standard &სტანდარტული - + Standard items სტანდარტული ელემენტები - + Toolbar ხელსაწყოთა ზოლი - + &Categories &კატეგორიები - + Error categories შეცდომის კატეგორიები - + &Open XML... &XML-ის გახსნა... - + Open P&roject File... პ&პროექტის ფაილის გახსნა... - + Ctrl+Shift+O Ctrl+Shift+O - + Sh&ow Scratchpad... ბლ&ოკნოტის ჩვენება... - + &New Project File... &ახალი პროექტის ფაილი... - + Ctrl+Shift+N Ctrl+Shift+N - + &Log View ჟურნა&ლის ხედი - + Log View ჟურნალის ხედი - + C&lose Project File პროექტის ფაი&ლის დახურვა - + &Edit Project File... პროექტის ფაილის ჩასწორ&ება... - + &Statistics &სტატისტიკა - + &Warnings &გაფრთხილებები - + Per&formance warnings წარმატების გა&ფრთხილებები - + &Information &ინფორმაცია - + &Portability &გადატანადობა - + P&latforms პ&ლატფორმები - + C++&11 C++&11 - + C&99 C&99 - + &Posix &Posix - + C&11 C&11 - + &C89 &C89 - + &C++03 &C++03 - + &Library Editor... ბიბ&ლიოთეკის რედაქტორი... - + &Auto-detect language ენის &ავტოდადგენა - + &Enforce C++ ძ&ალით C++ - + E&nforce C ძა&ლით C - + C++14 C++14 - + Reanalyze and check library ბიბლიოთეკის თავიდან ანალიზი და შემოწმება - + Check configuration (defines, includes) კონფიგურაციის შემოწმება (defines, includes) - + C++17 C++17 - + C++20 C++20 - + Compliance report... შესაბამისობის ანგარიში... - + Normal ნორმალური - + Misra C Misra C - + Misra C++ 2008 - + Cert C Cert C - + Cert C++ Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + &Contents &შემცველობა - + Categories კატეგორიები - - + + Show style warnings სტილის გაფრთხილების ჩვენება - + Open the help contents დახმარების შემცველობის გახსნა - + F1 F1 - + &Help &დახმარება - - + + Quick Filter: სწრაფი ფილტრი: - + Select configuration აირჩიეთ კონფიგურაცია - + Found project file: %1 Do you want to load this project file instead? @@ -1102,61 +1089,61 @@ Do you want to load this project file instead? გნებავთ, სამაგიეროდ, ეს პროექტის ფაილი ჩატვირთოთ? - + File not found ფაილი ნაპოვნი არაა - + Bad XML არასწორი XML - + Missing attribute აკლია ატრიბუტი - + Bad attribute value არასწორი ატრიბუტის მნიშვნელობა - + Unsupported format მხარდაუჭერელი ფორმატი - + Duplicate define გამეორებული აღწერა - + Failed to load the selected library '%1'. %2 ჩავარდა ჩატვირთვა მონიშნული ბიბლიოთეკისთვის '%1'. %2 - + File not found: '%1' ფაილი ვერ ვიპოვე: '%1' - + Failed to load/setup addon %1: %2 დამატების (%1) ჩატვირთვა/მორგება ჩავარდა: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. @@ -1165,8 +1152,8 @@ Analysis is aborted. ანალიზი შეწყდა. - - + + %1 Analysis is aborted. @@ -1175,149 +1162,143 @@ Analysis is aborted. ანალიზი შეწყვეტილია. - + License ლიცენზია - + Authors ავტორები - + Save the report file ანგარიშის ფაილში ჩაწერა - - + + XML files (*.xml) XML ფაილები (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! ახალი ფაილების ან საქაღალდეების არჩევამდე პრორექტის ფაილი უნდა დახუროთ! - + The library '%1' contains unknown elements: %2 ბიბლიოთეკა '%1' უცნობ ელემენტებს შეიცავს: %2 - + Duplicate platform type გამეორებული პლატფორმის ტიპი - + Platform type redefined პლატფორმის ტიპი თავდან აღიწერა - + Unknown element უცნობი ელემენტი - - Unknown element - Unknown issue - უცნობი პრობლემა - - - - - - + + + + Error შეცდომა - + Open the report file ანგარიშის ფაილის გახსნა - + Text files (*.txt) ტექსტური ფაილები (*.txt) - + CSV files (*.csv) CSV ფაილები (*.csv) - + Project files (*.cppcheck);;All files(*.*) პროექტის ფაილები (*.cppcheck);;ყველა ფაილი(*.*) - + Select Project File აირჩიეთ პროექტის ფაილი - - - - + + + + Project: პროექტი: - + No suitable files found to analyze! ანალიზისათვის შესაფერისი ფაილები აღმოჩენილი არაა! - + C/C++ Source C/C++ საწყისი კოდი - + Compile database მონაცემთა ბაზის კომპილაცია - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze აირჩეთ ფაილები ანალიზისთვის - + Select directory to analyze აირჩიეთ საქაღალდე ანალიზისთვის - + Select the configuration that will be analyzed აირჩიეთ კონფიგურაცია ანალიზისთვის - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1326,7 +1307,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1337,7 +1318,7 @@ Do you want to proceed? გნებავთ, გააგრძელოთ? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1346,47 +1327,46 @@ Do you want to stop the analysis and exit Cppcheck? გნებავთ, გააჩეროთ ანალიზი და გახვიდეთ Cppcheck-დან? - + About შესახებ - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ფაილები (*.xml);;ტექსტური ფაილები (*.txt);;CSV ფაილები (*.csv) - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - შესაბამისობის ანგარიშის გენერაცია ახლა შეუძლებელია, რადგან ჯერ ანალიზი წარმატებით უნდა დასრულდეს. სცადეთ, კოდის ანალიზი თავიდან გაუშვათ და დარწმუნდეთ, რომ კრიტიკული შეცდომები არ არსებობს. + შესაბამისობის ანგარიშის გენერაცია ახლა შეუძლებელია, რადგან ჯერ ანალიზი წარმატებით უნდა დასრულდეს. სცადეთ, კოდის ანალიზი თავიდან გაუშვათ და დარწმუნდეთ, რომ კრიტიკული შეცდომები არ არსებობს. - + Build dir '%1' does not exist, create it? აგების საქაღალდე (%1) არ არსებობს. შევქმნა? - + To check the project using addons, you need a build directory. პროექტის დამატებებით შესამოწმებლად აგების საქაღალდე გჭირდებათ. - + Failed to open file ფაილის გახსნის შეცდომა - + Unknown project file format უცნობი პროექტის ფაილის ფორმატი - + Failed to import project file პროექტის ფაილის შემოტანა ჩავარდა - + Failed to import '%1': %2 Analysis is stopped. @@ -1395,27 +1375,27 @@ Analysis is stopped. ანალიზი შეწყდა. - + Failed to import '%1' (%2), analysis is stopped '%1'-ის (%2) შემოტანა ჩავარდა. ანალიზი შეწყდა - + Project files (*.cppcheck) პროექტის ფაილები (*.cppcheck) - + Select Project Filename აირჩიეთ პროექტის ფაილის სახელი - + No project file loaded პროექტის ფაილი ჩატვირთული არაა - + The project file %1 @@ -1432,67 +1412,67 @@ Do you want to remove the file from the recently used projects -list? გნებავთ წაშალოთ ეს ფაილი ახლახან გამოყენებული პროექტების სიიდან? - + Install დაყენება - + New version available: %1. %2 ხელმისაწვდომია ახალი ვერსია: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1636,67 +1616,67 @@ Options: აღწერები წერტილმძიმით უნდა იყოს გამოყოფილი. მაგ: DEF1;DEF2=5;DEF3=int - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. შენიშვნა: ჩადეთ თქვენი .cfg ფაილები იგივე საქაღალდეში, სადაც პროექტის ფაილია. მათ ზემოთ დაინახავთ. - + Clang (experimental) Clang (ექსპერიმენტული) - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) თავსართის ფაილებში არსებული კოდის შეწმება (ნაგულისხმევად, ეს ჩართულია. თუ გნებავთ შეზღუდული სწრაფი ანალიზი, მაშინ გამორთეთ ეს) - + Max recursion in template instantiation - + Filepaths in warnings will be relative to this path ფაილის ბილიკები ამ ბილიკის ფარდობითი იქნება - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. თუ ჭდეები დამატებულია, შეგიძლიათ, გაფრთხილებებზე მარჯვენა ღილაკით დააწკაპუნოთ და დააყენოთ ერთ-ერთი ჭდე. გაფრთხილებების კატეგორიებად დალაგება ხელით შეგიძლიათ. - + Exclude source files კოდის ფაილების ამოღება - + Exclude folder... საქაღალდის ამოღება... - + Exclude file... ფაილის ამოღება... - + MISRA rule texts MISRA-ის წესის ტექსტები - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + ... ... @@ -1707,8 +1687,7 @@ Options: - - + Browse... ნუსხა... @@ -1736,15 +1715,15 @@ Options: - + Edit ჩასწორება - - + + Remove წაშლა @@ -1764,124 +1743,134 @@ Options: ჩასმის ბილიკები: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions ტიპები და ფუნქციები - - + + Analysis ანალიზი - + This is a workfolder that Cppcheck will use for various purposes. ეს სამუშაო საქაღალდეა, რომელსაც Cppcheck სხვადასხვა მიზნებისთვის გამოიყენებს. - + Parser ანალიზატორი - + Cppcheck (built in) Cppcheck (ჩაშენებული) - + Check level შემოწმების დონე - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. ნორმალური -- ნიშნავს ნორმალურ ანალიზს CI-ში. ანალიზი მისაღებ დროში დასრულდება. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). ამომწურავი -- განკუთვნილია ღამის აგებებისთვის და ა.შ. ანალიზის დრო, შეიძლება, უფრო მეტიც იყოს (კომპილაციაზე 10x მეტი დრო ჩვეულებრივი ამბავია). - + Check that each class has a safe public interface შემოწმება, აქვს თუ არა ყველა კლასს უსაფრთხო საჯარო ინტერფეისი - + Limit analysis ანალიზის შეზღუდვა - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth CTU-ის მაქსიმალური სიღრმე - - Premium License - - - - + Enable inline suppressions შეცდომების ხაზშივე ჩახშობის ჩართვა - + 2025 2025 - + Misra C++ Misra C++ - + 2008 2008 - + Cert C Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) CERT-INT35-C: მთელი რიცხვის სიზუსტე (თუ ზომა სიზუსტეს ემთხვევა, შეგიძლიათ, ცარიელი დატოვოთ) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting შეცდომებზე ნადირობა - + External tools გარე ხელსაწყოები @@ -1896,104 +1885,104 @@ Options: ქვემოთ - + Platform პლატფორმა - + Warning options გაფრთხილების მორგება - + Root path: Root ბილიკი: - + Warning tags (separated by semicolon) გაფრთხილების ჭდეები (წერტილმძიმით გამოყოფილი) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck-ის აგების საქაღალდე (მთელი პროგრამის ანალიზი, ინკრემენტული ანალიზი, სტატისტიკა და ა.შ.) - + Libraries ბიბლიოთეკები - + Suppressions ჩახშობები - + Add დამატება - - + + Addons დამატებები - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. შენიშვნა: დამატებას დაყენებული <a href="https://www.python.org/">Python</a> სჭირდება. - + Y2038 Y2038 - + Thread safety ნაკადების უსაფრთხოება - + Coding standards კოდირების სტანდარტები - + Misra C Misra C - + 2012 2012 - - + + 2023 2023 - + Cert C++ Cert C++ - + Bug hunting (Premium) შეცდომებზე ნადირობა (ფასიანი) - + Clang analyzer Clang-ის ანალიზატორი - + Clang-tidy Clang-tidy @@ -2006,82 +1995,93 @@ Options: ProjectFileDialog - + Project file: %1 პროექტის ფაილი: %1 - + Select Cppcheck build dir აირჩიეთ Cppcheck-ის აგების საქაღალდე - + Select include directory აირჩიეთ ჩასასმელი საქაღალდე - + Select a directory to check აირჩიეთ შესამოწმებელი საქაღალდე - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) Clang-tidy (ვერ ვიპოვე) - + Visual Studio Visual Studio - + Compile database მონაცემთა ბაზის კომპილაცია - + Borland C++ Builder 6 Borland C++ Builder 6 - + Import Project პროექტის შემოტანა - + + C/C++ header + + + + + Include file + + + + Select directory to ignore აირჩიეთ გამოსატოვებელი საქაღალდე - + Source files კოდის ფაილები - + + All files ყველა ფაილი - + Exclude file ფაილის ამოღება - + Select MISRA rule texts file აირჩიეთ MISRA-ის წესების ტექსტის ფაილი - + MISRA rule texts file (%1) MISRA-ის წესის ტექსტების ფაილი (%1) @@ -2116,7 +2116,7 @@ Options: ხაზი %1: აუცილებელი ატრიბუტი '%2' '%3'-ში აღმოჩენილი არაა - + (Not found) (ვერ ვიპოვე) @@ -2540,56 +2540,56 @@ Please check the application path and parameters are correct. ResultsView - + Print Report ანგარიშის დაბეჭდვა - + No errors found, nothing to print. შეცდომები ვერ ვიპოვე. დასაბეჭდი არაფერია. - + %p% (%1 of %2 files checked) %p% (შემოწმებულია %1 ფაილი %2-დან) - - + + Cppcheck Cppcheck - + No errors found. შეცდომების გარეშე. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. აღმოჩენილია შეცდომები, მაგრამ მითითებულია, რომ ისინი დაიმალოს. იმისათვის, რომ გადართოთ, რა სახის შეცდომებია ნაჩვენები, გახსენით მენიუ 'ხედი'. - - + + Failed to read the report. ანგარიშის წაკითხვა ჩავარდა. - + XML format version 1 is no longer supported. XML-ის ფორმატის პირველი ვერსია მხარდაჭერილი აღარაა. - + First included by პირველად ჩასმულია ფაილში - + Id Id @@ -2598,48 +2598,48 @@ To toggle what kind of errors are shown, open view menu. შეცდომებზე ნადირობის ანალიზი დაუსრულებელია - + Clear Log ჟურნალის გასუფთავება - + Copy this Log entry ამ ჟურნალის ჩანაწერის კოპირება - + Copy complete Log სრული ჟურნალის კოპირება - + Analysis was stopped ანალიზი გაუქმებულია - + There was a critical error with id '%1' აღმოჩენილია კრიტიკული შეცდომა id-ით '%1' - + when checking %1 %1-ის შემოწმებისას - + when checking a file ფაილის შემოწმებისას - + Analysis was aborted. ანალიზი შეწყვეტილია. - - + + Failed to save the report. ანგარიშის შენახვა ჩავარდა. @@ -2945,14 +2945,14 @@ To toggle what kind of errors are shown, open view menu. - - + + Statistics სტატისტიკა - + Project პროექტი @@ -2983,7 +2983,7 @@ To toggle what kind of errors are shown, open view menu. - + Previous Scan წინა სკანირება @@ -3063,103 +3063,103 @@ To toggle what kind of errors are shown, open view menu. PDF-ად გატანა - + 1 day 1 დღე - + %1 days %1 დღე - + 1 hour %1 საათი - + %1 hours %1 საათი - + 1 minute %1 წუთი - + %1 minutes %1 წთ - + 1 second 1 წამი - + %1 seconds %1 წამი - + 0.%1 seconds 0.%1 წამი - + and და - + Export PDF PDF-ში გატანა - + Project Settings პროექტის პარამეტრები - + Paths ბილიკები - + Include paths ჩასმის ბილიკები - + Defines აღწერები - + Undefines წაშლილი მაკროაღწერები - + Path selected არჩეული ბილიკი - + Number of files scanned დასკანერებულია ფაილების რაოდენობა - + Scan duration სკანირების ხანგრძლივობა - - + + Errors შედომები @@ -3174,32 +3174,32 @@ To toggle what kind of errors are shown, open view menu. Cppcheck-ის აგების საქაღალდის გარეშე - - + + Warnings გაფრთხილებები - - + + Style warnings სტილის გაფრთხილებები - - + + Portability warnings გადატანადობის გაფრთხილებები - - + + Performance warnings წარმადობის გაფრთხილებები - - + + Information messages საინფორმაციო შეტყობინებები diff --git a/gui/cppcheck_ko.ts b/gui/cppcheck_ko.ts index da6bac85bb7..18720477f08 100644 --- a/gui/cppcheck_ko.ts +++ b/gui/cppcheck_ko.ts @@ -116,70 +116,6 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -217,12 +153,12 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - + Helpfile '%1' was not found - + Cppcheck Cppcheck @@ -485,20 +421,20 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck @@ -518,366 +454,366 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: 파일(&F) - + &View 보기(&V) - + &Toolbars 도구바(&T) - - + + Report - + &Help 도움말(&H) - + &Edit 편집(&E) - + Standard 표준 도구 - + Categories 분류 도구 - + Filter 필터 도구 - + &License... 저작권(&L)... - + A&uthors... 제작자(&u)... - + &About... 정보(&A)... - + &Files... 파일(&F)... - + Ctrl+F Ctrl+F - + &Directory... 디렉토리(&D)... - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop 중지(&S) - + Esc Esc - + &Save results to file... 결과를 파일에 저장(&S)... - + Ctrl+S Ctrl+S - + &Quit 종료(&Q) - + &Clear results 결과 지우기(&C) - + &Preferences 설정(&P) - - + + Show style warnings 스타일 경고 표시 - - - + + + Show errors 애러 표시 - + &Check all 전체 선택(&C) - + &Uncheck all 전체 해제(&U) - + Collapse &all 전체 접기(&A) - + &Expand all 전체 펼치기(&E) - + &Standard 표준 도구(&S) - + Standard items 표준 아이템 - + &Contents 내용(&C) - + Open the help contents 도움말을 엽니다 - + F1 F1 - + Toolbar 도구바 - + &Categories 분류 도구(&C) - + Error categories 에러 종류 - + &Open XML... XML 열기(&O)... - + Open P&roject File... 프로젝트 파일 열기(&R)... - + &New Project File... 새 프로젝트 파일(&N)... - + &Log View 로그 보기(&L) - + Log View 로그 보기 - + C&lose Project File 프로젝트 파일 닫기(&L) - + &Edit Project File... 프로젝트 파일 편집(&E)... - + &Statistics 통계 보기(&S) - - - + + + Show warnings 경고 표시 - - + + Show performance warnings 성능 경고 표시 - + Show &hidden 숨기기 보기(&H) - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - - + + Information 정보 - + Show information messages 정보 표시 - + Show portability warnings 이식성 경고 표시 - + &Filter 필터 도구(&F) - + Filter results 필터링 결과 - + Windows 32-bit ANSI Windows 32-bit ANSI - + Windows 32-bit Unicode Windows 32-bit Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - - + + Quick Filter: 빠른 필터: - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -886,12 +822,12 @@ This is probably because the settings were changed between the Cppcheck versions Cppcheck 버전간 설정 방법 차이때문인 것으로 보입니다. 편집기 설정을 검사(및 수정)해주세요, 그렇지 않으면 편집기가 제대로 시작하지 않습니다. - + You must close the project file before selecting new files or directories! 새로운 파일이나 디렉토리를 선택하기 전에 프로젝트 파일을 닫으세요! - + Found project file: %1 Do you want to load this project file instead? @@ -900,215 +836,210 @@ Do you want to load this project file instead? 이 프로젝트 파일을 불러오겠습니까? - - + + XML files (*.xml) XML 파일 (*.xml) - + Open the report file 보고서 파일 열기 - + License 저작권 - + Authors 제작자 - + Save the report file 보고서 파일 저장 - + Text files (*.txt) 텍스트 파일 (*.txt) - + CSV files (*.csv) CSV 파일 (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Project files (*.cppcheck);;All files(*.*) 프로젝트 파일 (*.cppcheck);;모든 파일(*.*) - + Select Project File 프로젝트 파일 선택 - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information - - - - + + + + Project: 프로젝트: - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + About - + To check the project using addons, you need a build directory. - + Select Project Filename 프로젝트 파일이름 선택 - + No project file loaded 프로젝트 파일 불러오기 실패 - + The project file %1 @@ -1130,103 +1061,97 @@ Do you want to remove the file from the recently used projects -list? - + C++ standard - - - - + + + + Error - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Failed to load the selected library '%1'. %2 - + Unsupported format - + The library '%1' contains unknown elements: %2 - + Duplicate platform type - + Platform type redefined - + &Print... - + Print the Current Report - + Print Pre&view... - + Open a Print Preview Dialog for the Current Results - + Open library editor - - Unknown element - - - - + Unknown element - Unknown issue - + Select configuration @@ -1249,259 +1174,259 @@ Options: - + Build dir '%1' does not exist, create it? - - + + Analyze files - - + + Analyze directory - + &Reanalyze modified files - - + + Stop analysis - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + No suitable files found to analyze! - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + A&nalyze - + &C standard - + Reanal&yze all files - + Ctrl+Q - + Style war&nings - + E&rrors - + Ctrl+Shift+O - + Sh&ow Scratchpad... - + Ctrl+Shift+N - + &Warnings - + Per&formance warnings - + &Information - + &Portability - + Show Cppcheck results - + Clang - + Show Clang results - + P&latforms - + C++&11 - + C&99 - + &Posix - + C&11 - + &C89 - + &C++03 - + &Library Editor... - + &Auto-detect language - + &Enforce C++ - + E&nforce C - + C++14 C++14 - + Project files (*.cppcheck) - + Reanalyze and check library - + Check configuration (defines, includes) - + C++17 C++17 - + C++20 C++20 - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1601,15 +1526,15 @@ Do you want to proceed? - + Edit 편집 - - + + Remove 제거 @@ -1624,22 +1549,22 @@ Do you want to proceed? 아래로 - + Suppressions - + Add - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. - + ... @@ -1664,17 +1589,17 @@ Do you want to proceed? - + Root path: - + Warning tags (separated by semicolon) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) @@ -1684,95 +1609,109 @@ Do you want to proceed? - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions - + Libraries - + Parser - + Cppcheck (built in) - + Check that each class has a safe public interface - + Limit analysis - - + + Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 - + Thread safety - + Coding standards - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Bug hunting - + Clang analyzer - + Clang-tidy - - + Browse... @@ -1782,153 +1721,148 @@ Do you want to proceed? - + Platform - + This is a workfolder that Cppcheck will use for various purposes. - + Clang (experimental) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + Max recursion in template instantiation - - Premium License - - - - + Warning options - + Filepaths in warnings will be relative to this path - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Enable inline suppressions Inline suppression 사용 - + Misra C - + 2012 - - + + 2023 - + 2025 - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + Misra C++ - + 2008 - + Cert C++ - + Safety profiles (defined in C++ core guidelines) - + Bug hunting (Premium) - + External tools @@ -1948,19 +1882,19 @@ Do you want to proceed? - - + + Analysis - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth @@ -1968,82 +1902,93 @@ Do you want to proceed? ProjectFileDialog - + Project file: %1 프로젝트 파일: %1 - + Select include directory Include 디렉토리 선택 - + Select a directory to check 검사할 디렉토리 선택 - + Select directory to ignore 무시할 디렉토리 선택 - + Select Cppcheck build dir - + Import Project - + Clang-tidy (not found) - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Source files - + + All files - + + C/C++ header + + + + + Include file + + + + Exclude file - + Select MISRA rule texts file - + MISRA rule texts file (%1) - + Visual Studio - + Compile database - + Borland C++ Builder 6 @@ -2076,7 +2021,7 @@ Do you want to proceed? - + (Not found) @@ -2487,87 +2432,87 @@ Please check the application path and parameters are correct. 결과 - - + + Failed to save the report. 결과 저장 실패. - + %p% (%1 of %2 files checked) %p% (%2 중 %1 파일 검사됨) - - + + Cppcheck Cppcheck - + No errors found. 에러가 발견되지 않았습니다. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. 에러가 발견되었지만, 감추도록 설정되어 있습니다. 에러 종류를 표시하도록 설정하려면, 보기 메뉴를 선택하세요. - - + + Failed to read the report. 결과 불러오기 실패. - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. - + Id - + Print Report - + No errors found, nothing to print. - + First included by - + XML format version 1 is no longer supported. @@ -2587,17 +2532,17 @@ To toggle what kind of errors are shown, open view menu. - + Clear Log - + Copy this Log entry - + Copy complete Log @@ -2882,14 +2827,14 @@ To toggle what kind of errors are shown, open view menu. - - + + Statistics 통계 - + Project 프로젝트 @@ -2915,7 +2860,7 @@ To toggle what kind of errors are shown, open view menu. - + Previous Scan 직전 검사 @@ -2980,123 +2925,123 @@ To toggle what kind of errors are shown, open view menu. 클립보드에 복사 - + 1 day 1일 - + %1 days %1일 - + 1 hour 1시간 - + %1 hours %1시간 - + 1 minute 1분 - + %1 minutes %1분 - + 1 second 1초 - + %1 seconds %1초 - + 0.%1 seconds 0.%1초 - + and 및 - + Project Settings 프로젝트 설정 - + Paths 경로 - + Include paths Include 경로 - + Defines Defines - + Path selected 선택된 경로 - + Number of files scanned 검사된 파일 수 - + Scan duration 검사 시간 - - + + Errors 에러 - - + + Warnings 경고 - - + + Style warnings 스타일 경고 - - + + Portability warnings 이식성 경고 - - + + Performance warnings 성능 경고 - - + + Information messages 정보 메시지 @@ -3106,7 +3051,7 @@ To toggle what kind of errors are shown, open view menu. - + Export PDF @@ -3136,7 +3081,7 @@ To toggle what kind of errors are shown, open view menu. - + Undefines diff --git a/gui/cppcheck_nl.ts b/gui/cppcheck_nl.ts index 2d3149d2f0a..cd14a92bdc2 100644 --- a/gui/cppcheck_nl.ts +++ b/gui/cppcheck_nl.ts @@ -116,70 +116,6 @@ Parameters: -l(lijn) (bestand) Geef een naam op, een pad en eventueel parameters voor de toepassing! - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -219,12 +155,12 @@ Parameters: -l(lijn) (bestand) - + Helpfile '%1' was not found - + Cppcheck Cppcheck @@ -489,30 +425,30 @@ Parameters: -l(lijn) (bestand) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck - + A&nalyze - + Standard Standaard @@ -522,245 +458,245 @@ Parameters: -l(lijn) (bestand) &Bestand - + &View &Weergave - + &Toolbars &Werkbalken - + C++ standard C++standaard - + &C standard C standard C standaard - + &Edit Be&werken - + &License... &Licentie... - + A&uthors... A&uteurs... - + &About... &Over... - + &Files... &Bestanden... - - + + Analyze files Check files Controleer bestanden - + Ctrl+F Ctrl+F - + &Directory... &Mappen... - - + + Analyze directory Check directory Controleer Map - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop &Stop - - + + Stop analysis Stop checking Stop controle - + Esc Esc - + &Save results to file... &Resultaten opslaan... - + Ctrl+S Ctrl+S - + &Quit &Afsluiten - + &Clear results &Resultaten wissen - + &Preferences &Voorkeuren - - - + + + Show errors Toon fouten - - - + + + Show warnings Toon waarschuwingen - - + + Show performance warnings Toon presentatie waarschuwingen - + Show &hidden Toon &verborgen - - + + Information Informatie - + Show information messages Toon informatie bericht - + Show portability warnings Toon portabiliteit waarschuwingen - + Show Cppcheck results - + Clang - + Show Clang results - + &Filter &Filter - + Filter results Filter resultaten - + Windows 32-bit ANSI Windows 32-bit ANSI - + Windows 32-bit Unicode - + Unix 32-bit - + Unix 64-bit - + Windows 64-bit - + &Print... - + Print the Current Report - + Print Pre&view... - + Open a Print Preview Dialog for the Current Results - + Open library editor - + &Check all &Controleer alles @@ -775,336 +711,336 @@ Parameters: -l(lijn) (bestand) Verberg - - + + Report - + Filter - + &Reanalyze modified files &Recheck modified files - + Reanal&yze all files - + Ctrl+Q - + Style war&nings - + E&rrors - + &Uncheck all Selecteer &niets - + Collapse &all Alles Inkl&appen - + &Expand all Alles &Uitklappen - + &Standard &Standaard - + Standard items Standaard items - + Toolbar Werkbalk - + &Categories &Categorieën - + Error categories Foute Categorieën - + &Open XML... - + Open P&roject File... Open P&oject bestand... - + Ctrl+Shift+O - + Sh&ow Scratchpad... - + &New Project File... &Nieuw Project Bestand... - + Ctrl+Shift+N - + &Log View &Log weergave - + Log View Log weergave - + C&lose Project File &Sluit Project Bestand - + &Edit Project File... &Bewerk Project Bestand... - + &Statistics &Statistieken - + &Warnings - + Per&formance warnings - + &Information - + &Portability - + P&latforms - + C++&11 - + C&99 - + &Posix - + C&11 - + &C89 - + &C++03 - + &Library Editor... - + &Auto-detect language - + &Enforce C++ - + E&nforce C - + C++14 - + Reanalyze and check library - + Check configuration (defines, includes) - + C++17 - + C++20 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + &Contents &Inhoud - + Categories Categorieën - - + + Show style warnings Toon stijl waarschuwingen - + Open the help contents Open de help inhoud - + F1 - + &Help &Help - - + + Quick Filter: Snel Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? @@ -1112,91 +1048,91 @@ Do you want to load this project file instead? Wilt u dit project laden in plaats van? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licentie - + Authors Auteurs - + Save the report file Rapport opslaan - - + + XML files (*.xml) XML bestanden (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1205,132 +1141,126 @@ This is probably because the settings were changed between the Cppcheck versions Dit is waarschijnlijk omdat de instellingen zijn gewijzigd tussen de versies van cppcheck. Controleer (en maak) de bewerker instellingen, anders zal de bewerker niet correct starten. - + You must close the project file before selecting new files or directories! Je moet project bestanden sluiten voordat je nieuwe bestanden of mappen selekteerd! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - - Unknown element - - - - + Unknown element - Unknown issue - - - - + + + + Error - + Open the report file Open het rapport bestand - + Text files (*.txt) Tekst bestanden (*.txt) - + CSV files (*.csv) CSV bestanden (*.csv) - + Project files (*.cppcheck);;All files(*.*) Project bestanden (*.cppcheck);;Alle bestanden(*.*) - + Select Project File Selecteer project bestand - - - - + + + + Project: Project: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1338,81 +1268,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Selecteer project bestandsnaam - + No project file loaded Geen project bestand geladen - + The project file %1 @@ -1428,67 +1353,67 @@ Kan niet worden gevonden! Wilt u het bestand van de onlangs gebruikte project verwijderen -lijst? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1619,58 +1544,58 @@ Options: - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Misra C - + 2012 - - + + 2023 - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + ... @@ -1681,8 +1606,7 @@ Options: - - + Browse... @@ -1710,15 +1634,15 @@ Options: - + Edit Bewerk - - + + Remove Verwijder @@ -1738,124 +1662,134 @@ Options: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions - - + + Analysis - + This is a workfolder that Cppcheck will use for various purposes. - + Parser - + Cppcheck (built in) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + Check that each class has a safe public interface - + Limit analysis - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth - - Premium License - - - - + Enable inline suppressions Schakel inline suppressies in - + 2025 - + Misra C++ - + 2008 - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting - + External tools @@ -1870,113 +1804,113 @@ Options: Omlaag - + Platform - + Clang (experimental) - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + Max recursion in template instantiation - + Warning options - + Root path: - + Filepaths in warnings will be relative to this path - + Warning tags (separated by semicolon) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) - + Libraries - + Suppressions - + Add - - + + Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 - + Thread safety - + Coding standards - + Cert C++ - + Bug hunting (Premium) - + Clang analyzer - + Clang-tidy @@ -1989,82 +1923,93 @@ Options: ProjectFileDialog - + Project file: %1 Project Bestand %1 - + Select Cppcheck build dir - + Select include directory Selecteer include map - + Select a directory to check Selecteer een map om te controleren - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) - + Visual Studio - + Compile database - + Borland C++ Builder 6 - + Import Project - + + C/C++ header + + + + + Include file + + + + Select directory to ignore Selecteer een map om te negeren - + Source files - + + All files - + Exclude file - + Select MISRA rule texts file - + MISRA rule texts file (%1) @@ -2099,7 +2044,7 @@ Options: - + (Not found) @@ -2510,102 +2455,102 @@ Gelieve te controleren of de het pad en de parameters correct zijn. ResultsView - + Print Report - + No errors found, nothing to print. - + %p% (%1 of %2 files checked) %p% (%1 van %2 bestanden gecontroleerd) - - + + Cppcheck Cppcheck - + No errors found. Geen fouten gevonden. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Fouten werden gevonden, maar volgens de configuratie zijn deze verborgen. Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. - - + + Failed to read the report. Kon rapport niet lezen. - + XML format version 1 is no longer supported. - + First included by - + Id Id - + Clear Log - + Copy this Log entry - + Copy complete Log - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. - - + + Failed to save the report. Kon het rapport niet opslaan. @@ -2907,14 +2852,14 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. - - + + Statistics Statistieken - + Project Project @@ -2945,7 +2890,7 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. - + Previous Scan Vorige scan @@ -3025,103 +2970,103 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. - + 1 day 1 dag - + %1 days %1 dagen - + 1 hour 1 uur - + %1 hours %1 uren - + 1 minute 1 minuut - + %1 minutes %1 minuten - + 1 second 1 seconde - + %1 seconds %1 secondes - + 0.%1 seconds 0.%1 secondes - + and en - + Export PDF - + Project Settings Project instellingen - + Paths Paden - + Include paths Bevat paden - + Defines Omschrijft - + Undefines - + Path selected Pad Geselekteerd - + Number of files scanned Aantal bestanden gescanned - + Scan duration Scan tijd - - + + Errors Fouten @@ -3136,32 +3081,32 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. - - + + Warnings Waarschuwingen - - + + Style warnings Stijl waarschuwingen - - + + Portability warnings Portabiliteit waarschuwingen - - + + Performance warnings Presentatie waarschuwingen - - + + Information messages Informatie bericht diff --git a/gui/cppcheck_ru.ts b/gui/cppcheck_ru.ts index 124e4d783aa..464bfb0d34b 100644 --- a/gui/cppcheck_ru.ts +++ b/gui/cppcheck_ru.ts @@ -116,70 +116,6 @@ Parameters: -l(line) (file) Вы должны задать название и путь к приложению! - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -219,12 +155,12 @@ Parameters: -l(line) (file) - + Helpfile '%1' was not found - + Cppcheck Cppcheck @@ -489,30 +425,30 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck - + A&nalyze Анализ - + Standard Стандартные @@ -522,245 +458,245 @@ Parameters: -l(line) (file) &Файл - + &View &Вид - + &Toolbars &Панель инструментов - + C++ standard Стандарт C++ - + &C standard C standard &Стандарт C - + &Edit &Правка - + &License... &Лицензия... - + A&uthors... &Авторы... - + &About... &О программе... - + &Files... &Файлы... - - + + Analyze files Check files Проверить файлы - + Ctrl+F Ctrl+F - + &Directory... &Каталог... - - + + Analyze directory Check directory Проверка каталога - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop Остановить - - + + Stop analysis Stop checking Остановить проверку - + Esc Esc - + &Save results to file... Сохранить отчёт в файл... - + Ctrl+S Ctrl+S - + &Quit Выход - + &Clear results Очистить отчёт - + &Preferences Параметры - - - + + + Show errors Показать ошибки - - - + + + Show warnings Показать предупреждения - - + + Show performance warnings Показать предупреждения производительности - + Show &hidden Показать скрытые - - + + Information Информационные сообщения - + Show information messages Показать информационные сообщения - + Show portability warnings Показать предупреждения переносимости - + Show Cppcheck results Просмотр результатов Cppcheck - + Clang Clang - + Show Clang results Просмотр результатов Clang - + &Filter Фильтр - + Filter results Результаты фильтрации - + Windows 32-bit ANSI Windows 32-bit ANSI - + Windows 32-bit Unicode Windows 32-bit Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - + &Print... Печать... - + Print the Current Report Напечатать текущий отчет - + Print Pre&view... Предварительный просмотр... - + Open a Print Preview Dialog for the Current Results Открыть диалог печати для текущих результатов - + Open library editor Открыть редактор библиотек - + &Check all Отметить все @@ -775,336 +711,336 @@ Parameters: -l(line) (file) Скрыть - - + + Report - + Filter Фильтр - + &Reanalyze modified files &Recheck modified files Заново проверить измененные файлы - + Reanal&yze all files Заново проверить все файлы - + Ctrl+Q - + Style war&nings Стилистические предупреждения - + E&rrors Ошибки - + &Uncheck all Сбросить все - + Collapse &all Свернуть все - + &Expand all Развернуть все - + &Standard Стандартные - + Standard items Стандартные элементы - + Toolbar Панель инструментов - + &Categories Категории - + Error categories Категории ошибок - + &Open XML... &Открыть XML... - + Open P&roject File... Открыть файл &проекта... - + Ctrl+Shift+O - + Sh&ow Scratchpad... Показать Блокнот - + &New Project File... &Новый файл проекта... - + Ctrl+Shift+N - + &Log View Посмотреть &лог - + Log View Посмотреть лог - + C&lose Project File &Закрыть файл проекта - + &Edit Project File... &Изменить файл проекта... - + &Statistics &Статистика - + &Warnings Предупреждения - + Per&formance warnings Предупреждения производительности - + &Information Информационные предупреждения - + &Portability Предупреждения переносимости - + P&latforms Платформы - + C++&11 - + C&99 - + &Posix - + C&11 - + &C89 - + &C++03 - + &Library Editor... Редактор библиотеки - + &Auto-detect language Автоматическое определение языка - + &Enforce C++ Принудительно C++ - + E&nforce C Принудительно C - + C++14 C++14 - + Reanalyze and check library Повторный анализ библиотеки - + Check configuration (defines, includes) Проверить конфигурацию (defines, includes) - + C++17 C++17 - + C++20 C++20 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + &Contents Помощь - + Categories Категории - - + + Show style warnings Показать стилистические предупреждения - + Open the help contents Открыть помощь - + F1 F1 - + &Help Помощь - - + + Quick Filter: Быстрый фильтр: - + Select configuration Выбор конфигурации - + Found project file: %1 Do you want to load this project file instead? @@ -1113,97 +1049,97 @@ Do you want to load this project file instead? Вы хотите загрузить этот проект? - + File not found Файл не найден - + Bad XML Некорректный XML - + Missing attribute Пропущен атрибут - + Bad attribute value Некорректное значение атрибута - + Unsupported format Неподдерживаемый формат - + Duplicate define - + Failed to load the selected library '%1'. %2 Не удалось загрузить выбранную библиотеку '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Лицензия - + Authors Авторы - + Save the report file Сохранить файл с отчетом - - + + XML files (*.xml) XML-файлы (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1212,43 +1148,37 @@ This is probably because the settings were changed between the Cppcheck versions Возможно, это связано с изменениями в версии программы. Пожалуйста, проверьте (и исправьте) настройки приложения. - + You must close the project file before selecting new files or directories! Вы должны закрыть проект перед выбором новых файлов или каталогов! - + The library '%1' contains unknown elements: %2 Библиотека '%1' содержит неизвестные элементы: %2 - + Duplicate platform type Дубликат типа платформы - + Platform type redefined Переобъявление типа платформы - + Unknown element Неизвестный элемент - - Unknown element - Unknown issue - Неизвестная проблема - - - - - - + + + + Error Ошибка @@ -1257,80 +1187,80 @@ This is probably because the settings were changed between the Cppcheck versions Невозможно загрузить %1. Cppcheck установлен некорректно. Вы можете использовать --data-dir=<directory> в командной строке для указания расположения файлов конфигурации. Обратите внимание, что --data-dir предназначен для использования сценариями установки. При включении данной опции, графический интерфейс пользователя не запускается. - + Open the report file Открыть файл с отчетом - + Text files (*.txt) Текстовые файлы (*.txt) - + CSV files (*.csv) CSV файлы(*.csv) - + Project files (*.cppcheck);;All files(*.*) Файлы проекта (*.cppcheck);;Все файлы(*.*) - + Select Project File Выберите файл проекта - - - - + + + + Project: Проект: - + No suitable files found to analyze! Не найдено подходящих файлов для анализа - + C/C++ Source Исходный код C/C++ - + Compile database - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze Выбор файлов для анализа - + Select directory to analyze Выбор каталога для анализа - + Select the configuration that will be analyzed Выбор используемой конфигурации - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1339,7 +1269,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1350,7 +1280,7 @@ Do you want to proceed? Вы хотите продолжить? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1359,109 +1289,104 @@ Do you want to stop the analysis and exit Cppcheck? Вы хотите остановить анализ и выйти из Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML файлы (*.xml);;Текстовые файлы (*.txt);;CSV файлы (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Build dir '%1' does not exist, create it? Директория для сборки '%1' не существует, создать? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1470,22 +1395,22 @@ Analysis is stopped. Невозможно импортировать '%1', анализ остановлен - + Project files (*.cppcheck) Файлы проекта (*.cppcheck) - + Select Project Filename Выберите имя файла для проекта - + No project file loaded Файл с проектом не загружен - + The project file %1 @@ -1501,12 +1426,12 @@ Do you want to remove the file from the recently used projects -list? Хотите удалить его из списка проектов? - + Install - + New version available: %1. %2 @@ -1650,52 +1575,52 @@ Options: Defines должны быть разделены точкой с запятой ';' - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Положите свои .cfg-файлы в один каталог с файлом проекта. Вы увидите их сверху. - + Clang (experimental) - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + Max recursion in template instantiation - + Filepaths in warnings will be relative to this path - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... @@ -1704,17 +1629,17 @@ Options: MISRA C 2012 - + MISRA rule texts Файл с текстами правил MISRA - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Скопируйте текст из Appendix A &quot;Summary of guidelines&quot; из фала правил MISRA C 2012 pdf в текстовый файл.</p></body></html> - + ... ... @@ -1725,8 +1650,7 @@ Options: - - + Browse... Обзор... @@ -1754,15 +1678,15 @@ Options: - + Edit Изменить - - + + Remove Удалить @@ -1782,124 +1706,134 @@ Options: Пути заголовочных файлов: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions - - + + Analysis Анализ - + This is a workfolder that Cppcheck will use for various purposes. - + Parser - + Cppcheck (built in) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + Check that each class has a safe public interface - + Limit analysis - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) Проверить код в неиспользуемых шаблонах - + Max CTU depth Максимальная глубина CTU - - Premium License - - - - + Enable inline suppressions Включить inline-подавление ошибок - + 2025 - + Misra C++ - + 2008 - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting - + External tools Внешние инструменты @@ -1914,104 +1848,104 @@ Options: Вниз - + Platform Платформа - + Warning options Опции предупреждений - + Root path: Корневой каталог: - + Warning tags (separated by semicolon) Теги предупреждений (через ';') - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Каталог сборки Cppcheck - + Libraries Библиотеки - + Suppressions Подавления - + Add Добавить - - + + Addons Дополнения - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 - + Thread safety - + Coding standards Стандарты кодирования - + Misra C - + 2012 - - + + 2023 - + Cert C++ - + Bug hunting (Premium) - + Clang analyzer - + Clang-tidy @@ -2024,82 +1958,93 @@ Options: ProjectFileDialog - + Project file: %1 Файл проекта: %1 - + Select Cppcheck build dir Выбрать директорию сборки Cppcheck - + Select include directory Выберите директорию для поиска заголовочных файлов - + Select a directory to check Выберите директорию для проверки - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) Clang-tidy (не найден) - + Visual Studio Visual Studio - + Compile database - + Borland C++ Builder 6 Borland C++ Builder 6 - + Import Project Импорт проекта - + + C/C++ header + + + + + Include file + + + + Select directory to ignore Выберите директорию, которую надо проигнорировать - + Source files - + + All files - + Exclude file - + Select MISRA rule texts file Выбрать файл текстов правил MISRA - + MISRA rule texts file (%1) Файл текстов правил MISRA (%1) @@ -2134,7 +2079,7 @@ Options: - + (Not found) (Недоступно) @@ -2555,102 +2500,102 @@ Please check the application path and parameters are correct. ResultsView - + Print Report Распечатать отчет - + No errors found, nothing to print. Ошибок не найдено, нечего распечатывать. - + %p% (%1 of %2 files checked) %p% (%1 из %2 файлов проверено) - - + + Cppcheck Cppcheck - + No errors found. Ошибок не найдено. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Были обнаружены ошибки, но они настроены быть скрыты. Для переключения какие ошибки отображаются, откройте меню представления. - - + + Failed to read the report. Не удалось прочитать отчет. - + XML format version 1 is no longer supported. XML формат версии 1 больше не поддерживается. - + First included by Только первый включенный - + Id Id - + Clear Log Очистить лог - + Copy this Log entry Скопировать данную запись - + Copy complete Log Скопировать полный лог - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. - - + + Failed to save the report. Не удалось сохранить отчет. @@ -2956,14 +2901,14 @@ To toggle what kind of errors are shown, open view menu. - - + + Statistics Статистика - + Project Проект @@ -2994,7 +2939,7 @@ To toggle what kind of errors are shown, open view menu. - + Previous Scan Последнее сканирование @@ -3074,103 +3019,103 @@ To toggle what kind of errors are shown, open view menu. Экспорт PDF - + 1 day 1 день - + %1 days %1 дней - + 1 hour 1 час - + %1 hours %1 часов - + 1 minute 1 минута - + %1 minutes %1 минут - + 1 second 1 секунда - + %1 seconds %1 секунд - + 0.%1 seconds 0.1%1 секунд - + and и - + Export PDF Экспорт PDF - + Project Settings Настройки проекта - + Paths Пути - + Include paths Включенные пути - + Defines Объявленные макроопределения: - + Undefines Удаленные макроопределения: - + Path selected Выбранные пути - + Number of files scanned Количество просканированных файлов - + Scan duration Продолжительность сканирования - - + + Errors Ошибки @@ -3185,32 +3130,32 @@ To toggle what kind of errors are shown, open view menu. Не задана директория сборки - - + + Warnings Предупреждения - - + + Style warnings Стилистические предупреждения - - + + Portability warnings Предупреждения переносимости - - + + Performance warnings Предупреждения производительности - - + + Information messages Информационные сообщения diff --git a/gui/cppcheck_sr.ts b/gui/cppcheck_sr.ts index 70b04dd196f..190dbdbe751 100644 --- a/gui/cppcheck_sr.ts +++ b/gui/cppcheck_sr.ts @@ -106,70 +106,6 @@ Parameters: -l(line) (file) - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -207,12 +143,12 @@ Parameters: -l(line) (file) - + Helpfile '%1' was not found - + Cppcheck Cppcheck @@ -477,30 +413,30 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck - + A&nalyze - + Standard Standard @@ -510,245 +446,245 @@ Parameters: -l(line) (file) &File - + &View &View - + &Toolbars - + C++ standard - + &C standard C standard - + &Edit &Edit - + &License... &License... - + A&uthors... A&uthors... - + &About... &About... - + &Files... &Files... - - + + Analyze files Check files - + Ctrl+F Ctrl+F - + &Directory... &Directory... - - + + Analyze directory Check directory - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop &Stop - - + + Stop analysis Stop checking - + Esc Esc - + &Save results to file... &Save results to file... - + Ctrl+S Ctrl+S - + &Quit &Quit - + &Clear results &Clear results - + &Preferences &Preferences - - - + + + Show errors - - - + + + Show warnings - - + + Show performance warnings - + Show &hidden - - + + Information - + Show information messages - + Show portability warnings - + Show Cppcheck results - + Clang - + Show Clang results - + &Filter - + Filter results - + Windows 32-bit ANSI Windows 32-bit ANSI - + Windows 32-bit Unicode Windows 32-bit Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - + &Print... - + Print the Current Report - + Print Pre&view... - + Open a Print Preview Dialog for the Current Results - + Open library editor - + &Check all &Check all @@ -763,559 +699,553 @@ Parameters: -l(line) (file) - - + + Report - + Filter - + &Reanalyze modified files &Recheck modified files - + Reanal&yze all files - + Ctrl+Q - + Style war&nings - + E&rrors - + &Uncheck all &Uncheck all - + Collapse &all Collapse &all - + &Expand all &Expand all - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... - + Open P&roject File... - + Ctrl+Shift+O - + Sh&ow Scratchpad... - + &New Project File... - + Ctrl+Shift+N - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Warnings - + Per&formance warnings - + &Information - + &Portability - + P&latforms - + C++&11 - + C&99 - + &Posix - + C&11 - + &C89 - + &C++03 - + &Library Editor... - + &Auto-detect language - + &Enforce C++ - + E&nforce C - + C++14 C++14 - + Reanalyze and check library - + Check configuration (defines, includes) - + C++17 C++17 - + C++20 C++20 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + &Contents - + Categories - - + + Show style warnings - + Open the help contents - + F1 F1 - + &Help &Help - - + + Quick Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License License - + Authors Authors - + Save the report file Save the report file - - + + XML files (*.xml) XML files (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - - Unknown element - - - - + Unknown element - Unknown issue - - - - + + + + Error - + Open the report file - + Text files (*.txt) Text files (*.txt) - + CSV files (*.csv) - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - - - - + + + + Project: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1323,81 +1253,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename - + No project file loaded - + The project file %1 @@ -1408,67 +1333,67 @@ Do you want to remove the file from the recently used projects -list? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1599,22 +1524,22 @@ Options: - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + ... @@ -1625,8 +1550,7 @@ Options: - - + Browse... @@ -1654,15 +1578,15 @@ Options: - + Edit - - + + Remove @@ -1692,271 +1616,281 @@ Options: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Platform - - + + Analysis - + This is a workfolder that Cppcheck will use for various purposes. - + Clang (experimental) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth - + Max recursion in template instantiation - - Premium License - - - - + Warning options - + Root path: - + Filepaths in warnings will be relative to this path - + Warning tags (separated by semicolon) - + Enable inline suppressions - + 2025 - + Misra C++ - + 2008 - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting - + External tools - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) - + Types and Functions - + Libraries - + Parser - + Cppcheck (built in) - + Check that each class has a safe public interface - + Limit analysis - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Suppressions - + Add - - + + Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 - + Thread safety - + Coding standards - + Misra C - + 2012 - - + + 2023 - + Cert C++ - + Bug hunting (Premium) - + Clang analyzer - + Clang-tidy @@ -1969,82 +1903,93 @@ Options: ProjectFileDialog - + Project file: %1 - + Select Cppcheck build dir - + Select include directory - + Select a directory to check - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) - + Visual Studio - + Compile database - + Borland C++ Builder 6 - + Import Project - + + C/C++ header + + + + + Include file + + + + Select directory to ignore - + Source files - + + All files - + Exclude file - + Select MISRA rule texts file - + MISRA rule texts file (%1) @@ -2077,7 +2022,7 @@ Options: - + (Not found) @@ -2472,102 +2417,102 @@ Please check the application path and parameters are correct. ResultsView - + Print Report - + No errors found, nothing to print. - + %p% (%1 of %2 files checked) - - + + Cppcheck Cppcheck - + No errors found. No errors found. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. - - + + Failed to read the report. - + XML format version 1 is no longer supported. - + First included by - + Id - + Clear Log - + Copy this Log entry - + Copy complete Log - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. - - + + Failed to save the report. Failed to save the report. @@ -2864,14 +2809,14 @@ To toggle what kind of errors are shown, open view menu. - - + + Statistics - + Project @@ -2902,7 +2847,7 @@ To toggle what kind of errors are shown, open view menu. - + Previous Scan @@ -2982,103 +2927,103 @@ To toggle what kind of errors are shown, open view menu. - + 1 day - + %1 days - + 1 hour - + %1 hours - + 1 minute - + %1 minutes - + 1 second - + %1 seconds - + 0.%1 seconds - + and - + Export PDF - + Project Settings - + Paths - + Include paths - + Defines - + Undefines - + Path selected - + Number of files scanned - + Scan duration - - + + Errors @@ -3093,32 +3038,32 @@ To toggle what kind of errors are shown, open view menu. - - + + Warnings - - + + Style warnings - - + + Portability warnings - - + + Performance warnings - - + + Information messages diff --git a/gui/cppcheck_sv.ts b/gui/cppcheck_sv.ts index f37121c2f2f..4f548b454d0 100644 --- a/gui/cppcheck_sv.ts +++ b/gui/cppcheck_sv.ts @@ -116,70 +116,6 @@ Parametrar: -l(line) (file) Du måste ange namn, sökväg samt eventuellt parametrar för applikationen! - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -219,12 +155,12 @@ Parametrar: -l(line) (file) - + Helpfile '%1' was not found - + Cppcheck Cppcheck @@ -495,30 +431,30 @@ Exempel: MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck - + A&nalyze Analysera - + Standard Standard @@ -528,245 +464,245 @@ Exempel: &Arkiv - + &View &Visa - + &Toolbars Verktygsfält - + C++ standard C++ standard - + &C standard C standard C standard - + &Edit &Redigera - + &License... &Licens... - + A&uthors... &Utvecklat av... - + &About... &Om... - + &Files... &Filer... - - + + Analyze files Check files Analysera filer - + Ctrl+F Ctrl+F - + &Directory... &Katalog... - - + + Analyze directory Check directory Analysera mapp - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop &Stoppa - - + + Stop analysis Stop checking Stoppa analys - + Esc Esc - + &Save results to file... &Spara resultat till fil... - + Ctrl+S Ctrl+S - + &Quit &Avsluta - + &Clear results &Töm resultat - + &Preferences &Inställningar - - - + + + Show errors Visa fel - - - + + + Show warnings Visa varningar - - + + Show performance warnings Visa prestanda varningar - + Show &hidden Visa dolda - - + + Information Information - + Show information messages Visa informations meddelanden - + Show portability warnings Visa portabilitets varningar - + Show Cppcheck results Visa Cppcheck resultat - + Clang Clang - + Show Clang results Visa Clang resultat - + &Filter &Filter - + Filter results Filtrera resultat - + Windows 32-bit ANSI Windows 32-bit ANSI - + Windows 32-bit Unicode Windows 32-bit Unicode - + Unix 32-bit Unix 32-bit - + Unix 64-bit Unix 64-bit - + Windows 64-bit Windows 64-bit - + &Print... Skriv ut... - + Print the Current Report Skriv ut aktuell rapport - + Print Pre&view... Förhandsgranska utskrift... - + Open a Print Preview Dialog for the Current Results Öppnar förhandsgranskning för nuvarande resultat - + Open library editor Öppna library editor - + &Check all &Kryssa alla @@ -781,337 +717,337 @@ Exempel: Dölj - - + + Report - + Filter Filter - + &Reanalyze modified files &Recheck modified files Analysera om ändrade filer - + Reanal&yze all files Analysera om alla filer - + Ctrl+Q - + Style war&nings Style varningar - + E&rrors Fel - + &Uncheck all Kryssa &ur alla - + Collapse &all Ingen bra översättning! &Fäll ihop alla - + &Expand all &Expandera alla - + &Standard &Standard - + Standard items Standard poster - + Toolbar Verktygsfält - + &Categories &Kategorier - + Error categories Fel kategorier - + &Open XML... &Öppna XML... - + Open P&roject File... Öppna Projektfil... - + Ctrl+Shift+O - + Sh&ow Scratchpad... Visa Scratchpad... - + &New Project File... Ny projektfil... - + Ctrl+Shift+N - + &Log View - + Log View Logg vy - + C&lose Project File Stäng projektfil - + &Edit Project File... Redigera projektfil... - + &Statistics Statistik - + &Warnings Varningar - + Per&formance warnings Optimerings varningar - + &Information Information - + &Portability Portabilitet - + P&latforms Plattformar - + C++&11 C++11 - + C&99 C99 - + &Posix Posix - + C&11 C11 - + &C89 C89 - + &C++03 C++03 - + &Library Editor... Library Editor... - + &Auto-detect language Detektera språk automatiskt - + &Enforce C++ Tvinga C++ - + E&nforce C Tvinga C - + C++14 C++14 - + Reanalyze and check library - + Check configuration (defines, includes) - + C++17 C++17 - + C++20 C++20 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + &Contents &Innehåll - + Categories Kategorier - - + + Show style warnings Visa stil varningar - + Open the help contents Öppna hjälp - + F1 F1 - + &Help &Hjälp - - + + Quick Filter: Snabbfilter: - + Select configuration Välj konfiguration - + Found project file: %1 Do you want to load this project file instead? @@ -1120,97 +1056,97 @@ Do you want to load this project file instead? Vill du ladda denna projektfil istället? - + File not found Filen hittades ej - + Bad XML Ogiltig XML - + Missing attribute Attribut finns ej - + Bad attribute value Ogiltigt attribut värde - + Unsupported format Format stöds ej - + Duplicate define - + Failed to load the selected library '%1'. %2 Misslyckades att ladda valda library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licens - + Authors Utvecklare - + Save the report file Spara rapport - - + + XML files (*.xml) XML filer (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1219,43 +1155,37 @@ This is probably because the settings were changed between the Cppcheck versions En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Kontrollera programinställningarna. - + You must close the project file before selecting new files or directories! Du måste stänga projektfilen innan nya filer eller sökvägar kan väljas! - + The library '%1' contains unknown elements: %2 Library filen '%1' har element som ej hanteras: %2 - + Duplicate platform type Dubbel plattformstyp - + Platform type redefined Plattformstyp definieras igen - + Unknown element Element hanteras ej - - Unknown element - Unknown issue - Något problem - - - - - - + + + + Error Fel @@ -1264,80 +1194,80 @@ En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Misslyckades att ladda %1. Din Cppcheck installation är ej komplett. Du kan använda --data-dir<directory> på kommandoraden för att specificera var denna fil finns. Det är meningen att --data-dir kommandot skall köras under installationen,så GUIt kommer ej visas när --data-dir används allt som händer är att en inställning görs. - + Open the report file Öppna rapportfilen - + Text files (*.txt) Text filer (*.txt) - + CSV files (*.csv) CSV filer (*.csv) - + Project files (*.cppcheck);;All files(*.*) Projektfiler (*.cppcheck);;Alla filer(*.*) - + Select Project File Välj projektfil - - - - + + + + Project: Projekt: - + No suitable files found to analyze! Inga filer hittades att analysera! - + C/C++ Source - + Compile database - + Visual Studio Visual Studio - + Borland C++ Builder 6 - + Select files to analyze Välj filer att analysera - + Select directory to analyze Välj mapp att analysera - + Select the configuration that will be analyzed Välj konfiguration som kommer analyseras - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1346,7 +1276,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1354,7 +1284,7 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1363,109 +1293,104 @@ Do you want to stop the analysis and exit Cppcheck? Vill du stoppa analysen och avsluta Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML filer (*.xml);;Text filer (*.txt);;CSV filer (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Build dir '%1' does not exist, create it? Build dir '%1' existerar ej, skapa den? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1474,22 +1399,22 @@ Analysis is stopped. Misslyckades att importera '%1', analysen stoppas - + Project files (*.cppcheck) Projekt filer (*.cppcheck) - + Select Project Filename Välj Projektfil - + No project file loaded Inget projekt laddat - + The project file %1 @@ -1506,12 +1431,12 @@ Do you want to remove the file from the recently used projects -list? Vill du ta bort filen från 'senast använda projekt'-listan? - + Install - + New version available: %1. %2 @@ -1655,12 +1580,12 @@ Options: Defines separeras med semicolon ';' - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Obs: Lägg dina egna .cfg filer i samma folder som projekt filen. De skall isåfall visas ovan. - + ... ... @@ -1671,8 +1596,7 @@ Options: - - + Browse... @@ -1700,15 +1624,15 @@ Options: - + Edit Redigera - - + + Remove Ta bort @@ -1728,143 +1652,153 @@ Options: Include sökvägar: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + This is a workfolder that Cppcheck will use for various purposes. - + Clang (experimental) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + Max recursion in template instantiation - - Premium License - - - - + Filepaths in warnings will be relative to this path - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files - + Exclude folder... - + Exclude file... - + Enable inline suppressions Använd inline suppressions - + Misra C - + 2012 - - + + 2023 - + 2025 - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + Misra C++ - + 2008 - + Cert C++ - + Safety profiles (defined in C++ core guidelines) - + Bug hunting (Premium) - + External tools @@ -1879,140 +1813,140 @@ Options: Ned - + Platform - - + + Analysis - + Parser - + Cppcheck (built in) - + Check that each class has a safe public interface - + Limit analysis - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) - + Max CTU depth - + Warning options - + Root path: Bas sökväg: - + Warning tags (separated by semicolon) Varnings taggar (separerade med semikolon) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck build dir (whole program analys, incremental analys, statistik, etc) - + Types and Functions - + Libraries Libraries - + Suppressions Suppressions - + Add Lägg till - - + + Addons Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 Y2038 - + Thread safety Tråd säkerhet - + Coding standards Kodstandarder - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Bug hunting - + Clang analyzer Clang analyzer - + Clang-tidy Clang-tidy @@ -2025,82 +1959,93 @@ Options: ProjectFileDialog - + Project file: %1 Projektfil: %1 - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) - + Select Cppcheck build dir Välj Cppcheck build dir - + + C/C++ header + + + + + Include file + + + + Select include directory Välj include sökväg - + Source files - + + All files - + Exclude file - + Select MISRA rule texts file - + MISRA rule texts file (%1) - + Select a directory to check Välj mapp att analysera - + Visual Studio Visual Studio - + Compile database - + Borland C++ Builder 6 - + Import Project Importera Projekt - + Select directory to ignore Välj sökväg att ignorera @@ -2135,7 +2080,7 @@ Options: - + (Not found) @@ -2559,102 +2504,102 @@ Kontrollera att sökvägen och parametrarna är korrekta. ResultsView - + Print Report Skriv ut rapport - + No errors found, nothing to print. Inga fel hittades, inget att skriva ut. - + %p% (%1 of %2 files checked) %p% (%1 av %2 filer analyserade) - - + + Cppcheck Cppcheck - + No errors found. Inga fel hittades. - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. Fel hittades, men de visas ej. För att ställa in vilka fel som skall visas använd visa menyn. - - + + Failed to read the report. Misslyckades att läsa rapporten. - + XML format version 1 is no longer supported. XML format version 1 stöds ej längre. - + First included by Först inkluderad av - + Id Id - + Clear Log - + Copy this Log entry - + Copy complete Log - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. - - + + Failed to save the report. Misslyckades med att spara rapporten. @@ -2960,14 +2905,14 @@ För att ställa in vilka fel som skall visas använd visa menyn. - - + + Statistics Statistik - + Project Projekt @@ -2998,7 +2943,7 @@ För att ställa in vilka fel som skall visas använd visa menyn. - + Previous Scan Föregående analys @@ -3078,103 +3023,103 @@ För att ställa in vilka fel som skall visas använd visa menyn. Pdf Export - + 1 day 1 dag - + %1 days %1 dagar - + 1 hour 1 timme - + %1 hours %1 timmar - + 1 minute 1 minut - + %1 minutes %1 minuter - + 1 second 1 sekund - + %1 seconds %1 sekunder - + 0.%1 seconds 0.%1 sekunder - + and och - + Export PDF Exportera PDF - + Project Settings Projekt inställningar - + Paths Sökvägar - + Include paths Include sökvägar - + Defines Definitioner - + Undefines - + Path selected Vald sökväg - + Number of files scanned Antal analyserade filer - + Scan duration Tid - - + + Errors Fel @@ -3189,32 +3134,32 @@ För att ställa in vilka fel som skall visas använd visa menyn. Ingen Cppcheck build dir - - + + Warnings Varningar - - + + Style warnings Stil varningar - - + + Portability warnings Portabilitetsvarningar - - + + Performance warnings Prestanda varningar - - + + Information messages Informationsmeddelanden diff --git a/gui/cppcheck_zh_CN.ts b/gui/cppcheck_zh_CN.ts index 02477e72e81..952fbcd4d14 100644 --- a/gui/cppcheck_zh_CN.ts +++ b/gui/cppcheck_zh_CN.ts @@ -115,70 +115,6 @@ Parameters: -l(line) (file) 你必须为应用程序指定名称、路径以及可选参数! - - ComplianceReportDialog - - - Compliance Report - - - - - Project name - - - - - Project version - - - - - Coding Standard - - - - - Misra C - - - - - Cert C - - - - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - - HTML files (*.html) - - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - - - FileViewDialog @@ -216,12 +152,12 @@ Parameters: -l(line) (file) 索引 - + Helpfile '%1' was not found 帮助文件 '%1' 未找到 - + Cppcheck Cppcheck @@ -496,20 +432,20 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck @@ -519,281 +455,281 @@ Parameters: -l(line) (file) 文件(&F) - + &View 查看(&V) - + &Toolbars 工具栏(&T) - + &Help 帮助(&H) - + C++ standard C++ 标准 - + &C standard C standard &C 标准 - + &Edit 编辑(&E) - + Standard 标准 - + Categories 分类 - + &License... 许可证(&L)... - + A&uthors... 作者(&U)... - + &About... 关于(&A)... - + &Files... 文件(&F)... - - + + Analyze files Check files 分析文件 - + Ctrl+F Ctrl+F - + &Directory... 目录(&D)... - - + + Analyze directory Check directory 分析目录 - + Ctrl+D Ctrl+D - + Ctrl+R Ctrl+R - + &Stop 停止(&S) - - + + Stop analysis Stop checking 停止分析 - + Esc Esc - + &Save results to file... 保存结果到文件(&S)... - + Ctrl+S Ctrl+S - + &Quit 退出(&Q) - + &Clear results 清空结果(&C) - + &Preferences 首选项(&P) - - + + Show style warnings 显示风格警告 - - - + + + Show errors 显示错误 - - + + Information 信息 - + Show information messages 显示信息消息 - + Show portability warnings 显示可移植性警告 - + Show Cppcheck results 显示 Cppcheck 结果 - + Clang Clang - + Show Clang results 显示 Clang 结果 - + &Filter 滤器(&F) - + Filter results 过滤结果 - + Windows 32-bit ANSI - + Windows 32-bit Unicode - + Unix 32-bit - + Unix 64-bit - + Windows 64-bit - + &Print... 打印(&P)... - + Print the Current Report 打印当前报告 - + Print Pre&view... 打印预览(&v)... - + Open a Print Preview Dialog for the Current Results 打开当前结果的打印预览窗口 - + Open library editor 打开库编辑器 - + C&lose Project File 关闭项目文件(&L) - + &Edit Project File... 编辑项目文件(&E)... - + &Statistics 统计(&S) - - - + + + Show warnings 显示警告 - - + + Show performance warnings 显示性能警告 - + Show &hidden 显示隐藏项(&H) - + &Check all 全部选中(&C) @@ -808,299 +744,299 @@ Parameters: -l(line) (file) 隐藏 - - + + Report - + A&nalyze 分析(&A) - + Filter 滤器 - + &Reanalyze modified files &Recheck modified files 重新分析已修改的文件(&R) - + Reanal&yze all files 重新分析全部文件(&y) - + Ctrl+Q Ctrl+Q - + Style war&nings 风格警告(&n) - + E&rrors 编辑(&r) - + &Uncheck all 全部取消选中(&U) - + Collapse &all 全部折叠(&A) - + &Expand all 全部展开(&E) - + &Standard 标准(&S) - + Standard items 标准项 - + &Contents 内容(&C) - + Open the help contents 打开帮助内容 - + F1 F1 - + Toolbar 工具栏 - + &Categories 分类(&C) - + Error categories 错误分类 - + &Open XML... 打开 XML (&O)... - + Open P&roject File... 打开项目文件(&R)... - + Ctrl+Shift+O Ctrl+Shift+O - + Sh&ow Scratchpad... 显示便条(&o)... - + &New Project File... 新建项目文件(&N)... - + Ctrl+Shift+N Ctrl+Shift+N - + &Log View 日志视图(&L) - + Log View 日志视图 - + &Warnings 警告(&W) - + Per&formance warnings 性能警告(&f) - + &Information 信息(&I) - + &Portability 可移植性(&P) - + P&latforms 平台(&l) - + C++&11 C++&11 - + C&99 C&99 - + &Posix &Posix - + C&11 C&11 - + &C89 &C89 - + &C++03 &C++03 - + &Library Editor... 库编辑器(&L)... - + &Auto-detect language 自动检测语言(&A) - + &Enforce C++ &Enforce C++ - + E&nforce C E&nforce C - + C++14 C++14 - + Reanalyze and check library 重新分析并检查库 - + Check configuration (defines, includes) 检查配置(defines, includes) - + C++17 C++17 - + C++20 C++20 - + Compliance report... - + Normal 常规 - + Misra C - + Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1109,23 +1045,23 @@ This is probably because the settings were changed between the Cppcheck versions 这可能是因为 Cppcheck 不同版本间的设置有所不同。请检查(并修复)编辑器应用程序设置,否则编辑器程序可能不会正确启动。 - + You must close the project file before selecting new files or directories! 在选择新的文件或目录之前,你必须先关闭此项目文件! - - + + Quick Filter: 快速滤器: - + Select configuration 选择配置 - + Found project file: %1 Do you want to load this project file instead? @@ -1134,70 +1070,64 @@ Do you want to load this project file instead? 你是否想加载该项目文件? - + The library '%1' contains unknown elements: %2 库 '%1' 包含未知元素: %2 - + File not found 文件未找到 - + Bad XML 无效的 XML - + Missing attribute 缺失属性 - + Bad attribute value 无效的属性值 - + Unsupported format 不支持的格式 - + Duplicate platform type 重复的平台类型 - + Platform type redefined 平台类型重定义 - + Unknown element 位置元素 - - Unknown element - Unknown issue - 未知问题 - - - + Failed to load the selected library '%1'. %2 选择的库 '%1' 加载失败。 %2 - - - - + + + + Error 错误 @@ -1206,143 +1136,138 @@ Do you want to load this project file instead? 加载 %1 失败。您的 Cppcheck 安装已损坏。您可以在命令行添加 --data-dir=<目录> 参数来指定文件位置。请注意,'--data-dir' 参数应当由安装脚本使用,因此,当使用此参数时,GUI不会启动,所发生的一切只是配置了设置。 - - + + XML files (*.xml) XML 文件(*.xml) - + Open the report file 打开报告文件 - + License 许可证 - + Authors 作者 - + Save the report file 保存报告文件 - + Text files (*.txt) 文本文件(*.txt) - + CSV files (*.csv) CSV 文件(*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Project files (*.cppcheck);;All files(*.*) 项目文件(*.cppcheck);;所有文件(*.*) - + Select Project File 选择项目文件 - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Install - + New version available: %1. %2 - - - - + + + + Project: 项目: - + No suitable files found to analyze! 没有找到合适的文件来分析! - + C/C++ Source C/C++ 源码 - + Compile database Compile database - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze 选择要分析的文件 - + Select directory to analyze 选择要分析的目录 - + Select the configuration that will be analyzed 选择要分析的配置 - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1351,44 +1276,44 @@ Do you want to proceed analysis without using any of these project files? - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1399,7 +1324,7 @@ Do you want to proceed? 你想继续吗? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1408,77 +1333,77 @@ Do you want to stop the analysis and exit Cppcheck? 您想停止分析并退出 Cppcheck 吗? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML 文件 (*.xml);;文本文件 (*.txt);;CSV 文件 (*.csv) - + Build dir '%1' does not exist, create it? 构建文件夹 '%1' 不能存在,创建它吗? - + To check the project using addons, you need a build directory. 要使用插件检查项目,您需要一个构建目录。 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1487,22 +1412,22 @@ Do you want to stop the analysis and exit Cppcheck? 导入 '%1' 失败,分析已停止 - + Project files (*.cppcheck) 项目文件 (*.cppcheck) - + Select Project Filename 选择项目文件名 - + No project file loaded 项目文件未加载 - + The project file %1 @@ -1657,27 +1582,27 @@ Options: 定义必须用分号分隔。例如:DEF1;DEF2=5;DEF3=int - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. 注意:把你自己的 .cfg 文件放在和项目文件相同的文件夹中。你应该在上面看到它们。 - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. 如果添加了标记,您将能够右键单击警告并设置其中一个标记。您可以手动对警告进行分类。 - + Exclude source files 排除源文件 - + Exclude folder... 排除文件夹... - + Exclude file... 排除文件... @@ -1686,17 +1611,17 @@ Options: MISRA C 2012 - + MISRA rule texts MISRA 规则文本 - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>从 MISRA C 2012 PDF 的附录 A &quot;指南摘要&quot; 复制/粘贴文本到一个文本文件。</p></body></html> - + ... ... @@ -1707,8 +1632,7 @@ Options: - - + Browse... 浏览... @@ -1736,15 +1660,15 @@ Options: - + Edit 编辑 - - + + Remove 移除 @@ -1764,124 +1688,134 @@ Options: 包含目录: - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions 类型和函数 - - + + Analysis 分析 - + This is a workfolder that Cppcheck will use for various purposes. 这是一个 Cppcheck 将用于各种目的的工作文件夹。 - + Parser 解析器 - + Cppcheck (built in) Cppcheck (内建) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + Check that each class has a safe public interface 检查每个类是否有一个安全的公共接口 - + Limit analysis 极限分析 - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) 检查未使用模板中的代码(正常情况下应该是打开,但理论上可以忽略未使用模板中的警告) - + Max CTU depth 最大 CTU 深度 - - Premium License - - - - + Enable inline suppressions 启用内联方案 - + 2025 - + Misra C++ - + 2008 - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting - + External tools 外部工具 @@ -1896,129 +1830,129 @@ Options: 向下 - + Platform 平台 - + Clang (experimental) Clang (实验性的) - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. 如果你想要设计你的类尽可能的灵活和健壮,那么公共接口必须非常健壮。Cppcheck 将假设参数可以取 *任何* 值。 - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) 检查头文件中的代码(通常应该是打开的。如果您想要一个有限的快速分析,那么关掉它)) - + Max recursion in template instantiation 模板实例化中的最大递归 - + Warning options 警告选项 - + Root path: 根路径: - + Filepaths in warnings will be relative to this path 警告中的文件路径将相对于此路径 - + Warning tags (separated by semicolon) 警告标志(用分号隔开) - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck 构建目录 (整个程序分析、增量分析、统计数据等) - + Libraries 库 - + Suppressions 抑制 - + Add 添加 - - + + Addons 插件 - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. 注意:插件需要安装 <a href="https://www.python.org/">Python</a>。 - + Y2038 Y2038 - + Thread safety 线程安全 - + Coding standards 编码标准 - + Misra C - + 2012 - - + + 2023 - + Cert C++ - + Bug hunting (Premium) - + Clang analyzer Clang analyzer - + Clang-tidy Clang-tidy @@ -2031,82 +1965,93 @@ Options: ProjectFileDialog - + Project file: %1 项目文件: %1 - + Select Cppcheck build dir 选择 Cppcheck 构建目录 - + Select include directory 选择 Include 目录 - + Select a directory to check 选择一个检查目录 - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) Clang-tidy (未找到) - + Visual Studio Visual Studio - + Compile database Compile database - + Borland C++ Builder 6 Borland C++ Builder 6 - + Import Project 导入项目 - + + C/C++ header + + + + + Include file + + + + Select directory to ignore 选择忽略的目录 - + Source files 源文件 - + + All files 全部文件 - + Exclude file 排除文件 - + Select MISRA rule texts file 选择 MISRA 规则文本文件 - + MISRA rule texts file (%1) MISRA 规则文本文件 (%1) @@ -2139,7 +2084,7 @@ Options: 第%1行:在 "%3" 中缺失的必选属性 "%2" - + (Not found) (未找到) @@ -2583,62 +2528,62 @@ Please check the application path and parameters are correct. 警告详情 - - + + Failed to save the report. 保存报告失败。 - + Print Report 打印报告 - + No errors found, nothing to print. 没有错误发现,没有可打印内容。 - + %p% (%1 of %2 files checked) %p% (%2 个文件已检查 %1 个) - - + + Cppcheck Cppcheck - + No errors found. 未发现错误。 - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. 发现错误,但它们被设为隐藏。 打开“查看”菜单,切换需要显示的错误。 - - + + Failed to read the report. 读取报告失败。 - + XML format version 1 is no longer supported. 不再支持 XML 格式版本 1。 - + First included by 首次包含于 - + Id Id @@ -2647,42 +2592,42 @@ To toggle what kind of errors are shown, open view menu. 错误搜寻分析未完成 - + Clear Log 清空日志 - + Copy this Log entry 复制此日志条目 - + Copy complete Log 复制完整日志 - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. @@ -2968,14 +2913,14 @@ To toggle what kind of errors are shown, open view menu. - - + + Statistics 统计 - + Project 项目 @@ -3006,7 +2951,7 @@ To toggle what kind of errors are shown, open view menu. - + Previous Scan 上一次扫描 @@ -3086,103 +3031,103 @@ To toggle what kind of errors are shown, open view menu. 导出 PDF - + 1 day 1 天 - + %1 days %1 天 - + 1 hour 1 小时 - + %1 hours %1 小时 - + 1 minute 1 分钟 - + %1 minutes %1 分钟 - + 1 second 1 秒 - + %1 seconds %1 秒 - + 0.%1 seconds 0.%1 秒 - + and 与 - + Export PDF 导出 PDF - + Project Settings 项目设置 - + Paths 路径 - + Include paths 包含路径 - + Defines 定义 - + Undefines 未定义 - + Path selected 选中的路径 - + Number of files scanned 扫描的文件数 - + Scan duration 扫描时间 - - + + Errors 错误 @@ -3197,32 +3142,32 @@ To toggle what kind of errors are shown, open view menu. 没有 cppcheck 构建目录 - - + + Warnings 警告 - - + + Style warnings 风格警告 - - + + Portability warnings 移植可能性警告 - - + + Performance warnings 性能警告 - - + + Information messages 信息 diff --git a/gui/cppcheck_zh_TW.ts b/gui/cppcheck_zh_TW.ts index 644e92e7b49..1de96423481 100644 --- a/gui/cppcheck_zh_TW.ts +++ b/gui/cppcheck_zh_TW.ts @@ -108,65 +108,16 @@ Parameters: -l(line) (file) ComplianceReportDialog - - Compliance Report - - - - Project name - 專案名稱 + 專案名稱 - Project version - 專案版本 - - - - Coding Standard - - - - - Misra C - - - - - Cert C - + 專案版本 - - Cert C++ - - - - - List of files with md5 checksums - - - - - Compliance report - - - - HTML files (*.html) - HTML 檔案 (*.html) - - - - - Save compliance report - - - - - Failed to import '%1' (%2), can not show files in compliance report - + HTML 檔案 (*.html) @@ -206,12 +157,12 @@ Parameters: -l(line) (file) 索引 - + Helpfile '%1' was not found 找不到幫助檔 '%1' - + Cppcheck Cppcheck @@ -474,20 +425,20 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - + + + + + + + + + + - - - - + + + Cppcheck Cppcheck @@ -507,563 +458,563 @@ Parameters: -l(line) (file) 檔案(&F) - + &View 檢視(&V) - + &Toolbars 工具條(&T) - - + + Report - + &Help 幫助(&H) - + A&nalyze 分析(&N) - + C++ standard C++ 標準 - + &C standard C 標準(&C) - + &Edit 編輯(&E) - + Standard 標準 - + Categories 分類 - + Filter 篩選 - + &License... 授權(&L)... - + A&uthors... 作者(&U)... - + &About... 關於(&A)... - + &Files... 檔案(&F)... - - + + Analyze files 分析檔案 - + Ctrl+F Ctrl+F - + &Directory... 目錄(&D)... - - + + Analyze directory 分析目錄 - + Ctrl+D Ctrl+D - + &Reanalyze modified files 重新分析已修改的檔案(&R) - + Ctrl+R Ctrl+R - + Reanal&yze all files 重新分析所有檔案(&Y) - + &Stop 停止(&S) - - + + Stop analysis 停止分析 - + Esc Esc - + &Save results to file... 儲存結果為檔案(&S)... - + Ctrl+S Ctrl+S - + &Quit 退出(&Q) - + Ctrl+Q Ctrl+Q - + &Clear results 清除結果(&C) - + &Preferences 偏好設定(&P) - + Style war&nings 樣式警告(&N) - - + + Show style warnings 顯示樣式警告 - + E&rrors 錯誤(&R) - - - + + + Show errors 顯示錯誤 - + &Check all 全部檢查(&C) - + &Uncheck all - + Collapse &all 全部摺疊(&A) - + &Expand all 全部展開(&E) - + &Standard 標準(&S) - + Standard items 標準項目 - + &Contents 內容(&C) - + Open the help contents 開啟幫助內容 - + F1 F1 - + Toolbar 工具條 - + &Categories 分類(&C) - + Error categories 錯誤分類 - + &Open XML... 開啟 XML(&O)... - + Open P&roject File... 開啟專案檔(&R)... - + Ctrl+Shift+O Ctrl+Shift+O - + Sh&ow Scratchpad... - + &New Project File... 新增專案檔(&N)... - + Ctrl+Shift+N Ctrl+Shift+N - + &Log View 日誌檢視(&L) - + Log View 日誌檢視 - + C&lose Project File 關閉專案檔(&L) - + &Edit Project File... 編輯專案檔(&E)... - + &Statistics 統計資料(&S) - + &Warnings 警告(&W) - - - + + + Show warnings 顯示警告 - + Per&formance warnings 效能警告(&F) - - + + Show performance warnings 顯示下效能警告 - + Show &hidden 顯示隱藏項目(&H) - + &Information 資訊(&I) - + Show information messages 顯示資訊訊息 - + &Portability 可移植性(&P) - + Show portability warnings 顯示可移植性警告 - + Show Cppcheck results 顯示 Cppcheck 結果 - + Clang Clang - + Show Clang results 顯示 Clang 結果 - + &Filter 篩選(&F) - + Filter results 篩選結果 - + Windows 32-bit ANSI Windows 32 位元 ANSI - + Windows 32-bit Unicode Windows 32 位元 Unicode - + Unix 32-bit Unix 32 位元 - + Unix 64-bit Unix 64 位元 - + Windows 64-bit Windows 64 位元 - + P&latforms 平臺(&L) - + C++&11 C++&11 - + C&99 C&99 - + &Posix - + C&11 C&11 - + &C89 &C89 - + &C++03 &C++03 - + &Print... 列印(&P)... - + Print the Current Report 列印當前報告 - + Print Pre&view... 列印預覽(&V)... - + Open a Print Preview Dialog for the Current Results 開啟當前結果的列印預覽視窗 - + &Library Editor... 程式庫編輯器(&L)... - + Open library editor 開啟程式庫編輯器 - + &Auto-detect language 自動偵測語言(&A) - + &Enforce C++ - + E&nforce C - + C++14 C++14 - + Reanalyze and check library 重新分析並檢查程式庫 - + Check configuration (defines, includes) 檢查組態 (定義、包含) - + C++17 C++17 - + C++20 C++20 - + Compliance report... - + Normal - + Misra C - + Misra C++ 2008 Misra C++ 2008 - + Cert C - + Cert C++ - + Misra C++ 2023 Misra C++ 2023 - + Autosar - + EULA... - + Thread Details - + Show thread details @@ -1091,202 +1042,196 @@ Options: Cppcheck GUI - 命令行參數 - - + + Quick Filter: 快速篩選: - - - - + + + + Project: 專案: - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + No suitable files found to analyze! 找不到適合的檔案來分析! - + You must close the project file before selecting new files or directories! 您必須在選取新檔案或目錄之前關閉該專案檔! - + C/C++ Source C/C++ 來源檔 - + Compile database 編譯資料庫 - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze 選取要分析的檔案 - + Select directory to analyze 選取要分析的目錄 - + Select configuration 選取組態 - + Select the configuration that will be analyzed 選取要分析的組態 - + Found project file: %1 Do you want to load this project file instead? - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - - + + Information 資訊 - + The library '%1' contains unknown elements: %2 - + File not found 找不到檔案 - + Bad XML - + Missing attribute - + Bad attribute value - + Unsupported format 未支援的格式 - + Duplicate platform type 重複的平臺型別 - + Platform type redefined 平臺型別重定義 - + Duplicate define - + Unknown element 未知的元素 - - Unknown element - Unknown issue - 未知的議題 - - - + Failed to load the selected library '%1'. %2 無法載入選取的程式庫 '%1'。 %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - - - - + + + + Error 錯誤 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1294,18 +1239,18 @@ Do you want to proceed? - - + + XML files (*.xml) XML 檔案 (*.xml) - + Open the report file 開啟報告檔 - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1314,82 +1259,77 @@ Do you want to stop the analysis and exit Cppcheck? 您想停止分析並離開 Cppcheck 嗎? - + About 關於 - + License 授權 - + Authors 作者 - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML 檔案 (*.xml);;文字檔 (*.txt);;CSV 檔案 (*.csv) - + Save the report file 儲存報告檔 - + Text files (*.txt) 文字檔 (*.txt) - + CSV files (*.csv) CSV 檔案 (*.csv) - - Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. - - - - + Project files (*.cppcheck);;All files(*.*) 專案檔 (*.cppcheck);;所有檔案 (*.*) - + Select Project File 選取專案檔 - + Build dir '%1' does not exist, create it? 建置目錄 '%1' 不存在,是否建立它? - + To check the project using addons, you need a build directory. - + Failed to open file 無法開啟檔案 - + Unknown project file format 未知的專案檔格式 - + Failed to import project file 無法匯入專案檔 - + Failed to import '%1': %2 Analysis is stopped. @@ -1398,62 +1338,62 @@ Analysis is stopped. 停止分析。 - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1462,22 +1402,22 @@ Analysis is stopped. 無法匯入 '%1',停止分析 - + Project files (*.cppcheck) 專案檔 (*.cppcheck) - + Select Project Filename 選取專案檔案名稱 - + No project file loaded - + The project file %1 @@ -1494,12 +1434,12 @@ Do you want to remove the file from the recently used projects -list? 您要從最近使用的專案列表中移除該檔案嗎? - + Install 安章 - + New version available: %1. %2 可用的新版本: %1. %2 @@ -1589,8 +1529,7 @@ Do you want to remove the file from the recently used projects -list? - - + Browse... 瀏覽... @@ -1623,15 +1562,15 @@ Do you want to remove the file from the recently used projects -list? - + Edit 編輯 - - + + Remove 移除 @@ -1671,225 +1610,235 @@ Do you want to remove the file from the recently used projects -list? - + + Include file + + + + + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + + + + + Browse.. + + + + Types and Functions 型別與函式 - + Platform 平臺 - + Libraries 程式庫 - + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. - - + + Analysis 分析 - + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) - + This is a workfolder that Cppcheck will use for various purposes. - + Parser 剖析器 - + Cppcheck (built in) Cppcheck (內建) - + Clang (experimental) - + Check level - + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. - + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). - + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. - + Check that each class has a safe public interface - + Limit analysis - + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) - + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) - + Max CTU depth - + Max recursion in template instantiation - - Premium License - - - - + Warning options 警告選項 - + Root path: 根路徑: - + Filepaths in warnings will be relative to this path - + Warning tags (separated by semicolon) 警告標記 (由分號分隔) - + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. - + Exclude source files 排除來源檔 - + Exclude folder... 排除資料夾... - + Exclude file... 排除檔案... - + Suppressions 抑制 - + Add 新增 - + Enable inline suppressions - - + + Addons - + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. - + Y2038 Y2038 - + Thread safety 執行緒安全 - + Coding standards - + Misra C - + 2012 - - + + 2023 - + 2025 - + Misra C++ - + 2008 @@ -1898,17 +1847,17 @@ Do you want to remove the file from the recently used projects -list? Misra C 2012 - + MISRA rule texts - + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> - + ... ... @@ -1917,52 +1866,52 @@ Do you want to remove the file from the recently used projects -list? Misra C++ 2008 - + Cert C - + CERT-INT35-C: int precision (if size equals precision, you can leave empty) - + Cert C++ - + Autosar - + Safety profiles (defined in C++ core guidelines) - + Bug hunting (Premium) - + Bug hunting - + External tools 外部工具 - + Clang-tidy Clang-tidy - + Clang analyzer Clang 分析器 @@ -1970,82 +1919,93 @@ Do you want to remove the file from the recently used projects -list? ProjectFileDialog - + Project file: %1 專案檔: %1 - + Note: Open source Cppcheck does not fully implement Misra C 2012 - + Clang-tidy (not found) Clang-tidy (找不到) - + Select Cppcheck build dir 選取 Cppcheck 建置目錄 - + Visual Studio Visual Studio - + Compile database 編譯資料庫 - + Borland C++ Builder 6 Borland C++ Builder 6 - + Import Project 匯入專案 - + + C/C++ header + + + + + Include file + + + + Select a directory to check 選取要檢查的目錄 - + Select include directory 選取包含目錄 - + Select directory to ignore 選取要忽略的目錄 - + Source files 來源檔 - + + All files 所有檔案 - + Exclude file 排除檔案 - + Select MISRA rule texts file 選取 MISRA 規則文字檔 - + MISRA rule texts file (%1) MISRA 規則文字檔 (%1) @@ -2198,7 +2158,7 @@ Do you want to remove the file from the recently used projects -list? - + (Not found) (找不到) @@ -2498,101 +2458,101 @@ Please check the application path and parameters are correct. 警告詳細資訊 - - + + Failed to save the report. 無法載入報告。 - + Print Report 列印報告 - + No errors found, nothing to print. - + %p% (%1 of %2 files checked) - - + + Cppcheck Cppcheck - + No errors found. 找不到錯誤。 - + Errors were found, but they are configured to be hidden. To toggle what kind of errors are shown, open view menu. - - + + Failed to read the report. 無法讀取報告。 - + XML format version 1 is no longer supported. 不再支援 XML 格式版本 1。 - + First included by - + Id 識別號 - + Clear Log 清除日誌 - + Copy this Log entry 複製該日誌條目 - + Copy complete Log 複製完整的日誌 - + Analysis was stopped - + There was a critical error with id '%1' - + when checking %1 - + when checking a file - + Analysis was aborted. @@ -2869,14 +2829,14 @@ To toggle what kind of errors are shown, open view menu. - - + + Statistics 統計資料 - + Project 專案 @@ -2907,7 +2867,7 @@ To toggle what kind of errors are shown, open view menu. - + Previous Scan 上一次掃描 @@ -2997,133 +2957,133 @@ To toggle what kind of errors are shown, open view menu. 沒有 cppcheck 建置目錄 - + 1 day 1 天 - + %1 days %1 天 - + 1 hour 1 小時 - + %1 hours %1 小時 - + 1 minute 1 分鐘 - + %1 minutes %1 分鐘 - + 1 second 1 秒鐘 - + %1 seconds %1 秒鐘 - + 0.%1 seconds 0.%1 秒鐘 - + and - - + + Errors 錯誤 - - + + Warnings 警告 - - + + Style warnings 樣式警告 - - + + Portability warnings 可移植性警告 - - + + Performance warnings 效能警告 - - + + Information messages 資訊訊息 - + Export PDF 匯出 PDF - + Project Settings 專案設定 - + Paths 路徑 - + Include paths 包含路徑 - + Defines 定義 - + Undefines 未定義 - + Path selected 選取的路徑 - + Number of files scanned 已掃描的檔案數量 - + Scan duration 掃描時間 From 9a97ccf697e1bac605ca648f50b62a04dd52bde4 Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Tue, 2 Jun 2026 10:06:51 +0200 Subject: [PATCH 144/493] fixed #14746 import project: include path in compile_commands.json not handled well (#8591) --- lib/importproject.cpp | 6 ++++-- lib/importproject.h | 2 +- test/testimportproject.cpp | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 96e8b98f2e8..0bcda5a43bf 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1699,8 +1699,10 @@ void ImportProject::setRelativePaths(const std::string &filename) const std::vector basePaths{Path::fromNativeSeparators(Path::getCurrentPath())}; for (auto &fs: fileSettings) { fs.file.setPath(Path::getRelativePath(fs.filename(), basePaths)); - for (auto &includePath: fs.includePaths) - includePath = Path::getRelativePath(includePath, basePaths); + for (auto &includePath: fs.includePaths) { + const std::string rel = Path::getRelativePath(includePath, basePaths); + includePath = rel.empty() ? "." : rel; + } } } diff --git a/lib/importproject.h b/lib/importproject.h index 608af552408..b8bbbed3fa3 100644 --- a/lib/importproject.h +++ b/lib/importproject.h @@ -110,6 +110,7 @@ class CPPCHECKLIB WARN_UNUSED ImportProject { bool importCompileCommands(std::istream &istr); bool importCppcheckGuiProject(std::istream &istr, Settings &settings, Suppressions &supprs); static std::string collectArgs(const std::string &cmd, std::vector &args); + void setRelativePaths(const std::string &filename); struct SharedItemsProject { bool successful = false; @@ -123,7 +124,6 @@ class CPPCHECKLIB WARN_UNUSED ImportProject { private: static void parseArgs(FileSettings &fs, const std::vector &args); - void setRelativePaths(const std::string &filename); bool importSln(std::istream &istr, const std::string &path, const std::vector &fileFilters); bool importSlnx(const std::string& filename, const std::vector& fileFilters); diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index 6f8633dbeea..88ca2fe75b7 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -42,6 +42,7 @@ class TestImporter final : public ImportProject { using ImportProject::collectArgs; using ImportProject::fsSetDefines; using ImportProject::fsSetIncludePaths; + using ImportProject::setRelativePaths; }; @@ -56,6 +57,7 @@ class TestImportProject : public TestFixture { TEST_CASE(setIncludePaths1); TEST_CASE(setIncludePaths2); TEST_CASE(setIncludePaths3); // macro names are case insensitive + TEST_CASE(setRelativePathsInclude); // #14746 TEST_CASE(importCompileCommands1); TEST_CASE(importCompileCommands2); // #8563, #9567 TEST_CASE(importCompileCommands3); // check with existing trailing / in directory @@ -134,6 +136,18 @@ class TestImportProject : public TestFixture { ASSERT_EQUALS("c:/abc/other/", fs.includePaths.front()); } + void setRelativePathsInclude() const { + const std::string cwd = Path::fromNativeSeparators(Path::getCurrentPath()); + TestImporter importer; + FileSettings fs{cwd + "/sub/a.c", Standards::Language::C, 0}; + fs.includePaths.push_back(cwd + "/"); + importer.fileSettings.push_back(fs); + importer.setRelativePaths("compile_commands.json"); + fs = importer.fileSettings.front(); + ASSERT_EQUALS(".", fs.includePaths.front()); + ASSERT_EQUALS("sub/a.c", fs.filename()); + } + void importCompileCommands1() const { REDIRECT; constexpr char json[] = R"([{ From 868451412c802b6df1b3f9516f240ccbf4d00716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 2 Jun 2026 12:07:53 +0200 Subject: [PATCH 145/493] pass `ErrorLogger` by reference in `Check`/`CheckImpl` (#8601) --- lib/check.h | 4 ++-- lib/check64bit.cpp | 4 ++-- lib/check64bit.h | 6 ++--- lib/checkassert.cpp | 4 ++-- lib/checkassert.h | 6 ++--- lib/checkautovariables.cpp | 4 ++-- lib/checkautovariables.h | 6 ++--- lib/checkbool.cpp | 4 ++-- lib/checkbool.h | 6 ++--- lib/checkbufferoverrun.cpp | 6 ++--- lib/checkbufferoverrun.h | 6 ++--- lib/checkclass.cpp | 8 +++---- lib/checkclass.h | 6 ++--- lib/checkcondition.cpp | 4 ++-- lib/checkcondition.h | 6 ++--- lib/checkexceptionsafety.cpp | 4 ++-- lib/checkexceptionsafety.h | 6 ++--- lib/checkfunctions.cpp | 4 ++-- lib/checkfunctions.h | 6 ++--- lib/checkimpl.cpp | 9 ++------ lib/checkimpl.h | 4 ++-- lib/checkinternal.cpp | 4 ++-- lib/checkinternal.h | 6 ++--- lib/checkio.cpp | 4 ++-- lib/checkio.h | 6 ++--- lib/checkleakautovar.cpp | 4 ++-- lib/checkleakautovar.h | 6 ++--- lib/checkmemoryleak.cpp | 23 +++++++++---------- lib/checkmemoryleak.h | 26 +++++++++++----------- lib/checknullpointer.cpp | 6 ++--- lib/checknullpointer.h | 6 ++--- lib/checkother.cpp | 4 ++-- lib/checkother.h | 6 ++--- lib/checkpostfixoperator.cpp | 4 ++-- lib/checkpostfixoperator.h | 6 ++--- lib/checksizeof.cpp | 4 ++-- lib/checksizeof.h | 6 ++--- lib/checkstl.cpp | 4 ++-- lib/checkstl.h | 6 ++--- lib/checkstring.cpp | 4 ++-- lib/checkstring.h | 6 ++--- lib/checktype.cpp | 4 ++-- lib/checktype.h | 6 ++--- lib/checkuninitvar.cpp | 6 ++--- lib/checkuninitvar.h | 6 ++--- lib/checkunusedvar.cpp | 4 ++-- lib/checkunusedvar.h | 6 ++--- lib/checkvaarg.cpp | 4 ++-- lib/checkvaarg.h | 6 ++--- lib/cppcheck.cpp | 4 ++-- test/fixture.h | 2 +- test/test64bit.cpp | 2 +- test/testassert.cpp | 2 +- test/testautovariables.cpp | 2 +- test/testbool.cpp | 2 +- test/testbufferoverrun.cpp | 8 +++---- test/testcharvar.cpp | 2 +- test/testclass.cpp | 38 ++++++++++++++++---------------- test/testcondition.cpp | 6 ++--- test/testconstructors.cpp | 2 +- test/testexceptionsafety.cpp | 2 +- test/testfunctions.cpp | 2 +- test/testgarbage.cpp | 2 +- test/testincompletestatement.cpp | 2 +- test/testinternal.cpp | 2 +- test/testio.cpp | 4 ++-- test/testleakautovar.cpp | 10 ++++----- test/testmemleak.cpp | 12 +++++----- test/testnullpointer.cpp | 4 ++-- test/testother.cpp | 12 +++++----- test/testpostfixoperator.cpp | 2 +- test/testsizeof.cpp | 4 ++-- test/teststl.cpp | 6 ++--- test/teststring.cpp | 2 +- test/testtype.cpp | 6 ++--- test/testuninitvar.cpp | 6 ++--- test/testunusedprivfunc.cpp | 2 +- test/testunusedvar.cpp | 8 +++---- test/testvaarg.cpp | 2 +- 79 files changed, 224 insertions(+), 232 deletions(-) diff --git a/lib/check.h b/lib/check.h index 7deab9e52e7..8dda3e41825 100644 --- a/lib/check.h +++ b/lib/check.h @@ -62,10 +62,10 @@ class CPPCHECKLIB Check { Check& operator=(const Check &) = delete; /** run checks, the token list is not simplified */ - virtual void runChecks(const Tokenizer &, ErrorLogger *) = 0; + virtual void runChecks(const Tokenizer &, ErrorLogger&) = 0; /** get error messages */ - virtual void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const = 0; + virtual void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const = 0; /** class name, used to generate documentation */ const std::string& name() const { diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index 6c45c68aaeb..345d66d9846 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -183,13 +183,13 @@ void Check64BitPortabilityImpl::returnIntegerError(const Token *tok) "The safe way is to always return a pointer.", CWE758, Certainty::normal); } -void Check64BitPortability::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void Check64BitPortability::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { Check64BitPortabilityImpl check64BitPortability(&tokenizer, tokenizer.getSettings(), errorLogger); check64BitPortability.pointerassignment(); } -void Check64BitPortability::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void Check64BitPortability::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { Check64BitPortabilityImpl c(nullptr, settings, errorLogger); c.assignmentAddressToIntegerError(nullptr); diff --git a/lib/check64bit.h b/lib/check64bit.h index bafb5646aaa..4354d2217ba 100644 --- a/lib/check64bit.h +++ b/lib/check64bit.h @@ -49,9 +49,9 @@ class CPPCHECKLIB Check64BitPortability : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check if there is 64-bit portability issues:\n" @@ -63,7 +63,7 @@ class CPPCHECKLIB Check64BitPortability : public Check { class CPPCHECKLIB Check64BitPortabilityImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - Check64BitPortabilityImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + Check64BitPortabilityImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Check for pointer assignment */ diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index 8240304d83f..1d0ecde7959 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -178,13 +178,13 @@ bool CheckAssertImpl::inSameScope(const Token* returnTok, const Token* assignTok return returnTok->scope() == assignTok->scope(); } -void CheckAssert::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckAssert::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckAssertImpl checkAssert(&tokenizer, tokenizer.getSettings(), errorLogger); checkAssert.assertWithSideEffects(); } -void CheckAssert::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckAssert::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckAssertImpl c(nullptr, settings, errorLogger); c.sideEffectInAssertError(nullptr, "function"); diff --git a/lib/checkassert.h b/lib/checkassert.h index f6190bb8d25..2db9d804fcb 100644 --- a/lib/checkassert.h +++ b/lib/checkassert.h @@ -47,8 +47,8 @@ class CPPCHECKLIB CheckAssert : public Check { private: /** run checks, the token list is not simplified */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).\n"; @@ -57,7 +57,7 @@ class CPPCHECKLIB CheckAssert : public Check { class CPPCHECKLIB CheckAssertImpl : public CheckImpl { public: - CheckAssertImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckAssertImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} void assertWithSideEffects(); diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 48ca74253a5..0493f3ea459 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -817,7 +817,7 @@ void CheckAutoVariablesImpl::errorInvalidDeallocation(const Token *tok, const Va "that has been allocated dynamically.", CWE590, Certainty::normal); } -void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckAutoVariablesImpl checkAutoVariables(&tokenizer, tokenizer.getSettings(), errorLogger); checkAutoVariables.assignFunctionArg(); @@ -825,7 +825,7 @@ void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger *erro checkAutoVariables.checkVarLifetime(); } -void CheckAutoVariables::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckAutoVariables::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckAutoVariablesImpl c(nullptr,settings,errorLogger); c.errorAutoVariableAssignment(nullptr, false); diff --git a/lib/checkautovariables.h b/lib/checkautovariables.h index 4bdbfc4c730..23d7a55a488 100644 --- a/lib/checkautovariables.h +++ b/lib/checkautovariables.h @@ -52,9 +52,9 @@ class CPPCHECKLIB CheckAutoVariables : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "A pointer to a variable is only valid as long as the variable is in scope.\n" @@ -72,7 +72,7 @@ class CPPCHECKLIB CheckAutoVariablesImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckAutoVariablesImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckAutoVariablesImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** assign function argument */ diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index 0d7516a9418..3d36c9936a1 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -512,7 +512,7 @@ void CheckBoolImpl::returnValueBoolError(const Token *tok) reportError(tok, Severity::style, "returnNonBoolInBooleanFunction", "Non-boolean value returned from function returning bool"); } -void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckBoolImpl checkBool(&tokenizer, tokenizer.getSettings(), errorLogger); @@ -529,7 +529,7 @@ void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkBool.checkBitwiseOnBoolean(); } -void CheckBool::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckBool::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckBoolImpl c(nullptr, settings, errorLogger); c.assignBoolToPointerError(nullptr); diff --git a/lib/checkbool.h b/lib/checkbool.h index 5eafc4d692d..53cc19c2486 100644 --- a/lib/checkbool.h +++ b/lib/checkbool.h @@ -46,9 +46,9 @@ class CPPCHECKLIB CheckBool : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Boolean type checks\n" @@ -67,7 +67,7 @@ class CPPCHECKLIB CheckBoolImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckBoolImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckBoolImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for comparison of function returning bool*/ diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 7f0612963b9..9beef9c3079 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -990,7 +990,7 @@ Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLEle /** @brief Analyse all file infos for all TU */ bool CheckBufferOverrun::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) { - CheckBufferOverrunImpl dummy(nullptr, settings, &errorLogger); + CheckBufferOverrunImpl dummy(nullptr, settings, errorLogger); dummy. logChecker("CheckBufferOverrun::analyseWholeProgram"); @@ -1214,7 +1214,7 @@ void CheckBufferOverrunImpl::negativeMemoryAllocationSizeError(const Token* tok, msg, CWE131, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckBufferOverrun::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckBufferOverrun::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckBufferOverrunImpl checkBufferOverrun(&tokenizer, tokenizer.getSettings(), errorLogger); checkBufferOverrun.arrayIndex(); @@ -1227,7 +1227,7 @@ void CheckBufferOverrun::runChecks(const Tokenizer &tokenizer, ErrorLogger *erro checkBufferOverrun.negativeArraySize(); } -void CheckBufferOverrun::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckBufferOverrun::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckBufferOverrunImpl c(nullptr, settings, errorLogger); c.arrayIndexError(nullptr, std::vector(), std::vector()); diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index b71f4520d48..566ed76bd85 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -64,7 +64,7 @@ class CPPCHECKLIB CheckBufferOverrun : public Check { CheckBufferOverrun() : Check("Bounds checking") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** @brief Parse current TU and extract file info */ Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; @@ -72,7 +72,7 @@ class CPPCHECKLIB CheckBufferOverrun : public Check { /** @brief Analyse all file infos for all TU */ bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; @@ -96,7 +96,7 @@ class CPPCHECKLIB CheckBufferOverrunImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckBufferOverrunImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckBufferOverrunImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} void arrayIndex(); diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index d7eb9b43b35..e917c95191e 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -106,7 +106,7 @@ static bool isVclTypeInit(const Type *type) } //--------------------------------------------------------------------------- -CheckClassImpl::CheckClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) +CheckClassImpl::CheckClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger), mSymbolDatabase(tokenizer?tokenizer->getSymbolDatabase():nullptr) {} @@ -3833,7 +3833,7 @@ bool CheckClass::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check the code for each class.\n" @@ -100,7 +100,7 @@ class CPPCHECKLIB CheckClass : public Check { class CPPCHECKLIB CheckClassImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger); + CheckClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger); /** @brief Set of the STL types whose operator[] is not const */ static const std::set stl_containers_not_const; diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 365a677b5cb..72b61fd68b9 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -2095,7 +2095,7 @@ void CheckConditionImpl::compareValueOutOfTypeRangeError(const Token *comparison Certainty::normal); } -void CheckCondition::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckCondition::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckConditionImpl checkCondition(&tokenizer, tokenizer.getSettings(), errorLogger); checkCondition.multiCondition(); @@ -2115,7 +2115,7 @@ void CheckCondition::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLog checkCondition.alwaysTrueFalse(); } -void CheckCondition::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckCondition::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckConditionImpl c(nullptr, settings, errorLogger); diff --git a/lib/checkcondition.h b/lib/checkcondition.h index 56d2c6f25e0..232b2b5b340 100644 --- a/lib/checkcondition.h +++ b/lib/checkcondition.h @@ -54,9 +54,9 @@ class CPPCHECKLIB CheckCondition : public Check { CheckCondition() : Check("Condition") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Match conditions with assignments and other conditions:\n" @@ -81,7 +81,7 @@ class CPPCHECKLIB CheckCondition : public Check { class CPPCHECKLIB CheckConditionImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckConditionImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckConditionImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** mismatching assignment / comparison */ diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index b0c510ed80a..29342fb4dbc 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -409,7 +409,7 @@ void CheckExceptionSafetyImpl::rethrowNoCurrentExceptionError(const Token *tok) CWE480, Certainty::normal); } -void CheckExceptionSafety::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckExceptionSafety::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { if (tokenizer.isC()) return; @@ -424,7 +424,7 @@ void CheckExceptionSafety::runChecks(const Tokenizer &tokenizer, ErrorLogger *er checkExceptionSafety.rethrowNoCurrentException(); } -void CheckExceptionSafety::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckExceptionSafety::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckExceptionSafetyImpl c(nullptr, settings, errorLogger); c.destructorsError(nullptr, "Class"); diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index 7de91ba812c..8b52d773a93 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -50,10 +50,10 @@ class CPPCHECKLIB CheckExceptionSafety : public Check { CheckExceptionSafety() : Check("Exception Safety") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** Generate all possible errors (for --errorlist) */ - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; /** wiki formatted description of the class (for --doc) */ std::string classInfo() const override { @@ -71,7 +71,7 @@ class CPPCHECKLIB CheckExceptionSafety : public Check { class CPPCHECKLIB CheckExceptionSafetyImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckExceptionSafetyImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckExceptionSafetyImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Don't throw exceptions in destructors */ diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index db50846b262..d04f9d9cc1d 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -853,7 +853,7 @@ void CheckFunctionsImpl::useStandardLibraryError(const Token *tok, const std::st "Consider using " + expected + " instead of loop."); } -void CheckFunctions::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckFunctions::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckFunctionsImpl checkFunctions(&tokenizer, tokenizer.getSettings(), errorLogger); @@ -872,7 +872,7 @@ void CheckFunctions::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLog checkFunctions.useStandardLibrary(); } -void CheckFunctions::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckFunctions::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckFunctionsImpl c(nullptr, settings, errorLogger); diff --git a/lib/checkfunctions.h b/lib/checkfunctions.h index 42281774482..ea7278bf0c8 100644 --- a/lib/checkfunctions.h +++ b/lib/checkfunctions.h @@ -52,9 +52,9 @@ class CPPCHECKLIB CheckFunctions : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check function usage:\n" @@ -73,7 +73,7 @@ class CPPCHECKLIB CheckFunctions : public Check { class CPPCHECKLIB CheckFunctionsImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckFunctionsImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckFunctionsImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Check for functions that should not be used */ diff --git a/lib/checkimpl.cpp b/lib/checkimpl.cpp index 2b28b829277..fb1c71a66b3 100644 --- a/lib/checkimpl.cpp +++ b/lib/checkimpl.cpp @@ -24,25 +24,20 @@ #include "tokenize.h" #include "vfvalue.h" -#include #include void CheckImpl::reportError(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty) { - assert(mErrorLogger); - // TODO: report debug warning when error is for a disabled severity const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty); - mErrorLogger->reportErr(errmsg); + mErrorLogger.reportErr(errmsg); } void CheckImpl::reportError(ErrorPath errorPath, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty) { - assert(mErrorLogger); - // TODO: report debug warning when error is for a disabled severity const ErrorMessage errmsg(std::move(errorPath), mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty); - mErrorLogger->reportErr(errmsg); + mErrorLogger.reportErr(errmsg); } bool CheckImpl::wrongData(const Token *tok, const char *str) diff --git a/lib/checkimpl.h b/lib/checkimpl.h index 36f04a23d1f..17f92da8553 100644 --- a/lib/checkimpl.h +++ b/lib/checkimpl.h @@ -37,7 +37,7 @@ class CPPCHECKLIB CheckImpl { protected: /** This constructor is used when running checks. */ - CheckImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger) {} public: @@ -47,7 +47,7 @@ class CPPCHECKLIB CheckImpl protected: const Tokenizer* const mTokenizer{}; const Settings& mSettings; - ErrorLogger* const mErrorLogger{}; + ErrorLogger& mErrorLogger; /** report an error */ void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg) { diff --git a/lib/checkinternal.cpp b/lib/checkinternal.cpp index 727df306e63..93b10210404 100644 --- a/lib/checkinternal.cpp +++ b/lib/checkinternal.cpp @@ -377,7 +377,7 @@ void CheckInternalImpl::extraWhitespaceError(const Token* tok, const std::string ); } -void CheckInternal::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckInternal::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { if (!tokenizer.getSettings().checks.isEnabled(Checks::internalCheck)) return; @@ -393,7 +393,7 @@ void CheckInternal::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogg checkInternal.checkRedundantTokCheck(); } -void CheckInternal::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckInternal::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckInternalImpl c(nullptr, settings, errorLogger); c.simplePatternError(nullptr, "class {", "Match"); diff --git a/lib/checkinternal.h b/lib/checkinternal.h index c1e5addc4da..18a1535a73f 100644 --- a/lib/checkinternal.h +++ b/lib/checkinternal.h @@ -46,9 +46,9 @@ class CPPCHECKLIB CheckInternal : public Check { CheckInternal() : Check("cppcheck internal API usage") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { // Don't include these checks on the WIKI where people can read what @@ -60,7 +60,7 @@ class CPPCHECKLIB CheckInternal : public Check { class CPPCHECKLIB CheckInternalImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckInternalImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckInternalImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check if a simple pattern is used inside Token::Match or Token::findmatch */ diff --git a/lib/checkio.cpp b/lib/checkio.cpp index a62955d3017..8012d540898 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -2050,7 +2050,7 @@ void CheckIOImpl::invalidScanfFormatWidthError(const Token* tok, nonneg int numF } } -void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckIOImpl checkIO(&tokenizer, tokenizer.getSettings(), errorLogger); @@ -2060,7 +2060,7 @@ void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkIO.invalidScanf(); } -void CheckIO::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckIO::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckIOImpl c(nullptr, settings, errorLogger); c.coutCerrMisusageError(nullptr, "cout"); diff --git a/lib/checkio.h b/lib/checkio.h index e881e22cbf3..6fb3c9f80c2 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -50,9 +50,9 @@ class CPPCHECKLIB CheckIO : public Check { private: /** @brief Run checks on the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check format string input/output operations.\n" @@ -72,7 +72,7 @@ class CPPCHECKLIB CheckIO : public Check { class CPPCHECKLIB CheckIOImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckIOImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckIOImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for missusage of std::cout */ diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 11d1086ee5d..2fd16e85eaa 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -1278,13 +1278,13 @@ void CheckLeakAutoVarImpl::ret(const Token *tok, VarInfo &varInfo, const bool is varInfo.erase(varId); } -void CheckLeakAutoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckLeakAutoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckLeakAutoVarImpl checkLeakAutoVar(&tokenizer, tokenizer.getSettings(), errorLogger); checkLeakAutoVar.check(); } -void CheckLeakAutoVar::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckLeakAutoVar::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckLeakAutoVarImpl c(nullptr, settings, errorLogger); c.deallocReturnError(nullptr, nullptr, "p"); diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index 5d4fa07ec06..b613b357119 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -111,9 +111,9 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check { CheckLeakAutoVar() : Check("Leaks (auto variables)") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Detect when a auto variable is allocated but not deallocated or deallocated twice.\n"; @@ -123,7 +123,7 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check { class CPPCHECKLIB CheckLeakAutoVarImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckLeakAutoVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckLeakAutoVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** check for leaks in all scopes */ diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index d02bb607b33..dcde32737d5 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -31,7 +31,6 @@ #include "utils.h" #include -#include #include #include #include @@ -286,10 +285,8 @@ void CheckMemoryLeakImpl::reportErr(const Token *tok, Severity severity, const s void CheckMemoryLeakImpl::reportErr(const std::list &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe) const { - assert(mErrorLogger); - const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, Certainty::normal); - mErrorLogger->reportErr(errmsg); + mErrorLogger.reportErr(errmsg); } void CheckMemoryLeakImpl::memleakError(const Token *tok, const std::string &varname) const @@ -490,13 +487,13 @@ void CheckMemoryLeakInFunctionImpl::checkReallocUsage() } } -void CheckMemoryLeakInFunction::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckMemoryLeakInFunction::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, tokenizer.getSettings(), errorLogger); checkMemoryLeak.checkReallocUsage(); } -void CheckMemoryLeakInFunction::getErrorMessages(ErrorLogger *e, const Settings &settings) const +void CheckMemoryLeakInFunction::getErrorMessages(ErrorLogger& e, const Settings &settings) const { CheckMemoryLeakInFunctionImpl c(nullptr, settings, e); c.memleakError(nullptr, "varname"); @@ -691,7 +688,7 @@ void CheckMemoryLeakInClassImpl::publicAllocationError(const Token *tok, const s reportError(tok, Severity::warning, "publicAllocationError", "$symbol:" + varname + "\nPossible leak in public function. The pointer '$symbol' is not deallocated before it is allocated.", CWE398, Certainty::normal); } -void CheckMemoryLeakInClass::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckMemoryLeakInClass::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { if (!tokenizer.isCPP()) return; @@ -700,7 +697,7 @@ void CheckMemoryLeakInClass::runChecks(const Tokenizer &tokenizer, ErrorLogger * checkMemoryLeak.check(); } -void CheckMemoryLeakInClass::getErrorMessages(ErrorLogger *e, const Settings &settings) const +void CheckMemoryLeakInClass::getErrorMessages(ErrorLogger& e, const Settings &settings) const { CheckMemoryLeakInClassImpl c(nullptr, settings, e); c.publicAllocationError(nullptr, "varname"); @@ -966,15 +963,15 @@ void CheckMemoryLeakStructMemberImpl::checkStructVariable(const Variable* const } } -void CheckMemoryLeakStructMember::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckMemoryLeakStructMember::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckMemoryLeakStructMemberImpl checkMemoryLeak(&tokenizer, tokenizer.getSettings(), errorLogger); checkMemoryLeak.check(); } -void CheckMemoryLeakStructMember::getErrorMessages(ErrorLogger * errorLogger, const Settings & settings) const +void CheckMemoryLeakStructMember::getErrorMessages(ErrorLogger& errorLogger, const Settings & settings) const { - (void)errorLogger; + (void)&errorLogger; (void)settings; } @@ -1218,13 +1215,13 @@ void CheckMemoryLeakNoVarImpl::unsafeArgAllocError(const Token *tok, const std:: Certainty::inconclusive); // Inconclusive because funcName may never throw } -void CheckMemoryLeakNoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckMemoryLeakNoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckMemoryLeakNoVarImpl checkMemoryLeak(&tokenizer, tokenizer.getSettings(), errorLogger); checkMemoryLeak.check(); } -void CheckMemoryLeakNoVar::getErrorMessages(ErrorLogger *e, const Settings &settings) const +void CheckMemoryLeakNoVar::getErrorMessages(ErrorLogger& e, const Settings &settings) const { CheckMemoryLeakNoVarImpl c(nullptr, settings, e); c.functionCallLeak(nullptr, "funcName", "funcName"); diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 4fa69742277..037363160de 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -72,10 +72,10 @@ class CPPCHECKLIB CheckMemoryLeakInFunction : public Check { CheckMemoryLeakInFunction() : Check("Memory leaks (function variables)") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** Report all possible errors (for the --errorlist) */ - void getErrorMessages(ErrorLogger *e, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& e, const Settings &settings) const override; /** * Get class information (--doc) @@ -98,9 +98,9 @@ class CPPCHECKLIB CheckMemoryLeakInClass : public Check { CheckMemoryLeakInClass() : Check("Memory leaks (class variables)") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *e, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& e, const Settings &settings) const override; std::string classInfo() const override { return "If the constructor allocate memory then the destructor must deallocate it.\n"; @@ -118,9 +118,9 @@ class CPPCHECKLIB CheckMemoryLeakStructMember : public Check { CheckMemoryLeakStructMember() : Check("Memory leaks (struct members)") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger * errorLogger, const Settings & settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings & settings) const override; std::string classInfo() const override { return "Don't forget to deallocate struct members\n"; @@ -138,9 +138,9 @@ class CPPCHECKLIB CheckMemoryLeakNoVar : public Check { CheckMemoryLeakNoVar() : Check("Memory leaks (address not taken)") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *e, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& e, const Settings &settings) const override; std::string classInfo() const override { return "Not taking the address to allocated memory\n"; @@ -175,7 +175,7 @@ class CPPCHECKLIB CheckMemoryLeakImpl : public CheckImpl { CheckMemoryLeakImpl(const CheckMemoryLeakImpl &) = delete; CheckMemoryLeakImpl& operator=(const CheckMemoryLeakImpl &) = delete; - CheckMemoryLeakImpl(const Tokenizer *t, const Settings &s, ErrorLogger *e) + CheckMemoryLeakImpl(const Tokenizer *t, const Settings &s, ErrorLogger &e) : CheckImpl(t, s, e) {} /** @brief What type of allocation are used.. the "Many" means that several types of allocation and deallocation are used */ @@ -254,7 +254,7 @@ class CPPCHECKLIB CheckMemoryLeakImpl : public CheckImpl { class CPPCHECKLIB CheckMemoryLeakInFunctionImpl : public CheckMemoryLeakImpl { public: /** @brief This constructor is used when running checks */ - CheckMemoryLeakInFunctionImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckMemoryLeakInFunctionImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} /** @@ -271,7 +271,7 @@ class CPPCHECKLIB CheckMemoryLeakInFunctionImpl : public CheckMemoryLeakImpl { class CPPCHECKLIB CheckMemoryLeakInClassImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakInClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckMemoryLeakInClassImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); @@ -292,7 +292,7 @@ class CPPCHECKLIB CheckMemoryLeakInClassImpl : private CheckMemoryLeakImpl { class CPPCHECKLIB CheckMemoryLeakStructMemberImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakStructMemberImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckMemoryLeakStructMemberImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); @@ -309,7 +309,7 @@ class CPPCHECKLIB CheckMemoryLeakStructMemberImpl : private CheckMemoryLeakImpl class CPPCHECKLIB CheckMemoryLeakNoVarImpl : private CheckMemoryLeakImpl { public: - CheckMemoryLeakNoVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckMemoryLeakNoVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckMemoryLeakImpl(tokenizer, settings, errorLogger) {} void check(); diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 92938b4a60f..5a83c3c6979 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -632,7 +632,7 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo &ctu, const std:: { (void)settings; - CheckNullPointerImpl dummy(nullptr, settings, &errorLogger); + CheckNullPointerImpl dummy(nullptr, settings, errorLogger); dummy. logChecker("CheckNullPointer::analyseWholeProgram"); @@ -692,7 +692,7 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo &ctu, const std:: return foundErrors; } -void CheckNullPointer::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckNullPointer::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckNullPointerImpl checkNullPointer(&tokenizer, tokenizer.getSettings(), errorLogger); checkNullPointer.nullPointer(); @@ -700,7 +700,7 @@ void CheckNullPointer::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorL checkNullPointer.nullConstantDereference(); } -void CheckNullPointer::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckNullPointer::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckNullPointerImpl c(nullptr, settings, errorLogger); c.nullPointerError(nullptr, "pointer", nullptr, false); diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index 8e35fd7565a..a1ccdefb658 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -56,7 +56,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** @brief Parse current TU and extract file info */ Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& currentConfig) const override; @@ -67,7 +67,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; /** Get error messages. Used by --errorlist */ - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; /** class info in WIKI format. Used by --doc */ std::string classInfo() const override { @@ -80,7 +80,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { class CPPCHECKLIB CheckNullPointerImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckNullPointerImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckNullPointerImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 1adcaeb9c3a..f34db383aa1 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4787,7 +4787,7 @@ void CheckOtherImpl::overlappingWriteFunction(const Token *tok, const std::strin reportError(tok, Severity::error, "overlappingWriteFunction", "Overlapping read/write in " + funcname + "() is undefined behavior"); } -void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckOtherImpl checkOther(&tokenizer, tokenizer.getSettings(), errorLogger); @@ -4839,7 +4839,7 @@ void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkOther.checkUnionZeroInit(); } -void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckOther::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckOtherImpl c(nullptr, settings, errorLogger); diff --git a/lib/checkother.h b/lib/checkother.h index 97291b53769..58a61ff772a 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -60,9 +60,9 @@ class CPPCHECKLIB CheckOther : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Other checks\n" @@ -127,7 +127,7 @@ class CPPCHECKLIB CheckOther : public Check { class CPPCHECKLIB CheckOtherImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckOtherImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckOtherImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is less than zero? */ diff --git a/lib/checkpostfixoperator.cpp b/lib/checkpostfixoperator.cpp index 0d72b8e3860..f15fa293c49 100644 --- a/lib/checkpostfixoperator.cpp +++ b/lib/checkpostfixoperator.cpp @@ -94,7 +94,7 @@ void CheckPostfixOperatorImpl::postfixOperatorError(const Token *tok) "adds a little extra code.", CWE398, Certainty::normal); } -void CheckPostfixOperator::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckPostfixOperator::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { if (tokenizer.isC()) return; @@ -103,7 +103,7 @@ void CheckPostfixOperator::runChecks(const Tokenizer &tokenizer, ErrorLogger *er checkPostfixOperator.postfixOperator(); } -void CheckPostfixOperator::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckPostfixOperator::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckPostfixOperatorImpl c(nullptr, settings, errorLogger); c.postfixOperatorError(nullptr); diff --git a/lib/checkpostfixoperator.h b/lib/checkpostfixoperator.h index de51a34fe42..ac1a053afe8 100644 --- a/lib/checkpostfixoperator.h +++ b/lib/checkpostfixoperator.h @@ -48,9 +48,9 @@ class CPPCHECKLIB CheckPostfixOperator : public Check { CheckPostfixOperator() : Check("Using postfix operators") {} private: - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Warn if using postfix operators ++ or -- rather than prefix operator\n"; } @@ -59,7 +59,7 @@ class CPPCHECKLIB CheckPostfixOperator : public Check { class CPPCHECKLIB CheckPostfixOperatorImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckPostfixOperatorImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckPostfixOperatorImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Check postfix operators */ diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index 694f73eeff6..b9c495733e0 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -498,7 +498,7 @@ void CheckSizeofImpl::arithOperationsOnVoidPointerError(const Token* tok, const reportError(tok, Severity::portability, "arithOperationsOnVoidPointer", "$symbol:" + varname + '\n' + message + '\n' + verbose, CWE467, Certainty::normal); } -void CheckSizeof::runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) +void CheckSizeof::runChecks(const Tokenizer& tokenizer, ErrorLogger& errorLogger) { CheckSizeofImpl checkSizeof(&tokenizer, tokenizer.getSettings(), errorLogger); @@ -513,7 +513,7 @@ void CheckSizeof::runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger checkSizeof.sizeofVoid(); } -void CheckSizeof::getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const +void CheckSizeof::getErrorMessages(ErrorLogger& errorLogger, const Settings& settings) const { CheckSizeofImpl c(nullptr, settings, errorLogger); c.sizeofForArrayParameterError(nullptr); diff --git a/lib/checksizeof.h b/lib/checksizeof.h index 6fa7908eb92..7540fe6785d 100644 --- a/lib/checksizeof.h +++ b/lib/checksizeof.h @@ -46,9 +46,9 @@ class CPPCHECKLIB CheckSizeof : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) override; + void runChecks(const Tokenizer& tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings& settings) const override; std::string classInfo() const override { return "sizeof() usage checks\n" @@ -66,7 +66,7 @@ class CPPCHECKLIB CheckSizeof : public Check { class CPPCHECKLIB CheckSizeofImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckSizeofImpl(const Tokenizer* tokenizer, const Settings& settings, ErrorLogger* errorLogger) + CheckSizeofImpl(const Tokenizer* tokenizer, const Settings& settings, ErrorLogger& errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for 'sizeof sizeof ..' */ diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 08ac141610a..c8fcca48f1a 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -3453,7 +3453,7 @@ void CheckStlImpl::checkMutexes() } } -void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { if (!tokenizer.isCPP()) { return; @@ -3490,7 +3490,7 @@ void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkStl.size(); } -void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const +void CheckStl::getErrorMessages(ErrorLogger& errorLogger, const Settings& settings) const { CheckStlImpl c(nullptr, settings, errorLogger); c.outOfBoundsError(nullptr, "container", nullptr, "x", nullptr); diff --git a/lib/checkstl.h b/lib/checkstl.h index b67632fbfed..4218090e707 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -53,9 +53,9 @@ class CPPCHECKLIB CheckStl : public Check { private: /** run checks, the token list is not simplified */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings& settings) const override; std::string classInfo() const override { return "Check for invalid usage of STL:\n" @@ -83,7 +83,7 @@ class CPPCHECKLIB CheckStl : public Check { class CPPCHECKLIB CheckStlImpl : public CheckImpl { public: /** This constructor is used when running checks. */ - CheckStlImpl(const Tokenizer* tokenizer, const Settings& settings, ErrorLogger* errorLogger) + CheckStlImpl(const Tokenizer* tokenizer, const Settings& settings, ErrorLogger& errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** Accessing container out of bounds using ValueFlow */ diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 00fa80998c1..1d391895c3e 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -471,7 +471,7 @@ void CheckStringImpl::sprintfOverlappingDataError(const Token *funcTok, const To "to sprintf() or snprintf(), the results are undefined.\"", CWE628, Certainty::normal); } -void CheckString::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckString::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckStringImpl checkString(&tokenizer, tokenizer.getSettings(), errorLogger); @@ -485,7 +485,7 @@ void CheckString::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger checkString.checkAlwaysTrueOrFalseStringCompare(); } -void CheckString::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckString::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckStringImpl c(nullptr, settings, errorLogger); c.stringLiteralWriteError(nullptr, nullptr); diff --git a/lib/checkstring.h b/lib/checkstring.h index 2c19d64332c..1614e4dc7d3 100644 --- a/lib/checkstring.h +++ b/lib/checkstring.h @@ -46,9 +46,9 @@ class CPPCHECKLIB CheckString : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Detect misusage of C-style strings:\n" @@ -65,7 +65,7 @@ class CPPCHECKLIB CheckString : public Check { class CPPCHECKLIB CheckStringImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckStringImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckStringImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief undefined behaviour, writing string literal */ diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 262cb37a612..447a8924360 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -531,7 +531,7 @@ void CheckTypeImpl::floatToIntegerOverflowError(const Token *tok, const ValueFlo errmsg.str(), CWE190, value.isInconclusive() ? Certainty::inconclusive : Certainty::normal); } -void CheckType::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckType::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { // These are not "simplified" because casts can't be ignored CheckTypeImpl checkType(&tokenizer, tokenizer.getSettings(), errorLogger); @@ -542,7 +542,7 @@ void CheckType::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) checkType.checkFloatToIntegerOverflow(); } -void CheckType::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckType::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckTypeImpl c(nullptr, settings, errorLogger); c.tooBigBitwiseShiftError(nullptr, 32, ValueFlow::Value(64)); diff --git a/lib/checktype.h b/lib/checktype.h index 8ebfb0fb5b2..83eedda5583 100644 --- a/lib/checktype.h +++ b/lib/checktype.h @@ -52,9 +52,9 @@ class CPPCHECKLIB CheckType : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Type checks\n" @@ -70,7 +70,7 @@ class CPPCHECKLIB CheckType : public Check { class CPPCHECKLIB CheckTypeImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckTypeImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckTypeImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for bitwise shift with too big right operand */ diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index bdfc07a8d47..7c00b705879 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1753,7 +1753,7 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo &ctu, const std::li { (void)settings; - CheckUninitVarImpl dummy(nullptr, settings, &errorLogger); + CheckUninitVarImpl dummy(nullptr, settings, errorLogger); dummy. logChecker("CheckUninitVar::analyseWholeProgram"); @@ -1797,14 +1797,14 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo &ctu, const std::li return foundErrors; } -void CheckUninitVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckUninitVar::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckUninitVarImpl checkUninitVar(&tokenizer, tokenizer.getSettings(), errorLogger); checkUninitVar.valueFlowUninit(); checkUninitVar.check(); } -void CheckUninitVar::getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const +void CheckUninitVar::getErrorMessages(ErrorLogger& errorLogger, const Settings& settings) const { CheckUninitVarImpl c(nullptr, settings, errorLogger); diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index f558fe84709..dd92b3c892b 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -66,7 +66,7 @@ class CPPCHECKLIB CheckUninitVar : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** @brief Parse current TU and extract file info */ Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; @@ -76,7 +76,7 @@ class CPPCHECKLIB CheckUninitVar : public Check { /** @brief Analyse all file infos for all TU */ bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - void getErrorMessages(ErrorLogger* errorLogger, const Settings& settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings& settings) const override; std::string classInfo() const override { return "Uninitialized variables\n" @@ -88,7 +88,7 @@ class CPPCHECKLIB CheckUninitVar : public Check { class CPPCHECKLIB CheckUninitVarImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckUninitVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckUninitVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} enum Alloc : std::uint8_t { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY }; diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index dd30f65db58..fcc8746c30e 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1725,7 +1725,7 @@ bool CheckUnusedVarImpl::isEmptyType(const Type* type) return (emptyType = false); } -void CheckUnusedVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckUnusedVar::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckUnusedVarImpl checkUnusedVar(&tokenizer, tokenizer.getSettings(), errorLogger); @@ -1734,7 +1734,7 @@ void CheckUnusedVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLog checkUnusedVar.checkFunctionVariableUsage(); } -void CheckUnusedVar::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckUnusedVar::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckUnusedVarImpl c(nullptr, settings, errorLogger); c.unusedVariableError(nullptr, "varname"); diff --git a/lib/checkunusedvar.h b/lib/checkunusedvar.h index cddc36bb7e3..693d3213869 100644 --- a/lib/checkunusedvar.h +++ b/lib/checkunusedvar.h @@ -51,9 +51,9 @@ class CPPCHECKLIB CheckUnusedVar : public Check { private: /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "UnusedVar checks\n" @@ -70,7 +70,7 @@ class CPPCHECKLIB CheckUnusedVar : public Check { class CPPCHECKLIB CheckUnusedVarImpl : public CheckImpl { public: /** @brief This constructor is used when running checks. */ - CheckUnusedVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckUnusedVarImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} /** @brief %Check for unused function variables */ diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index 60a27b897b5..ae8b1626ba6 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -173,14 +173,14 @@ void CheckVaargImpl::va_start_subsequentCallsError(const Token *tok, const std:: "va_start_subsequentCalls", "va_start() or va_copy() called subsequently on '" + varname + "' without va_end() in between.", CWE664, Certainty::normal); } -void CheckVaarg::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +void CheckVaarg::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) { CheckVaargImpl check(&tokenizer, tokenizer.getSettings(), errorLogger); check.va_start_argument(); check.va_list_usage(); } -void CheckVaarg::getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const +void CheckVaarg::getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const { CheckVaargImpl c(nullptr, settings, errorLogger); c.wrongParameterTo_va_start_error(nullptr, "arg1", "arg2"); diff --git a/lib/checkvaarg.h b/lib/checkvaarg.h index 6d50bd94d0d..eea3f345bcc 100644 --- a/lib/checkvaarg.h +++ b/lib/checkvaarg.h @@ -44,10 +44,10 @@ class CPPCHECKLIB CheckVaarg : public Check { public: CheckVaarg() : Check("Vaarg") {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; + void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; private: - void getErrorMessages(ErrorLogger *errorLogger, const Settings &settings) const override; + void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; std::string classInfo() const override { return "Check for misusage of variable argument lists:\n" @@ -62,7 +62,7 @@ class CPPCHECKLIB CheckVaarg : public Check { class CPPCHECKLIB CheckVaargImpl : public CheckImpl { public: - CheckVaargImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + CheckVaargImpl(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger &errorLogger) : CheckImpl(tokenizer, settings, errorLogger) {} void va_start_argument(); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 471a1a8ff1e..856e9a14efa 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1358,7 +1358,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation } Timer::run(c->name() + "::runChecks", mTimerResults, [&]() { - c->runChecks(tokenizer, &mErrorLogger); + c->runChecks(tokenizer, mErrorLogger); }); } } @@ -1714,7 +1714,7 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) // call all "getErrorMessages" in all registered Check classes for (const Check * const c : CheckInstances::get()) - c->getErrorMessages(&errorlogger, s); + c->getErrorMessages(errorlogger, s); CheckUnusedFunctions::getErrorMessages(errorlogger); Preprocessor::getErrorMessages(errorlogger, s); diff --git a/test/fixture.h b/test/fixture.h index b927dc5de65..c5828033fd7 100644 --- a/test/fixture.h +++ b/test/fixture.h @@ -139,7 +139,7 @@ class TestFixture : public ErrorLogger { return check; } - static void runChecks(Check& check, const Tokenizer &tokenizer, ErrorLogger *errorLogger) + static void runChecks(Check& check, const Tokenizer &tokenizer, ErrorLogger& errorLogger) { check.runChecks(tokenizer, errorLogger); } diff --git a/test/test64bit.cpp b/test/test64bit.cpp index ca2654b12f1..cc96da48577 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -49,7 +49,7 @@ class Test64BitPortability : public TestFixture { SimpleTokenizer tokenizer(settings, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); - Check64BitPortabilityImpl check64BitPortability(&tokenizer, settings, this); + Check64BitPortabilityImpl check64BitPortability(&tokenizer, settings, *this); check64BitPortability.pointerassignment(); } diff --git a/test/testassert.cpp b/test/testassert.cpp index 651897af057..80bb5d3b827 100644 --- a/test/testassert.cpp +++ b/test/testassert.cpp @@ -40,7 +40,7 @@ class TestAssert : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckAssert check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void run() override { diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 2474c2fe6a5..47484d7023e 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -48,7 +48,7 @@ class TestAutoVariables : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckAutoVariables check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void run() override { diff --git a/test/testbool.cpp b/test/testbool.cpp index 6156e089aee..6074bbab46a 100644 --- a/test/testbool.cpp +++ b/test/testbool.cpp @@ -89,7 +89,7 @@ class TestBool : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckBool check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 29d8fa13d17..54fcabab6d1 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -57,7 +57,7 @@ class TestBufferOverrun : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckBufferOverrun check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } // TODO: get rid of this @@ -67,7 +67,7 @@ class TestBufferOverrun : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckBufferOverrun check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) @@ -80,7 +80,7 @@ class TestBufferOverrun : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckBufferOverrun check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void run() override { @@ -5171,7 +5171,7 @@ class TestBufferOverrun : public TestFixture { // Ticket #2292: segmentation fault when using --errorlist CheckBufferOverrun check; const Check& c = getCheck(check); - c.getErrorMessages(this, settingsDefault); + c.getErrorMessages(*this, settingsDefault); // we are not interested in the output - just consume it ignore_errout(); } diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index 347557bd051..7d4a17489fc 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -47,7 +47,7 @@ class TestCharVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check char variable usage.. - CheckOtherImpl checkOther(&tokenizer, settings, this); + CheckOtherImpl checkOther(&tokenizer, settings, *this); checkOther.checkCharVariable(); } diff --git a/test/testclass.cpp b/test/testclass.cpp index 8fba8d4a340..7f1a668cae1 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -270,7 +270,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); (checkClass.checkCopyCtorAndEqOperator)(); } @@ -371,7 +371,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings0, this); + CheckClassImpl checkClass(&tokenizer, settings0, *this); (checkClass.checkExplicitConstructors)(); } @@ -528,7 +528,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, *this); (checkClass.checkDuplInheritedMembers)(); } @@ -752,7 +752,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings3, this); + CheckClassImpl checkClass(&tokenizer, settings3, *this); checkClass.copyconstructors(); } @@ -1223,7 +1223,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings0, this); + CheckClassImpl checkClass(&tokenizer, settings0, *this); checkClass.operatorEqRetRefThis(); } @@ -1694,7 +1694,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, *this); checkClass.operatorEqToSelf(); } @@ -2657,7 +2657,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, s, this); + CheckClassImpl checkClass(&tokenizer, s, *this); checkClass.virtualDestructor(); } @@ -2994,7 +2994,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); checkClass.checkMemset(); } @@ -3640,7 +3640,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, *this); checkClass.thisSubtraction(); } @@ -3680,7 +3680,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); (checkClass.checkConst)(); } @@ -7863,7 +7863,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings2, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, settings2, this); + CheckClassImpl checkClass(&tokenizer, settings2, *this); checkClass.initializerListOrder(); } @@ -8017,7 +8017,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); checkClass.initializationListUsage(); } @@ -8241,7 +8241,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings0, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, settings0, this); + CheckClassImpl checkClass(&tokenizer, settings0, *this); (checkClass.checkSelfInitialization)(); } @@ -8351,7 +8351,7 @@ class TestClass : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); checkClass.checkVirtualFunctionCallInConstructor(); } @@ -8696,7 +8696,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); (checkClass.checkOverride)(); } @@ -8908,7 +8908,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); (checkClass.checkUselessOverride)(); } @@ -9098,7 +9098,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); (checkClass.checkUnsafeClassRefMember)(); } @@ -9116,7 +9116,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, *this); (checkClass.checkThisUseAfterFree)(); } @@ -9353,7 +9353,7 @@ class TestClass : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check.. - CheckClassImpl checkClass(&tokenizer, settings, this); + CheckClassImpl checkClass(&tokenizer, settings, *this); (checkClass.checkReturnByReference)(); } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index e5aedae6609..3143b6eb201 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -150,7 +150,7 @@ class TestCondition : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckCondition check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) @@ -163,7 +163,7 @@ class TestCondition : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckCondition check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void assignAndCompare() { @@ -528,7 +528,7 @@ class TestCondition : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckCondition check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void multicompare() { diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index b4f17cd25b8..5f2fd228dc4 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -52,7 +52,7 @@ class TestConstructors : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check class constructors.. - CheckClassImpl checkClass(&tokenizer, settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, *this); checkClass.constructors(); } diff --git a/test/testexceptionsafety.cpp b/test/testexceptionsafety.cpp index 46c995c231b..1be46fbf282 100644 --- a/test/testexceptionsafety.cpp +++ b/test/testexceptionsafety.cpp @@ -76,7 +76,7 @@ class TestExceptionSafety : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckExceptionSafety check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void destructors() { diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index 9ddb4c1f43c..788ff7a0d14 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -133,7 +133,7 @@ class TestFunctions : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckFunctions check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void prohibitedFunctions_posix() { diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 289b22b284e..7d91a013940 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -287,7 +287,7 @@ class TestGarbage : public TestFixture { // call all "runChecks" in all registered Check classes for (Check * const c : CheckInstances::get()) { - c->runChecks(tokenizer, this); + c->runChecks(tokenizer, *this); } return tokenizer.tokens()->stringifyList(false, false, false, true, false, nullptr, nullptr); diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index be0b3e7ad3d..b72b6524872 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -50,7 +50,7 @@ class TestIncompleteStatement : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for incomplete statements.. - CheckOtherImpl checkOther(&tokenizer, settings1, this); + CheckOtherImpl checkOther(&tokenizer, settings1, *this); checkOther.checkIncompleteStatement(); } diff --git a/test/testinternal.cpp b/test/testinternal.cpp index b724c860fae..61c36a8e7dd 100644 --- a/test/testinternal.cpp +++ b/test/testinternal.cpp @@ -57,7 +57,7 @@ class TestInternal : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckInternal check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void simplePatternInTokenMatch() { diff --git a/test/testio.cpp b/test/testio.cpp index c622bc5936d..15a65ef79c9 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -109,12 +109,12 @@ class TestIO : public TestFixture { // Check.. if (options.onlyFormatStr) { - CheckIOImpl checkIO(&tokenizer, settings1, this); + CheckIOImpl checkIO(&tokenizer, settings1, *this); checkIO.checkWrongPrintfScanfArguments(); return; } CheckIO check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void coutCerrMisusage() { diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 265e31bf3c2..b7f8b024a8c 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -236,7 +236,7 @@ class TestLeakAutoVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckLeakAutoVar check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void assign1() { @@ -3267,7 +3267,7 @@ class TestLeakAutoVarRecursiveCountLimit : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckLeakAutoVar check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void run() override { @@ -3314,7 +3314,7 @@ class TestLeakAutoVarStrcpy : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckLeakAutoVar check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void run() override { @@ -3419,7 +3419,7 @@ class TestLeakAutoVarWindows : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckLeakAutoVar check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void run() override { @@ -3492,7 +3492,7 @@ class TestLeakAutoVarPosix : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckLeakAutoVar check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void run() override { diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 6e3d28010a1..fda118826bb 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -44,7 +44,7 @@ class TestMemleak : public TestFixture { SimpleTokenizer tokenizer(settingsDefault, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - const CheckMemoryLeakImpl c(&tokenizer, settingsDefault, this); + const CheckMemoryLeakImpl c(&tokenizer, settingsDefault, *this); return (c.functionReturnType)(&tokenizer.getSymbolDatabase()->scopeList.front().functionList.front()); } @@ -93,7 +93,7 @@ class TestMemleak : public TestFixture { // there is no allocation const Token *tok = Token::findsimplematch(tokenizer.tokens(), "ret ="); - const CheckMemoryLeakImpl check(&tokenizer, settingsDefault, nullptr); + const CheckMemoryLeakImpl check(&tokenizer, settingsDefault, *this); ASSERT_EQUALS(CheckMemoryLeakImpl::No, check.getAllocationType(tok->tokAt(2), 1)); } }; @@ -119,7 +119,7 @@ class TestMemleakInFunction : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, settings, this); + CheckMemoryLeakInFunctionImpl checkMemoryLeak(&tokenizer, settings, *this); checkMemoryLeak.checkReallocUsage(); } @@ -501,7 +501,7 @@ class TestMemleakInClass : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakInClassImpl checkMemoryLeak(&tokenizer, settings, this); + CheckMemoryLeakInClassImpl checkMemoryLeak(&tokenizer, settings, *this); (checkMemoryLeak.check)(); } @@ -1706,7 +1706,7 @@ class TestMemleakStructMember : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakStructMemberImpl checkMemoryLeakStructMember(&tokenizer, settings, this); + CheckMemoryLeakStructMemberImpl checkMemoryLeakStructMember(&tokenizer, settings, *this); (checkMemoryLeakStructMember.check)(); } @@ -2388,7 +2388,7 @@ class TestMemleakNoVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for memory leaks.. - CheckMemoryLeakNoVarImpl checkMemoryLeakNoVar(&tokenizer, settings, this); + CheckMemoryLeakNoVarImpl checkMemoryLeakNoVar(&tokenizer, settings, *this); (checkMemoryLeakNoVar.check)(); } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 3e9d4011500..b628d294a59 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -200,7 +200,7 @@ class TestNullPointer : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckNullPointer check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) @@ -212,7 +212,7 @@ class TestNullPointer : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckNullPointer check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } diff --git a/test/testother.cpp b/test/testother.cpp index 2394cfefe7c..e720d9c7224 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -368,7 +368,7 @@ class TestOther : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckOther check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } struct CheckPOptions @@ -385,7 +385,7 @@ class TestOther : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckOther check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } template @@ -2055,7 +2055,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizerCpp(settings, *this); ASSERT_LOC(tokenizerCpp.tokenize(code), file, line); - CheckOtherImpl checkOtherCpp(&tokenizerCpp, settings, this); + CheckOtherImpl checkOtherCpp(&tokenizerCpp, settings, *this); checkOtherCpp.warningOldStylePointerCast(); checkOtherCpp.warningDangerousTypeCast(); } @@ -2341,7 +2341,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizerCpp(settings, *this); ASSERT_LOC(tokenizerCpp.tokenize(code), file, line); - CheckOtherImpl checkOtherCpp(&tokenizerCpp, settings, this); + CheckOtherImpl checkOtherCpp(&tokenizerCpp, settings, *this); checkOtherCpp.warningIntToPointerCast(); } @@ -2380,7 +2380,7 @@ class TestOther : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckOtherImpl checkOtherCpp(&tokenizer, settings, this); + CheckOtherImpl checkOtherCpp(&tokenizer, settings, *this); checkOtherCpp.invalidPointerCast(); } @@ -12315,7 +12315,7 @@ class TestOther : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckOther check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void testEvaluationOrder() { diff --git a/test/testpostfixoperator.cpp b/test/testpostfixoperator.cpp index 07b7c03ca00..2277039820f 100644 --- a/test/testpostfixoperator.cpp +++ b/test/testpostfixoperator.cpp @@ -38,7 +38,7 @@ class TestPostfixOperator : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CheckPostfixOperatorImpl checkPostfixOperator(&tokenizer, settings, this); + CheckPostfixOperatorImpl checkPostfixOperator(&tokenizer, settings, *this); checkPostfixOperator.postfixOperator(); } diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index ee9416a65bc..9337252f92c 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -55,7 +55,7 @@ class TestSizeof : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckSizeof check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) @@ -67,7 +67,7 @@ class TestSizeof : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckSizeof check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void sizeofsizeof() { diff --git a/test/teststl.cpp b/test/teststl.cpp index 18549e08f9f..51fab0e6021 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -200,7 +200,7 @@ class TestStl : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckStl check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } // TODO: get rid of this @@ -211,7 +211,7 @@ class TestStl : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckStl check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } #define checkNormal(...) checkNormal_(__FILE__, __LINE__, __VA_ARGS__) @@ -222,7 +222,7 @@ class TestStl : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckStl check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void outOfBounds() { diff --git a/test/teststring.cpp b/test/teststring.cpp index 7f28f58c80a..80073ac7d91 100644 --- a/test/teststring.cpp +++ b/test/teststring.cpp @@ -75,7 +75,7 @@ class TestString : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckString check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void stringLiteralWrite() { diff --git a/test/testtype.cpp b/test/testtype.cpp index 80c3dfd32b8..2bcab8c91dc 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -62,7 +62,7 @@ class TestType : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckType check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } // TODO: get rid of this @@ -74,7 +74,7 @@ class TestType : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckType check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } struct CheckPOptions @@ -94,7 +94,7 @@ class TestType : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); CheckType check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void checkTooBigShift_Unix32() { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 0d71efbc897..b9e8a623cb7 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -127,7 +127,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVarImpl checkuninitvar(&tokenizer, settings1, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, settings1, *this); checkuninitvar.check(); } @@ -137,7 +137,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVarImpl checkuninitvar(&tokenizer, settings, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, settings, *this); checkuninitvar.check(); } @@ -3673,7 +3673,7 @@ class TestUninitVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. - CheckUninitVarImpl checkuninitvar(&tokenizer, settings, this); + CheckUninitVarImpl checkuninitvar(&tokenizer, settings, *this); (checkuninitvar.valueFlowUninit)(); } diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 06c41bbb9c2..4a2a6ca1894 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -104,7 +104,7 @@ class TestUnusedPrivateFunction : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused private functions.. - CheckClassImpl checkClass(&tokenizer, settings1, this); + CheckClassImpl checkClass(&tokenizer, settings1, *this); checkClass.privateFunctions(); } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index ae44305ef6a..2efe658b52e 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -291,7 +291,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for unused variables.. - CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, *this); checkUnusedVar.checkFunctionVariableUsage(); } @@ -311,7 +311,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for unused variables.. - CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, *this); (checkUnusedVar.checkStructMemberUsage)(); } @@ -324,7 +324,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused variables.. - CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, *this); (checkUnusedVar.checkStructMemberUsage)(); } @@ -337,7 +337,7 @@ class TestUnusedVar : public TestFixture { ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); // Check for unused variables.. - CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, this); + CheckUnusedVarImpl checkUnusedVar(&tokenizer, settings, *this); (checkUnusedVar.checkFunctionVariableUsage)(); } diff --git a/test/testvaarg.cpp b/test/testvaarg.cpp index 3f44b687ff3..826438fe355 100644 --- a/test/testvaarg.cpp +++ b/test/testvaarg.cpp @@ -39,7 +39,7 @@ class TestVaarg : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); CheckVaarg check; - runChecks(check, tokenizer, this); + runChecks(check, tokenizer, *this); } void run() override { From cb7c24de1886ebc2c292bf84170d7a2151897472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 2 Jun 2026 12:08:17 +0200 Subject: [PATCH 146/493] CI-windows.yml: removed hard-coded aqt version (#8604) this was missed in 4f31d0aa75c672a81c65aa37e586ce3ec7b0ee9d --- .github/workflows/CI-windows.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml index 71d72025cf9..a76997eb007 100644 --- a/.github/workflows/CI-windows.yml +++ b/.github/workflows/CI-windows.yml @@ -47,7 +47,6 @@ jobs: modules: 'qtcharts' setup-python: 'false' cache: true - aqtversion: '==3.1.*' # TODO: remove when aqtinstall 3.2.2 is available - name: Run CMake run: | @@ -128,7 +127,6 @@ jobs: modules: 'qtcharts' setup-python: 'false' cache: true - aqtversion: '==3.1.*' # TODO: remove when aqtinstall 3.2.2 is available - name: Run CMake (without GUI) run: | From 8c2ed4e256a3d9c781019f40270bc9607f00d693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 2 Jun 2026 13:09:40 +0200 Subject: [PATCH 147/493] fix #14802: false positive: shadowFunction (shadowing non-static in static) (#8605) --- lib/checkother.cpp | 3 +++ lib/token.cpp | 7 ------- test/testother.cpp | 6 ++++++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index f34db383aa1..b5fd0dda361 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4194,6 +4194,9 @@ void CheckOtherImpl::checkShadowVariables() (functionScope->function->isStatic() || functionScope->function->isFriend()) && shadowed->variable() && !shadowed->variable()->isLocal()) return; + if (functionScope->functionOf && functionScope->functionOf->isClassOrStructOrUnion() && functionScope->function && + functionScope->function->isStatic() && shadowed->function() && !shadowed->function()->isStatic()) + return; if (var.scope() && var.scope()->function && var.scope()->function->isConstructor()) { if (shadowed->variable() && shadowed->variable()->isMember()) return; diff --git a/lib/token.cpp b/lib/token.cpp index 539141c0b0f..2b30419b9df 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -614,7 +614,6 @@ bool Token::simpleMatch(const Token *tok, const char pattern[], size_t pattern_l return false; // shortcut const char *current = pattern; const char *end = pattern + pattern_len; - // cppcheck-suppress shadowFunction - TODO: fix this const char *next = static_cast(std::memchr(pattern, ' ', pattern_len)); if (!next) next = end; @@ -769,7 +768,6 @@ nonneg int Token::getStrArraySize(const Token *tok) { assert(tok != nullptr); assert(tok->tokType() == eString); - // cppcheck-suppress shadowFunction - TODO: fix this const std::string str(getStringLiteral(tok->str())); int sizeofstring = 1; for (int i = 0; i < static_cast(str.size()); i++) { @@ -2359,11 +2357,9 @@ const ::Type* Token::typeOf(const Token* tok, const Token** typeTok) if (tok->valueType() && tok->valueType()->typeScope && tok->valueType()->typeScope->definedType) return tok->valueType()->typeScope->definedType; if (Token::simpleMatch(tok, "return")) { - // cppcheck-suppress shadowFunction - TODO: fix this const Scope *scope = tok->scope(); if (!scope) return nullptr; - // cppcheck-suppress shadowFunction - TODO: fix this const Function *function = scope->function; if (!function) return nullptr; @@ -2473,18 +2469,15 @@ std::pair Token::typeDecl(const Token* tok, bool poi return {var->typeStartToken(), var->typeEndToken()->next()}; } if (Token::simpleMatch(tok, "return")) { - // cppcheck-suppress shadowFunction - TODO: fix this const Scope* scope = tok->scope(); if (!scope) return {}; - // cppcheck-suppress shadowFunction - TODO: fix this const Function* function = scope->function; if (!function) return {}; return { function->retDef, function->returnDefEnd() }; } if (tok->previous() && tok->previous()->function()) { - // cppcheck-suppress shadowFunction - TODO: fix this const Function *function = tok->previous()->function(); return {function->retDef, function->returnDefEnd()}; } diff --git a/test/testother.cpp b/test/testother.cpp index e720d9c7224..93e67229f43 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -13118,6 +13118,12 @@ class TestOther : public TestFixture { check("struct S { int v(); explicit S(int v); };\n" "S::S(int v) : v(v) {}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S { int i(); static void f(int i) {} };\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S { static int i(); static void f(int i) {} };\n"); + ASSERT_EQUALS("[test.cpp:1:23] -> [test.cpp:1:46]: (style) Argument 'i' shadows outer function [shadowFunction]\n", errout_str()); } void knownArgument() { From 01e22541a84135ce2ddecdf35865a44d9fe1dfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 2 Jun 2026 13:10:18 +0200 Subject: [PATCH 148/493] extracted `Rule` from `settings.h` to `rule.h` / added `Regex::engine()` / removed unnecessary `Rule::engine` (#8580) --- Makefile | 262 +++++++++++------------ cli/cmdlineparser.cpp | 10 +- gui/test/projectfile/testprojectfile.cpp | 5 + lib/cppcheck.cpp | 5 +- lib/cppcheck.vcxproj | 1 + lib/regex.cpp | 5 + lib/regex.h | 2 + lib/rule.h | 43 ++++ lib/settings.cpp | 12 ++ lib/settings.h | 29 +-- oss-fuzz/Makefile | 96 ++++----- test/testcmdlineparser.cpp | 11 +- test/testregex.cpp | 4 +- tools/dmake/dmake.cpp | 1 + 14 files changed, 277 insertions(+), 209 deletions(-) create mode 100644 lib/rule.h diff --git a/Makefile b/Makefile index dd739e8e6de..0fc1d8e94e6 100644 --- a/Makefile +++ b/Makefile @@ -483,13 +483,13 @@ check-nonneg: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/regex.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp -$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp -$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp $(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/addoninfo.h lib/config.h lib/json.h lib/path.h lib/standards.h lib/utils.h @@ -498,28 +498,28 @@ $(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/ad $(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: lib/astutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/astutils.o: lib/astutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h @@ -528,64 +528,64 @@ $(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h $(libcppdir)/checkersidmapping.o: lib/checkersidmapping.cpp lib/checkers.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersidmapping.cpp -$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h +$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/addoninfo.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/addoninfo.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp -$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp $(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkimpl.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/standards.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp $(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h @@ -594,13 +594,13 @@ $(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h l $(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h +$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/rule.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp $(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h @@ -609,13 +609,13 @@ $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/ $(libcppdir)/findtoken.o: lib/findtoken.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp -$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp -$(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp $(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h @@ -642,70 +642,70 @@ $(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatc $(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp $(libcppdir)/regex.o: lib/regex.cpp lib/config.h lib/regex.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp -$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h +$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp -$(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/utils.h lib/vfvalue.h +$(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/rule.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/settings.cpp $(libcppdir)/standards.o: lib/standards.cpp externals/simplecpp/simplecpp.h lib/config.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp -$(libcppdir)/summaries.o: lib/summaries.cpp lib/addoninfo.h lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/summaries.o: lib/summaries.cpp lib/addoninfo.h lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp -$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: lib/timer.cpp lib/config.h lib/timer.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp -$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vfvalue.cpp -frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h +frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/addoninfo.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_FE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ frontend/frontend.cpp -cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h +cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp -cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp -cli/executor.o: cli/executor.cpp cli/executor.h lib/addoninfo.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/executor.o: cli/executor.cpp cli/executor.h lib/addoninfo.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/standards.h lib/utils.h @@ -714,7 +714,7 @@ cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesetti cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/main.cpp -cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/processexecutor.cpp cli/sehwrapper.o: cli/sehwrapper.cpp cli/sehwrapper.h lib/config.h lib/utils.h @@ -723,247 +723,247 @@ cli/sehwrapper.o: cli/sehwrapper.cpp cli/sehwrapper.h lib/config.h lib/utils.h cli/signalhandler.o: cli/signalhandler.cpp cli/signalhandler.h cli/stacktrace.h lib/config.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/signalhandler.cpp -cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h +cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/singleexecutor.cpp cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/stacktrace.cpp -cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h +test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp -test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h +test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp -test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/main.cpp test/options.o: test/options.cpp lib/config.h lib/timer.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp -test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp -test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp -test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp -test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp -test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp -test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp -test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp -test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp -test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheckersreport.cpp -test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp -test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp -test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp -test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp -test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp -test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h +test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp -test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp -test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexecutor.cpp -test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp -test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp -test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp -test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp -test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp -test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h +test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp -test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp -test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp -test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp -test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp -test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp -test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp -test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp -test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp -test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp -test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp -test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp -test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpathmatch.cpp -test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp -test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp -test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp -test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp -test/testprogrammemory.o: test/testprogrammemory.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testprogrammemory.o: test/testprogrammemory.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprogrammemory.cpp test/testregex.o: test/testregex.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testregex.cpp -test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsarifreport.cpp -test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp -test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytemplate.cpp -test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytokens.cpp -test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytypedef.cpp -test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifyusing.cpp -test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp -test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp -test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp -test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp -test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsummaries.cpp -test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp -test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp -test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp -test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h +test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp -test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtoken.cpp -test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenize.cpp -test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenlist.cpp -test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp -test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp -test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp -test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp -test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp -test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp -test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp -test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp -test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp -test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvfvalue.cpp externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 5f735c4ec56..1ad0863d96d 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -57,6 +57,7 @@ #ifdef HAVE_RULES #include "regex.h" +#include "rule.h" // xml is used for rules #include "xml.h" @@ -1304,7 +1305,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a // Rule given at command line else if (std::strncmp(argv[i], "--rule=", 7) == 0) { #ifdef HAVE_RULES - Settings::Rule rule; + Rule rule; rule.pattern = 7 + argv[i]; if (rule.pattern.empty()) { @@ -1340,7 +1341,8 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a if (node && strcmp(node->Value(), "rules") == 0) node = node->FirstChildElement("rule"); for (; node && strcmp(node->Value(), "rule") == 0; node = node->NextSiblingElement()) { - Settings::Rule rule; + Rule rule; + Regex::Engine regexEngine = Regex::Engine::Pcre; for (const tinyxml2::XMLElement *subnode = node->FirstChildElement(); subnode; subnode = subnode->NextSiblingElement()) { const char * const subname = subnode->Name(); @@ -1373,7 +1375,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a else if (std::strcmp(subname, "engine") == 0) { const char * const engine = empty_if_null(subtext); if (std::strcmp(engine, "pcre") == 0) { - rule.engine = Regex::Engine::Pcre; + regexEngine = Regex::Engine::Pcre; } else { mLogger.printError(std::string("unknown regex engine '") + engine + "'."); @@ -1407,7 +1409,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a } std::string regex_err; - auto regex = Regex::create(rule.pattern, rule.engine, regex_err); + auto regex = Regex::create(rule.pattern, regexEngine, regex_err); if (!regex) { mLogger.printError("unable to load rule-file '" + ruleFile + "' - pattern '" + rule.pattern + "' failed to compile (" + regex_err + ")."); return Result::Fail; diff --git a/gui/test/projectfile/testprojectfile.cpp b/gui/test/projectfile/testprojectfile.cpp index 1eb43f7d72f..3eaa2b10386 100644 --- a/gui/test/projectfile/testprojectfile.cpp +++ b/gui/test/projectfile/testprojectfile.cpp @@ -24,6 +24,10 @@ #include "settings.h" #include "suppressions.h" +#ifdef HAVE_RULES +#include "rule.h" +#endif + #include #include #include @@ -38,6 +42,7 @@ const char Settings::SafeChecks::XmlExternalFunctions[] = "external-functions"; const char Settings::SafeChecks::XmlInternalFunctions[] = "internal-functions"; const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables"; Settings::Settings() : maxCtuDepth(10) {} +Settings::~Settings() = default; Platform::Platform() = default; Library::Library() = default; Library::~Library() = default; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 856e9a14efa..5eee5dbd98c 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -47,6 +47,7 @@ #ifdef HAVE_RULES #include "regex.h" +#include "rule.h" #endif #include @@ -1415,7 +1416,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation #ifdef HAVE_RULES bool CppCheck::hasRule(const std::string &tokenlist) const { - return std::any_of(mSettings.rules.cbegin(), mSettings.rules.cend(), [&](const Settings::Rule& rule) { + return std::any_of(mSettings.rules.cbegin(), mSettings.rules.cend(), [&](const Rule& rule) { return rule.tokenlist == tokenlist; }); } @@ -1433,7 +1434,7 @@ void CppCheck::executeRules(const std::string &tokenlist, const TokenList &list) str += tok->str(); } - for (const Settings::Rule &rule : mSettings.rules) { + for (const Rule &rule : mSettings.rules) { if (rule.tokenlist != tokenlist) continue; diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 5e5b9ae743a..553392c53c2 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -168,6 +168,7 @@ + diff --git a/lib/regex.cpp b/lib/regex.cpp index df92982204a..74e3a988cd3 100644 --- a/lib/regex.cpp +++ b/lib/regex.cpp @@ -179,6 +179,10 @@ namespace { std::string compile(); std::string match(const std::string& str, const MatchFn& matchFn) const override; + Engine engine() const override { + return Engine::Pcre; + } + private: std::string mPattern; pcre* mRe{}; @@ -254,6 +258,7 @@ static T* createAndCompileRegex(std::string pattern, std::string& err) return regex; } +// cppcheck-suppress shadowFunction - FP see #14802 std::shared_ptr Regex::create(std::string pattern, Engine engine, std::string& err) { Regex* regex = nullptr; diff --git a/lib/regex.h b/lib/regex.h index 9717ff6f05d..c17fba41d4e 100644 --- a/lib/regex.h +++ b/lib/regex.h @@ -44,6 +44,8 @@ class CPPCHECKLIB Regex Pcre = 1 }; + virtual Engine engine() const = 0; + static std::shared_ptr create(std::string pattern, Engine engine, std::string& err); }; diff --git a/lib/rule.h b/lib/rule.h new file mode 100644 index 00000000000..dd5cf92effd --- /dev/null +++ b/lib/rule.h @@ -0,0 +1,43 @@ +/* -*- C++ -*- + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2026 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ruleH +#define ruleH + +#ifdef HAVE_RULES + +#include "errortypes.h" + +#include +#include + +class Regex; + +/** Rule */ +struct Rule +{ + std::string tokenlist = "normal"; // use normal tokenlist + std::string pattern; + std::string id = "rule"; // default id + std::string summary; + Severity severity = Severity::style; // default severity + std::shared_ptr regex; +}; +#endif // HAVE_RULES + +#endif // ruleH diff --git a/lib/settings.cpp b/lib/settings.cpp index 0df9907b3ab..a9ba14dd72b 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -24,6 +24,10 @@ #include "suppressions.h" #include "vfvalue.h" +#ifdef HAVE_RULES +#include "rule.h" +#endif + #include #include #include @@ -69,6 +73,14 @@ Settings::Settings() pid = getPid(); } +Settings::~Settings() = default; + +Settings::Settings(const Settings&) = default; +Settings & Settings::operator=(const Settings &) = default; + +Settings::Settings(Settings&&) noexcept = default; +Settings & Settings::operator=(Settings &&) noexcept = default; + std::string Settings::loadCppcheckCfg(Settings& settings, Suppressions& suppressions, bool debug) { static const std::string cfgFilename = "cppcheck.cfg"; diff --git a/lib/settings.h b/lib/settings.h index 25dee019739..80f3853bde6 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -44,20 +44,13 @@ #endif #ifdef HAVE_RULES -#include "errortypes.h" -#include "regex.h" - -#include - -class Regex; -#else -enum class Severity : std::uint8_t; +struct Rule; #endif - struct Suppressions; namespace ValueFlow { class Value; } +enum class Severity : std::uint8_t; enum class Certainty : std::uint8_t; enum class Checks : std::uint8_t; @@ -115,6 +108,13 @@ class CPPCHECKLIB WARN_UNUSED Settings { public: Settings(); + ~Settings(); + + Settings(const Settings&); + Settings& operator=(const Settings&); + + Settings(Settings&&) noexcept; + Settings& operator=(Settings&&) noexcept; static std::string loadCppcheckCfg(Settings& settings, Suppressions& suppressions, bool debug = false); @@ -372,17 +372,6 @@ class CPPCHECKLIB WARN_UNUSED Settings { int reportProgress{-1}; #ifdef HAVE_RULES - /** Rule */ - struct CPPCHECKLIB Rule { - std::string tokenlist = "normal"; // use normal tokenlist - std::string pattern; - std::string id = "rule"; // default id - std::string summary; - Severity severity = Severity::style; // default severity - Regex::Engine engine = Regex::Engine::Pcre; - std::shared_ptr regex; - }; - /** * @brief Extra rules */ diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index bf40964b338..988b5cb901b 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -153,13 +153,13 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -D_LARGEFILE_SOURCE -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/regex.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp -$(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp -$(libcppdir)/symboldatabase.o: ../lib/symboldatabase.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/symboldatabase.o: ../lib/symboldatabase.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp $(libcppdir)/addoninfo.o: ../lib/addoninfo.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/config.h ../lib/json.h ../lib/path.h ../lib/standards.h ../lib/utils.h @@ -168,28 +168,28 @@ $(libcppdir)/addoninfo.o: ../lib/addoninfo.cpp ../externals/picojson/picojson.h $(libcppdir)/analyzerinfo.o: ../lib/analyzerinfo.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/addoninfo.h ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/addoninfo.h ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: ../lib/checkers.cpp ../lib/checkers.h ../lib/config.h @@ -198,64 +198,64 @@ $(libcppdir)/checkers.o: ../lib/checkers.cpp ../lib/checkers.h ../lib/config.h $(libcppdir)/checkersidmapping.o: ../lib/checkersidmapping.cpp ../lib/checkers.h ../lib/config.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersidmapping.cpp -$(libcppdir)/checkersreport.o: ../lib/checkersreport.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkersreport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/standards.h ../lib/utils.h +$(libcppdir)/checkersreport.o: ../lib/checkersreport.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkersreport.h ../lib/config.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp -$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp $(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/standards.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp $(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h @@ -264,13 +264,13 @@ $(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/c $(libcppdir)/color.o: ../lib/color.cpp ../lib/color.h ../lib/config.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checks.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h +$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checks.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/rule.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp $(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h @@ -279,13 +279,13 @@ $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortyp $(libcppdir)/findtoken.o: ../lib/findtoken.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp -$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp -$(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp $(libcppdir)/infer.o: ../lib/infer.cpp ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/mathlib.h ../lib/smallvector.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h @@ -312,55 +312,55 @@ $(libcppdir)/pathmatch.o: ../lib/pathmatch.cpp ../lib/config.h ../lib/path.h ../ $(libcppdir)/platform.o: ../lib/platform.cpp ../externals/tinyxml2/tinyxml2.h ../lib/config.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: ../lib/preprocessor.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h +$(libcppdir)/preprocessor.o: ../lib/preprocessor.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: ../lib/programmemory.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/programmemory.o: ../lib/programmemory.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp $(libcppdir)/regex.o: ../lib/regex.cpp ../lib/config.h ../lib/regex.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp -$(libcppdir)/reverseanalyzer.o: ../lib/reverseanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/reverseanalyzer.o: ../lib/reverseanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/sarifreport.o: ../lib/sarifreport.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/sarifreport.h ../lib/settings.h ../lib/standards.h ../lib/utils.h +$(libcppdir)/sarifreport.o: ../lib/sarifreport.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/sarifreport.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp -$(libcppdir)/settings.o: ../lib/settings.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/settings.o: ../lib/settings.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/rule.h ../lib/settings.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/settings.cpp $(libcppdir)/standards.o: ../lib/standards.cpp ../externals/simplecpp/simplecpp.h ../lib/config.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp -$(libcppdir)/summaries.o: ../lib/summaries.cpp ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/summaries.o: ../lib/summaries.cpp ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp -$(libcppdir)/suppressions.o: ../lib/suppressions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/suppressions.o: ../lib/suppressions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/templatesimplifier.o: ../lib/templatesimplifier.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: ../lib/templatesimplifier.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: ../lib/timer.cpp ../lib/config.h ../lib/timer.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: ../lib/token.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/tokenrange.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/token.o: ../lib/token.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/tokenrange.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: ../lib/utils.cpp ../lib/config.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_analyzers.o: ../lib/vf_analyzers.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_analyzers.o: ../lib/vf_analyzers.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp -$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/regex.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp $(libcppdir)/vfvalue.o: ../lib/vfvalue.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/smallvector.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 135b7c782be..3b88e050f82 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -33,6 +33,11 @@ #include "suppressions.h" #include "utils.h" +#ifdef HAVE_RULES +#include "regex.h" +#include "rule.h" +#endif + #include #include #include @@ -2728,14 +2733,14 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); ASSERT_EQUALS(2, settings->rules.size()); auto it = settings->rules.cbegin(); - ASSERT_EQUALS_ENUM(Regex::Engine::Pcre, it->engine); + ASSERT_EQUALS_ENUM(Regex::Engine::Pcre, it->regex->engine()); ASSERT_EQUALS("raw", it->tokenlist); ASSERT_EQUALS(".+", it->pattern); ASSERT_EQUALS_ENUM(Severity::error, it->severity); ASSERT_EQUALS("ruleId1", it->id); ASSERT_EQUALS("ruleSummary1", it->summary); ++it; - ASSERT_EQUALS_ENUM(Regex::Engine::Pcre, it->engine); + ASSERT_EQUALS_ENUM(Regex::Engine::Pcre, it->regex->engine()); ASSERT_EQUALS("define", it->tokenlist); ASSERT_EQUALS(".*", it->pattern); ASSERT_EQUALS_ENUM(Severity::warning, it->severity); @@ -2759,7 +2764,7 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); ASSERT_EQUALS(1, settings->rules.size()); auto it = settings->rules.cbegin(); - ASSERT_EQUALS_ENUM(Regex::Engine::Pcre, it->engine); + ASSERT_EQUALS_ENUM(Regex::Engine::Pcre, it->regex->engine()); ASSERT_EQUALS("define", it->tokenlist); ASSERT_EQUALS(".+", it->pattern); ASSERT_EQUALS_ENUM(Severity::error, it->severity); diff --git a/test/testregex.cpp b/test/testregex.cpp index 85ab8007478..f26a9fee4fa 100644 --- a/test/testregex.cpp +++ b/test/testregex.cpp @@ -47,8 +47,10 @@ class TestRegExBase : public TestFixture { std::shared_ptr assertRegex_(const char* file, int line, std::string pattern, const std::string& exp_err = "") const { std::string regex_err; auto r = Regex::create(std::move(pattern), mEngine, regex_err); - if (exp_err.empty()) + if (exp_err.empty()) { ASSERT_LOC(!!r.get(), file, line); + ASSERT_EQUALS_ENUM_LOC(mEngine, r->engine(), file, line); + } else ASSERT_LOC(!r.get(), file, line); // only not set if we encountered an error ASSERT_EQUALS_LOC(exp_err, regex_err, file, line); diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index d2147efa8c6..a434c710631 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -502,6 +502,7 @@ int main(int argc, char **argv) libfiles_h.emplace("json.h"); libfiles_h.emplace("matchcompiler.h"); libfiles_h.emplace("precompiled.h"); + libfiles_h.emplace("rule.h"); libfiles_h.emplace("smallvector.h"); libfiles_h.emplace("sourcelocation.h"); libfiles_h.emplace("tokenrange.h"); From 21ea669c0750a00583a1d060e8301b0da8b974cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 2 Jun 2026 13:11:00 +0200 Subject: [PATCH 149/493] some `Check::FileInfo`/`CTU::FileInfo` usage cleanups (#8612) --- lib/check.h | 13 ++++++------- lib/checkbufferoverrun.cpp | 10 ++++++---- lib/checkbufferoverrun.h | 6 +++--- lib/checkclass.cpp | 10 ++++++---- lib/checkclass.h | 6 +++--- lib/checknullpointer.cpp | 8 ++++---- lib/checknullpointer.h | 6 +++--- lib/checkuninitvar.cpp | 8 ++++---- lib/checkuninitvar.h | 6 +++--- lib/cppcheck.cpp | 11 +++++------ lib/cppcheck.h | 2 +- lib/ctu.cpp | 2 +- lib/ctu.h | 4 +++- test/testbufferoverrun.cpp | 4 ++-- test/testclass.cpp | 4 ++-- test/testnullpointer.cpp | 4 ++-- test/testuninitvar.cpp | 4 ++-- 17 files changed, 56 insertions(+), 52 deletions(-) diff --git a/lib/check.h b/lib/check.h index 8dda3e41825..00a360d1bf2 100644 --- a/lib/check.h +++ b/lib/check.h @@ -78,25 +78,24 @@ class CPPCHECKLIB Check { /** Base class used for whole-program analysis */ class CPPCHECKLIB FileInfo { public: - explicit FileInfo(std::string f0 = {}) : file0(std::move(f0)) {} + explicit FileInfo(std::string f0) : file0(std::move(f0)) {} virtual ~FileInfo() = default; - virtual std::string toString() const { - return std::string(); - } + virtual std::string toString() const = 0; std::string file0; }; - virtual FileInfo * getFileInfo(const Tokenizer& /*tokenizer*/, const Settings& /*settings*/, const std::string& /*currentConfig*/) const { + virtual const FileInfo * getFileInfo(const Tokenizer& /*tokenizer*/, const Settings& /*settings*/, const std::string& /*currentConfig*/) const { return nullptr; } - virtual FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const { + virtual const FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const { (void)xmlElement; + (void)file0; return nullptr; } // Return true if an error is reported. - virtual bool analyseWholeProgram(const CTU::FileInfo& /*ctu*/, const std::list& /*fileInfo*/, const Settings& /*settings*/, ErrorLogger & /*errorLogger*/) { + virtual bool analyseWholeProgram(const CTU::FileInfo& /*ctu*/, const std::list& /*fileInfo*/, const Settings& /*settings*/, ErrorLogger & /*errorLogger*/) { return false; } diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 9beef9c3079..d278208fcc3 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -900,6 +900,8 @@ namespace /** data for multifile checking */ class MyFileInfo : public Check::FileInfo { public: + explicit MyFileInfo(std::string f0) : Check::FileInfo(std::move(f0)) {} + using Check::FileInfo::FileInfo; /** unsafe array index usage */ std::list unsafeArrayIndex; @@ -952,7 +954,7 @@ bool CheckBufferOverrunImpl::isCtuUnsafePointerArith(const Settings &settings, c } /** @brief Parse current TU and extract file info */ -Check::FileInfo *CheckBufferOverrun::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const +const Check::FileInfo *CheckBufferOverrun::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const { const std::list &unsafeArrayIndex = CTU::getUnsafeUsage(tokenizer, settings, CheckBufferOverrunImpl::isCtuUnsafeArrayIndex); const std::list &unsafePointerArith = CTU::getUnsafeUsage(tokenizer, settings, CheckBufferOverrunImpl::isCtuUnsafePointerArith); @@ -965,12 +967,12 @@ Check::FileInfo *CheckBufferOverrun::getFileInfo(const Tokenizer &tokenizer, con return fileInfo; } -Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const +const Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const { const std::string arrayIndex("array-index"); const std::string pointerArith("pointer-arith"); - auto *fileInfo = new MyFileInfo; + auto *fileInfo = new MyFileInfo(file0); for (const tinyxml2::XMLElement *e = xmlElement->FirstChildElement(); e; e = e->NextSiblingElement()) { const char* name = e->Name(); if (name == arrayIndex) @@ -988,7 +990,7 @@ Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLEle } /** @brief Analyse all file infos for all TU */ -bool CheckBufferOverrun::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) +bool CheckBufferOverrun::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) { CheckBufferOverrunImpl dummy(nullptr, settings, errorLogger); dummy. diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 566ed76bd85..b0e8b28eba0 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -67,14 +67,14 @@ class CPPCHECKLIB CheckBufferOverrun : public Check { void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; + const Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; /** @brief Analyse all file infos for all TU */ - bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; + bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; - Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; + const Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const override; std::string classInfo() const override { return "Out of bounds checking:\n" diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index e917c95191e..7d3fa5c51ec 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -3693,6 +3693,8 @@ namespace /* multifile checking; one definition rule violations */ class MyFileInfo : public Check::FileInfo { public: + explicit MyFileInfo(std::string f0) : Check::FileInfo(std::move(f0)) {} + using Check::FileInfo::FileInfo; struct NameLoc { std::string className; @@ -3728,7 +3730,7 @@ namespace }; } -Check::FileInfo *CheckClass::getFileInfo(const Tokenizer &tokenizer, const Settings& /*settings*/, const std::string& currentConfig) const +const Check::FileInfo *CheckClass::getFileInfo(const Tokenizer &tokenizer, const Settings& /*settings*/, const std::string& currentConfig) const { if (!tokenizer.isCPP()) return nullptr; @@ -3798,9 +3800,9 @@ Check::FileInfo *CheckClass::getFileInfo(const Tokenizer &tokenizer, const Setti return fileInfo; } -Check::FileInfo * CheckClass::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const +const Check::FileInfo * CheckClass::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const { - auto *fileInfo = new MyFileInfo; + auto *fileInfo = new MyFileInfo(file0); for (const tinyxml2::XMLElement *e = xmlElement->FirstChildElement(); e; e = e->NextSiblingElement()) { if (std::strcmp(e->Name(), "class") != 0) continue; @@ -3828,7 +3830,7 @@ Check::FileInfo * CheckClass::loadFileInfoFromXml(const tinyxml2::XMLElement *xm return fileInfo; } -bool CheckClass::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) +bool CheckClass::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) { (void)ctu; (void)settings; diff --git a/lib/checkclass.h b/lib/checkclass.h index 6a91646ba57..a5d20432351 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -61,12 +61,12 @@ class CPPCHECKLIB CheckClass : public Check { void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings& /*settings*/, const std::string& currentConfig) const override; + const Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings& /*settings*/, const std::string& currentConfig) const override; - Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; + const Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const override; /** @brief Analyse all file infos for all TU */ - bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; + bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 5a83c3c6979..9790f7f2724 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -604,7 +604,7 @@ namespace }; } -Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& currentConfig) const +const Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& currentConfig) const { (void)currentConfig; @@ -617,18 +617,18 @@ Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer &tokenizer, const return fileInfo; } -Check::FileInfo * CheckNullPointer::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const +const Check::FileInfo * CheckNullPointer::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const { const std::list &unsafeUsage = CTU::loadUnsafeUsageListFromXml(xmlElement); if (unsafeUsage.empty()) return nullptr; - auto *fileInfo = new MyFileInfo; + auto *fileInfo = new MyFileInfo(file0); fileInfo->unsafeUsage = unsafeUsage; return fileInfo; } -bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) +bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) { (void)settings; diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index a1ccdefb658..d0bc44899a9 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -59,12 +59,12 @@ class CPPCHECKLIB CheckNullPointer : public Check { void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& currentConfig) const override; + const Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& currentConfig) const override; - Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; + const Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const override; /** @brief Analyse all file infos for all TU */ - bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; + bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; /** Get error messages. Used by --errorlist */ void getErrorMessages(ErrorLogger& errorLogger, const Settings &settings) const override; diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 7c00b705879..6bc2a86b8a5 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1727,7 +1727,7 @@ static bool isVariableUsage(const Settings &settings, const Token *argtok, CTU:: return isVariableUsage(settings, argtok, &value->value); } -Check::FileInfo *CheckUninitVar::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const +const Check::FileInfo *CheckUninitVar::getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const { const std::list &unsafeUsage = CTU::getUnsafeUsage(tokenizer, settings, ::isVariableUsage); if (unsafeUsage.empty()) @@ -1738,18 +1738,18 @@ Check::FileInfo *CheckUninitVar::getFileInfo(const Tokenizer &tokenizer, const S return fileInfo; } -Check::FileInfo * CheckUninitVar::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const +const Check::FileInfo * CheckUninitVar::loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const { const std::list &unsafeUsage = CTU::loadUnsafeUsageListFromXml(xmlElement); if (unsafeUsage.empty()) return nullptr; - auto *fileInfo = new MyFileInfo; + auto *fileInfo = new MyFileInfo(file0); fileInfo->unsafeUsage = unsafeUsage; return fileInfo; } -bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) +bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) { (void)settings; diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index dd92b3c892b..47d9061be18 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -69,12 +69,12 @@ class CPPCHECKLIB CheckUninitVar : public Check { void runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) override; /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; + const Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings, const std::string& /*currentConfig*/) const override; - Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; + const Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement, const std::string& file0) const override; /** @brief Analyse all file infos for all TU */ - bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; + bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; void getErrorMessages(ErrorLogger& errorLogger, const Settings& settings) const override; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 5eee5dbd98c..da078e5eb20 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1379,7 +1379,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation if (mSettings.useSingleJob() || analyzerInformation) { // Analyse the tokens.. { - CTU::FileInfo * const fi1 = CTU::getFileInfo(tokenizer); + const CTU::FileInfo * const fi1 = CTU::getFileInfo(tokenizer); if (analyzerInformation) analyzerInformation->setFileInfo("ctu", fi1->toString()); if (mSettings.useSingleJob()) @@ -1390,7 +1390,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation if (!doUnusedFunctionOnly) { for (const Check * const c : CheckInstances::get()) { - if (Check::FileInfo * const fi = c->getFileInfo(tokenizer, mSettings, currentConfig)) { + if (const Check::FileInfo * const fi = c->getFileInfo(tokenizer, mSettings, currentConfig)) { if (analyzerInformation) analyzerInformation->setFileInfo(c->name(), fi->toString()); if (mSettings.useSingleJob()) @@ -1855,7 +1855,7 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st executeAddonsWholeProgram(files, fileSettings, ctuInfo); - std::list fileInfoList; + std::list fileInfoList; CTU::FileInfo ctuFileInfo; const auto handler = [&fileInfoList, &ctuFileInfo](const char* checkattr, const tinyxml2::XMLElement* e, const AnalyzerInformation::Info& filesTxtInfo) { @@ -1865,8 +1865,7 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st } for (const Check *check : CheckInstances::get()) { if (checkattr == check->name()) { - if (Check::FileInfo* fi = check->loadFileInfoFromXml(e)) { - fi->file0 = filesTxtInfo.sourceFile; + if (const Check::FileInfo* fi = check->loadFileInfoFromXml(e, filesTxtInfo.sourceFile)) { fileInfoList.push_back(fi); } } @@ -1884,7 +1883,7 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st c->analyseWholeProgram(ctuFileInfo, fileInfoList, mSettings, mErrorLogger); } - for (Check::FileInfo *fi : fileInfoList) + for (const Check::FileInfo *fi : fileInfoList) delete fi; return mLogger->exitcode(); diff --git a/lib/cppcheck.h b/lib/cppcheck.h index d72e65ebb34..014b15e393a 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -250,7 +250,7 @@ class CPPCHECKLIB CppCheck { bool mUseGlobalSuppressions; /** File info used for whole program analysis */ - std::list mFileInfo; + std::list mFileInfo; /** Callback for executing a shell command (exe, args, output) */ ExecuteCmdFn mExecuteCommand; diff --git a/lib/ctu.cpp b/lib/ctu.cpp index 938bb2a4dcc..fee3acb85ae 100644 --- a/lib/ctu.cpp +++ b/lib/ctu.cpp @@ -310,7 +310,7 @@ static int isCallFunction(const Scope *scope, int argnr, const Token *&tok) } -CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer) +const CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer) { const SymbolDatabase * const symbolDatabase = tokenizer.getSymbolDatabase(); diff --git a/lib/ctu.h b/lib/ctu.h index 4f5e0b0294c..60120064284 100644 --- a/lib/ctu.h +++ b/lib/ctu.h @@ -52,6 +52,8 @@ namespace tinyxml2 { namespace CTU { class CPPCHECKLIB FileInfo : public Check::FileInfo { public: + FileInfo() : Check::FileInfo("") {} + enum class InvalidValueType : std::uint8_t { null, uninit, bufferOverflow }; std::string toString() const override; @@ -160,7 +162,7 @@ namespace CTU { CPPCHECKLIB std::string getFunctionId(const Tokenizer &tokenizer, const Function *function); /** @brief Parse current TU and extract file info */ - CPPCHECKLIB RET_NONNULL FileInfo *getFileInfo(const Tokenizer &tokenizer); + CPPCHECKLIB RET_NONNULL const FileInfo *getFileInfo(const Tokenizer &tokenizer); CPPCHECKLIB std::list getUnsafeUsage(const Tokenizer &tokenizer, const Settings &settings, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, FileInfo::Value *value)); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 54fcabab6d1..23e55748ce6 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -5361,9 +5361,9 @@ class TestBufferOverrun : public TestFixture { SimpleTokenizer tokenizer(settings0, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); + const CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); - std::list fileInfo; + std::list fileInfo; CheckBufferOverrun check; Check& c = getCheck(check); fileInfo.push_back(c.getFileInfo(tokenizer, settings0, "")); diff --git a/test/testclass.cpp b/test/testclass.cpp index 7f1a668cae1..ae5068dcb9d 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -9282,7 +9282,7 @@ class TestClass : public TestFixture { Check &check = getCheck(checkClass); // getFileInfo - std::list fileInfo; + std::list fileInfo; for (const std::string& c: code) { const std::string filename = std::to_string(fileInfo.size()) + ".cpp"; SimpleTokenizer tokenizer{settingsDefault, *this, filename}; @@ -9333,7 +9333,7 @@ class TestClass : public TestFixture { CheckClass check; const Check& c = getCheck(check); - Check::FileInfo * fileInfo = (c.getFileInfo)(tokenizer, settings1, ""); + const Check::FileInfo * fileInfo = (c.getFileInfo)(tokenizer, settings1, ""); delete fileInfo; } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index b628d294a59..99ece1c57fc 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -4690,11 +4690,11 @@ class TestNullPointer : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); + const CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); CheckNullPointer check; Check& c = getCheck(check); - std::list fileInfo; + std::list fileInfo; fileInfo.push_back(c.getFileInfo(tokenizer, settings, "")); c.analyseWholeProgram(*ctu, fileInfo, settings, *this); // TODO: check result while (!fileInfo.empty()) { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index b9e8a623cb7..e0c5512f1fd 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -5576,10 +5576,10 @@ class TestUninitVar : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); + const CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); // Check code.. - std::list fileInfo; + std::list fileInfo; CheckUninitVar check; Check& c = getCheck(check); fileInfo.push_back(c.getFileInfo(tokenizer, settings, "")); From cc77855312f0c80ef68107c4beb4e362f2b6863e Mon Sep 17 00:00:00 2001 From: Andrew C Aitchison <45234463+andrew-aitchison@users.noreply.github.com> Date: Tue, 2 Jun 2026 14:29:43 +0100 Subject: [PATCH 150/493] Add functions thread-unsafe in Ubuntu 26.04 (#8598) --- addons/threadsafety.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/threadsafety.py b/addons/threadsafety.py index 9475e1a5b0d..390a245d4e1 100755 --- a/addons/threadsafety.py +++ b/addons/threadsafety.py @@ -111,6 +111,8 @@ 'cuserid', 'drand48', 'ecvt', + 'elf_fill', + 'elf_flagelf', 'encrypt', 'endfsent', 'endgrent', From 54b9fa5523d2744250d72219afb3170756a4d8f3 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:50:27 +0200 Subject: [PATCH 151/493] Fix #14808 FN leakNoVarFunctionCall with new (#8611) --- lib/checkmemoryleak.cpp | 3 +++ test/testmemleak.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index dcde32737d5..cc8b6853f11 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -1049,6 +1049,9 @@ void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scop if (alloc == New || alloc == NewArray) { const Token* typeTok = arg->next(); bool bail = !typeTok->isStandardType() && + (!typeTok->valueType() || + (typeTok->valueType()->type < ValueType::Type::SMART_POINTER && + typeTok->valueType()->type != ValueType::Type::POD)) && !mSettings.library.detectContainerOrIterator(typeTok) && !mSettings.library.podtype(typeTok->expressionString()); if (bail && typeTok->type() && typeTok->type()->classScope && diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index fda118826bb..783a10ad089 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2613,6 +2613,21 @@ class TestMemleakNoVar : public TestFixture { ASSERT_EQUALS("[test.cpp:2:19]: (error) Allocation with new, strlen doesn't release it. [leakNoVarFunctionCall]\n" "[test.cpp:5:20]: (error) Allocation with new, strlen doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); + + check("int* f1() { return new int; }\n" // #14808 + "std::string* f2() { return new std::string(\"abc\"); }\n" + "std::clock_t* f3() { return new std::clock_t; }\n" + "QWidget* f4(QObject* parent) { return new QWidget(parent); }\n" + "void g(QObject* parent) {\n" + " assert(f1());\n" + " assert(f2());\n" + " assert(f3());\n" + " assert(f4(parent));\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6:12]: (error) Allocation with f1, assert doesn't release it. [leakNoVarFunctionCall]\n" + "[test.cpp:7:12]: (error) Allocation with f2, assert doesn't release it. [leakNoVarFunctionCall]\n" + "[test.cpp:8:12]: (error) Allocation with f3, assert doesn't release it. [leakNoVarFunctionCall]\n", + errout_str()); } void missingAssignment() { From 8cc4d37530b6d97d1bb71d47b93961a5d7dbe87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 2 Jun 2026 17:33:24 +0200 Subject: [PATCH 152/493] regex.cpp: fixed `unmatchedSuppression` (#8617) --- lib/regex.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/regex.cpp b/lib/regex.cpp index 74e3a988cd3..3a94b293ed5 100644 --- a/lib/regex.cpp +++ b/lib/regex.cpp @@ -258,7 +258,6 @@ static T* createAndCompileRegex(std::string pattern, std::string& err) return regex; } -// cppcheck-suppress shadowFunction - FP see #14802 std::shared_ptr Regex::create(std::string pattern, Engine engine, std::string& err) { Regex* regex = nullptr; From 26bff2d66cfb3572d994eca6556d5a9a05fee89e Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Tue, 2 Jun 2026 19:49:58 +0200 Subject: [PATCH 153/493] Update get_checkers.py and lib/checkers.cpp (#8616) Co-authored-by: William Jakobsson --- lib/checkers.cpp | 375 ++++++++++++++++++++++-------------------- tools/get_checkers.py | 85 +++++++--- 2 files changed, 251 insertions(+), 209 deletions(-) diff --git a/lib/checkers.cpp b/lib/checkers.cpp index f7d7f913da6..3b425926b9e 100644 --- a/lib/checkers.cpp +++ b/lib/checkers.cpp @@ -109,7 +109,7 @@ namespace checkers { {"CheckMemoryLeakNoVar::check",""}, {"CheckMemoryLeakNoVar::checkForUnsafeArgAlloc",""}, {"CheckMemoryLeakStructMember::check",""}, - {"CheckNullPointer::analyseWholeProgram","unusedfunctions"}, + {"CheckNullPointer::analyseWholeProgram",""}, {"CheckNullPointer::arithmetic",""}, {"CheckNullPointer::nullConstantDereference",""}, {"CheckNullPointer::nullPointer",""}, @@ -1677,9 +1677,25 @@ std::vector checkers::autosarInfo{ }; std::vector checkers::certCInfo{ - {"PRE30-C", "L3"}, - {"PRE31-C", "L3"}, - {"PRE32-C", "L3"}, + {"ARR30-C", "L2"}, + {"ARR32-C", "L2"}, + {"ARR36-C", "L3"}, + {"ARR37-C", "L2"}, + {"ARR38-C", "L2"}, + {"ARR39-C", "L2"}, + {"CON30-C", "L3"}, + {"CON31-C", "L3"}, + {"CON32-C", "L3"}, + {"CON33-C", "L3"}, + {"CON34-C", "L3"}, + {"CON35-C", "L3"}, + {"CON36-C", "L3"}, + {"CON37-C", "L3"}, + {"CON38-C", "L3"}, + {"CON39-C", "L3"}, + {"CON40-C", "L2"}, + {"CON41-C", "L3"}, + {"CON43-C", "L3"}, {"DCL30-C", "L2"}, {"DCL31-C", "L3"}, {"DCL36-C", "L2"}, @@ -1688,6 +1704,15 @@ std::vector checkers::certCInfo{ {"DCL39-C", "L3"}, {"DCL40-C", "L3"}, {"DCL41-C", "L2"}, + {"ENV30-C", "L3"}, + {"ENV31-C", "L3"}, + {"ENV32-C", "L1"}, + {"ENV33-C", "L1"}, + {"ENV34-C", "L3"}, + {"ERR30-C", "L1"}, + {"ERR32-C", "L3"}, + {"ERR33-C", "L1"}, + {"ERR34-C", "L2"}, {"EXP30-C", "L2"}, {"EXP32-C", "L2"}, {"EXP33-C", "L1"}, @@ -1695,7 +1720,7 @@ std::vector checkers::certCInfo{ {"EXP35-C", "L2"}, {"EXP36-C", "L3"}, {"EXP37-C", "L3"}, - {"EXP39-C", "L2"}, + {"EXP39-C", "L3"}, {"EXP40-C", "L3"}, {"EXP42-C", "L1"}, {"EXP43-C", "L3"}, @@ -1703,36 +1728,6 @@ std::vector checkers::certCInfo{ {"EXP45-C", "L2"}, {"EXP46-C", "L2"}, {"EXP47-C", "L2"}, - {"INT30-C", "L2"}, - {"INT31-C", "L1"}, - {"INT32-C", "L1"}, - {"INT33-C", "L2"}, - {"INT34-C", "L3"}, - {"INT35-C", "L3"}, - {"INT36-C", "L3"}, - {"FLP30-C", "L2"}, - {"FLP32-C", "L1"}, - {"FLP34-C", "L3"}, - {"FLP36-C", "L3"}, - {"FLP37-C", "L3"}, - {"ARR30-C", "L2"}, - {"ARR32-C", "L2"}, - {"ARR36-C", "L3"}, - {"ARR37-C", "L2"}, - {"ARR38-C", "L2"}, - {"ARR39-C", "L2"}, - {"STR30-C", "L2"}, - {"STR31-C", "L2"}, - {"STR32-C", "L1"}, - {"STR34-C", "L2"}, - {"STR37-C", "L3"}, - {"STR38-C", "L1"}, - {"MEM30-C", "L2"}, - {"MEM31-C", "L3"}, - {"MEM33-C", "L3"}, - {"MEM34-C", "L2"}, - {"MEM35-C", "L2"}, - {"MEM36-C", "L3"}, {"FIO30-C", "L1"}, {"FIO32-C", "L3"}, {"FIO34-C", "L1"}, @@ -1746,32 +1741,24 @@ std::vector checkers::certCInfo{ {"FIO45-C", "L2"}, {"FIO46-C", "L3"}, {"FIO47-C", "L2"}, - {"ENV30-C", "L3"}, - {"ENV31-C", "L3"}, - {"ENV32-C", "L1"}, - {"ENV33-C", "L1"}, - {"ENV34-C", "L3"}, - {"SIG30-C", "L1"}, - {"SIG31-C", "L1"}, - {"SIG34-C", "L3"}, - {"SIG35-C", "L3"}, - {"ERR30-C", "L1"}, - {"ERR32-C", "L3"}, - {"ERR33-C", "L1"}, - {"ERR34-C", "L2"}, - {"CON30-C", "L3"}, - {"CON31-C", "L3"}, - {"CON32-C", "L3"}, - {"CON33-C", "L3"}, - {"CON34-C", "L3"}, - {"CON35-C", "L3"}, - {"CON36-C", "L3"}, - {"CON37-C", "L3"}, - {"CON38-C", "L3"}, - {"CON39-C", "L3"}, - {"CON40-C", "L2"}, - {"CON41-C", "L3"}, - {"CON43-C", "L3"}, + {"FLP30-C", "L2"}, + {"FLP32-C", "L1"}, + {"FLP34-C", "L3"}, + {"FLP36-C", "L3"}, + {"FLP37-C", "L3"}, + {"INT30-C", "L2"}, + {"INT31-C", "L1"}, + {"INT32-C", "L1"}, + {"INT33-C", "L2"}, + {"INT34-C", "L3"}, + {"INT35-C", "L3"}, + {"INT36-C", "L3"}, + {"MEM30-C", "L2"}, + {"MEM31-C", "L3"}, + {"MEM33-C", "L3"}, + {"MEM34-C", "L2"}, + {"MEM35-C", "L2"}, + {"MEM36-C", "L3"}, {"MSC30-C", "L3"}, {"MSC32-C", "L1"}, {"MSC33-C", "L2"}, @@ -1796,21 +1783,42 @@ std::vector checkers::certCInfo{ {"POS52-C", "L3"}, {"POS53-C", "L2"}, {"POS54-C", "L1"}, + {"PRE30-C", "L3"}, + {"PRE31-C", "L3"}, + {"PRE32-C", "L3"}, + {"SIG30-C", "L1"}, + {"SIG31-C", "L1"}, + {"SIG34-C", "L3"}, + {"SIG35-C", "L3"}, + {"STR30-C", "L2"}, + {"STR31-C", "L2"}, + {"STR32-C", "L1"}, + {"STR34-C", "L2"}, + {"STR37-C", "L3"}, + {"STR38-C", "L1"}, {"WIN30-C", "L3"}, // Recommendations - {"PRE00-C", "L3"}, - {"PRE01-C", "L1"}, - {"PRE02-C", "L1"}, - {"PRE04-C", "L3"}, - {"PRE05-C", "L3"}, - {"PRE06-C", "L3"}, - {"PRE07-C", "L3"}, - {"PRE08-C", "L3"}, - {"PRE09-C", "L1"}, - {"PRE10-C", "L1"}, - {"PRE11-C", "L2"}, - {"PRE12-C", "L3"}, - {"PRE13-C", "L3"}, + {"API00-C", "L3"}, + {"API01-C", "L1"}, + {"API02-C", "L1"}, + {"API03-C", "L3"}, + {"API04-C", "L3"}, + {"API05-C", "L1"}, + {"API07-C", "L3"}, + {"API09-C", "L3"}, + {"API10-C", "L3"}, + {"ARR00-C", "L2"}, + {"ARR01-C", "L1"}, + {"ARR02-C", "L2"}, + {"CON01-C", "L3"}, + {"CON02-C", "L3"}, + {"CON03-C", "L3"}, + {"CON04-C", "L3"}, + {"CON05-C", "L3"}, + {"CON06-C", "L3"}, + {"CON07-C", "L2"}, + {"CON08-C", "L3"}, + {"CON09-C", "L3"}, {"DCL00-C", "L3"}, {"DCL01-C", "L3"}, {"DCL02-C", "L3"}, @@ -1834,6 +1842,16 @@ std::vector checkers::certCInfo{ {"DCL21-C", "L3"}, {"DCL22-C", "L3"}, {"DCL23-C", "L2"}, + {"ENV01-C", "L2"}, + {"ENV02-C", "L3"}, + {"ENV03-C", "L2"}, + {"ERR00-C", "L3"}, + {"ERR01-C", "L2"}, + {"ERR02-C", "L3"}, + {"ERR04-C", "L3"}, + {"ERR05-C", "L2"}, + {"ERR06-C", "L3"}, + {"ERR07-C", "L1"}, {"EXP00-C", "L2"}, {"EXP02-C", "L3"}, {"EXP03-C", "L3"}, @@ -1850,44 +1868,6 @@ std::vector checkers::certCInfo{ {"EXP16-C", "L2"}, {"EXP19-C", "L1"}, {"EXP20-C", "L1"}, - {"INT00-C", "L3"}, - {"INT01-C", "L2"}, - {"INT02-C", "L3"}, - {"INT04-C", "L1"}, - {"INT05-C", "L2"}, - {"INT07-C", "L1"}, - {"INT08-C", "L3"}, - {"INT09-C", "L3"}, - {"INT10-C", "L3"}, - {"INT12-C", "L3"}, - {"INT13-C", "L2"}, - {"INT14-C", "L3"}, - {"INT15-C", "L2"}, - {"INT16-C", "L3"}, - {"INT17-C", "L3"}, - {"INT18-C", "L1"}, - {"FLP00-C", "L3"}, - {"FLP01-C", "L3"}, - {"FLP02-C", "L3"}, - {"FLP03-C", "L3"}, - {"FLP04-C", "L3"}, - {"FLP05-C", "L3"}, - {"FLP06-C", "L3"}, - {"FLP07-C", "L3"}, - {"ARR00-C", "L2"}, - {"ARR01-C", "L1"}, - {"ARR02-C", "L2"}, - {"STR00-C", "L3"}, - {"STR01-C", "L3"}, - {"STR02-C", "L2"}, - {"STR03-C", "L3"}, - {"STR04-C", "L3"}, - {"STR05-C", "L3"}, - {"STR06-C", "L2"}, - {"STR08-C", "L2"}, - {"STR09-C", "L3"}, - {"STR10-C", "L3"}, - {"STR11-C", "L2"}, {"FIO01-C", "L1"}, {"FIO02-C", "L3"}, {"FIO03-C", "L3"}, @@ -1908,36 +1888,41 @@ std::vector checkers::certCInfo{ {"FIO22-C", "L3"}, {"FIO23-C", "L3"}, {"FIO24-C", "L3"}, - {"ENV01-C", "L2"}, - {"ENV02-C", "L3"}, - {"ENV03-C", "L2"}, - {"SIG00-C", "L2"}, - {"SIG01-C", "L3"}, - {"SIG02-C", "L2"}, - {"ERR00-C", "L3"}, - {"ERR01-C", "L2"}, - {"ERR02-C", "L3"}, - {"ERR04-C", "L3"}, - {"ERR05-C", "L2"}, - {"ERR06-C", "L3"}, - {"ERR07-C", "L1"}, - {"API00-C", "L3"}, - {"API01-C", "L1"}, - {"API02-C", "L1"}, - {"API03-C", "L3"}, - {"API04-C", "L3"}, - {"API05-C", "L1"}, - {"API07-C", "L3"}, - {"API09-C", "L3"}, - {"API10-C", "L3"}, - {"CON01-C", "L3"}, - {"CON02-C", "L3"}, - {"CON04-C", "L3"}, - {"CON05-C", "L3"}, - {"CON06-C", "L3"}, - {"CON07-C", "L2"}, - {"CON08-C", "L3"}, - {"CON09-C", "L3"}, + {"FLP00-C", "L3"}, + {"FLP01-C", "L3"}, + {"FLP02-C", "L3"}, + {"FLP03-C", "L3"}, + {"FLP04-C", "L3"}, + {"FLP05-C", "L3"}, + {"FLP06-C", "L3"}, + {"FLP07-C", "L3"}, + {"INT00-C", "L3"}, + {"INT01-C", "L2"}, + {"INT02-C", "L3"}, + {"INT04-C", "L1"}, + {"INT05-C", "L2"}, + {"INT07-C", "L1"}, + {"INT08-C", "L3"}, + {"INT09-C", "L3"}, + {"INT10-C", "L3"}, + {"INT12-C", "L3"}, + {"INT13-C", "L2"}, + {"INT14-C", "L3"}, + {"INT15-C", "L2"}, + {"INT16-C", "L3"}, + {"INT17-C", "L3"}, + {"INT18-C", "L1"}, + {"MEM00-C", "L1"}, + {"MEM01-C", "L2"}, + {"MEM02-C", "L3"}, + {"MEM03-C", "L3"}, + {"MEM04-C", "L2"}, + {"MEM05-C", "L2"}, + {"MEM06-C", "L3"}, + {"MEM07-C", "L2"}, + {"MEM10-C", "L3"}, + {"MEM11-C", "L3"}, + {"MEM12-C", "L3"}, {"MSC00-C", "L3"}, {"MSC01-C", "L3"}, {"MSC04-C", "L3"}, @@ -1964,6 +1949,32 @@ std::vector checkers::certCInfo{ {"POS02-C", "L2"}, {"POS04-C", "L3"}, {"POS05-C", "L3"}, + {"PRE00-C", "L3"}, + {"PRE01-C", "L1"}, + {"PRE02-C", "L1"}, + {"PRE04-C", "L3"}, + {"PRE05-C", "L3"}, + {"PRE06-C", "L3"}, + {"PRE07-C", "L3"}, + {"PRE08-C", "L3"}, + {"PRE09-C", "L1"}, + {"PRE10-C", "L1"}, + {"PRE11-C", "L2"}, + {"PRE12-C", "L3"}, + {"PRE13-C", "L3"}, + {"SIG00-C", "L2"}, + {"SIG01-C", "L3"}, + {"SIG02-C", "L2"}, + {"STR00-C", "L3"}, + {"STR01-C", "L3"}, + {"STR02-C", "L2"}, + {"STR03-C", "L3"}, + {"STR04-C", "L3"}, + {"STR05-C", "L3"}, + {"STR06-C", "L2"}, + {"STR09-C", "L3"}, + {"STR10-C", "L3"}, + {"STR11-C", "L2"}, {"WIN00-C", "L2"}, {"WIN01-C", "L1"}, {"WIN02-C", "L1"}, @@ -1972,6 +1983,22 @@ std::vector checkers::certCInfo{ }; std::vector checkers::certCppInfo{ + {"CON50-CPP", "L3"}, + {"CON51-CPP", "L2"}, + {"CON52-CPP", "L3"}, + {"CON53-CPP", "L3"}, + {"CON54-CPP", "L3"}, + {"CON55-CPP", "L3"}, + {"CON56-CPP", "L3"}, + {"CTR50-CPP", "L2"}, + {"CTR51-CPP", "L2"}, + {"CTR52-CPP", "L2"}, + {"CTR53-CPP", "L2"}, + {"CTR54-CPP", "L3"}, + {"CTR55-CPP", "L2"}, + {"CTR56-CPP", "L2"}, + {"CTR57-CPP", "L3"}, + {"CTR58-CPP", "L2"}, {"DCL50-CPP", "L1"}, {"DCL51-CPP", "L3"}, {"DCL52-CPP", "L3"}, @@ -1983,6 +2010,19 @@ std::vector checkers::certCppInfo{ {"DCL58-CPP", "L2"}, {"DCL59-CPP", "L3"}, {"DCL60-CPP", "L2"}, + {"ERR50-CPP", "L3"}, + {"ERR51-CPP", "L2"}, + {"ERR52-CPP", "L3"}, + {"ERR53-CPP", "L3"}, + {"ERR54-CPP", "L1"}, + {"ERR55-CPP", "L2"}, + {"ERR56-CPP", "L2"}, + {"ERR57-CPP", "L3"}, + {"ERR58-CPP", "L2"}, + {"ERR59-CPP", "L2"}, + {"ERR60-CPP", "L3"}, + {"ERR61-CPP", "L3"}, + {"ERR62-CPP", "L3"}, {"EXP50-CPP", "L2"}, {"EXP51-CPP", "L3"}, {"EXP52-CPP", "L3"}, @@ -1997,20 +2037,9 @@ std::vector checkers::certCppInfo{ {"EXP61-CPP", "L2"}, {"EXP62-CPP", "L1"}, {"EXP63-CPP", "L2"}, + {"FIO50-CPP", "L2"}, + {"FIO51-CPP", "L3"}, {"INT50-CPP", "L3"}, - {"CTR50-CPP", "L2"}, - {"CTR51-CPP", "L2"}, - {"CTR52-CPP", "L2"}, - {"CTR53-CPP", "L2"}, - {"CTR54-CPP", "L3"}, - {"CTR55-CPP", "L2"}, - {"CTR56-CPP", "L2"}, - {"CTR57-CPP", "L3"}, - {"CTR58-CPP", "L2"}, - {"STR50-CPP", "L2"}, - {"STR51-CPP", "L1"}, - {"STR52-CPP", "L2"}, - {"STR53-CPP", "L3"}, {"MEM50-CPP", "L2"}, {"MEM51-CPP", "L2"}, {"MEM52-CPP", "L1"}, @@ -2019,21 +2048,11 @@ std::vector checkers::certCppInfo{ {"MEM55-CPP", "L2"}, {"MEM56-CPP", "L2"}, {"MEM57-CPP", "L3"}, - {"FIO50-CPP", "L2"}, - {"FIO51-CPP", "L3"}, - {"ERR50-CPP", "L3"}, - {"ERR51-CPP", "L2"}, - {"ERR52-CPP", "L3"}, - {"ERR53-CPP", "L3"}, - {"ERR54-CPP", "L1"}, - {"ERR55-CPP", "L2"}, - {"ERR56-CPP", "L2"}, - {"ERR57-CPP", "L3"}, - {"ERR58-CPP", "L2"}, - {"ERR59-CPP", "L2"}, - {"ERR60-CPP", "L3"}, - {"ERR61-CPP", "L3"}, - {"ERR62-CPP", "L3"}, + {"MSC50-CPP", "L3"}, + {"MSC51-CPP", "L1"}, + {"MSC52-CPP", "L2"}, + {"MSC53-CPP", "L3"}, + {"MSC54-CPP", "L2"}, {"OOP50-CPP", "L3"}, {"OOP51-CPP", "L3"}, {"OOP52-CPP", "L3"}, @@ -2043,17 +2062,9 @@ std::vector checkers::certCppInfo{ {"OOP56-CPP", "L3"}, {"OOP57-CPP", "L1"}, {"OOP58-CPP", "L2"}, - {"CON50-CPP", "L3"}, - {"CON51-CPP", "L2"}, - {"CON52-CPP", "L3"}, - {"CON53-CPP", "L3"}, - {"CON54-CPP", "L3"}, - {"CON55-CPP", "L3"}, - {"CON56-CPP", "L3"}, - {"MSC50-CPP", "L3"}, - {"MSC51-CPP", "L1"}, - {"MSC52-CPP", "L2"}, - {"MSC53-CPP", "L3"}, - {"MSC54-CPP", "L2"}, + {"STR50-CPP", "L2"}, + {"STR51-CPP", "L1"}, + {"STR52-CPP", "L2"}, + {"STR53-CPP", "L3"}, }; diff --git a/tools/get_checkers.py b/tools/get_checkers.py index 4594b773dc2..48455200fb5 100644 --- a/tools/get_checkers.py +++ b/tools/get_checkers.py @@ -2,8 +2,18 @@ import glob import os import re +import sys import requests +try: + from tqdm import tqdm +except ImportError: + # Fallback: passthrough iterator if tqdm is not installed + def tqdm(iterable, total=None, desc=None, **kwargs): + if desc: + print(desc, file=sys.stderr) + return iterable + def print_checkers(glob_pattern:str): checkers = {} for filename in glob.glob(glob_pattern): @@ -908,44 +918,65 @@ def print_checkers(glob_pattern:str): }; """) +# SEI CERT is available as markdown files at +# https://github.com/cmu-sei/secure-coding-standards +CERT_REPO = 'cmu-sei/secure-coding-standards' +CERT_BRANCH = 'main' + +# Cache git tree +_cert_tree = None + +def listCertFiles(content_subdir:str): + """Lists the rules and recommendation files for one part of the standard.""" + global _cert_tree + if _cert_tree is None: + url = 'https://api.github.com/repos/%s/git/trees/%s?recursive=1' % (CERT_REPO, CERT_BRANCH) + _cert_tree = requests.get(url, timeout=50).json()['tree'] + prefix = 'content/' + content_subdir + files = [] + for entry in _cert_tree: + path = entry['path'] + if entry['type'] != 'blob' or not path.startswith(prefix) or not path.endswith('.md'): + continue + if 'index' in path.rsplit('/', 1)[-1].lower(): + continue + files.append(path) + return sorted(files) -def getCertCInfo(main_url:str): +def printCertCInfo(content_subdir:str): """Fetches CERT C rules information.""" - # Fetching the CERT C rules page - r = requests.get(main_url, timeout=30) - mainpage = r.text - for line in mainpage.split('\n'): - res = re.search(r'(Rule|Rec.) \d\d[.] [A-Za-z ]+ [(][A-Z][A-Z][A-Z][)]', line) + paths = listCertFiles(content_subdir) + rules = {} + for path in tqdm(paths, total=len(paths), desc=f'Fetching {content_subdir}', file=sys.stderr): + raw = 'https://raw.githubusercontent.com/%s/%s/%s' % (CERT_REPO, CERT_BRANCH, path) + text = requests.get(raw, timeout=30).text + res = re.search(r'^#\s+([A-Z]{3}\d{2}-C(?:PP)?)\b', text, re.MULTILINE) if res is None: continue - r = requests.get('https://wiki.sei.cmu.edu' + res.group(1), timeout=30) - text = r.text.replace('\n', '').replace('', '\n').replace('', '\n') - rules = [] - for line in text.split('\n'): - if not line.startswith(']+>([A-Z][A-Z][A-Z][0-9][0-9]-CP*)<.*>(L[1-3])<.+', line) - if res: - if res.group(1) == 'EXP40-C' and 'EXP39-C' not in rules: - print(' {"EXP39-C", "L2"},') - print(' {"%s", "%s"},' % (res.group(1), res.group(2))) - rules.append(res.group(1)) - if 'EXP45-C' in rules: - if 'EXP46-C' not in rules: - print(' {"EXP46-C", "L2"},') - if 'EXP47-C' not in rules: - print(' {"EXP47-C", "L2"},') + head = re.search(r'^#{0,4}\s*Risk Assessments?\s*$', text, re.MULTILINE) + if head is None: + continue + section = text[head.end():] + nexthead = re.search(r'^#{1,4}\s+\S', section, re.MULTILINE) + if nexthead: + section = section[:nexthead.start()] + level = re.search(r'\bL[1-3]\b', section) + if level is None: + continue + rules[res.group(1)] = level.group(0) + for rule_id, level in dict(sorted(rules.items())).items(): + print(' {"%s", "%s"},' % (rule_id, level)) + print('std::vector checkers::certCInfo{') -getCertCInfo('https://wiki.sei.cmu.edu/confluence/display/c/2+Rules') +printCertCInfo('4.sei-cert-c-coding-standard/03.rules/') print(' // Recommendations') -getCertCInfo('https://wiki.sei.cmu.edu/confluence/display/c/3+Recommendations') +printCertCInfo('4.sei-cert-c-coding-standard/08.recommendations/') print('};') print('') print('std::vector checkers::certCppInfo{') -getCertCInfo('https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682') +printCertCInfo('5.sei-cert-cpp-coding-standard/3.rules/') print('};') print('') From e1053dba3b0988dc828d7a9c4b2a8f6c9866035b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 3 Jun 2026 08:37:59 +0200 Subject: [PATCH 154/493] Add test for #11841 (#8621) Co-authored-by: chrchr-github --- test/testsymboldatabase.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index e981c8ea546..84681b00c85 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -430,6 +430,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(symboldatabase110); TEST_CASE(symboldatabase111); // [[fallthrough]] TEST_CASE(symboldatabase112); // explicit operator + TEST_CASE(symboldatabase113); TEST_CASE(createSymbolDatabaseFindAllScopes1); TEST_CASE(createSymbolDatabaseFindAllScopes2); @@ -5864,6 +5865,33 @@ class TestSymbolDatabase : public TestFixture { ASSERT(f && f->function() && f->function()->isExplicit()); } + void symboldatabase113() { // #11841 + GET_SYMBOL_DB("template \n" + "struct S {\n" + " S();\n" + " int& g() { return a; }\n" + " struct I;\n" + "private:\n" + " int a;\n" + "};\n" + "template <>\n" + "struct S::I{};\n"); + ASSERT(db->scopeList.size() == 4); + auto it = db->scopeList.begin(); + ++it; + ASSERT_EQUALS_ENUM(ScopeType::eStruct, it->type); + ASSERT_EQUALS("I", it->className); + ASSERT_EQUALS(0, it->varlist.size()); + ++it; + ASSERT_EQUALS_ENUM(ScopeType::eStruct, it->type); + ASSERT_EQUALS("S < int >", it->className); + ASSERT_EQUALS(1, it->varlist.size()); + ++it; + ASSERT_EQUALS_ENUM(ScopeType::eFunction, it->type); + ASSERT_EQUALS("g", it->className); + ASSERT_EQUALS(0, it->varlist.size()); + } + void createSymbolDatabaseFindAllScopes1() { GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }"); ASSERT(db->scopeList.size() == 3); From 49b8c2aade94ccb592411a7fd35a0aafe91d7914 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 3 Jun 2026 19:32:41 +0200 Subject: [PATCH 155/493] Add test for #12041 (#8626) --- test/testsimplifytypedef.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 022412139f1..84a95a81cfc 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -232,6 +232,7 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedef159); TEST_CASE(simplifyTypedef160); TEST_CASE(simplifyTypedef161); + TEST_CASE(simplifyTypedef162); TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -3859,6 +3860,14 @@ class TestSimplifyTypedef : public TestFixture { TODO_ASSERT_EQUALS(exp2, cur2, tok(code2)); } + void simplifyTypedef162() { + const char code[] = "using std::vector;\n" // #12041 + "typedef vector ints;\n" + "void f(ints v);\n"; + const char exp[] = "void f ( std :: vector < int > v ) ;"; + ASSERT_EQUALS(exp, tok(code)); + } + void simplifyTypedefFunction1() { { const char code[] = "typedef void (*my_func)();\n" From 9f74c2db8bc800b1f1e612dd8cccf868725eaaf4 Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Thu, 4 Jun 2026 09:06:25 +0200 Subject: [PATCH 156/493] fix #14813 crash: recheck in gui sometimes crashes (#8628) --- gui/resultstree.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index c553855e99e..fc70fdb84af 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -427,8 +427,8 @@ void ResultsTree::clear(const QString &filename) if (stripped == fileItem->text() || filename == fileItem->errorItem->file0) { - mModel->removeRow(i); mErrorList.removeAll(fileItem->errorItem->toString()); + mModel->removeRow(i); break; } } @@ -445,8 +445,8 @@ void ResultsTree::clearRecheckFile(const QString &filename) QString storedfile = fileItem->getErrorPathItem().file; storedfile = ((!mCheckPath.isEmpty() && storedfile.startsWith(mCheckPath)) ? storedfile.mid(mCheckPath.length() + 1) : storedfile); if (actualfile == storedfile) { - mModel->removeRow(i); mErrorList.removeAll(fileItem->errorItem->toString()); + mModel->removeRow(i); break; } } From bb69f669438f9d243a2a12aec509b0431aae4fe4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 4 Jun 2026 09:44:08 +0200 Subject: [PATCH 157/493] Fix #14772 FN returnDanglingLifetime for new expression (#8570) --- lib/checkautovariables.cpp | 7 +++++-- test/testautovariables.cpp | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 0493f3ea459..b848928ebf4 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -614,8 +614,11 @@ void CheckAutoVariablesImpl::checkVarLifetimeScope(const Token * start, const To } } } - const bool escape = Token::simpleMatch(tok->astParent(), "throw") || - (Token::simpleMatch(tok->astParent(), "return") && !Function::returnsStandardType(scope->function)); + const Token* retThrow = tok->astParent(); + if (Token::simpleMatch(retThrow, "new")) + retThrow = retThrow->astParent(); + const bool escape = Token::simpleMatch(retThrow, "throw") || + (Token::simpleMatch(retThrow, "return") && !Function::returnsStandardType(scope->function)); std::unordered_set exprs; for (const ValueFlow::Value& val:tok->values()) { if (!val.isLocalLifetimeValue() && !val.isSubFunctionLifetimeValue()) diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 47484d7023e..9fe3e126660 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -4062,6 +4062,14 @@ class TestAutoVariables : public TestFixture { " struct S s = { .i = 0, true };\n" "}\n"); // don't crash ASSERT_EQUALS("", errout_str()); + + check("struct A { int& r; };\n" // #14772 + "A* f() {\n" + " int x = 0;\n" + " return new A{ x };\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:19] -> [test.cpp:3:9] -> [test.cpp:4:17]: (error) Returning object that points to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); } void danglingLifetimeInitList() { From 56d86d3fabb33f2d2ca392d008dcbb80301bd1cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 4 Jun 2026 09:59:14 +0200 Subject: [PATCH 158/493] settings.h: forward declare `AddonInfo` (#8602) --- Makefile | 248 +++++++++++------------ gui/test/projectfile/testprojectfile.cpp | 1 + lib/settings.cpp | 1 + lib/settings.h | 2 +- oss-fuzz/Makefile | 88 ++++---- 5 files changed, 171 insertions(+), 169 deletions(-) diff --git a/Makefile b/Makefile index 0fc1d8e94e6..42b754733ec 100644 --- a/Makefile +++ b/Makefile @@ -483,13 +483,13 @@ check-nonneg: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp -$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp -$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp $(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/addoninfo.h lib/config.h lib/json.h lib/path.h lib/standards.h lib/utils.h @@ -498,28 +498,28 @@ $(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/ad $(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: lib/astutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h @@ -531,61 +531,61 @@ $(libcppdir)/checkersidmapping.o: lib/checkersidmapping.cpp lib/checkers.h lib/c $(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/addoninfo.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp -$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkio.o: lib/checkio.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkother.o: lib/checkother.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp $(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkimpl.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/standards.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checktype.o: lib/checktype.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp $(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h @@ -600,7 +600,7 @@ $(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h external $(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h @@ -609,13 +609,13 @@ $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/ $(libcppdir)/findtoken.o: lib/findtoken.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp -$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp -$(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp $(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h @@ -642,19 +642,19 @@ $(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatc $(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp $(libcppdir)/regex.o: lib/regex.cpp lib/config.h lib/regex.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp -$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h +$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp $(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/rule.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/utils.h lib/vfvalue.h @@ -663,49 +663,49 @@ $(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addo $(libcppdir)/standards.o: lib/standards.cpp externals/simplecpp/simplecpp.h lib/config.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp -$(libcppdir)/summaries.o: lib/summaries.cpp lib/addoninfo.h lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/summaries.o: lib/summaries.cpp lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp $(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: lib/timer.cpp lib/config.h lib/timer.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp -$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vfvalue.cpp -frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/addoninfo.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h +frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_FE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ frontend/frontend.cpp cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp -cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp -cli/executor.o: cli/executor.cpp cli/executor.h lib/addoninfo.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/executor.o: cli/executor.cpp cli/executor.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/standards.h lib/utils.h @@ -714,7 +714,7 @@ cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesetti cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/main.cpp -cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/processexecutor.cpp cli/sehwrapper.o: cli/sehwrapper.cpp cli/sehwrapper.h lib/config.h lib/utils.h @@ -723,247 +723,247 @@ cli/sehwrapper.o: cli/sehwrapper.cpp cli/sehwrapper.h lib/config.h lib/utils.h cli/signalhandler.o: cli/signalhandler.cpp cli/signalhandler.h cli/stacktrace.h lib/config.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/signalhandler.cpp -cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h +cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/singleexecutor.cpp cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/stacktrace.cpp -cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h +test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp -test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h +test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp -test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/main.cpp test/options.o: test/options.cpp lib/config.h lib/timer.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp -test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp -test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp -test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp -test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testastutils.o: test/testastutils.cpp lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp -test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testautovariables.o: test/testautovariables.cpp lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp -test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testbool.o: test/testbool.cpp lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp -test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp -test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheck.o: test/testcheck.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheckersreport.cpp -test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testclass.o: test/testclass.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp -test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcolor.o: test/testcolor.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp -test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcondition.o: test/testcondition.cpp lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp -test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testconstructors.o: test/testconstructors.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp -test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h +test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp -test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp -test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexecutor.cpp -test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp -test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilesettings.o: test/testfilesettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp -test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfrontend.o: test/testfrontend.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp -test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testfunctions.o: test/testfunctions.cpp lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp -test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testgarbage.o: test/testgarbage.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp -test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h +test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp -test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testincompletestatement.o: test/testincompletestatement.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp -test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testinternal.o: test/testinternal.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp -test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testio.o: test/testio.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp -test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testleakautovar.o: test/testleakautovar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp -test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testlibrary.o: test/testlibrary.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp -test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testmathlib.o: test/testmathlib.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp -test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testmemleak.o: test/testmemleak.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp -test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testnullpointer.o: test/testnullpointer.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp -test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/testoptions.o: test/testoptions.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp -test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testother.o: test/testother.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp -test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpath.o: test/testpath.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp -test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testpathmatch.o: test/testpathmatch.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpathmatch.cpp -test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp -test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp -test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp -test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp -test/testprogrammemory.o: test/testprogrammemory.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testprogrammemory.o: test/testprogrammemory.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprogrammemory.cpp -test/testregex.o: test/testregex.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testregex.o: test/testregex.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testregex.cpp -test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsarifreport.cpp -test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsettings.o: test/testsettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp -test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytemplate.cpp -test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytokens.cpp -test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytypedef.cpp -test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifyusing.cpp -test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp -test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsizeof.o: test/testsizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp -test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/teststandards.o: test/teststandards.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststl.o: test/teststl.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp -test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststring.o: test/teststring.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp -test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsummaries.o: test/testsummaries.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsummaries.cpp test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp -test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp -test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp -test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h +test/testtimer.o: test/testtimer.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp -test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtoken.o: test/testtoken.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtoken.cpp -test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenize.cpp -test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenlist.cpp -test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenrange.o: test/testtokenrange.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testtype.o: test/testtype.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp -test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testuninitvar.o: test/testuninitvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp -test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp -test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp -test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp -test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testutils.o: test/testutils.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp -test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testvaarg.o: test/testvaarg.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp -test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvalueflow.o: test/testvalueflow.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp -test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvarid.o: test/testvarid.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp -test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testvfvalue.o: test/testvfvalue.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvfvalue.cpp externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h diff --git a/gui/test/projectfile/testprojectfile.cpp b/gui/test/projectfile/testprojectfile.cpp index 3eaa2b10386..efc1dce6c4f 100644 --- a/gui/test/projectfile/testprojectfile.cpp +++ b/gui/test/projectfile/testprojectfile.cpp @@ -18,6 +18,7 @@ #include "testprojectfile.h" +#include "addoninfo.h" #include "library.h" #include "platform.h" #include "projectfile.h" diff --git a/lib/settings.cpp b/lib/settings.cpp index a9ba14dd72b..95d4c4e953b 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include "addoninfo.h" #include "config.h" #include "errortypes.h" #include "settings.h" diff --git a/lib/settings.h b/lib/settings.h index 80f3853bde6..04ddb9adb9a 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -21,7 +21,6 @@ #define settingsH //--------------------------------------------------------------------------- -#include "addoninfo.h" #include "config.h" #include "library.h" #include "platform.h" @@ -47,6 +46,7 @@ struct Rule; #endif struct Suppressions; +struct AddonInfo; namespace ValueFlow { class Value; } diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 988b5cb901b..eeb795bd35c 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -153,13 +153,13 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -D_LARGEFILE_SOURCE -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp -$(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp -$(libcppdir)/symboldatabase.o: ../lib/symboldatabase.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/symboldatabase.o: ../lib/symboldatabase.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp $(libcppdir)/addoninfo.o: ../lib/addoninfo.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/config.h ../lib/json.h ../lib/path.h ../lib/standards.h ../lib/utils.h @@ -168,28 +168,28 @@ $(libcppdir)/addoninfo.o: ../lib/addoninfo.cpp ../externals/picojson/picojson.h $(libcppdir)/analyzerinfo.o: ../lib/analyzerinfo.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/addoninfo.h ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: ../lib/checkers.cpp ../lib/checkers.h ../lib/config.h @@ -201,61 +201,61 @@ $(libcppdir)/checkersidmapping.o: ../lib/checkersidmapping.cpp ../lib/checkers.h $(libcppdir)/checkersreport.o: ../lib/checkersreport.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkersreport.h ../lib/config.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp -$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp $(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/standards.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp $(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h @@ -270,7 +270,7 @@ $(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h .. $(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h @@ -279,13 +279,13 @@ $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortyp $(libcppdir)/findtoken.o: ../lib/findtoken.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp -$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp -$(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp $(libcppdir)/infer.o: ../lib/infer.cpp ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/mathlib.h ../lib/smallvector.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h @@ -312,19 +312,19 @@ $(libcppdir)/pathmatch.o: ../lib/pathmatch.cpp ../lib/config.h ../lib/path.h ../ $(libcppdir)/platform.o: ../lib/platform.cpp ../externals/tinyxml2/tinyxml2.h ../lib/config.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: ../lib/preprocessor.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h +$(libcppdir)/preprocessor.o: ../lib/preprocessor.cpp ../externals/simplecpp/simplecpp.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: ../lib/programmemory.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/programmemory.o: ../lib/programmemory.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp $(libcppdir)/regex.o: ../lib/regex.cpp ../lib/config.h ../lib/regex.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp -$(libcppdir)/reverseanalyzer.o: ../lib/reverseanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/reverseanalyzer.o: ../lib/reverseanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/sarifreport.o: ../lib/sarifreport.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/sarifreport.h ../lib/settings.h ../lib/standards.h ../lib/utils.h +$(libcppdir)/sarifreport.o: ../lib/sarifreport.cpp ../externals/picojson/picojson.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/sarifreport.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp $(libcppdir)/settings.o: ../lib/settings.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/rule.h ../lib/settings.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/utils.h ../lib/vfvalue.h @@ -333,34 +333,34 @@ $(libcppdir)/settings.o: ../lib/settings.cpp ../externals/picojson/picojson.h .. $(libcppdir)/standards.o: ../lib/standards.cpp ../externals/simplecpp/simplecpp.h ../lib/config.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp -$(libcppdir)/summaries.o: ../lib/summaries.cpp ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/summaries.o: ../lib/summaries.cpp ../lib/analyzerinfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp $(libcppdir)/suppressions.o: ../lib/suppressions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/templatesimplifier.o: ../lib/templatesimplifier.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: ../lib/templatesimplifier.cpp ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: ../lib/timer.cpp ../lib/config.h ../lib/timer.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: ../lib/token.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/tokenrange.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/token.o: ../lib/token.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/tokenrange.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: ../lib/utils.cpp ../lib/config.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_analyzers.o: ../lib/vf_analyzers.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_analyzers.o: ../lib/vf_analyzers.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp -$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp $(libcppdir)/vfvalue.o: ../lib/vfvalue.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/smallvector.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h From 550189be664fa27e754df5eb8f182748e7dd56df Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:26:32 +0200 Subject: [PATCH 159/493] fixed #14738 gui recheck file not working properly when importing compile_commands.json (#8625) --- gui/mainwindow.cpp | 11 +++++++++-- gui/mainwindow.h | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 15f3e8e0665..bf73828bed4 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -559,13 +559,20 @@ void MainWindow::saveSettings() const mUI->mResults->saveSettings(mSettings); } -void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bool checkConfig) +void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bool checkConfig, const QStringList& recheckFiles) { Settings checkSettings; auto supprs = std::make_shared(); if (!getCppcheckSettings(checkSettings, *supprs)) return; + // filter requested files + if (!recheckFiles.isEmpty()) { + p.fileSettings.remove_if([&](const FileSettings& fs) { + return !recheckFiles.contains(QString::fromStdString(fs.filename())); + }); + } + clearResults(); mIsLogfileLoaded = false; @@ -1958,7 +1965,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis msg.exec(); return; } - doAnalyzeProject(p, checkLib, checkConfig); // TODO: avoid copy + doAnalyzeProject(p, checkLib, checkConfig, recheckFiles); // TODO: avoid copy return; } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index febd3a41d4c..c654a2c94f0 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -309,7 +309,7 @@ private slots: * @param checkLib Flag to indicate if library should be checked * @param checkConfig Flag to indicate if the configuration should be checked. */ - void doAnalyzeProject(ImportProject p, bool checkLib = false, bool checkConfig = false); + void doAnalyzeProject(ImportProject p, bool checkLib = false, bool checkConfig = false, const QStringList& recheckFiles = QStringList()); /** * @brief Analyze all files specified in parameter files From 0491f5911627315760adcda62217a2763b3d71bb Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:37:08 +0200 Subject: [PATCH 160/493] Clear releasenotes [skip ci] (#8623) --- releasenotes.txt | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/releasenotes.txt b/releasenotes.txt index 4fb45b90070..185f06390e3 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -1,14 +1,11 @@ -Release Notes for Cppcheck 2.21 +Release Notes for Cppcheck 2.22 Major bug fixes & crashes: - New checks: -- MISRA C 2012 rule 10.3 now warns on assigning integer literals 0 and 1 to bool in C99 and later while preserving the existing C89 behavior. -- funcArgNamesDifferentUnnamed warns on function declarations/definitions where a parameter in either location is unnamed -- uninitMemberVarNoCtor warns on user-defined types where (1) some but not all members requiring initialization have in-class initializers or (2) there is a mixture of members which do/do not require initialization. -- fcloseInLoopCondition warns when fclose() is used as a while loop condition, which may skip the loop body or double-close the file handle. +- C/C++ support: - @@ -23,9 +20,4 @@ Infrastructure & dependencies: - Other: -- Make it possible to specify the regular expression engine using the `engine` element in a rule XML. -- Added CLI option `--exitcode-suppress` to specify an error ID which should not result in a non-zero exitcode. -- Moved source code from https://github.com/danmar/cppcheck to https://github.com/cppcheck-opensource/cppcheck -- The official Windows binary is now built with Visual Studio 2026. -- Updated simplecpp to 1.7.0. - From 2285c1daf9e61ce9f27c16a62a362130c799422f Mon Sep 17 00:00:00 2001 From: Tomo Dote Date: Fri, 5 Jun 2026 05:02:53 +0900 Subject: [PATCH 161/493] Update Japanese translation for v2.21 (#8630) Update only Japanese translation - modified: gui/cppcheck_ja.ts --- gui/cppcheck_ja.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index b3252ec769d..a071727ad56 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -1732,17 +1732,17 @@ Options: Include file - + インクルードファイル <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> - + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">ヘッダファイルを強制的にインクルードします</span></p></body></html> Browse.. - + ブラウズ.. @@ -2091,12 +2091,12 @@ Options: C/C++ header - + C/C++のヘッダー Include file - + ファイルのインクルード From 70af35891e33d2d077137910437e8f2626b0a08f Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Fri, 5 Jun 2026 12:57:55 +0200 Subject: [PATCH 162/493] createrelease: tweaks [skip ci] (#8635) --- createrelease | 93 ++++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/createrelease b/createrelease index de85d64395b..6a611a5a469 100755 --- a/createrelease +++ b/createrelease @@ -1,6 +1,6 @@ #!/bin/bash # -# A script for creating release packages. The release packages are create in the home directory. +# A script for creating release packages. The release packages are created in the home directory. # # Create release candidate # ======================== @@ -8,15 +8,22 @@ # Review trac roadmap, are tickets closed properly? # Only tickets that should be retargeted should be open. # -# update cppcheck used in premium addon CI -# create jira issue "CI: update cppcheck binary" -# cd ~/cppchecksolutions/addon/tools && python3 ci-update-cppcheck.py +# Versioning scheme +# ======================== +# VERSION=2.22.0 # the new release tag created +# PREV=2.21.0 # the previous release +# BRANCH=2.22.x # release branch +# +# 2.22.x BRANCH - release branch +# 2.22.0 TAG - the release +# 2.22.1, ... TAG - patch releases +# 2.22.0-rc1 TAG - release candidate # -# update mappings.. +# Update mappings: # cd ~/cppchecksolutions/addon/coverage # CPPCHECK_REPO=~/cppchecksolutions/cppcheck python3 coverage.py --code # -# check every isPremiumEnabled call: TODO write helper script +# Check every isPremiumEnabled call: TODO write helper script # - every id should be in --errorlist # git grep 'isPremiumEnabled[(]"' | sed 's/.*isPremiumEnabled[(]"//' | sed 's/".*//' | sort | uniq > ids1.txt # ./cppcheck --errorlist | grep ' id="' | sed 's/.* id="//' | sed 's/".*//' | sort | uniq > ids2.txt @@ -29,93 +36,97 @@ # - ensure latest build was successful # - ensure cfg files etc are included (win_installer/cppcheck.wxs) # -# self check, fix critical issues: +# Self check, fix critical issues: # make clean && make CXXOPTS=-O2 MATCHCOMPILER=yes -j4 # ./cppcheck -D__CPPCHECK__ -D__GNUC__ -DCHECK_INTERNAL -DHAVE_RULES --std=c++11 --library=cppcheck-lib --library=qt --enable=style --inconclusive --inline-suppr --suppress=bitwiseOnBoolean --suppress=shadowFunction --suppress=useStlAlgorithm --suppress=*:externals/picojson.h --suppress=functionConst --suppress=functionStatic --suppress=normalCheckLevelMaxBranches --xml cli gui/*.cpp lib 2> selfcheck.xml # -# Generate lib/checkers.cpp (TODO the premium checkers should not be statically coded) +# Generate lib/checkers.cpp: (TODO the premium checkers should not be statically coded) # cd ~/cppchecksolutions/cppcheck && python3 tools/get_checkers.py > lib/checkers.cpp # -# Update copyright year TODO release script -# git diff 2.8 -- */*.cpp */*.h | grep '^diff --git a/' | sed 's|.* b/||' | xargs sed -i 's/Copyright (C) 2007-20[12]./Copyright (C) 2007-2022/' +# Update copyright year: TODO release script +# git diff $PREV -- */*.cpp */*.h | grep '^diff --git a/' | sed 's|.* b/||' | xargs sed -i "s/Copyright (C) 2007-20[12]./Copyright (C) 2007-$(date +%Y)/" # git diff | grep '^diff --git a/' # # Make sure "cppcheck --errorlist" works: # make clean && make -j4 && ./cppcheck --errorlist > errlist.xml && xmllint --noout errlist.xml # # Update AUTHORS using output from: -# git log --format='%aN' 2.7..HEAD | sort -u > AUTHORS2 && diff -y AUTHORS AUTHORS2 | less +# git log --format='%aN' $PREV..HEAD | sort -u > AUTHORS2 && diff -y AUTHORS AUTHORS2 | less +# Include github usernames in PR title and commit message # -# Update GUI translations -# lupdate gui.pro +# Update GUI translations: +# cd ~/cppchecksolutions/cppcheck/gui && lupdate gui.pro # -# Create 2.18.x branch -# git checkout -b 2.18.x ; git push -u origin 2.18.x +# Create new release branch: +# git checkout -b $BRANCH && git push -u origin $BRANCH # in fork: -# * add upstream: git remote add upstream git@github.com:/cppcheck-opensource//cppcheck.git -# * add branch: git fetch upstream 2.19.x +# * add upstream: git remote add upstream git@github.com:cppcheck-opensource/cppcheck.git +# * add branch: git fetch upstream $BRANCH # # Release notes: # - ensure safety critical issues are listed properly # - empty the releasenotes.txt in main branch # # Update version numbers in: -# python3 tools/release-set-version.py 2.19.0 +# python3 tools/release-set-version.py $VERSION # Verify: # grep '\.99' */*.[ch]* && grep '[0-9][0-9] dev' */*.[ch]* # egrep "2\.[0-9]+" */*.h */*.cpp man/*.md | grep -v "test/test" | less -# git commit -a -m "2.8: Set versions" +# git commit -a -m "$VERSION: Set versions" # # Build and test the windows installer # # Update the Makefile: # make dmake && ./dmake --release -# git commit -a -m "2.8: Updated Makefile" +# git commit -a -m "$VERSION: Updated Makefile" +# +# Push changes: +# git push # # Ensure that CI is happy # # Tag: -# git tag 2.8-rc1 +# git tag $VERSION-rc1 # git push --tags # # Release -# ======= +# ======================== # # Remove "-rc1" from versions. Test: git grep "\-rc[0-9]" # # Create a release folder on sourceforge: # https://sourceforge.net/projects/cppcheck/files/cppcheck/ # -# git tag 2.8 ; git push --tags -# ./createrelease 2.8 +# git tag $VERSION && git push --tags +# ./createrelease $VERSION # -# copy msi from release-windows, install and test cppcheck -# copy manual from build-manual +# Copy msi from release-windows, install and test cppcheck +# Copy manual from build-manual # # Update download link on index.php main page # # Trac: -# 1. Create ticket "2.18 safety cosmetic changes" -# git log --format=oneline 2.17.0..HEAD | egrep -v "^[0-9a-f]*[ ][ ]*([Ff]ix|fixed|Fixup|Fixes|refs)?[ ]*#*[0-9]+" +# 1. Create ticket "$VERSION safety cosmetic changes" +# git log --format=oneline $PREV..HEAD | egrep -v "^[0-9a-f]*[ ][ ]*([Ff]ix|fixed|Fixup|Fixes|refs)?[ ]*#*[0-9]+" # 2. Check priorities for all tickets in milestone. Should be: safety-* # 3. Create new milestone # 4. Close old milestone # -# write a news +# Write a news # -# save "cppcheck --doc" output on wiki +# Save "cppcheck --doc" output on wiki # -# compile new democlient: +# Compile new democlient: # ssh -t danielmarjamaki,cppcheck@shell.sourceforge.net create # ./build-cppcheck.sh # -# create a ticket with data from http://cppcheck1.osuosl.org:8000/time_gt.html for performance tracking +# Create a ticket with data from http://cppcheck1.osuosl.org:8000/time_gt.html for performance tracking # (example: https://trac.cppcheck.net/ticket/13715) # - type: defect # - component: Performance -# - summary: [meta] performance regressions in 2.x +# - summary: [meta] performance regressions in $VERSION # -# run daca with new release +# Run daca with new release: # 1. edit tools/donate-cpu-server.py. Update OLD_VERSION and SERVER_VERSION # 2. scp -i ~/.ssh/osuosl_id_rsa tools/donate-cpu-server.py danielmarjamaki@cppcheck1.osuosl.org:/var/daca@home/ # @@ -123,14 +134,14 @@ # * trac: cd /var && nice tar -cJf ~/trac.tar.xz trac-cppcheck/db/trac.db # * daca: cd /var && nice tar -cJf ~/daca.tar.xz daca@home # * git: git checkout -f && git checkout main && git pull && tar -cJf git.tar.xz .git -# * git log 2.16.0..2.17.0 > Changelog -# * mkdir out && python3 ~/cppchecksolutions/release/getWorkflowAndIssueLogs.py -r /cppcheck-opensource//cppcheck -t 2.15.0 -p out +# * git log $PREV..$VERSION > Changelog +# * mkdir out && python3 ~/cppchecksolutions/release/getWorkflowAndIssueLogs.py -r /cppcheck-opensource//cppcheck -t $VERSION -p out -# Folder/tag to use -folder=$1 -tag=$folder.0 +# Folder/tag to use: +tag=$1 +folder=${tag%.*} -# Name of release +# Name of release: releasename=cppcheck-$tag set -e @@ -162,7 +173,7 @@ scp htdocs/* danielmarjamaki,cppcheck@web.sourceforge.net:htdocs/ cd .. rm -rf upload -# Local cppcheck binary +# Local cppcheck binary: mkdir -p ~/.cppcheck/$tag cd ~/.cppcheck/$tag cp -R ~/cppcheck/cfg . From 117bdff20d2355c669b8bb56dd53db7b90d5dc48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 5 Jun 2026 16:55:36 +0200 Subject: [PATCH 163/493] bumped version to 2.21.99/2.22 (#8633) --- CMakeLists.txt | 2 +- cli/main.cpp | 2 +- lib/version.h | 4 ++-- man/manual.md | 2 +- man/reference-cfg-format.md | 2 +- man/writing-addons.md | 2 +- win_installer/productInfo.wxi | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c037a10b36..b5857a8413a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.22) -project(Cppcheck VERSION 2.20.99 LANGUAGES CXX) +project(Cppcheck VERSION 2.21.99 LANGUAGES CXX) include(cmake/options.cmake) diff --git a/cli/main.cpp b/cli/main.cpp index 9bea4336c84..d1a635e1f6f 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -20,7 +20,7 @@ /** * * @mainpage Cppcheck - * @version 2.20.99 + * @version 2.21.99 * * @section overview_sec Overview * Cppcheck is a simple tool for static analysis of C/C++ code. diff --git a/lib/version.h b/lib/version.h index 2a64885ffa8..6d25dd4c158 100644 --- a/lib/version.h +++ b/lib/version.h @@ -20,8 +20,8 @@ #ifndef versionH #define versionH -#define CPPCHECK_VERSION_STRING "2.21 dev" -#define CPPCHECK_VERSION 2,20,99,0 +#define CPPCHECK_VERSION_STRING "2.22 dev" +#define CPPCHECK_VERSION 2,21,99,0 #define LEGALCOPYRIGHT L"Copyright (C) 2007-2026 Cppcheck team." diff --git a/man/manual.md b/man/manual.md index 8d8d5b22350..47a3a43fd36 100644 --- a/man/manual.md +++ b/man/manual.md @@ -1,6 +1,6 @@ --- title: Cppcheck manual -subtitle: Version 2.21 dev +subtitle: Version 2.22 dev author: Cppcheck team lang: en documentclass: report diff --git a/man/reference-cfg-format.md b/man/reference-cfg-format.md index 3067d0a8f2c..f426057ab47 100644 --- a/man/reference-cfg-format.md +++ b/man/reference-cfg-format.md @@ -1,6 +1,6 @@ --- title: Cppcheck .cfg format -subtitle: Version 2.21 dev +subtitle: Version 2.22 dev author: Cppcheck team lang: en documentclass: report diff --git a/man/writing-addons.md b/man/writing-addons.md index e593c2e9cce..2627671fa87 100644 --- a/man/writing-addons.md +++ b/man/writing-addons.md @@ -1,6 +1,6 @@ --- title: Writing addons -subtitle: Version 2.21 dev +subtitle: Version 2.22 dev author: Cppcheck team lang: en documentclass: report diff --git a/win_installer/productInfo.wxi b/win_installer/productInfo.wxi index f89e956dbb8..85e73ea3ca2 100644 --- a/win_installer/productInfo.wxi +++ b/win_installer/productInfo.wxi @@ -1,8 +1,8 @@ - + - + From 707f262560ac3be5136a0e6e9cf62b388fd6d946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 5 Jun 2026 16:56:00 +0200 Subject: [PATCH 164/493] daca: update OLD_VERSION (#8631) --- tools/donate-cpu-server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/donate-cpu-server.py b/tools/donate-cpu-server.py index 6f44ea679a7..63a55f5b338 100755 --- a/tools/donate-cpu-server.py +++ b/tools/donate-cpu-server.py @@ -26,10 +26,10 @@ # Version scheme (MAJOR.MINOR.PATCH) should orientate on "Semantic Versioning" https://semver.org/ # Every change in this script should result in increasing the version number accordingly (exceptions may be cosmetic # changes) -SERVER_VERSION = "1.3.68" +SERVER_VERSION = "1.3.69" # TODO: fetch from GitHub tags -OLD_VERSION = '2.20.0' +OLD_VERSION = '2.21.0' HEAD_MARKER = 'head results:' INFO_MARKER = 'info messages:' From fdbb42c76083d717b9b1206ec368c7f0431fb12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Mon, 8 Jun 2026 08:35:56 +0200 Subject: [PATCH 165/493] removed unnecessary friend declarations from checks (#8613) --- lib/check64bit.h | 2 -- lib/checkclass.h | 4 ---- lib/checkio.h | 2 -- lib/checkmemoryleak.h | 8 -------- lib/checknullpointer.h | 2 -- lib/checkother.h | 4 ---- lib/checkpostfixoperator.h | 2 -- lib/checkuninitvar.h | 2 -- lib/checkunusedvar.h | 2 -- 9 files changed, 28 deletions(-) diff --git a/lib/check64bit.h b/lib/check64bit.h index 4354d2217ba..cab82cf1148 100644 --- a/lib/check64bit.h +++ b/lib/check64bit.h @@ -41,8 +41,6 @@ class Tokenizer; */ class CPPCHECKLIB Check64BitPortability : public Check { - friend class Test64BitPortability; - public: /** This constructor is used when registering the Check64BitPortability */ Check64BitPortability() : Check("64-bit portability") {} diff --git a/lib/checkclass.h b/lib/checkclass.h index a5d20432351..2573d99f2f5 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -49,10 +49,6 @@ enum class FunctionType : std::uint8_t; /** @brief %Check classes. Uninitialized member variables, non-conforming operators, missing virtual destructor, etc */ class CPPCHECKLIB CheckClass : public Check { - friend class TestClass; - friend class TestConstructors; - friend class TestUnusedPrivateFunction; - public: /** @brief This constructor is used when registering the CheckClass */ CheckClass() : Check("Class") {} diff --git a/lib/checkio.h b/lib/checkio.h index 6fb3c9f80c2..9f125e6bd7b 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -42,8 +42,6 @@ enum class Severity : std::uint8_t; /** @brief %Check input output operations. */ class CPPCHECKLIB CheckIO : public Check { - friend class TestIO; - public: /** @brief This constructor is used when registering CheckIO */ CheckIO() : Check("IO using format string") {} diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 037363160de..fdb7748f9ed 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -65,8 +65,6 @@ enum class Severity : std::uint8_t; */ class CPPCHECKLIB CheckMemoryLeakInFunction : public Check { - friend class TestMemleakInFunction; - public: /** @brief This constructor is used when registering this class */ CheckMemoryLeakInFunction() : Check("Memory leaks (function variables)") {} @@ -92,8 +90,6 @@ class CPPCHECKLIB CheckMemoryLeakInFunction : public Check { */ class CPPCHECKLIB CheckMemoryLeakInClass : public Check { - friend class TestMemleakInClass; - public: CheckMemoryLeakInClass() : Check("Memory leaks (class variables)") {} @@ -112,8 +108,6 @@ class CPPCHECKLIB CheckMemoryLeakInClass : public Check { /** @brief detect simple memory leaks for struct members */ class CPPCHECKLIB CheckMemoryLeakStructMember : public Check { - friend class TestMemleakStructMember; - public: CheckMemoryLeakStructMember() : Check("Memory leaks (struct members)") {} @@ -132,8 +126,6 @@ class CPPCHECKLIB CheckMemoryLeakStructMember : public Check { /** @brief detect simple memory leaks (address not taken) */ class CPPCHECKLIB CheckMemoryLeakNoVar : public Check { - friend class TestMemleakNoVar; - public: CheckMemoryLeakNoVar() : Check("Memory leaks (address not taken)") {} diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index d0bc44899a9..bc494dad70f 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -48,8 +48,6 @@ namespace ValueFlow /** @brief check for null pointer dereferencing */ class CPPCHECKLIB CheckNullPointer : public Check { - friend class TestNullPointer; - public: /** @brief This constructor is used when registering the CheckNullPointer */ CheckNullPointer() : Check("Null pointer") {} diff --git a/lib/checkother.h b/lib/checkother.h index 58a61ff772a..7f21ffc00f8 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -50,10 +50,6 @@ struct UnionMember; /** @brief Various small checks */ class CPPCHECKLIB CheckOther : public Check { - friend class TestCharVar; - friend class TestIncompleteStatement; - friend class TestOther; - public: /** @brief This constructor is used when registering the CheckClass */ CheckOther() : Check("Other") {} diff --git a/lib/checkpostfixoperator.h b/lib/checkpostfixoperator.h index ac1a053afe8..5898cefcc3c 100644 --- a/lib/checkpostfixoperator.h +++ b/lib/checkpostfixoperator.h @@ -41,8 +41,6 @@ class Tokenizer; */ class CPPCHECKLIB CheckPostfixOperator : public Check { - friend class TestPostfixOperator; - public: /** This constructor is used when registering the CheckPostfixOperator */ CheckPostfixOperator() : Check("Using postfix operators") {} diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index 47d9061be18..a9156adfe36 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -58,8 +58,6 @@ struct VariableValue { /** @brief Checking for uninitialized variables */ class CPPCHECKLIB CheckUninitVar : public Check { - friend class TestUninitVar; - public: /** @brief This constructor is used when registering the CheckUninitVar */ CheckUninitVar() : Check("Uninitialized variables") {} diff --git a/lib/checkunusedvar.h b/lib/checkunusedvar.h index 693d3213869..2239b4a60d8 100644 --- a/lib/checkunusedvar.h +++ b/lib/checkunusedvar.h @@ -43,8 +43,6 @@ class Tokenizer; /** @brief Various small checks */ class CPPCHECKLIB CheckUnusedVar : public Check { - friend class TestUnusedVar; - public: /** @brief This constructor is used when registering the CheckClass */ CheckUnusedVar() : Check("UnusedVar") {} From 22b3464e06086b68a31ed4200054834191c0b528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Mon, 8 Jun 2026 08:40:06 +0200 Subject: [PATCH 166/493] constified more pointers in containers (#8615) --- lib/clangimport.cpp | 2 +- lib/symboldatabase.cpp | 8 ++++---- lib/templatesimplifier.cpp | 4 ++-- lib/templatesimplifier.h | 8 ++++---- lib/tokenize.cpp | 20 ++++++++++---------- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index c96a678347a..417e94e8798 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -303,7 +303,7 @@ namespace clangimport { } // "}" tokens that are not end-of-scope - std::set mNotScope; + std::set mNotScope; std::map scopeAccessControl; private: diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index dda3e9b1e0b..4b923a328ca 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -175,9 +175,9 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() // Store current access in each scope (depends on evaluation progress) std::map access; - std::map> forwardDecls; + std::map> forwardDecls; - const std::function findForwardDeclScope = [&](const Token *tok, Scope *startScope) { + const std::function findForwardDeclScope = [&](const Token *tok, const Scope *startScope) { if (tok->str() == "::") return findForwardDeclScope(tok->next(), &scopeList.front()); @@ -187,14 +187,14 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() }); if (it == startScope->nestedList.cend()) - return static_cast(nullptr); + return static_cast(nullptr); return findForwardDeclScope(tok->tokAt(2), *it); } auto it = forwardDecls.find(startScope); if (it == forwardDecls.cend()) - return static_cast(nullptr); + return static_cast(nullptr); return it->second.count(tok->str()) > 0 ? startScope : nullptr; }; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 1fe1df10037..9c8c8fdde9a 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -623,7 +623,7 @@ void TemplateSimplifier::deleteToken(Token *tok) tok->deleteThis(); } -static void invalidateForwardDecls(const Token* beg, const Token* end, std::map* forwardDecls) { +static void invalidateForwardDecls(const Token* beg, const Token* end, std::map* forwardDecls) { if (!forwardDecls) return; for (auto& fwd : *forwardDecls) { @@ -635,7 +635,7 @@ static void invalidateForwardDecls(const Token* beg, const Token* end, std::map< } } -bool TemplateSimplifier::removeTemplate(Token *tok, std::map* forwardDecls) +bool TemplateSimplifier::removeTemplate(Token *tok, std::map* forwardDecls) { if (!Token::simpleMatch(tok, "template <")) return false; diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index f6e507459a9..3c5fed3ea1c 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -463,7 +463,7 @@ class CPPCHECKLIB TemplateSimplifier { /** * Remove a specific "template < ..." template class/function */ - static bool removeTemplate(Token *tok, std::map* forwardDecls = nullptr); + static bool removeTemplate(Token *tok, std::map* forwardDecls = nullptr); /** Syntax error * @throws InternalError thrown unconditionally @@ -512,9 +512,9 @@ class CPPCHECKLIB TemplateSimplifier { std::list mTemplateDeclarations; std::list mTemplateForwardDeclarations; - std::map mTemplateForwardDeclarationsMap; - std::map mTemplateSpecializationMap; - std::map mTemplatePartialSpecializationMap; + std::map mTemplateForwardDeclarationsMap; + std::map mTemplateSpecializationMap; + std::map mTemplatePartialSpecializationMap; std::list mTemplateInstantiations; std::list mInstantiatedTemplates; std::list mMemberFunctionsToDelete; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6305e0f021a..c5b001f5d32 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -549,9 +549,9 @@ namespace { private: Token* mTypedefToken; // The "typedef" token Token* mEndToken{nullptr}; // Semicolon - std::pair mRangeType; - std::pair mRangeTypeQualifiers; - std::pair mRangeAfterVar; + std::pair mRangeType; + std::pair mRangeTypeQualifiers; + std::pair mRangeAfterVar; Token* mNameToken{nullptr}; bool mFail = false; bool mReplaceFailed = false; @@ -565,13 +565,13 @@ namespace { // TODO handle unnamed structs etc if (Token::Match(start, "const| enum|struct|union|class %name%| {")) { - const std::pair rangeBefore(start, Token::findsimplematch(start, "{")); + const std::pair rangeBefore(start, Token::findsimplematch(start, "{")); // find typedef name token Token* nameToken = rangeBefore.second->link()->next(); while (Token::Match(nameToken, "%name%|* %name%|*")) nameToken = nameToken->next(); - const std::pair rangeQualifiers(rangeBefore.second->link()->next(), nameToken); + const std::pair rangeQualifiers(rangeBefore.second->link()->next(), nameToken); if (Token::Match(nameToken, "%name% ;")) { if (Token::Match(rangeBefore.second->previous(), "enum|struct|union|class {")) @@ -723,7 +723,7 @@ namespace { // Special handling of function pointer cast if (isFunctionPointer && isCast(tok->previous())) { tok->insertToken("*"); - Token* const tok_1 = insertTokens(tok, std::pair(mRangeType.first, mNameToken->linkAt(1))); + Token* const tok_1 = insertTokens(tok, std::pair(mRangeType.first, mNameToken->linkAt(1))); tok_1->originalName(originalname); tok->deleteThis(); return; @@ -998,7 +998,7 @@ namespace { return false; } - static Token* insertTokens(Token* to, std::pair range) { + static Token* insertTokens(Token* to, std::pair range) { for (const Token* from = range.first; from != range.second; from = from->next()) { to->insertToken(from->str()); to->next()->column(to->column()); @@ -5537,7 +5537,7 @@ void Tokenizer::createLinks2() bool isStruct = false; std::stack type; - std::stack templateTokens; + std::stack templateTokens; for (Token *token = list.front(); token; token = token->next()) { if (Token::Match(token, "%name%|> %name% [:<]")) isStruct = true; @@ -7026,7 +7026,7 @@ void Tokenizer::simplifyFunctionParameters() // We have found old style function, now we need to change it // First step: Get list of argument names in parentheses - std::map argumentNames; + std::map argumentNames; bool bailOut = false; const Token * tokparam = nullptr; @@ -7145,7 +7145,7 @@ void Tokenizer::simplifyFunctionParameters() if (argumentNames.size() != argumentNames2.size()) { //move back 'tok1' to the last ';' tok1 = tok1->previous(); - for (const std::pair& argumentName : argumentNames) { + for (const std::pair& argumentName : argumentNames) { if (argumentNames2.find(argumentName.first) == argumentNames2.end()) { //add the missing parameter argument declaration tok1->insertToken(";"); From ac63eb55d1c2ea30ee663542f1a040af67364a5a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:43:09 +0200 Subject: [PATCH 167/493] Fix #14180 FN intToPointerCast with binary integer literal (#8643) Co-authored-by: chrchr-github --- lib/checkother.cpp | 2 ++ test/testother.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index b5fd0dda361..801dc529568 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -464,6 +464,8 @@ void CheckOtherImpl::warningIntToPointerCast() format = "decimal"; else if (MathLib::isOct(from->str())) format = "octal"; + else if (MathLib::isBin(from->str())) + format = "binary"; else continue; intToPointerCastError(tok, format); diff --git a/test/testother.cpp b/test/testother.cpp index 93e67229f43..73f10cbe76e 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2362,6 +2362,9 @@ class TestOther : public TestFixture { checkIntToPointerCast("struct S { int i; };\n" // #13886, don't crash "int f() { return sizeof(((struct S*)0)->i); }"); ASSERT_EQUALS("", errout_str()); + + checkIntToPointerCast("auto p = (int*)0b10;"); // #14180 + ASSERT_EQUALS("[test.cpp:1:10]: (portability) Casting non-zero binary integer literal to pointer. [intToPointerCast]\n", errout_str()); } struct CheckInvalidPointerCastOptions From 21de4faec57386799dff4abe7acdfd9b1c43f244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 10 Jun 2026 20:43:28 +0200 Subject: [PATCH 168/493] updated *.ts [skip ci] (#8634) --- gui/cppcheck_de.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_es.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_fi.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_fr.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_it.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_ja.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_ka.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_ko.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_nl.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_ru.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_sr.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_sv.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_zh_CN.ts | 182 +++++++++++++++++++++--------------------- gui/cppcheck_zh_TW.ts | 182 +++++++++++++++++++++--------------------- 14 files changed, 1274 insertions(+), 1274 deletions(-) diff --git a/gui/cppcheck_de.ts b/gui/cppcheck_de.ts index 3f9d9ed53d7..1361296b8ca 100644 --- a/gui/cppcheck_de.ts +++ b/gui/cppcheck_de.ts @@ -485,18 +485,18 @@ Parameter: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -636,14 +636,14 @@ Parameter: -l(line) (file) - + Show errors Zeige Fehler - + Show warnings Zeige Warnungen @@ -659,8 +659,8 @@ Parameter: -l(line) (file) Zeige &versteckte - - + + Information Information @@ -1083,17 +1083,17 @@ Parameter: -l(line) (file) - + Quick Filter: Schnellfilter: - + Select configuration Konfiguration wählen - + Found project file: %1 Do you want to load this project file instead? @@ -1102,97 +1102,97 @@ Do you want to load this project file instead? Möchten Sie stattdessen diese öffnen? - + File not found Datei nicht gefunden - + Bad XML Fehlerhaftes XML - + Missing attribute Fehlendes Attribut - + Bad attribute value Falscher Attributwert - + Duplicate platform type Plattformtyp doppelt - + Platform type redefined Plattformtyp neu definiert - + Duplicate define - + Failed to load the selected library '%1'. %2 Laden der ausgewählten Bibliothek '%1' schlug fehl. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Lizenz - + Authors Autoren - + Save the report file Speichert die Berichtdatei - - + + XML files (*.xml) XML-Dateien (*.xml) @@ -1206,32 +1206,32 @@ This is probably because the settings were changed between the Cppcheck versions Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bitte prüfen (und korrigieren) Sie die Einstellungen, andernfalls könnte die Editor-Anwendung nicht korrekt starten. - + You must close the project file before selecting new files or directories! Sie müssen die Projektdatei schließen, bevor Sie neue Dateien oder Verzeichnisse auswählen! - + The library '%1' contains unknown elements: %2 Die Bibliothek '%1' enthält unbekannte Elemente: %2 - + Unsupported format Nicht unterstütztes Format - + Unknown element Unbekanntes Element - - - - + + + + Error Fehler @@ -1240,80 +1240,80 @@ Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bi Laden von %1 fehlgeschlagen. Ihre Cppcheck-Installation ist defekt. Sie können --data-dir=<Verzeichnis> als Kommandozeilenparameter verwenden, um anzugeben, wo die Datei sich befindet. Bitte beachten Sie, dass --data-dir in Installationsroutinen genutzt werden soll, und die GUI bei dessen Nutzung nicht startet, sondern die Einstellungen konfiguriert. - + Open the report file Berichtdatei öffnen - + Text files (*.txt) Textdateien (*.txt) - + CSV files (*.csv) CSV-Dateien (*.csv) - + Project files (*.cppcheck);;All files(*.*) Projektdateien (*.cppcheck);;Alle Dateien(*.*) - + Select Project File Projektdatei auswählen - - - + + + Project: Projekt: - + No suitable files found to analyze! Keine passenden Dateien für Analyse gefunden! - + C/C++ Source C/C++-Quellcode - + Compile database Compilerdatenbank - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++-Builder 6 - + Select files to analyze Dateien für Analyse auswählen - + Select directory to analyze Verzeichnis für Analyse auswählen - + Select the configuration that will be analyzed Zu analysierende Konfiguration auswählen - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1322,7 +1322,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1333,7 +1333,7 @@ Eine neue XML-Datei zu öffnen wird die aktuellen Ergebnisse löschen Möchten sie fortfahren? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1342,104 +1342,104 @@ Do you want to stop the analysis and exit Cppcheck? Wollen sie die Analyse abbrechen und Cppcheck beenden? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML-Dateien (*.xml);;Textdateien (*.txt);;CSV-Dateien (*.csv) - + Build dir '%1' does not exist, create it? Erstellungsverzeichnis '%1' existiert nicht. Erstellen? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1448,22 +1448,22 @@ Analysis is stopped. Import von '%1' fehlgeschlagen; Analyse wurde abgebrochen. - + Project files (*.cppcheck) Projektdateien (*.cppcheck) - + Select Project Filename Projektnamen auswählen - + No project file loaded Keine Projektdatei geladen - + The project file %1 @@ -1480,12 +1480,12 @@ Do you want to remove the file from the recently used projects -list? Möchten Sie die Datei von der Liste der zuletzt benutzten Projekte entfernen? - + Install - + New version available: %1. %2 diff --git a/gui/cppcheck_es.ts b/gui/cppcheck_es.ts index 32485d556f3..bbe8bed24d5 100644 --- a/gui/cppcheck_es.ts +++ b/gui/cppcheck_es.ts @@ -414,18 +414,18 @@ Parameters: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -580,13 +580,13 @@ Parameters: -l(line) (file) - + Show errors Mostrar errores - - + + Information Información @@ -1000,7 +1000,7 @@ Parameters: -l(line) (file) - + Show warnings Mostrar advertencias @@ -1023,117 +1023,117 @@ This is probably because the settings were changed between the Cppcheck versions - + You must close the project file before selecting new files or directories! ¡Tienes que cerrar el proyecto antes de seleccionar nuevos ficheros o carpetas! - + Select configuration - + File not found Archivo no encontrado - + Bad XML XML malformado - + Missing attribute Falta el atributo - + Bad attribute value - + Unsupported format Formato no soportado - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - - + + XML files (*.xml) Archivos XML (*.xml) - + Open the report file Abrir informe - + License Licencia - + Authors Autores - + Save the report file Guardar informe - + Quick Filter: Filtro rápido: - + Found project file: %1 Do you want to load this project file instead? @@ -1142,112 +1142,112 @@ Do you want to load this project file instead? ¿Quiere cargar este fichero de proyecto en su lugar? - + The library '%1' contains unknown elements: %2 La biblioteca '%1' contiene elementos deconocidos: %2 - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error Error - + Text files (*.txt) Ficheros de texto (*.txt) - + CSV files (*.csv) Ficheros CVS (*.cvs) - + Project files (*.cppcheck);;All files(*.*) Ficheros de proyecto (*.cppcheck;;Todos los ficheros (*.*) - + Select Project File Selecciona el archivo de proyecto - - - + + + Project: Proyecto: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1255,76 +1255,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Selecciona el nombre del proyecto - + No project file loaded No hay ningún proyecto cargado - + The project file %1 @@ -1341,67 +1341,67 @@ Do you want to remove the file from the recently used projects -list? ¿Quiere eliminar el fichero de la lista de proyectos recientes? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information diff --git a/gui/cppcheck_fi.ts b/gui/cppcheck_fi.ts index 5a41a1cb41d..517362d852b 100644 --- a/gui/cppcheck_fi.ts +++ b/gui/cppcheck_fi.ts @@ -417,18 +417,18 @@ Parameters: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -572,14 +572,14 @@ Parameters: -l(line) (file) - + Show errors - + Show warnings @@ -595,8 +595,8 @@ Parameters: -l(line) (file) - - + + Information @@ -1020,103 +1020,103 @@ Parameters: -l(line) (file) - + Quick Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Lisenssi - + Authors Tekijät - + Save the report file Tallenna raportti - - + + XML files (*.xml) XML-tiedostot (*xml) @@ -1128,126 +1128,126 @@ This is probably because the settings were changed between the Cppcheck versions - + You must close the project file before selecting new files or directories! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file - + Text files (*.txt) Tekstitiedostot (*.txt) - + CSV files (*.csv) - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - - - + + + Project: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1255,76 +1255,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename - + No project file loaded - + The project file %1 @@ -1335,67 +1335,67 @@ Do you want to remove the file from the recently used projects -list? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information diff --git a/gui/cppcheck_fr.ts b/gui/cppcheck_fr.ts index 828dffa7ad2..7e8651d8ec3 100644 --- a/gui/cppcheck_fr.ts +++ b/gui/cppcheck_fr.ts @@ -423,18 +423,18 @@ Paramètres : -l(ligne) (fichier) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck @@ -645,38 +645,38 @@ Paramètres : -l(ligne) (fichier) - + License Licence - + Authors Auteurs - + Save the report file Sauvegarder le rapport - - + + XML files (*.xml) Fichiers XML (*.xml) - + About - + Text files (*.txt) Fichiers Texte (*.txt) - + CSV files (*.csv) Fichiers CSV (*.csv) @@ -699,7 +699,7 @@ Paramètres : -l(ligne) (fichier) - + Show errors Afficher les erreurs @@ -771,7 +771,7 @@ Paramètres : -l(ligne) (fichier) - + Show warnings Afficher les avertissements @@ -787,8 +787,8 @@ Paramètres : -l(ligne) (fichier) - - + + Information Information @@ -803,129 +803,129 @@ Paramètres : -l(ligne) (fichier) Afficher les problèmes de portabilité - + You must close the project file before selecting new files or directories! Vous devez d'abord fermer le projet avant de choisir des fichiers/répertoires - + Open the report file Ouvrir le rapport - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Select Project Filename - + No project file loaded - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -948,12 +948,12 @@ This is probably because the settings were changed between the Cppcheck versions - + Quick Filter: Filtre rapide : - + Found project file: %1 Do you want to load this project file instead? @@ -961,14 +961,14 @@ Do you want to load this project file instead? - - - + + + Project: Projet : - + The project file %1 @@ -1019,59 +1019,59 @@ Do you want to remove the file from the recently used projects -list? - - - - + + + + Error Erreur - + File not found Fichier introuvable - + Bad XML Mauvais fichier XML - + Missing attribute Attribut manquant - + Bad attribute value Mauvaise valeur d'attribut - + Failed to load the selected library '%1'. %2 Echec lors du chargement de la bibliothèque '%1'. %2 - + Unsupported format Format non supporté - + The library '%1' contains unknown elements: %2 La bibliothèque '%1' contient des éléments inconnus: %2 - + Duplicate platform type - + Platform type redefined @@ -1101,12 +1101,12 @@ Do you want to remove the file from the recently used projects -list? - + Unknown element - + Select configuration @@ -1129,7 +1129,7 @@ Options: - + Build dir '%1' does not exist, create it? @@ -1157,76 +1157,76 @@ Options: - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + No suitable files found to analyze! - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1373,7 +1373,7 @@ Do you want to stop the analysis and exit Cppcheck? - + Project files (*.cppcheck) @@ -1398,27 +1398,27 @@ Do you want to stop the analysis and exit Cppcheck? - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Current results will be cleared. Opening a new XML file will clear current results. diff --git a/gui/cppcheck_it.ts b/gui/cppcheck_it.ts index 46ec9cb51d8..2c19aa2e50b 100644 --- a/gui/cppcheck_it.ts +++ b/gui/cppcheck_it.ts @@ -426,18 +426,18 @@ Parametri: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -581,14 +581,14 @@ Parametri: -l(line) (file) - + Show errors Mostra gli errori - + Show warnings Mostra gli avvisi @@ -604,8 +604,8 @@ Parametri: -l(line) (file) Mostra &i nascosti - - + + Information Informazione @@ -1029,17 +1029,17 @@ Parametri: -l(line) (file) - + Quick Filter: Rapido filtro: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? @@ -1048,91 +1048,91 @@ Do you want to load this project file instead? Vuoi piuttosto caricare questo file di progetto? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Unsupported format - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licenza - + Authors Autori - + Save the report file Salva il file di rapporto - - + + XML files (*.xml) File XML (*.xml) @@ -1146,121 +1146,121 @@ This is probably because the settings were changed between the Cppcheck versions Probabilmente ciò è avvenuto perché le impostazioni sono state modificate tra le versioni di Cppcheck. Per favore controlla (e sistema) le impostazioni delle applicazioni editor, altrimenti il programma editor può non partire correttamente. - + You must close the project file before selecting new files or directories! Devi chiudere il file di progetto prima di selezionare nuovi file o cartelle! - + The library '%1' contains unknown elements: %2 - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file Apri il file di rapporto - + Text files (*.txt) File di testo (*.txt) - + CSV files (*.csv) Files CSV (*.csv) - + Project files (*.cppcheck);;All files(*.*) Files di progetto (*.cppcheck);;Tutti i files(*.*) - + Select Project File Seleziona il file di progetto - - - + + + Project: Progetto: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1268,76 +1268,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Seleziona il nome del file di progetto - + No project file loaded Nessun file di progetto caricato - + The project file %1 @@ -1354,67 +1354,67 @@ Do you want to remove the file from the recently used projects -list? Vuoi rimuovere il file dalla lista dei progetti recentemente usati? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index a071727ad56..6c8269b4143 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -491,18 +491,18 @@ Parameters: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -657,13 +657,13 @@ Parameters: -l(line) (file) - + Show errors エラーを表示 - - + + Information 情報 @@ -770,7 +770,7 @@ Parameters: -l(line) (file) - + Show warnings 警告を表示 @@ -1102,23 +1102,23 @@ This is probably because the settings were changed between the Cppcheck versions Cppcheckの古いバージョンの設定には互換性がありません。エディタアプリケーションの設定を確認して修正してください、そうしないと正しく起動できないかもしれません。 - + You must close the project file before selecting new files or directories! 新しいファイル/ディレクトリをチェックするには現在のプロジェクトを閉じてください! - + Quick Filter: クイックフィルタ: - + Select configuration コンフィグレーションの選択 - + Found project file: %1 Do you want to load this project file instead? @@ -1127,64 +1127,64 @@ Do you want to load this project file instead? 現在のプロジェクトの代わりにこのプロジェクトファイルを読み込んでもかまいませんか? - + The library '%1' contains unknown elements: %2 このライブラリ '%1' には次の不明な要素が含まれています。 %2 - + File not found ファイルがありません - + Bad XML 不正なXML - + Missing attribute 属性がありません - + Bad attribute value 不正な属性があります - + Unsupported format サポートされていないフォーマット - + Duplicate platform type プラットフォームの種類が重複しています - + Platform type redefined プラットフォームの種類が再定義されました - + Unknown element 不明な要素 - + Failed to load the selected library '%1'. %2 選択したライブラリの読み込みに失敗しました '%1' %2 - - - - + + + + Error エラー @@ -1197,38 +1197,38 @@ Do you want to load this project file instead? %1 - %2 の読み込みに失敗 - - + + XML files (*.xml) XML ファイル (*.xml) - + Open the report file レポートを開く - + License ライセンス - + Authors 作者 - + Save the report file レポートを保存 - + Text files (*.txt) テキストファイル (*.txt) - + CSV files (*.csv) CSV形式ファイル (*.csv) @@ -1237,32 +1237,32 @@ Do you want to load this project file instead? コンプライアンスレポートをすぐに生成できません。解析が完了し成功していなければなりません。コードを再解析して、致命的なエラーがないことを確認してください。 - + Project files (*.cppcheck);;All files(*.*) プロジェクトファイル (*.cppcheck);;すべてのファイル(*.*) - + Select Project File プロジェクトファイルを選択 - + Failed to open file ファイルを開くのに失敗しました - + Unknown project file format プロジェクトファイルの形式が不明です - + Failed to import project file プロジェクトファイルのインポートに失敗しました - + Failed to import '%1': %2 Analysis is stopped. @@ -1271,70 +1271,70 @@ Analysis is stopped. 解析を停止しました。 - + Failed to import '%1' (%2), analysis is stopped '%1' (%2) のインポートに失敗しました。解析は停止 - + Install インストール - + New version available: %1. %2 新しいバージョンが利用可能です。: %1. %2 - - - + + + Project: プロジェクト: - + No suitable files found to analyze! チェック対象のファイルがみつかりません! - + C/C++ Source C/C++のソースコード - + Compile database コンパイルデータベース - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze チェック対象のファイルを選択 - + Select directory to analyze チェックするディレクトリを選択してください - + Select the configuration that will be analyzed チェックの設定を選択 - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1343,37 +1343,37 @@ Do you want to proceed analysis without using any of these project files? - + Duplicate define 重複した定義 - + File not found: '%1' ファイルがありません: '%1' - + Failed to load/setup addon %1: %2 アドオンの読み込みまたは設定に失敗 %1 - %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. %1のロードに失敗しました。あなたの Cppcheck は正しくインストールされていません。あなたは --data-dir=<directory> コマンドラインオプションを使ってこのファイルの場所を指定できます。ただし、この --data-dir はインストールスクリプトによって使用されていなければなりません。またGUI版はこれを使用しません。さらに、全ての設定は調整済みでなければなりません。 - + Failed to load %1 - %2 Analysis is aborted. 読み込みに失敗 %1 - %2 - - + + %1 Analysis is aborted. @@ -1382,7 +1382,7 @@ Analysis is aborted. 解析は中止した。 - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1392,7 +1392,7 @@ Do you want to proceed? 新しくXMLファイルを開くと現在の結果が削除されます。実行しますか? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1401,77 +1401,77 @@ Do you want to stop the analysis and exit Cppcheck? チェックを中断して、Cppcheckを終了しますか? - + About CppCheckについて - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ファイル (*.xml);;テキストファイル (*.txt);;CSVファイル (*.csv) - + Build dir '%1' does not exist, create it? ビルドディレクトリ'%1'がありません。作成しますか? - + To check the project using addons, you need a build directory. アドオンを使用してプロジェクトをチェックするためには、ビルドディレクトリが必要です。 - + Show Mandatory 必須を表示 - + Show Required 要求を表示 - + Show Advisory 推奨を表示 - + Show Document ドキュメントを表示 - + Show L1 L1を表示 - + Show L2 L2を表示 - + Show L3 L3を表示 - + Show style スタイルを表示 - + Show portability 移植可能性を表示 - + Show performance パフォーマンスを表示 - + Show information 情報を表示 @@ -1480,22 +1480,22 @@ Do you want to stop the analysis and exit Cppcheck? '%1'のインポートに失敗しました。(チェック中断) - + Project files (*.cppcheck) プロジェクトファイル (*.cppcheck) - + Select Project Filename プロジェクトファイル名を選択 - + No project file loaded プロジェクトファイルが読み込まれていません - + The project file %1 diff --git a/gui/cppcheck_ka.ts b/gui/cppcheck_ka.ts index f6d571ab3f5..52c0657f646 100644 --- a/gui/cppcheck_ka.ts +++ b/gui/cppcheck_ka.ts @@ -467,18 +467,18 @@ Parameters: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -622,14 +622,14 @@ Parameters: -l(line) (file) - + Show errors შეცდომების ჩვენება - + Show warnings გაფრთხილების ჩვენება @@ -645,8 +645,8 @@ Parameters: -l(line) (file) დამალულის &ჩვენება - - + + Information ინფორმაცია @@ -1070,17 +1070,17 @@ Parameters: -l(line) (file) - + Quick Filter: სწრაფი ფილტრი: - + Select configuration აირჩიეთ კონფიგურაცია - + Found project file: %1 Do you want to load this project file instead? @@ -1089,61 +1089,61 @@ Do you want to load this project file instead? გნებავთ, სამაგიეროდ, ეს პროექტის ფაილი ჩატვირთოთ? - + File not found ფაილი ნაპოვნი არაა - + Bad XML არასწორი XML - + Missing attribute აკლია ატრიბუტი - + Bad attribute value არასწორი ატრიბუტის მნიშვნელობა - + Unsupported format მხარდაუჭერელი ფორმატი - + Duplicate define გამეორებული აღწერა - + Failed to load the selected library '%1'. %2 ჩავარდა ჩატვირთვა მონიშნული ბიბლიოთეკისთვის '%1'. %2 - + File not found: '%1' ფაილი ვერ ვიპოვე: '%1' - + Failed to load/setup addon %1: %2 დამატების (%1) ჩატვირთვა/მორგება ჩავარდა: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. @@ -1152,8 +1152,8 @@ Analysis is aborted. ანალიზი შეწყდა. - - + + %1 Analysis is aborted. @@ -1162,23 +1162,23 @@ Analysis is aborted. ანალიზი შეწყვეტილია. - + License ლიცენზია - + Authors ავტორები - + Save the report file ანგარიშის ფაილში ჩაწერა - - + + XML files (*.xml) XML ფაილები (*.xml) @@ -1190,115 +1190,115 @@ This is probably because the settings were changed between the Cppcheck versions - + You must close the project file before selecting new files or directories! ახალი ფაილების ან საქაღალდეების არჩევამდე პრორექტის ფაილი უნდა დახუროთ! - + The library '%1' contains unknown elements: %2 ბიბლიოთეკა '%1' უცნობ ელემენტებს შეიცავს: %2 - + Duplicate platform type გამეორებული პლატფორმის ტიპი - + Platform type redefined პლატფორმის ტიპი თავდან აღიწერა - + Unknown element უცნობი ელემენტი - - - - + + + + Error შეცდომა - + Open the report file ანგარიშის ფაილის გახსნა - + Text files (*.txt) ტექსტური ფაილები (*.txt) - + CSV files (*.csv) CSV ფაილები (*.csv) - + Project files (*.cppcheck);;All files(*.*) პროექტის ფაილები (*.cppcheck);;ყველა ფაილი(*.*) - + Select Project File აირჩიეთ პროექტის ფაილი - - - + + + Project: პროექტი: - + No suitable files found to analyze! ანალიზისათვის შესაფერისი ფაილები აღმოჩენილი არაა! - + C/C++ Source C/C++ საწყისი კოდი - + Compile database მონაცემთა ბაზის კომპილაცია - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze აირჩეთ ფაილები ანალიზისთვის - + Select directory to analyze აირჩიეთ საქაღალდე ანალიზისთვის - + Select the configuration that will be analyzed აირჩიეთ კონფიგურაცია ანალიზისთვის - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1307,7 +1307,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1318,7 +1318,7 @@ Do you want to proceed? გნებავთ, გააგრძელოთ? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1327,12 +1327,12 @@ Do you want to stop the analysis and exit Cppcheck? გნებავთ, გააჩეროთ ანალიზი და გახვიდეთ Cppcheck-დან? - + About შესახებ - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ფაილები (*.xml);;ტექსტური ფაილები (*.txt);;CSV ფაილები (*.csv) @@ -1341,32 +1341,32 @@ Do you want to stop the analysis and exit Cppcheck? შესაბამისობის ანგარიშის გენერაცია ახლა შეუძლებელია, რადგან ჯერ ანალიზი წარმატებით უნდა დასრულდეს. სცადეთ, კოდის ანალიზი თავიდან გაუშვათ და დარწმუნდეთ, რომ კრიტიკული შეცდომები არ არსებობს. - + Build dir '%1' does not exist, create it? აგების საქაღალდე (%1) არ არსებობს. შევქმნა? - + To check the project using addons, you need a build directory. პროექტის დამატებებით შესამოწმებლად აგების საქაღალდე გჭირდებათ. - + Failed to open file ფაილის გახსნის შეცდომა - + Unknown project file format უცნობი პროექტის ფაილის ფორმატი - + Failed to import project file პროექტის ფაილის შემოტანა ჩავარდა - + Failed to import '%1': %2 Analysis is stopped. @@ -1375,27 +1375,27 @@ Analysis is stopped. ანალიზი შეწყდა. - + Failed to import '%1' (%2), analysis is stopped '%1'-ის (%2) შემოტანა ჩავარდა. ანალიზი შეწყდა - + Project files (*.cppcheck) პროექტის ფაილები (*.cppcheck) - + Select Project Filename აირჩიეთ პროექტის ფაილის სახელი - + No project file loaded პროექტის ფაილი ჩატვირთული არაა - + The project file %1 @@ -1412,67 +1412,67 @@ Do you want to remove the file from the recently used projects -list? გნებავთ წაშალოთ ეს ფაილი ახლახან გამოყენებული პროექტების სიიდან? - + Install დაყენება - + New version available: %1. %2 ხელმისაწვდომია ახალი ვერსია: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information diff --git a/gui/cppcheck_ko.ts b/gui/cppcheck_ko.ts index 18720477f08..611eede0491 100644 --- a/gui/cppcheck_ko.ts +++ b/gui/cppcheck_ko.ts @@ -423,18 +423,18 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -578,7 +578,7 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - + Show errors 애러 표시 @@ -685,7 +685,7 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - + Show warnings 경고 표시 @@ -756,8 +756,8 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - - + + Information 정보 @@ -808,7 +808,7 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - + Quick Filter: 빠른 필터: @@ -822,12 +822,12 @@ This is probably because the settings were changed between the Cppcheck versions Cppcheck 버전간 설정 방법 차이때문인 것으로 보입니다. 편집기 설정을 검사(및 수정)해주세요, 그렇지 않으면 편집기가 제대로 시작하지 않습니다. - + You must close the project file before selecting new files or directories! 새로운 파일이나 디렉토리를 선택하기 전에 프로젝트 파일을 닫으세요! - + Found project file: %1 Do you want to load this project file instead? @@ -836,210 +836,210 @@ Do you want to load this project file instead? 이 프로젝트 파일을 불러오겠습니까? - - + + XML files (*.xml) XML 파일 (*.xml) - + Open the report file 보고서 파일 열기 - + License 저작권 - + Authors 제작자 - + Save the report file 보고서 파일 저장 - + Text files (*.txt) 텍스트 파일 (*.txt) - + CSV files (*.csv) CSV 파일 (*.csv) - + Project files (*.cppcheck);;All files(*.*) 프로젝트 파일 (*.cppcheck);;모든 파일(*.*) - + Select Project File 프로젝트 파일 선택 - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information - - - + + + Project: 프로젝트: - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + About - + To check the project using addons, you need a build directory. - + Select Project Filename 프로젝트 파일이름 선택 - + No project file loaded 프로젝트 파일 불러오기 실패 - + The project file %1 @@ -1066,57 +1066,57 @@ Do you want to remove the file from the recently used projects -list? - - - - + + + + Error - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Failed to load the selected library '%1'. %2 - + Unsupported format - + The library '%1' contains unknown elements: %2 - + Duplicate platform type - + Platform type redefined @@ -1146,12 +1146,12 @@ Do you want to remove the file from the recently used projects -list? - + Unknown element - + Select configuration @@ -1174,7 +1174,7 @@ Options: - + Build dir '%1' does not exist, create it? @@ -1202,39 +1202,39 @@ Options: - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + No suitable files found to analyze! - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1381,7 +1381,7 @@ Do you want to stop the analysis and exit Cppcheck? C++14 - + Project files (*.cppcheck) @@ -1406,27 +1406,27 @@ Do you want to stop the analysis and exit Cppcheck? C++20 - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Current results will be cleared. Opening a new XML file will clear current results. diff --git a/gui/cppcheck_nl.ts b/gui/cppcheck_nl.ts index cd14a92bdc2..7c58587662b 100644 --- a/gui/cppcheck_nl.ts +++ b/gui/cppcheck_nl.ts @@ -427,18 +427,18 @@ Parameters: -l(lijn) (bestand) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -582,14 +582,14 @@ Parameters: -l(lijn) (bestand) - + Show errors Toon fouten - + Show warnings Toon waarschuwingen @@ -605,8 +605,8 @@ Parameters: -l(lijn) (bestand) Toon &verborgen - - + + Information Informatie @@ -1030,17 +1030,17 @@ Parameters: -l(lijn) (bestand) - + Quick Filter: Snel Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? @@ -1048,86 +1048,86 @@ Do you want to load this project file instead? Wilt u dit project laden in plaats van? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licentie - + Authors Auteurs - + Save the report file Rapport opslaan - - + + XML files (*.xml) XML bestanden (*.xml) @@ -1141,126 +1141,126 @@ This is probably because the settings were changed between the Cppcheck versions Dit is waarschijnlijk omdat de instellingen zijn gewijzigd tussen de versies van cppcheck. Controleer (en maak) de bewerker instellingen, anders zal de bewerker niet correct starten. - + You must close the project file before selecting new files or directories! Je moet project bestanden sluiten voordat je nieuwe bestanden of mappen selekteerd! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file Open het rapport bestand - + Text files (*.txt) Tekst bestanden (*.txt) - + CSV files (*.csv) CSV bestanden (*.csv) - + Project files (*.cppcheck);;All files(*.*) Project bestanden (*.cppcheck);;Alle bestanden(*.*) - + Select Project File Selecteer project bestand - - - + + + Project: Project: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1268,76 +1268,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Selecteer project bestandsnaam - + No project file loaded Geen project bestand geladen - + The project file %1 @@ -1353,67 +1353,67 @@ Kan niet worden gevonden! Wilt u het bestand van de onlangs gebruikte project verwijderen -lijst? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information diff --git a/gui/cppcheck_ru.ts b/gui/cppcheck_ru.ts index 464bfb0d34b..a6608d90f7d 100644 --- a/gui/cppcheck_ru.ts +++ b/gui/cppcheck_ru.ts @@ -427,18 +427,18 @@ Parameters: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -582,14 +582,14 @@ Parameters: -l(line) (file) - + Show errors Показать ошибки - + Show warnings Показать предупреждения @@ -605,8 +605,8 @@ Parameters: -l(line) (file) Показать скрытые - - + + Information Информационные сообщения @@ -1030,17 +1030,17 @@ Parameters: -l(line) (file) - + Quick Filter: Быстрый фильтр: - + Select configuration Выбор конфигурации - + Found project file: %1 Do you want to load this project file instead? @@ -1049,92 +1049,92 @@ Do you want to load this project file instead? Вы хотите загрузить этот проект? - + File not found Файл не найден - + Bad XML Некорректный XML - + Missing attribute Пропущен атрибут - + Bad attribute value Некорректное значение атрибута - + Unsupported format Неподдерживаемый формат - + Duplicate define - + Failed to load the selected library '%1'. %2 Не удалось загрузить выбранную библиотеку '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Лицензия - + Authors Авторы - + Save the report file Сохранить файл с отчетом - - + + XML files (*.xml) XML-файлы (*.xml) @@ -1148,37 +1148,37 @@ This is probably because the settings were changed between the Cppcheck versions Возможно, это связано с изменениями в версии программы. Пожалуйста, проверьте (и исправьте) настройки приложения. - + You must close the project file before selecting new files or directories! Вы должны закрыть проект перед выбором новых файлов или каталогов! - + The library '%1' contains unknown elements: %2 Библиотека '%1' содержит неизвестные элементы: %2 - + Duplicate platform type Дубликат типа платформы - + Platform type redefined Переобъявление типа платформы - + Unknown element Неизвестный элемент - - - - + + + + Error Ошибка @@ -1187,80 +1187,80 @@ This is probably because the settings were changed between the Cppcheck versions Невозможно загрузить %1. Cppcheck установлен некорректно. Вы можете использовать --data-dir=<directory> в командной строке для указания расположения файлов конфигурации. Обратите внимание, что --data-dir предназначен для использования сценариями установки. При включении данной опции, графический интерфейс пользователя не запускается. - + Open the report file Открыть файл с отчетом - + Text files (*.txt) Текстовые файлы (*.txt) - + CSV files (*.csv) CSV файлы(*.csv) - + Project files (*.cppcheck);;All files(*.*) Файлы проекта (*.cppcheck);;Все файлы(*.*) - + Select Project File Выберите файл проекта - - - + + + Project: Проект: - + No suitable files found to analyze! Не найдено подходящих файлов для анализа - + C/C++ Source Исходный код C/C++ - + Compile database - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze Выбор файлов для анализа - + Select directory to analyze Выбор каталога для анализа - + Select the configuration that will be analyzed Выбор используемой конфигурации - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1269,7 +1269,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1280,7 +1280,7 @@ Do you want to proceed? Вы хотите продолжить? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1289,104 +1289,104 @@ Do you want to stop the analysis and exit Cppcheck? Вы хотите остановить анализ и выйти из Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML файлы (*.xml);;Текстовые файлы (*.txt);;CSV файлы (*.csv) - + Build dir '%1' does not exist, create it? Директория для сборки '%1' не существует, создать? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1395,22 +1395,22 @@ Analysis is stopped. Невозможно импортировать '%1', анализ остановлен - + Project files (*.cppcheck) Файлы проекта (*.cppcheck) - + Select Project Filename Выберите имя файла для проекта - + No project file loaded Файл с проектом не загружен - + The project file %1 @@ -1426,12 +1426,12 @@ Do you want to remove the file from the recently used projects -list? Хотите удалить его из списка проектов? - + Install - + New version available: %1. %2 diff --git a/gui/cppcheck_sr.ts b/gui/cppcheck_sr.ts index 190dbdbe751..07e8059f724 100644 --- a/gui/cppcheck_sr.ts +++ b/gui/cppcheck_sr.ts @@ -415,18 +415,18 @@ Parameters: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -570,14 +570,14 @@ Parameters: -l(line) (file) - + Show errors - + Show warnings @@ -593,8 +593,8 @@ Parameters: -l(line) (file) - - + + Information @@ -1018,103 +1018,103 @@ Parameters: -l(line) (file) - + Quick Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License License - + Authors Authors - + Save the report file Save the report file - - + + XML files (*.xml) XML files (*.xml) @@ -1126,126 +1126,126 @@ This is probably because the settings were changed between the Cppcheck versions - + You must close the project file before selecting new files or directories! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file - + Text files (*.txt) Text files (*.txt) - + CSV files (*.csv) - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - - - + + + Project: - + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Visual Studio - + Borland C++ Builder 6 - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1253,76 +1253,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename - + No project file loaded - + The project file %1 @@ -1333,67 +1333,67 @@ Do you want to remove the file from the recently used projects -list? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information diff --git a/gui/cppcheck_sv.ts b/gui/cppcheck_sv.ts index 4f548b454d0..4b8164d7775 100644 --- a/gui/cppcheck_sv.ts +++ b/gui/cppcheck_sv.ts @@ -433,18 +433,18 @@ Exempel: - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -588,14 +588,14 @@ Exempel: - + Show errors Visa fel - + Show warnings Visa varningar @@ -611,8 +611,8 @@ Exempel: Visa dolda - - + + Information Information @@ -1037,17 +1037,17 @@ Exempel: - + Quick Filter: Snabbfilter: - + Select configuration Välj konfiguration - + Found project file: %1 Do you want to load this project file instead? @@ -1056,92 +1056,92 @@ Do you want to load this project file instead? Vill du ladda denna projektfil istället? - + File not found Filen hittades ej - + Bad XML Ogiltig XML - + Missing attribute Attribut finns ej - + Bad attribute value Ogiltigt attribut värde - + Unsupported format Format stöds ej - + Duplicate define - + Failed to load the selected library '%1'. %2 Misslyckades att ladda valda library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licens - + Authors Utvecklare - + Save the report file Spara rapport - - + + XML files (*.xml) XML filer (*.xml) @@ -1155,37 +1155,37 @@ This is probably because the settings were changed between the Cppcheck versions En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Kontrollera programinställningarna. - + You must close the project file before selecting new files or directories! Du måste stänga projektfilen innan nya filer eller sökvägar kan väljas! - + The library '%1' contains unknown elements: %2 Library filen '%1' har element som ej hanteras: %2 - + Duplicate platform type Dubbel plattformstyp - + Platform type redefined Plattformstyp definieras igen - + Unknown element Element hanteras ej - - - - + + + + Error Fel @@ -1194,80 +1194,80 @@ En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Misslyckades att ladda %1. Din Cppcheck installation är ej komplett. Du kan använda --data-dir<directory> på kommandoraden för att specificera var denna fil finns. Det är meningen att --data-dir kommandot skall köras under installationen,så GUIt kommer ej visas när --data-dir används allt som händer är att en inställning görs. - + Open the report file Öppna rapportfilen - + Text files (*.txt) Text filer (*.txt) - + CSV files (*.csv) CSV filer (*.csv) - + Project files (*.cppcheck);;All files(*.*) Projektfiler (*.cppcheck);;Alla filer(*.*) - + Select Project File Välj projektfil - - - + + + Project: Projekt: - + No suitable files found to analyze! Inga filer hittades att analysera! - + C/C++ Source - + Compile database - + Visual Studio Visual Studio - + Borland C++ Builder 6 - + Select files to analyze Välj filer att analysera - + Select directory to analyze Välj mapp att analysera - + Select the configuration that will be analyzed Välj konfiguration som kommer analyseras - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1276,7 +1276,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1284,7 +1284,7 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1293,104 +1293,104 @@ Do you want to stop the analysis and exit Cppcheck? Vill du stoppa analysen och avsluta Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML filer (*.xml);;Text filer (*.txt);;CSV filer (*.csv) - + Build dir '%1' does not exist, create it? Build dir '%1' existerar ej, skapa den? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1399,22 +1399,22 @@ Analysis is stopped. Misslyckades att importera '%1', analysen stoppas - + Project files (*.cppcheck) Projekt filer (*.cppcheck) - + Select Project Filename Välj Projektfil - + No project file loaded Inget projekt laddat - + The project file %1 @@ -1431,12 +1431,12 @@ Do you want to remove the file from the recently used projects -list? Vill du ta bort filen från 'senast använda projekt'-listan? - + Install - + New version available: %1. %2 diff --git a/gui/cppcheck_zh_CN.ts b/gui/cppcheck_zh_CN.ts index 952fbcd4d14..5860c842a16 100644 --- a/gui/cppcheck_zh_CN.ts +++ b/gui/cppcheck_zh_CN.ts @@ -434,18 +434,18 @@ Parameters: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -600,13 +600,13 @@ Parameters: -l(line) (file) - + Show errors 显示错误 - - + + Information 信息 @@ -713,7 +713,7 @@ Parameters: -l(line) (file) - + Show warnings 显示警告 @@ -1045,23 +1045,23 @@ This is probably because the settings were changed between the Cppcheck versions 这可能是因为 Cppcheck 不同版本间的设置有所不同。请检查(并修复)编辑器应用程序设置,否则编辑器程序可能不会正确启动。 - + You must close the project file before selecting new files or directories! 在选择新的文件或目录之前,你必须先关闭此项目文件! - + Quick Filter: 快速滤器: - + Select configuration 选择配置 - + Found project file: %1 Do you want to load this project file instead? @@ -1070,64 +1070,64 @@ Do you want to load this project file instead? 你是否想加载该项目文件? - + The library '%1' contains unknown elements: %2 库 '%1' 包含未知元素: %2 - + File not found 文件未找到 - + Bad XML 无效的 XML - + Missing attribute 缺失属性 - + Bad attribute value 无效的属性值 - + Unsupported format 不支持的格式 - + Duplicate platform type 重复的平台类型 - + Platform type redefined 平台类型重定义 - + Unknown element 位置元素 - + Failed to load the selected library '%1'. %2 选择的库 '%1' 加载失败。 %2 - - - - + + + + Error 错误 @@ -1136,138 +1136,138 @@ Do you want to load this project file instead? 加载 %1 失败。您的 Cppcheck 安装已损坏。您可以在命令行添加 --data-dir=<目录> 参数来指定文件位置。请注意,'--data-dir' 参数应当由安装脚本使用,因此,当使用此参数时,GUI不会启动,所发生的一切只是配置了设置。 - - + + XML files (*.xml) XML 文件(*.xml) - + Open the report file 打开报告文件 - + License 许可证 - + Authors 作者 - + Save the report file 保存报告文件 - + Text files (*.txt) 文本文件(*.txt) - + CSV files (*.csv) CSV 文件(*.csv) - + Project files (*.cppcheck);;All files(*.*) 项目文件(*.cppcheck);;所有文件(*.*) - + Select Project File 选择项目文件 - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Install - + New version available: %1. %2 - - - + + + Project: 项目: - + No suitable files found to analyze! 没有找到合适的文件来分析! - + C/C++ Source C/C++ 源码 - + Compile database Compile database - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze 选择要分析的文件 - + Select directory to analyze 选择要分析的目录 - + Select the configuration that will be analyzed 选择要分析的配置 - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1276,44 +1276,44 @@ Do you want to proceed analysis without using any of these project files? - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1324,7 +1324,7 @@ Do you want to proceed? 你想继续吗? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1333,77 +1333,77 @@ Do you want to stop the analysis and exit Cppcheck? 您想停止分析并退出 Cppcheck 吗? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML 文件 (*.xml);;文本文件 (*.txt);;CSV 文件 (*.csv) - + Build dir '%1' does not exist, create it? 构建文件夹 '%1' 不能存在,创建它吗? - + To check the project using addons, you need a build directory. 要使用插件检查项目,您需要一个构建目录。 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1412,22 +1412,22 @@ Do you want to stop the analysis and exit Cppcheck? 导入 '%1' 失败,分析已停止 - + Project files (*.cppcheck) 项目文件 (*.cppcheck) - + Select Project Filename 选择项目文件名 - + No project file loaded 项目文件未加载 - + The project file %1 diff --git a/gui/cppcheck_zh_TW.ts b/gui/cppcheck_zh_TW.ts index 1de96423481..841650ba5b1 100644 --- a/gui/cppcheck_zh_TW.ts +++ b/gui/cppcheck_zh_TW.ts @@ -427,18 +427,18 @@ Parameters: -l(line) (file) - - - - - - - - - - - - + + + + + + + + + + + + Cppcheck Cppcheck @@ -640,7 +640,7 @@ Parameters: -l(line) (file) - + Show errors 顯示錯誤 @@ -768,7 +768,7 @@ Parameters: -l(line) (file) - + Show warnings 顯示警告 @@ -1043,15 +1043,15 @@ Options: - + Quick Filter: 快速篩選: - - - + + + Project: 專案: @@ -1063,175 +1063,175 @@ This is probably because the settings were changed between the Cppcheck versions - + No suitable files found to analyze! 找不到適合的檔案來分析! - + You must close the project file before selecting new files or directories! 您必須在選取新檔案或目錄之前關閉該專案檔! - + C/C++ Source C/C++ 來源檔 - + Compile database 編譯資料庫 - + Visual Studio Visual Studio - + Borland C++ Builder 6 Borland C++ Builder 6 - + Select files to analyze 選取要分析的檔案 - + Select directory to analyze 選取要分析的目錄 - + Select configuration 選取組態 - + Select the configuration that will be analyzed 選取要分析的組態 - + Found project file: %1 Do you want to load this project file instead? - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - - + + Information 資訊 - + The library '%1' contains unknown elements: %2 - + File not found 找不到檔案 - + Bad XML - + Missing attribute - + Bad attribute value - + Unsupported format 未支援的格式 - + Duplicate platform type 重複的平臺型別 - + Platform type redefined 平臺型別重定義 - + Duplicate define - + Unknown element 未知的元素 - + Failed to load the selected library '%1'. %2 無法載入選取的程式庫 '%1'。 %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - - - - + + + + Error 錯誤 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1239,18 +1239,18 @@ Do you want to proceed? - - + + XML files (*.xml) XML 檔案 (*.xml) - + Open the report file 開啟報告檔 - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1259,77 +1259,77 @@ Do you want to stop the analysis and exit Cppcheck? 您想停止分析並離開 Cppcheck 嗎? - + About 關於 - + License 授權 - + Authors 作者 - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML 檔案 (*.xml);;文字檔 (*.txt);;CSV 檔案 (*.csv) - + Save the report file 儲存報告檔 - + Text files (*.txt) 文字檔 (*.txt) - + CSV files (*.csv) CSV 檔案 (*.csv) - + Project files (*.cppcheck);;All files(*.*) 專案檔 (*.cppcheck);;所有檔案 (*.*) - + Select Project File 選取專案檔 - + Build dir '%1' does not exist, create it? 建置目錄 '%1' 不存在,是否建立它? - + To check the project using addons, you need a build directory. - + Failed to open file 無法開啟檔案 - + Unknown project file format 未知的專案檔格式 - + Failed to import project file 無法匯入專案檔 - + Failed to import '%1': %2 Analysis is stopped. @@ -1338,62 +1338,62 @@ Analysis is stopped. 停止分析。 - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1402,22 +1402,22 @@ Analysis is stopped. 無法匯入 '%1',停止分析 - + Project files (*.cppcheck) 專案檔 (*.cppcheck) - + Select Project Filename 選取專案檔案名稱 - + No project file loaded - + The project file %1 @@ -1434,12 +1434,12 @@ Do you want to remove the file from the recently used projects -list? 您要從最近使用的專案列表中移除該檔案嗎? - + Install 安章 - + New version available: %1. %2 可用的新版本: %1. %2 From 9becbb6e8a3b98f080fbf2a44e18997602f65c5b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 12 Jun 2026 15:50:12 +0200 Subject: [PATCH 169/493] Partial fix for #14833 FN returnDanglingLifetime with memcpy() (#8647) --- cfg/std.cfg | 28 ++++++++++++++-------------- test/cfg/std.cpp | 18 +++++++++++++++--- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index ec5fbb72548..245142c091d 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -3989,7 +3989,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
- + arg1 false @@ -4010,7 +4010,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + arg1 false @@ -4056,7 +4056,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + arg1 @@ -4077,7 +4077,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + arg1 @@ -4118,7 +4118,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + arg1 false @@ -4136,7 +4136,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + arg1 false @@ -4812,7 +4812,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + arg1 false @@ -4828,9 +4828,9 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + - + arg1 false @@ -4942,7 +4942,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + arg1 false @@ -5057,7 +5057,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + arg1 false @@ -5123,10 +5123,10 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + false - + arg1 @@ -5373,7 +5373,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + arg1 false diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 0344b98455c..77c9d99cd5d 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -869,7 +869,7 @@ char * overlappingWriteFunction_strncat(const char *src, char *dest, const std:: // cppcheck-suppress overlappingWriteFunction (void)strncat(dest, dest+1, 2); char buffer[] = "strncat"; - // cppcheck-suppress overlappingWriteFunction + // cppcheck-suppress [overlappingWriteFunction,returnDanglingLifetime] return strncat(buffer, buffer + 1, 3); } @@ -882,7 +882,7 @@ wchar_t * overlappingWriteFunction_wcsncat(const wchar_t *src, wchar_t *dest, co // cppcheck-suppress overlappingWriteFunction (void)wcsncat(dest, dest+1, 2); wchar_t buffer[] = L"strncat"; - // cppcheck-suppress overlappingWriteFunction + // cppcheck-suppress [overlappingWriteFunction,returnDanglingLifetime] return wcsncat(buffer, buffer + 1, 3); } @@ -917,8 +917,8 @@ char * overlappingWriteFunction_strncpy(char *buf, const std::size_t count) void * overlappingWriteFunction_memmove(void) { - // No warning shall be shown: char str[] = "memmove handles overlapping data well"; + // cppcheck-suppress returnDanglingLifetime return memmove(str,str+3,4); } @@ -4982,6 +4982,18 @@ std::span returnDanglingLifetime_std_span1() { } #endif +void* returnDanglingLifetime_memcpy() { // #14833 + char a[4]; + // cppcheck-suppress returnDanglingLifetime + return memcpy(a, "abc", 4); +} + +wchar_t* returnDanglingLifetime_wcscat() { + wchar_t a[10]{L"abc"}; + // cppcheck-suppress returnDanglingLifetime + return wcscat(a, L"def"); +} + void beginEnd() { std::vector v; From 2fac13df7df98b719c411e9b26bc2a8e641a8372 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 14 Jun 2026 22:32:36 +0200 Subject: [PATCH 170/493] Fix #14838 FP invalidLifetime, objectIndex with copy to pointer alias (#8649) Co-authored-by: chrchr-github --- lib/valueflow.cpp | 2 +- test/testvalueflow.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 64a48285fdc..68e989c0738 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2591,7 +2591,7 @@ static void valueFlowLifetimeFunction(Token *tok, const TokenList &tokenlist, Er std::vector args = getArguments(tok); if (iArg > 0 && iArg <= args.size()) { const Token* varTok = args[iArg - 1]; - if (varTok->variable() && varTok->variable()->isLocal()) + if (varTok->variable() && varTok->variable()->isLocal() && varTok->variable()->isArray()) LifetimeStore{ varTok, "Passed to '" + tok->str() + "'.", ValueFlow::Value::LifetimeKind::Address }.byRef( tok->next(), tokenlist, errorLogger, settings); } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 65f198dcbab..0c8addb3b94 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -908,6 +908,19 @@ class TestValueFlow : public TestFixture { ASSERT_EQUALS(true, lifetimes.size() == 1); ASSERT_EQUALS(true, lifetimes.front() == "a"); } + { + const char code[] = "void f(const char *s, size_t len) {\n" + " char buf[10];\n" + " {\n" + " char *tmp = buf;\n" + " s = strcpy(tmp, s);\n" + " }\n" + " if (s[len] == '\0') {}\n" + "}\n"; + lifetimes = lifetimeValues(code, "s ["); + ASSERT_EQUALS(true, lifetimes.size() == 1); + ASSERT_EQUALS(true, lifetimes.front() == "buf"); + } } void valueFlowArrayElement() { From 987d3b48a3fe1591444e9586da59e62feb4a7510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Mon, 15 Jun 2026 00:30:27 +0200 Subject: [PATCH 171/493] fwdanalysis: Remove unused What::ValueFlow mode (#8650) The What::ValueFlow mode and its state (mValueFlow, mValueFlowKnown, KnownAndToken) are not used since commit 921887a281, which switched to valueFlowForwardExpression instead of FwdAnalysis::valueFlow(). --- lib/fwdanalysis.cpp | 85 ++++----------------------------------------- lib/fwdanalysis.h | 14 ++------ 2 files changed, 9 insertions(+), 90 deletions(-) diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index c45213a4be9..ddcbbbd1fa9 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -30,6 +30,7 @@ #include #include #include +#include static bool isUnchanged(const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local) { @@ -94,7 +95,7 @@ static bool hasVolatileCastOrVar(const Token *expr) return ret; } -FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local, bool inInnerClass, int depth) +FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local, bool inInnerClass, int depth) const { // Parse the given tokens if (++depth > 1000) @@ -155,10 +156,6 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * } if (tok->str() == "}") { - // Known value => possible value - if (tok->scope() == expr->scope()) - mValueFlowKnown = false; - if (tok->scope()->isLoopScope()) { // check condition const Token *conditionStart = nullptr; @@ -195,65 +192,6 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * if (Token::simpleMatch(tok, "asm (")) return Result(Result::Type::BAILOUT); - if (mWhat == What::ValueFlow && (Token::Match(tok, "while|for (") || Token::simpleMatch(tok, "do {"))) { - const Token *bodyStart = nullptr; - const Token *conditionStart = nullptr; - if (Token::simpleMatch(tok, "do {")) { - bodyStart = tok->next(); - if (Token::simpleMatch(bodyStart->link(), "} while (")) - conditionStart = bodyStart->link()->tokAt(2); - } else { - conditionStart = tok->next(); - if (Token::simpleMatch(conditionStart->link(), ") {")) - bodyStart = conditionStart->link()->next(); - } - - if (!bodyStart || !conditionStart) - return Result(Result::Type::BAILOUT); - - // Is expr changed in condition? - if (!isUnchanged(conditionStart, conditionStart->link(), exprVarIds, local)) - return Result(Result::Type::BAILOUT); - - // Is expr changed in loop body? - if (!isUnchanged(bodyStart, bodyStart->link(), exprVarIds, local)) - return Result(Result::Type::BAILOUT); - } - - if (mWhat == What::ValueFlow && Token::simpleMatch(tok, "if (") && Token::simpleMatch(tok->linkAt(1), ") {")) { - const Token *bodyStart = tok->linkAt(1)->next(); - const Token *conditionStart = tok->next(); - const Token *condTok = conditionStart->astOperand2(); - if (const ValueFlow::Value* v = condTok->getKnownValue(ValueFlow::Value::ValueType::INT)) { - const bool cond = !!v->intvalue; - if (cond) { - FwdAnalysis::Result result = checkRecursive(expr, bodyStart, bodyStart->link(), exprVarIds, local, true, depth); - if (result.type != Result::Type::NONE) - return result; - } else if (Token::simpleMatch(bodyStart->link(), "} else {")) { - bodyStart = bodyStart->link()->tokAt(2); - FwdAnalysis::Result result = checkRecursive(expr, bodyStart, bodyStart->link(), exprVarIds, local, true, depth); - if (result.type != Result::Type::NONE) - return result; - } - } - tok = bodyStart->link(); - if (isReturnScope(tok, mSettings.library)) - return Result(Result::Type::BAILOUT); - if (Token::simpleMatch(tok, "} else {")) - tok = tok->linkAt(2); - if (!tok) - return Result(Result::Type::BAILOUT); - - // Is expr changed in condition? - if (!isUnchanged(conditionStart, conditionStart->link(), exprVarIds, local)) - return Result(Result::Type::BAILOUT); - - // Is expr changed in condition body? - if (!isUnchanged(bodyStart, bodyStart->link(), exprVarIds, local)) - return Result(Result::Type::BAILOUT); - } - if (!local && Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) { // TODO: this is a quick bailout return Result(Result::Type::BAILOUT); @@ -279,22 +217,15 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * parent = parent->astParent(); if (parent->str() == "(" && !parent->isCast()) break; - if (isSameExpression(false, expr, parent, mSettings, true, false, nullptr)) { + if (isSameExpression(false, expr, parent, mSettings, true, false, nullptr)) same = true; - if (mWhat == What::ValueFlow) { - KnownAndToken v; - v.known = mValueFlowKnown; - v.token = parent; - mValueFlow.push_back(v); - } - } if (Token::Match(parent, ". %var%") && parent->next()->varId() && exprVarIds.find(parent->next()->varId()) == exprVarIds.end() && isSameExpression(false, expr->astOperand1(), parent->astOperand1(), mSettings, true, false, nullptr)) { other = true; break; } } - if (mWhat != What::ValueFlow && same && Token::simpleMatch(parent->astParent(), "[") && parent == parent->astParent()->astOperand2()) { + if (same && Token::simpleMatch(parent->astParent(), "[") && parent == parent->astParent()->astOperand2()) { return Result(Result::Type::READ); } if (other) @@ -381,8 +312,6 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * return result1; if (mWhat == What::UnusedValue && result1.type == Result::Type::WRITE && expr->variable() && expr->variable()->isReference()) return result1; - if (mWhat == What::ValueFlow && result1.type == Result::Type::WRITE) - mValueFlowKnown = false; if (mWhat == What::Reassign && result1.type == Result::Type::BREAK) { const Token *scopeEndToken = findNextTokenFromBreak(result1.token); if (scopeEndToken) { @@ -394,8 +323,6 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * if (Token::simpleMatch(tok->linkAt(1), "} else {")) { const Token *elseStart = tok->linkAt(1)->tokAt(2); const Result &result2 = checkRecursive(expr, elseStart, elseStart->link(), exprVarIds, local, inInnerClass, depth); - if (mWhat == What::ValueFlow && result2.type == Result::Type::WRITE) - mValueFlowKnown = false; if (result2.type == Result::Type::READ || result2.type == Result::Type::BAILOUT) return result2; if (result1.type == Result::Type::WRITE && result2.type == Result::Type::WRITE) @@ -454,7 +381,7 @@ std::set FwdAnalysis::getExprVarIds(const Token* expr, bool* localOu return exprVarIds; } -FwdAnalysis::Result FwdAnalysis::check(const Token* expr, const Token* startToken, const Token* endToken) +FwdAnalysis::Result FwdAnalysis::check(const Token* expr, const Token* startToken, const Token* endToken) const { // all variable ids in expr. bool local = true; @@ -475,7 +402,7 @@ FwdAnalysis::Result FwdAnalysis::check(const Token* expr, const Token* startToke Result result = checkRecursive(expr, startToken, endToken, exprVarIds, local, false); // Break => continue checking in outer scope - while (mWhat!=What::ValueFlow && result.type == FwdAnalysis::Result::Type::BREAK) { + while (result.type == FwdAnalysis::Result::Type::BREAK) { const Token *scopeEndToken = findNextTokenFromBreak(result.token); if (!scopeEndToken) break; diff --git a/lib/fwdanalysis.h b/lib/fwdanalysis.h index 389ea195da2..34d0da24d4d 100644 --- a/lib/fwdanalysis.h +++ b/lib/fwdanalysis.h @@ -25,7 +25,6 @@ #include #include -#include class Token; class Settings; @@ -60,11 +59,6 @@ class FwdAnalysis { */ bool unusedValue(const Token *expr, const Token *startToken, const Token *endToken); - struct KnownAndToken { - bool known{}; - const Token* token{}; - }; - /** Is there some possible alias for given expression */ bool possiblyAliased(const Token *expr, const Token *startToken) const; @@ -80,13 +74,11 @@ class FwdAnalysis { const Token* token{}; }; - Result check(const Token *expr, const Token *startToken, const Token *endToken); - Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local, bool inInnerClass, int depth=0); + Result check(const Token *expr, const Token *startToken, const Token *endToken) const; + Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local, bool inInnerClass, int depth=0) const; const Settings &mSettings; - enum class What : std::uint8_t { Reassign, UnusedValue, ValueFlow } mWhat = What::Reassign; - std::vector mValueFlow; - bool mValueFlowKnown = true; + enum class What : std::uint8_t { Reassign, UnusedValue } mWhat = What::Reassign; }; #endif // fwdanalysisH From a7faefc9203cf14850ea4e4d35aed0f854eaeccd Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 16 Jun 2026 08:53:23 +0200 Subject: [PATCH 172/493] Fix #14847 Function pointer argument triggers false positive funcArgNamesDifferentUnnamed (#8653) --- lib/checkother.cpp | 4 ++-- test/testother.cpp | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 801dc529568..551c3a47543 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4043,7 +4043,7 @@ void CheckOtherImpl::checkFuncArgNamesDifferent() definitions[j] = variable->nameToken(); } // get the declaration (search for first token with varId) - while (decl && !Token::Match(decl, ",|)|;")) { + while (decl && !Token::Match(decl, "[,;]")) { // skip everything after the assignment because // it could also have a varId or be the first // token with a varId if there is no name token @@ -4052,7 +4052,7 @@ void CheckOtherImpl::checkFuncArgNamesDifferent() break; } // skip over templates and arrays - if (decl->link() && decl->str() != "(") + if (decl->link() && !Token::Match(decl, "[()]")) decl = decl->link(); else if (decl->varId()) declarations[j] = decl; diff --git a/test/testother.cpp b/test/testother.cpp index 73f10cbe76e..c8a95c9882b 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -12955,6 +12955,10 @@ class TestOther : public TestFixture { "[test.cpp:1:12]: (style, inconclusive) Function 'f' argument 1 names different: declaration 'a' definition ''. [funcArgNamesDifferentUnnamed]\n" "[test.cpp:4:12]: (style, inconclusive) Function 'g' argument 1 names different: declaration '' definition 'b'. [funcArgNamesDifferentUnnamed]\n", errout_str()); + + check("void f(void (*fp)(), int x);\n" // #14847 + "void f(void (*fp)(), int x) {}\n"); + ASSERT_EQUALS("", errout_str()); } void funcArgOrderDifferent() { From 051584cdbd6b0292e55492ea29cc1ef762eab7e1 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 16 Jun 2026 19:28:59 +0200 Subject: [PATCH 173/493] Refs #12986: Tokenizer: don't simplify init list containing default-constructed element (#8640) --- lib/tokenize.cpp | 3 ++- test/testsimplifytokens.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index c5b001f5d32..f195cdd7ad6 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3862,7 +3862,8 @@ void Tokenizer::simplifyRedundantConsecutiveBraces() for (Token *tok = list.front(); tok;) { if (Token::simpleMatch(tok, "= {")) { tok = tok->linkAt(1); - } else if (Token::simpleMatch(tok, "{ {") && Token::simpleMatch(tok->linkAt(1), "} }")) { + } else if (Token::simpleMatch(tok, "{ {") && Token::simpleMatch(tok->linkAt(1), "} }") && + !Token::Match(tok->previous(), "%name%")) { //remove internal parentheses tok->linkAt(1)->deleteThis(); tok->deleteNext(); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 6077438a9cf..2f04653a379 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -1422,6 +1422,7 @@ class TestSimplifyTokens : public TestFixture { ASSERT_EQUALS("void f ( ) { }", tok("void f(){{{}}}")); ASSERT_EQUALS("void f ( ) { for ( ; ; ) { } }", tok("void f () { for(;;){} }")); ASSERT_EQUALS("void f ( ) { { scope_lock lock ; foo ( ) ; } { scope_lock lock ; bar ( ) ; } }", tok("void f () { {scope_lock lock; foo();} {scope_lock lock; bar();} }")); + ASSERT_EQUALS("std :: map < int , int > m { { } } ;", tok("std::map m{ {} };")); } void simplifyOverride() { // ticket #5069 From 1d0ff1a3518ea32b87f175957dfe65cb92e94607 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:39:44 +0200 Subject: [PATCH 174/493] Fix #14842 FN memleak in function with trailing return type (regression) (#8651) Co-authored-by: chrchr-github --- lib/tokenize.cpp | 19 +++++++++++++++++-- test/testtokenize.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f195cdd7ad6..59da46a0b28 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7334,6 +7334,19 @@ void Tokenizer::simplifyVarDecl(const bool only_k_r_fpar) simplifyVarDecl(list.front(), nullptr, only_k_r_fpar); } +static Token* isTrailingReturnType(Token* tok) +{ + while (Token::Match(tok, "%name%|::|>")) { + if (Token* open = tok->findOpeningBracket()) + tok = open->tokAt(-1); + else + tok = tok->tokAt(-1); + } + if (tok && Token::simpleMatch(tok->tokAt(-1), ") .")) + return tok->tokAt(-1); + return nullptr; +} + // cppcheck-suppress functionConst - has side effects void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, const bool only_k_r_fpar) { @@ -7361,14 +7374,16 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co if (!tok->linkAt(1)) syntaxError(tokBegin); // Check for lambdas before skipping - if (Token::Match(tok->tokAt(-2), ") . %name%")) { // trailing return type + if (Token* trailingStart = isTrailingReturnType(tok)) { // TODO: support lambda without parameter clause? - Token* lambdaStart = tok->linkAt(-2)->previous(); + Token* lambdaStart = trailingStart->link()->tokAt(-1); if (Token::simpleMatch(lambdaStart, "]")) lambdaStart = lambdaStart->link(); Token* lambdaEnd = findLambdaEndScope(lambdaStart); if (lambdaEnd) simplifyVarDecl(lambdaEnd->link()->next(), lambdaEnd, only_k_r_fpar); + else + simplifyVarDecl(tok->tokAt(2), tok->linkAt(1), only_k_r_fpar); } else { for (Token* tok2 = tok->next(); tok2 != tok->linkAt(1); tok2 = tok2->next()) { Token* lambdaEnd = findLambdaEndScope(tok2); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 5f4d59503e2..b1e3e87cdcf 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -233,6 +233,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(vardecl32); TEST_CASE(vardecl33); TEST_CASE(vardecl34); + TEST_CASE(vardecl35); TEST_CASE(vardecl_stl_1); TEST_CASE(vardecl_stl_2); TEST_CASE(vardecl_stl_3); @@ -2857,6 +2858,32 @@ class TestTokenizer : public TestFixture { } } + void vardecl35() { // #14842 + { + const char code[] = "auto f() -> void {\n" + " auto p = new int;\n" + " *p = 0;\n" + "}\n"; + ASSERT_EQUALS("auto f ( ) . void {\n" + "auto p ; p = new int ;\n" + "* p = 0 ;\n" + "}", tokenizeAndStringify(code)); + ignore_errout(); + } + { + const char code[] = "auto f() -> ::std::vector {\n" + " int i = 0;\n" + " return { i };\n" + "}"; + ASSERT_EQUALS("auto f ( ) . :: std :: vector < int > {\n" + "int i ; i = 0 ;\n" + "return { i } ;\n" + "}", + tokenizeAndStringify(code)); + ignore_errout(); + } + } + void volatile_variables() { { const char code[] = "volatile int a=0;\n" From 6f17c161fddd038b82072027097de58b4b5f35c0 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:48:38 +0200 Subject: [PATCH 175/493] Fix #11751 FP accessMoved after passing value to function (#8646) --- lib/forwardanalyzer.cpp | 2 +- test/testvalueflow.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 5c97528372b..0999a08d908 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -845,7 +845,7 @@ namespace { return Break(); } else if (Token* callTok = callExpr(tok)) { // TODO: Dont traverse tokens a second time - if (start != callTok && tok != callTok && updateRecursive(callTok->astOperand1()) == Progress::Break) + if (start != callTok && tok != callTok && (tok->str() != "." || tok != callTok->astOperand1()) && updateRecursive(callTok->astOperand1()) == Progress::Break) return Break(); // Since the call could be an unknown macro, traverse the tokens as a range instead of recursively if (!Token::simpleMatch(callTok, "( )") && diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 0c8addb3b94..247d2ae6012 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1090,6 +1090,14 @@ class TestValueFlow : public TestFixture { " }\n" "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 13U, ValueFlow::Value::MoveKind::MovedVariable)); + + code = "struct S { int f(int); };\n" // #11751 + "S g(S);\n" + "void h() {\n" + " S x;\n" + " g(std::move(x)).f(1);\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 5U, ValueFlow::Value::MoveKind::MovedVariable)); } void valueFlowCalculations() { From 4a4e12d323cefc23ed5066cffbfbcf988c80b351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 16 Jun 2026 22:13:05 +0200 Subject: [PATCH 176/493] fixed #14084 - run CMake with `--warn-uninitialized` in CI (#8290) --- .github/workflows/CI-unixish-docker.yml | 2 +- .github/workflows/CI-unixish.yml | 40 +++++++++++++------------ .github/workflows/CI-windows.yml | 6 ++-- .github/workflows/clang-tidy.yml | 2 +- .github/workflows/iwyu.yml | 4 +-- .github/workflows/release-windows.yml | 2 +- .github/workflows/sanitizers.yml | 2 +- .github/workflows/selfcheck.yml | 10 +++---- cmake/options.cmake | 2 +- 9 files changed, 36 insertions(+), 34 deletions(-) diff --git a/.github/workflows/CI-unixish-docker.yml b/.github/workflows/CI-unixish-docker.yml index a38feb452f0..16c1615ed04 100644 --- a/.github/workflows/CI-unixish-docker.yml +++ b/.github/workflows/CI-unixish-docker.yml @@ -72,7 +72,7 @@ jobs: - name: Run CMake run: | - cmake -S . -B cmake.output -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=${{ matrix.with_gui }} -DWITH_QCHART=On -DBUILD_TRIAGE=${{ matrix.with_gui }} -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=${{ matrix.with_gui }} -DWITH_QCHART=On -DBUILD_TRIAGE=${{ matrix.with_gui }} -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - name: CMake build if: matrix.full_build diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index 3251a6b5adb..4a7d94c4057 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -58,13 +58,13 @@ jobs: - name: CMake build on ubuntu (with GUI / system tinyxml2) if: contains(matrix.os, 'ubuntu') run: | - cmake -S . -B cmake.output.tinyxml2 -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output.tinyxml2 -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache cmake --build cmake.output.tinyxml2 -- -j$(nproc) - name: CMake build on macos (with GUI / system tinyxml2) if: contains(matrix.os, 'macos') run: | - cmake -S . -B cmake.output.tinyxml2 -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 + cmake -S . -B cmake.output.tinyxml2 -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 cmake --build cmake.output.tinyxml2 -- -j$(nproc) - name: Run CMake test (system tinyxml2) @@ -127,12 +127,12 @@ jobs: - name: Run CMake on ubuntu (with GUI) if: contains(matrix.os, 'ubuntu') run: | - cmake -S . -B cmake.output -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install - name: Run CMake on macos (with GUI) if: contains(matrix.os, 'macos') run: | - cmake -S . -B cmake.output -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 - name: Run CMake build run: | @@ -154,13 +154,13 @@ jobs: - name: Run CMake on ubuntu (no CLI) if: matrix.os == 'ubuntu-22.04' run: | - cmake -S . -B cmake.output_nocli -Werror=dev -DBUILD_TESTING=Off -DBUILD_CLI=Off + cmake -S . -B cmake.output_nocli -Werror=dev --warn-uninitialized -DBUILD_TESTING=Off -DBUILD_CLI=Off - name: Run CMake on ubuntu (no CLI / with tests) if: matrix.os == 'ubuntu-22.04' run: | # the test and CLI code are too intertwined so for now we need to reject that - if cmake -S . -B cmake.output_nocli_tests -Werror=dev -DBUILD_TESTING=On -DBUILD_CLI=Off; then + if cmake -S . -B cmake.output_nocli_tests -Werror=dev --warn-uninitialized -DBUILD_TESTING=On -DBUILD_CLI=Off; then exit 1 else exit 0 @@ -169,18 +169,18 @@ jobs: - name: Run CMake on ubuntu (no CLI / with GUI) if: matrix.os == 'ubuntu-22.04' run: | - cmake -S . -B cmake.output_nocli_gui -Werror=dev -DBUILD_TESTING=Off -DBUILD_CLI=Off -DBUILD_GUI=On + cmake -S . -B cmake.output_nocli_gui -Werror=dev --warn-uninitialized -DBUILD_TESTING=Off -DBUILD_CLI=Off -DBUILD_GUI=On - name: Run CMake on ubuntu (no GUI) if: matrix.os == 'ubuntu-22.04' run: | - cmake -S . -B cmake.output_nogui -Werror=dev -DBUILD_TESTING=Off -DBUILD_GUI=Off + cmake -S . -B cmake.output_nogui -Werror=dev --warn-uninitialized -DBUILD_TESTING=Off -DBUILD_GUI=Off - name: Run CMake on ubuntu (no GUI / with triage) if: matrix.os == 'ubuntu-22.04' run: | # cannot build triage without GUI - if cmake -S . -B cmake.output_nogui_triage -Werror=dev -DBUILD_TESTING=Off -DBUILD_GUI=Off -DBUILD_TRIAGE=On; then + if cmake -S . -B cmake.output_nogui_triage -Werror=dev --warn-uninitialized -DBUILD_TESTING=Off -DBUILD_GUI=Off -DBUILD_TRIAGE=On; then exit 1 else exit 0 @@ -189,7 +189,7 @@ jobs: - name: Run CMake on ubuntu (no CLI / no GUI) if: matrix.os == 'ubuntu-22.04' run: | - cmake -S . -B cmake.output_nocli_nogui -Werror=dev -DBUILD_TESTING=Off -DBUILD_GUI=Off + cmake -S . -B cmake.output_nocli_nogui -Werror=dev --warn-uninitialized -DBUILD_TESTING=Off -DBUILD_GUI=Off build_cmake_cxxstd: @@ -243,12 +243,12 @@ jobs: - name: Run CMake on ubuntu (with GUI) if: contains(matrix.os, 'ubuntu') run: | - cmake -S . -B cmake.output -Werror=dev -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - name: Run CMake on macos (with GUI) if: contains(matrix.os, 'macos') run: | - cmake -S . -B cmake.output -Werror=dev -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 - name: Run CMake build run: | @@ -373,7 +373,7 @@ jobs: run: | # make sure we fail when Boost is requested and not available. # will fail because no package configuration is available. - if cmake -S . -B cmake.output.boost-force-noavail -Werror=dev -DBUILD_TESTING=Off -DUSE_BOOST=On; then + if cmake -S . -B cmake.output.boost-force-noavail -Werror=dev --warn-uninitialized -DBUILD_TESTING=Off -DUSE_BOOST=On; then exit 1 else exit 0 @@ -386,12 +386,12 @@ jobs: - name: Run CMake on macOS (force Boost) run: | - cmake -S . -B cmake.output.boost-force -Werror=dev -DBUILD_TESTING=Off -DUSE_BOOST=On + cmake -S . -B cmake.output.boost-force -Werror=dev --warn-uninitialized -DBUILD_TESTING=Off -DUSE_BOOST=On - name: Run CMake on macOS (no Boost) run: | # make sure Boost is not used when disabled even though it is available - cmake -S . -B cmake.output.boost-no -Werror=dev -DBUILD_TESTING=Off -DUSE_BOOST=Off + cmake -S . -B cmake.output.boost-no -Werror=dev --warn-uninitialized -DBUILD_TESTING=Off -DUSE_BOOST=Off if grep -q '\-DHAVE_BOOST' ./cmake.output.boost-no/compile_commands.json; then exit 1 else @@ -400,7 +400,7 @@ jobs: - name: Run CMake on macOS (with Boost) run: | - cmake -S . -B cmake.output.boost -Werror=dev -DBUILD_TESTING=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output.boost -Werror=dev --warn-uninitialized -DBUILD_TESTING=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache grep -q '\-DHAVE_BOOST' ./cmake.output.boost/compile_commands.json - name: Build with CMake on macOS (with Boost) @@ -436,11 +436,13 @@ jobs: - name: Run CMake (without GUI) run: | export PATH=cmake-${{ env.CMAKE_VERSION_FULL }}-linux-x86_64/bin:$PATH + # FIXME: cannot use --warn-uninitialized here as it completely breaks the build cmake -S . -B cmake.output -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On - name: Run CMake (with GUI) run: | export PATH=cmake-${{ env.CMAKE_VERSION_FULL }}-linux-x86_64/bin:$PATH + # FIXME: cannot use --warn-uninitialized here as it completely breaks the build cmake -S . -B cmake.output.gui -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On build: @@ -596,7 +598,7 @@ jobs: - name: Test Signalhandler run: | - cmake -S . -B build.cmake.signal -Werror=dev -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On + cmake -S . -B build.cmake.signal -Werror=dev --warn-uninitialized -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On cmake --build build.cmake.signal --target test-signalhandler -- -j$(nproc) # TODO: how to run this without copying the file? cp build.cmake.signal/bin/test-s* . @@ -607,7 +609,7 @@ jobs: - name: Test Stacktrace if: contains(matrix.os, 'ubuntu') run: | - cmake -S . -B build.cmake.stack -Werror=dev -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On + cmake -S . -B build.cmake.stack -Werror=dev --warn-uninitialized -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On cmake --build build.cmake.stack --target test-stacktrace -- -j$(nproc) # TODO: how to run this without copying the file? cp build.cmake.stack/bin/test-s* . @@ -734,7 +736,7 @@ jobs: - name: CMake run: | - cmake -S . -B cmake.output -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On - name: Generate dependencies run: | diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml index a76997eb007..f9d108eefc9 100644 --- a/.github/workflows/CI-windows.yml +++ b/.github/workflows/CI-windows.yml @@ -52,7 +52,7 @@ jobs: run: | rem TODO: enable rules? rem specify Release build so matchcompiler is used - cmake -S . -B build -Werror=dev -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DBUILD_TESTING=Off -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DBUILD_ONLINE_HELP=On -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake -S . -B build -Werror=dev --warn-uninitialized -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DBUILD_TESTING=Off -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DBUILD_ONLINE_HELP=On -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! - name: Build GUI release run: | @@ -91,7 +91,7 @@ jobs: - name: Run CMake run: | - cmake -S . -B build.cxxstd -Werror=dev -A x64 -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake -S . -B build.cxxstd -Werror=dev --warn-uninitialized -A x64 -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! - name: Build run: | @@ -270,7 +270,7 @@ jobs: - name: Test SEH wrapper if: matrix.config == 'release' run: | - cmake -S . -B build.cmake.seh -Werror=dev -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake -S . -B build.cmake.seh -Werror=dev --warn-uninitialized -DBUILD_TESTING=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! cmake --build build.cmake.seh --target test-sehwrapper || exit /b !errorlevel! :: TODO: how to run this without copying the file? copy build.cmake.seh\bin\Debug\test-sehwrapper.exe . || exit /b !errorlevel! diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index c4f8cc0cf6b..7a5b317693a 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -61,7 +61,7 @@ jobs: - name: Prepare CMake run: | - cmake -S . -B cmake.output -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_COMPILE_WARNING_AS_ERROR=On + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_COMPILE_WARNING_AS_ERROR=On env: CC: clang-22 CXX: clang++-22 diff --git a/.github/workflows/iwyu.yml b/.github/workflows/iwyu.yml index 3b972dca443..de047b8d10a 100644 --- a/.github/workflows/iwyu.yml +++ b/.github/workflows/iwyu.yml @@ -126,7 +126,7 @@ jobs: - name: Prepare CMake run: | # TODO: re-enable HAVE_RULES - cmake -S . -B cmake.output -Werror=dev -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=Off -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.stdlib == 'libc++' }} + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=Off -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.stdlib == 'libc++' }} env: CC: clang CXX: clang++ @@ -234,7 +234,7 @@ jobs: - name: Prepare CMake run: | # TODO: re-enable HAVE_RULES - cmake -S . -B cmake.output -Werror=dev -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=Off -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.use_libcxx }} + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=Off -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.use_libcxx }} env: CC: clang-22 CXX: clang++-22 diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index f59e77a2dca..8d09a55302e 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -85,7 +85,7 @@ jobs: run: | :: TODO: enable rules? :: specify Release build so matchcompiler is used - cmake -S . -B build -Werror=dev -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=Off -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_ONLINE_HELP=On -DUSE_BOOST=ON -DBOOST_INCLUDEDIR=%GITHUB_WORKSPACE%\boost -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake -S . -B build -Werror=dev --warn-uninitialized -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=Off -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_ONLINE_HELP=On -DUSE_BOOST=ON -DBOOST_INCLUDEDIR=%GITHUB_WORKSPACE%\boost -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! cmake --build build --target cppcheck-gui --config Release || exit /b !errorlevel! # TODO: package PDBs diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml index d7ff31939d0..ea0a0276c99 100644 --- a/.github/workflows/sanitizers.yml +++ b/.github/workflows/sanitizers.yml @@ -96,7 +96,7 @@ jobs: - name: CMake run: | - cmake -S . -B cmake.output -Werror=dev -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify ${{ matrix.cmake_opts }} -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DFILESDIR= -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify ${{ matrix.cmake_opts }} -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DFILESDIR= -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache env: CC: clang-22 CXX: clang++-22 diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index dcdf8bfbdd3..6bd87f9243f 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -64,7 +64,7 @@ jobs: # unusedFunction - start - name: CMake run: | - cmake -S . -B cmake.output -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off + cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off - name: Generate dependencies run: | @@ -90,7 +90,7 @@ jobs: # unusedFunction notest - start - name: CMake (no test) run: | - cmake -S . -B cmake.output.notest -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=Off -DBUILD_GUI=ON -DBUILD_TRIAGE=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off + cmake -S . -B cmake.output.notest -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=Off -DBUILD_GUI=ON -DBUILD_TRIAGE=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off - name: Generate dependencies (no test) run: | @@ -112,7 +112,7 @@ jobs: # unusedFunction notest nogui - start - name: CMake (no test / no gui) run: | - cmake -S . -B cmake.output.notest_nogui -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=Off -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off + cmake -S . -B cmake.output.notest_nogui -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=Off -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off - name: Generate dependencies (no test / no gui) run: | @@ -131,7 +131,7 @@ jobs: # unusedFunction notest nocli - start - name: CMake (no test / no cli) run: | - cmake -S . -B cmake.output.notest_nocli -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=Off -DBUILD_CLI=Off -DBUILD_GUI=ON -DWITH_QCHART=ON -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off + cmake -S . -B cmake.output.notest_nocli -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=Off -DBUILD_CLI=Off -DBUILD_GUI=ON -DWITH_QCHART=ON -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off - name: Generate dependencies (no test / no cli) run: | @@ -154,7 +154,7 @@ jobs: # unusedFunction notest nocli nogui - start - name: CMake (no test / no cli / no gui) run: | - cmake -S . -B cmake.output.notest_nocli_nogui -Werror=dev -DHAVE_RULES=On -DBUILD_TESTING=Off -DBUILD_CLI=Off -DBUILD_GUI=Off -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off + cmake -S . -B cmake.output.notest_nocli_nogui -Werror=dev --warn-uninitialized -DHAVE_RULES=On -DBUILD_TESTING=Off -DBUILD_CLI=Off -DBUILD_GUI=Off -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off - name: Generate dependencies (no test / no cli / no gui) run: | diff --git a/cmake/options.cmake b/cmake/options.cmake index d640710e428..0fa27e4734b 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -145,7 +145,7 @@ string(LENGTH "${FILESDIR}" _filesdir_len) # override FILESDIR if it is set or empty if(FILESDIR OR ${_filesdir_len} EQUAL 0) # TODO: verify that it is an absolute path? - set(FILESDIR_DEF ${FILESDIR}) + set(FILESDIR_DEF "${FILESDIR}") else() set(FILESDIR_DEF ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME} CACHE STRING "Cppcheck files directory") endif() From 0d7884dad223e7f472b4af125e4e04fdc9d6bb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Wed, 17 Jun 2026 08:45:11 +0200 Subject: [PATCH 177/493] Fix #958: warn when feof() is used as a while loop condition (#8422) feof() only returns true after a read has already failed, causing the loop body to execute once more after the last successful read. Read errors also go undetected since feof() does not distinguish them from EOF. --------- Signed-off-by: Francois Berder --- lib/checkers.cpp | 1 + lib/checkio.cpp | 133 +++++++++++++++++++++++++++++++++ lib/checkio.h | 4 + man/checkers/wrongfeofUsage.md | 42 +++++++++++ releasenotes.txt | 2 +- test/cli/other_test.py | 8 +- test/testio.cpp | 50 +++++++++++++ 7 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 man/checkers/wrongfeofUsage.md diff --git a/lib/checkers.cpp b/lib/checkers.cpp index 3b425926b9e..cc8c4054ea2 100644 --- a/lib/checkers.cpp +++ b/lib/checkers.cpp @@ -101,6 +101,7 @@ namespace checkers { {"CheckFunctions::useStandardLibrary","style"}, {"CheckIO::checkCoutCerrMisusage","c"}, {"CheckIO::checkFileUsage",""}, + {"CheckIO::checkWrongfeofUsage",""}, {"CheckIO::checkWrongPrintfScanfArguments",""}, {"CheckIO::invalidScanf",""}, {"CheckLeakAutoVar::check","notclang"}, diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 8012d540898..f632ca99e9e 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -507,6 +507,137 @@ void CheckIOImpl::invalidScanfError(const Token *tok) CWE119, Certainty::normal); } +static const Token* findFileReadCall(const Token *start, const Token *end, int varid) +{ + const Token* found = Token::findmatch(start, "fgets|fgetc|getc|fread|fscanf (", end); + while (found) { + const std::vector args = getArguments(found); + if (!args.empty()) { + const bool match = (found->str() == "fscanf") + ? args.front()->varId() == varid + : args.back()->varId() == varid; + if (match) + return found; + } + found = Token::findmatch(found->next(), "fgets|fgetc|getc|fread|fscanf (", end); + } + return nullptr; +} + +void CheckIOImpl::checkWrongfeofUsage() +{ + const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); + + logChecker("CheckIO::checkWrongfeofUsage"); + + for (const Scope * scope : symbolDatabase->functionScopes) { + for (const Token *tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { + // TODO: Handle for loops + if (!Token::Match(tok, "while ( ! feof ( %var% )")) + continue; + + // Bail out if we cannot identify file pointer + const int fpVarId = tok->tokAt(5)->varId(); + if (fpVarId == 0) + continue; + + const Token *endCond = tok->linkAt(1); + const Token *bodyStart; + const Token *bodyEnd; + + if (Token::simpleMatch(tok->previous(), "}") && tok->previous()->scope()->type == ScopeType::eDo) { + bodyEnd = tok->previous(); + bodyStart = bodyEnd->link(); + } else { + if (!Token::simpleMatch(endCond, ") {")) + continue; + bodyEnd = endCond->linkAt(1); + bodyStart = endCond->next(); + } + + // Bail out if the loop contains control flow (too complex to analyze) + if (Token::findmatch(bodyStart, "return|break|goto|continue|throw", bodyEnd)) + continue; + + // Bail out if fp is used outside of known file I/O functions. + // If it is passed to an unknown function, reads may occur there. + bool fpUsedElsewhere = false; + for (const Token *t = bodyStart->next(); t && t != bodyEnd; t = t->next()) { + if (t->varId() != fpVarId) + continue; + const Token *p = t->astParent(); + while (p && p->str() == ",") + p = p->astParent(); + if (!p || !Token::Match(p->astOperand1(), "fgets|fgetc|getc|fread|fscanf|fprintf|fwrite|fputs|fputc|putc")) { + fpUsedElsewhere = true; + break; + } + } + if (fpUsedElsewhere) + continue; + + // No file read call in the loop: feof can never become true inside it + const Token *loopFileReadCallTok = findFileReadCall(bodyStart, bodyEnd, fpVarId); + if (!loopFileReadCallTok) { + // TODO: Warn about infinite loop + continue; + } + + // Find last file read + const Token *lastLoopFileReadCallTok = loopFileReadCallTok; + while (loopFileReadCallTok) { + lastLoopFileReadCallTok = loopFileReadCallTok; + loopFileReadCallTok = findFileReadCall(lastLoopFileReadCallTok->next(), bodyEnd, fpVarId); + } + + // Warn if the destination of the last file read is used after the call before bodyEnd. + // If it is not, the stale buffer is never accessed on the extra iteration at EOF. + + if (lastLoopFileReadCallTok->str() == "fgetc" || lastLoopFileReadCallTok->str() == "getc") { + // Warn if the return value feeds into an expression (astParent of the call node) + if (lastLoopFileReadCallTok->astParent() && lastLoopFileReadCallTok->astParent()->astParent()) + wrongfeofUsage(getCondTok(tok)); + } else { + const std::vector args = getArguments(lastLoopFileReadCallTok); + // Collect destination varIds + std::vector destVarIds; + if (lastLoopFileReadCallTok->str() == "fscanf") { + // args[0]=fp, args[1]=format, args[2+]=destinations (typically &var) + for (std::size_t i = 2; i < args.size(); ++i) { + const Token *destTok = Token::Match(args[i], "& %var%") ? args[i]->next() : args[i]; + if (destTok->varId() != 0) + destVarIds.push_back(destTok->varId()); + } + } else { + // Handle fgets, fread + // First argument is the destination buffer + if (!args.empty() && args.front()->varId() != 0) + destVarIds.push_back(args.front()->varId()); + } + + // Search for any destination use between this call's ';' and endBody + const Token *semiColonTok = lastLoopFileReadCallTok->linkAt(1)->next(); + for (const Token *t = semiColonTok; t && t != bodyEnd; t = t->next()) { + if (std::find(destVarIds.begin(), destVarIds.end(), t->varId()) != destVarIds.end()) { + wrongfeofUsage(getCondTok(tok)); + break; + } + } + } + } + } +} + +void CheckIOImpl::wrongfeofUsage(const Token * tok) +{ + reportError(tok, Severity::warning, + "wrongfeofUsage", + "Using feof() as a loop condition causes the last line to be processed twice.\n" + "feof() returns true only after a read has failed due to end-of-file, so the loop " + "body executes once more after the last successful read. Check the return value of " + "the read function instead (e.g. fgets, fread, fscanf)."); +} + //--------------------------------------------------------------------------- // printf("%u", "xyz"); // Wrong argument type // printf("%u%s", 1); // Too few arguments @@ -2057,6 +2188,7 @@ void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) checkIO.checkWrongPrintfScanfArguments(); checkIO.checkCoutCerrMisusage(); checkIO.checkFileUsage(); + checkIO.checkWrongfeofUsage(); checkIO.invalidScanf(); } @@ -2072,6 +2204,7 @@ void CheckIO::getErrorMessages(ErrorLogger& errorLogger, const Settings &setting c.fcloseInLoopConditionError(nullptr, "fp"); c.seekOnAppendedFileError(nullptr); c.incompatibleFileOpenError(nullptr, "tmp"); + c.wrongfeofUsage(nullptr); c.invalidScanfError(nullptr); c.wrongPrintfScanfArgumentsError(nullptr, "printf",3,2); c.invalidScanfArgTypeError_s(nullptr, 1, "s", nullptr); diff --git a/lib/checkio.h b/lib/checkio.h index 9f125e6bd7b..dff49006bab 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -82,6 +82,9 @@ class CPPCHECKLIB CheckIOImpl : public CheckImpl { /** @brief scanf can crash if width specifiers are not used */ void invalidScanf(); + /** @brief %Check wrong usage of feof */ + void checkWrongfeofUsage(); + /** @brief %Checks type and number of arguments given to functions like printf or scanf*/ void checkWrongPrintfScanfArguments(); @@ -127,6 +130,7 @@ class CPPCHECKLIB CheckIOImpl : public CheckImpl { void seekOnAppendedFileError(const Token *tok); void incompatibleFileOpenError(const Token *tok, const std::string &filename); void invalidScanfError(const Token *tok); + void wrongfeofUsage(const Token *tok); void wrongPrintfScanfArgumentsError(const Token* tok, const std::string &functionName, nonneg int numFormat, diff --git a/man/checkers/wrongfeofUsage.md b/man/checkers/wrongfeofUsage.md new file mode 100644 index 00000000000..9a3d0bbf5f6 --- /dev/null +++ b/man/checkers/wrongfeofUsage.md @@ -0,0 +1,42 @@ +# wrongfeofUsage + +**Message**: Using feof() as a loop condition causes the last line to be processed twice.
+**Category**: Correctness
+**Severity**: Warning
+**Language**: C/C++ + +## Description + +`feof()` returns non-zero only after a read operation has failed because the end of file was reached. When used as the sole condition of a loop, the loop body executes one extra time after the last successful read: the read fails silently (or returns partial data), and only then does `feof()` return true and terminate the loop. + +This checker matches `while (!feof(fp))` and `do { ... } while (!feof(fp))` loops and warns when all of the following are true: + +- The loop body contains at least one file-read call (`fgets`, `fgetc`, `getc`, `fread`, or `fscanf`) on the same file pointer. +- The destination (return value or output buffer) of the **last** file-read call in the loop is used after that call within the same loop iteration. + +The checker skips loops that contain a control-flow statement (`return`, `break`, `goto`, `continue`, `throw`) as those are too complex to analyze reliably, and loops where the file pointer appears in a context other than a recognised I/O function (`fgets`, `fgetc`, `getc`, `fread`, `fscanf`, `fprintf`, `fwrite`, `fputs`, `fputc`, `putc`). + +## How to fix + +Check the return value of the read function directly in the loop condition. + +Before: +```c +void process(FILE *fp) { + char line[256]; + while (!feof(fp)) { /* wrong: processes last line twice */ + fgets(line, sizeof(line), fp); + puts(line); + } +} +``` + +After: +```c +void process(FILE *fp) { + char line[256]; + while (fgets(line, sizeof(line), fp) != NULL) { + puts(line); + } +} +``` \ No newline at end of file diff --git a/releasenotes.txt b/releasenotes.txt index 185f06390e3..2141c34f001 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -5,7 +5,7 @@ Major bug fixes & crashes: - New checks: -- +- Warn when feof() is used as a while loop condition (wrongfeofUsage). C/C++ support: - diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 243f600b5a6..f788a7d21c8 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4318,25 +4318,25 @@ def __test_active_checkers(tmp_path, active_cnt, total_cnt, use_misra=False, use def test_active_unusedfunction_only(tmp_path): - __test_active_checkers(tmp_path, 1, 186, use_unusedfunction_only=True) + __test_active_checkers(tmp_path, 1, 187, use_unusedfunction_only=True) def test_active_unusedfunction_only_builddir(tmp_path): checkers_exp = [ 'CheckUnusedFunctions::check' ] - __test_active_checkers(tmp_path, 1, 186, use_unusedfunction_only=True, checkers_exp=checkers_exp) + __test_active_checkers(tmp_path, 1, 187, use_unusedfunction_only=True, checkers_exp=checkers_exp) def test_active_unusedfunction_only_misra(tmp_path): - __test_active_checkers(tmp_path, 1, 386, use_unusedfunction_only=True, use_misra=True) + __test_active_checkers(tmp_path, 1, 387, use_unusedfunction_only=True, use_misra=True) def test_active_unusedfunction_only_misra_builddir(tmp_path): checkers_exp = [ 'CheckUnusedFunctions::check' ] - __test_active_checkers(tmp_path, 1, 386, use_unusedfunction_only=True, use_misra=True, checkers_exp=checkers_exp) + __test_active_checkers(tmp_path, 1, 387, use_unusedfunction_only=True, use_misra=True, checkers_exp=checkers_exp) def test_analyzerinfo(tmp_path): diff --git a/test/testio.cpp b/test/testio.cpp index 15a65ef79c9..adfb6e31daf 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -45,6 +45,7 @@ class TestIO : public TestFixture { TEST_CASE(seekOnAppendedFile); TEST_CASE(fflushOnInputStream); TEST_CASE(incompatibleFileOpen); + TEST_CASE(testWrongfeofUsage); // #958 TEST_CASE(testScanf1); // Scanf without field limiters TEST_CASE(testScanf2); @@ -766,6 +767,55 @@ class TestIO : public TestFixture { ASSERT_EQUALS("[test.cpp:3:16]: (warning) The file '\"tmp\"' is opened for read and write access at the same time on different streams [incompatibleFileOpen]\n", errout_str()); } + void testWrongfeofUsage() { // ticket #958 + check("void foo(FILE * fp) {\n" + " while (!feof(fp)) \n" + " {\n" + " char line[100];\n" + " fgets(line, sizeof(line), fp);\n" + " dostuff(line);\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:2:10]: (warning) Using feof() as a loop condition causes the last line to be processed twice. [wrongfeofUsage]\n", errout_str()); + + check("int foo(FILE *fp) {\n" + " char line[100];\n" + " while (fgets(line, sizeof(line), fp)) {}\n" + " if (!feof(fp))\n" + " return 1;\n" + " return 0;\n" + "}"); + ASSERT_EQUALS("", errout_str()); + + check("void foo(FILE *fp){\n" + " char line[100];\n" + " fgets(line, sizeof(line), fp);\n" + " while (!feof(fp)){\n" + " dostuff(line);\n" + " fgets(line, sizeof(line), fp);" + " }\n" + "}"); + ASSERT_EQUALS("", errout_str()); + + check("void foo(FILE *fp) {\n" + " char line[100];\n" + " do {\n" + " fgets(line, sizeof(line), fp);\n" + " dostuff(line);\n" + " } while (!feof(fp));\n" + "}"); + ASSERT_EQUALS("[test.cpp:6:12]: (warning) Using feof() as a loop condition causes the last line to be processed twice. [wrongfeofUsage]\n", errout_str()); + + check("void foo(FILE *fp) {\n" + " char line[100];\n" + " do {\n" + " dostuff(line);\n" + " fgets(line, sizeof(line), fp);\n" + " } while (!feof(fp));\n" + "}"); + ASSERT_EQUALS("", errout_str()); + } + void testScanf1() { check("void foo() {\n" From fec0f8daf8c4c5aed9750c84c7df764d436ca77e Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Wed, 17 Jun 2026 02:46:06 -0400 Subject: [PATCH 178/493] gtk.cfg: Remove extra semicolons from g_return* macros (#8632) The extra semicolons caused unknownMacro errors when checking code like this: ```c if (hadj) g_return_if_fail (GTK_IS_ADJUSTMENT (hadj)); else hadj = GTK_ADJUSTMENT (...) ``` They were introduced in commit c0b530947, but they are not actually present in the upstream GLib macros. --- cfg/gtk.cfg | 8 ++++---- test/cfg/gtk.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index 14cd032945e..71d0f3dee05 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -4,10 +4,10 @@ - - - - + + + + diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c index cab41ffa1cd..4accf7b63ec 100644 --- a/test/cfg/gtk.c +++ b/test/cfg/gtk.c @@ -596,3 +596,43 @@ void gtk_widget_destroy_test() { // cppcheck-suppress mismatchAllocDealloc g_object_unref(widget); } + +void g_return_if_fail_test(const char *s) { + // cppcheck-suppress valueFlowBailout + g_return_if_fail(s); + + if (*s) + // cppcheck-suppress valueFlowBailout + g_return_if_fail(*s == 'a'); + else + g_info("Test the else branch can be parsed"); +} + +int g_return_val_if_fail_test(const char *s) { + // cppcheck-suppress valueFlowBailout + g_return_val_if_fail(s, 1); + + if (*s) + // cppcheck-suppress valueFlowBailout + g_return_val_if_fail(*s == 'a', 1); + else + g_info("Test the else branch can be parsed"); + + return 0; +} + +void g_return_if_reached_test(const char *s) { + if (s) + g_return_if_reached(); + else + g_info("Test the else branch can be parsed"); +} + +int g_return_val_if_reached_test(const char *s) { + if (s) + g_return_val_if_reached(1); + else + g_info("Test the else branch can be parsed"); + + return 0; +} From be0052b65baf181d0ddd345878f4b577aa48a1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 17 Jun 2026 09:50:52 +0200 Subject: [PATCH 179/493] refs #14345 - dropped some untranslatable strings (#8073) --- gui/applicationdialog.cpp | 2 +- gui/cppcheck_de.ts | 100 ++++++-------------------- gui/cppcheck_es.ts | 118 ++++-------------------------- gui/cppcheck_fi.ts | 128 +++------------------------------ gui/cppcheck_fr.ts | 144 ------------------------------------- gui/cppcheck_it.ts | 118 ++++-------------------------- gui/cppcheck_ja.ts | 94 +++++++----------------- gui/cppcheck_ka.ts | 100 ++++++-------------------- gui/cppcheck_ko.ts | 118 ++++-------------------------- gui/cppcheck_nl.ts | 128 +++------------------------------ gui/cppcheck_ru.ts | 110 +++++----------------------- gui/cppcheck_sr.ts | 118 ++++-------------------------- gui/cppcheck_sv.ts | 110 +++++----------------------- gui/cppcheck_zh_CN.ts | 116 ++++-------------------------- gui/cppcheck_zh_TW.ts | 104 ++++++--------------------- gui/fileviewdialog.cpp | 4 +- gui/helpdialog.cpp | 2 +- gui/librarydialog.cpp | 6 +- gui/mainwindow.cpp | 30 ++++---- gui/mainwindow.ui | 14 ++-- gui/platforms.cpp | 10 +-- gui/projectfile.ui | 4 +- gui/projectfiledialog.cpp | 4 +- gui/resultstree.cpp | 6 +- gui/resultsview.cpp | 4 +- gui/translationhandler.cpp | 2 +- 26 files changed, 249 insertions(+), 1445 deletions(-) diff --git a/gui/applicationdialog.cpp b/gui/applicationdialog.cpp index bc8804d6f97..bdf9a4f827e 100644 --- a/gui/applicationdialog.cpp +++ b/gui/applicationdialog.cpp @@ -80,7 +80,7 @@ void ApplicationDialog::ok() { if (mUI->mName->text().isEmpty() || mUI->mPath->text().isEmpty()) { QMessageBox msg(QMessageBox::Warning, - tr("Cppcheck"), + "Cppcheck", tr("You must specify a name, a path and optionally parameters for the application!"), QMessageBox::Ok, this); diff --git a/gui/cppcheck_de.ts b/gui/cppcheck_de.ts index 1361296b8ca..a9429aa1c94 100644 --- a/gui/cppcheck_de.ts +++ b/gui/cppcheck_de.ts @@ -107,9 +107,8 @@ Parameter: -l(line) (file) Anzeigeanwendung auswählen - Cppcheck - Cppcheck + Cppcheck @@ -176,10 +175,8 @@ Parameter: -l(line) (file) Konnte die Datei nicht finden: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -210,9 +207,8 @@ Parameter: -l(line) (file) Hilfedatei '%1' nicht gefunden - Cppcheck - Cppcheck + Cppcheck @@ -332,11 +328,8 @@ Parameter: -l(line) (file) Bibliothek öffnen - - - Cppcheck - Cppcheck + Cppcheck @@ -482,23 +475,8 @@ Parameter: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -1006,29 +984,16 @@ Parameter: -l(line) (file) - Misra C - Misra C - - - - Misra C++ 2008 - + Misra C - Cert C - Cert C + Cert C - Cert C++ - Cert C++ - - - - Misra C++ 2023 - + Cert C++ @@ -1288,14 +1253,12 @@ Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bi Compilerdatenbank - Visual Studio - Visual Studio + Visual Studio - Borland C++ Builder 6 - Borland C++-Builder 6 + Borland C++-Builder 6 @@ -1567,29 +1530,24 @@ Options: Nativ - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit, ANSI + Windows 32-bit, ANSI - Windows 32-bit Unicode - Windows 32-bit, Unicode + Windows 32-bit, Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -1980,14 +1938,12 @@ Options: - Clang analyzer - Clang-Analyzer + Clang-Analyzer - Clang-tidy - Clang-Tidy + Clang-Tidy @@ -2028,9 +1984,8 @@ Options: Clang-tidy (nicht gefunden) - Visual Studio - Visual Studio + Visual Studio @@ -2038,9 +1993,8 @@ Options: Compilerdatenbank - Borland C++ Builder 6 - Borland C++-Builder 6 + Borland C++-Builder 6 @@ -2316,11 +2270,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2443,10 +2392,8 @@ Options: Kein Tag - - Cppcheck - Cppcheck + Cppcheck @@ -2534,10 +2481,8 @@ Bitte überprüfen Sie ob der Pfad und die Parameter der Anwendung richtig einge %p% (%1 von %2 Dateien geprüft) - - Cppcheck - Cppcheck + Cppcheck @@ -3210,9 +3155,8 @@ The user interface language has been reset to English. Open the Preferences-dial Die Sprache wurde auf Englisch zurückgesetzt. Öffnen Sie den Einstellungen-Dialog um eine verfügbare Sprache auszuwählen. - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_es.ts b/gui/cppcheck_es.ts index bbe8bed24d5..fa03b4457cc 100644 --- a/gui/cppcheck_es.ts +++ b/gui/cppcheck_es.ts @@ -95,9 +95,8 @@ Parameters: -l(line) (file) Selecciona la aplicación para visualizar - Cppcheck - Cppcheck + Cppcheck @@ -113,10 +112,8 @@ Parameters: -l(line) (file) No se ha encontrado el fichero: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -147,9 +144,8 @@ Parameters: -l(line) (file) - Cppcheck - Cppcheck + Cppcheck @@ -269,11 +265,8 @@ Parameters: -l(line) (file) Abrir archivo de biblioteca - - - Cppcheck - Cppcheck + Cppcheck @@ -411,23 +404,8 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -952,31 +930,6 @@ Parameters: -l(line) (file) Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1214,16 +1167,6 @@ Do you want to load this project file instead? Compile database - - - Visual Studio - - - - - Borland C++ Builder 6 - - Select files to analyze @@ -1482,29 +1425,24 @@ Options: - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit ANSI + Windows 32-bit ANSI - Windows 32-bit Unicode - Windows 32-bit Unicode + Windows 32-bit Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -1892,16 +1830,6 @@ Options: Bug hunting (Premium) - - - Clang analyzer - - - - - Clang-tidy - - Defines: @@ -1940,21 +1868,11 @@ Options: Clang-tidy (not found) - - - Visual Studio - - Compile database - - - Borland C++ Builder 6 - - Import Project @@ -2230,11 +2148,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2371,10 +2284,8 @@ Options: - - Cppcheck - Cppcheck + Cppcheck @@ -2483,10 +2394,8 @@ Por favor comprueba que la ruta a la aplicación y los parámetros son correctos %p% (%1 of %2 archivos comprobados) - - Cppcheck - Cppcheck + Cppcheck @@ -3133,9 +3042,8 @@ The user interface language has been reset to English. Open the Preferences-dial El idioma de la interfaz gráfica ha sido cambiado a Inglés. Abra la ventana de Preferencias para seleccionar alguno de los idiomas disponibles. - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_fi.ts b/gui/cppcheck_fi.ts index 517362d852b..bf379534998 100644 --- a/gui/cppcheck_fi.ts +++ b/gui/cppcheck_fi.ts @@ -96,9 +96,8 @@ Parameters: -l(line) (file) Valitse ohjelma jolla avata virhetiedosto - Cppcheck - Cppcheck + Cppcheck @@ -116,10 +115,8 @@ Parameters: -l(line) (file) Tiedostoa %1 ei löytynyt - - Cppcheck - Cppcheck + Cppcheck @@ -150,9 +147,8 @@ Parameters: -l(line) (file) - Cppcheck - Cppcheck + Cppcheck @@ -272,11 +268,8 @@ Parameters: -l(line) (file) - - - Cppcheck - Cppcheck + Cppcheck @@ -414,23 +407,8 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -942,31 +920,6 @@ Parameters: -l(line) (file) Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1214,16 +1167,6 @@ This is probably because the settings were changed between the Cppcheck versions Compile database - - - Visual Studio - - - - - Borland C++ Builder 6 - - Select files to analyze @@ -1475,31 +1418,6 @@ Options: Native - - - Unix 32-bit - - - - - Unix 64-bit - - - - - Windows 32-bit ANSI - - - - - Windows 32-bit Unicode - - - - - Windows 64-bit - - ProjectFile @@ -1886,16 +1804,6 @@ Options: Bug hunting (Premium) - - - Clang analyzer - - - - - Clang-tidy - - Defines: @@ -1934,21 +1842,11 @@ Options: Clang-tidy (not found) - - - Visual Studio - - Compile database - - - Borland C++ Builder 6 - - Import Project @@ -2226,11 +2124,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2349,10 +2242,8 @@ Options: - - Cppcheck - Cppcheck + Cppcheck @@ -2437,10 +2328,8 @@ Tarkista että ohjelman polku ja parametrit ovat oikeat. - - Cppcheck - Cppcheck + Cppcheck @@ -3102,9 +2991,8 @@ The user interface language has been reset to English. Open the Preferences-dial - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_fr.ts b/gui/cppcheck_fr.ts index 7e8651d8ec3..6d464bc46af 100644 --- a/gui/cppcheck_fr.ts +++ b/gui/cppcheck_fr.ts @@ -65,11 +65,6 @@ General Public License version 3 Select viewer application Sélection de l'application - - - Cppcheck - - &Executable: @@ -123,12 +118,6 @@ Paramètres : -l(ligne) (fichier) Could not find the file: %1 Ne trouve pas le fichier : %1 - - - - Cppcheck - - Could not read the file: %1 @@ -157,11 +146,6 @@ Paramètres : -l(ligne) (fichier) Helpfile '%1' was not found - - - Cppcheck - - LibraryAddFunctionDialog @@ -279,13 +263,6 @@ Paramètres : -l(ligne) (fichier) Save as - - - - - Cppcheck - - Save the library as @@ -419,25 +396,6 @@ Paramètres : -l(ligne) (fichier) MainWindow - - - - - - - - - - - - - - - - - Cppcheck - - Checking for updates @@ -599,31 +557,6 @@ Paramètres : -l(ligne) (fichier) Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1407,16 +1340,6 @@ Do you want to stop the analysis and exit Cppcheck? Compile database - - - Visual Studio - - - - - Borland C++ Builder 6 - - Current results will be cleared. @@ -1461,31 +1384,6 @@ Do you want to proceed? Platforms - - - Unix 32-bit - - - - - Unix 64-bit - - - - - Windows 32-bit ANSI - - - - - Windows 32-bit Unicode - - - - - Windows 64-bit - - Native @@ -1691,16 +1589,6 @@ Do you want to proceed? Bug hunting - - - Clang analyzer - - - - - Clang-tidy - - @@ -1969,21 +1857,11 @@ Do you want to proceed? MISRA rule texts file (%1) - - - Visual Studio - - Compile database - - - Borland C++ Builder 6 - - QObject @@ -2212,11 +2090,6 @@ Do you want to proceed? Tags - - - CWE - - QPlatformTheme @@ -2259,12 +2132,6 @@ Do you want to proceed? Undefined file Fichier indéterminé - - - - Cppcheck - - Could not start %1 @@ -2427,12 +2294,6 @@ Please select the default editor application in preferences/Applications.Results Résultats - - - - Cppcheck - - No errors found. @@ -3101,11 +2962,6 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. - - - Cppcheck - - TxtReport diff --git a/gui/cppcheck_it.ts b/gui/cppcheck_it.ts index 2c19aa2e50b..65b31b59b1e 100644 --- a/gui/cppcheck_it.ts +++ b/gui/cppcheck_it.ts @@ -107,9 +107,8 @@ Parametri: -l(line) (file) Seleziona l'applicazione di lettura - Cppcheck - Cppcheck + Cppcheck @@ -125,10 +124,8 @@ Parametri: -l(line) (file) File non trovato: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -159,9 +156,8 @@ Parametri: -l(line) (file) - Cppcheck - Cppcheck + Cppcheck @@ -281,11 +277,8 @@ Parametri: -l(line) (file) - - - Cppcheck - Cppcheck + Cppcheck @@ -423,23 +416,8 @@ Parametri: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -951,31 +929,6 @@ Parametri: -l(line) (file) Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1227,16 +1180,6 @@ Probabilmente ciò è avvenuto perché le impostazioni sono state modificate tra Compile database - - - Visual Studio - - - - - Borland C++ Builder 6 - - Select files to analyze @@ -1495,29 +1438,24 @@ Options: - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit, ANSI + Windows 32-bit, ANSI - Windows 32-bit Unicode - Windows 32-bit, Unicode + Windows 32-bit, Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -1905,16 +1843,6 @@ Options: Bug hunting (Premium) - - - Clang analyzer - - - - - Clang-tidy - - Defines: @@ -1953,21 +1881,11 @@ Options: Clang-tidy (not found) - - - Visual Studio - - Compile database - - - Borland C++ Builder 6 - - Import Project @@ -2243,11 +2161,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2374,10 +2287,8 @@ Options: - - Cppcheck - Cppcheck + Cppcheck @@ -2469,10 +2380,8 @@ Per favore verifica che il percorso dell'applicazione e i parametri siano c %p% (%1 su %2 file scansionati) - - Cppcheck - Cppcheck + Cppcheck @@ -3145,9 +3054,8 @@ The user interface language has been reset to English. Open the Preferences-dial L'interfaccia utente è stata risettata in Inglese. Apri la finestra di dialogo Preferenze per selezionare una qualunque lingua a disposizione. - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index 6c8269b4143..eedad8e9515 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -106,9 +106,8 @@ Parameters: -l(line) (file) 表示アプリケーションの選択 - Cppcheck - Cppcheck + Cppcheck @@ -179,10 +178,8 @@ Parameters: -l(line) (file) ファイル:%1 が見つかりません - - Cppcheck - Cppcheck + Cppcheck @@ -213,9 +210,8 @@ Parameters: -l(line) (file) ヘルプファイル '%1' が見つかりません - Cppcheck - Cppcheck + Cppcheck @@ -335,11 +331,8 @@ Parameters: -l(line) (file) ライブラリファイルを開く - - - Cppcheck - Cppcheck + Cppcheck @@ -488,23 +481,8 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -1048,29 +1026,24 @@ Parameters: -l(line) (file) ノーマル - Misra C - MISRA C + MISRA C - Misra C++ 2008 - MISRA C++ 2008 + MISRA C++ 2008 - Cert C - CERT C + CERT C - Cert C++ - Cert C++ + Cert C++ - Misra C++ 2023 - MISRA C++ 2023 + MISRA C++ 2023 @@ -1309,14 +1282,12 @@ Analysis is stopped. コンパイルデータベース - Visual Studio - Visual Studio + Visual Studio - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -1594,29 +1565,24 @@ Options: ネイティブ - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit ANSIエンコード + Windows 32-bit ANSIエンコード - Windows 32-bit Unicode - Windows 32-bit Unicode + Windows 32-bit Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -2021,14 +1987,12 @@ Options: バグハント - Clang analyzer - Clang Analyzer + Clang Analyzer - Clang-tidy - Clang-tidy + Clang-tidy @@ -2069,9 +2033,8 @@ Options: Clang-tidy (みつかりません) - Visual Studio - Visual Studio + Visual Studio @@ -2079,9 +2042,8 @@ Options: コンパイルデータベース - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -2367,9 +2329,8 @@ Options: タグ - CWE - CWE + CWE @@ -2501,10 +2462,8 @@ Options: タグなし - - Cppcheck - Cppcheck + Cppcheck @@ -2631,10 +2590,8 @@ Please check the application path and parameters are correct. %p% (%1 / %2 :ファイル数) - - Cppcheck - Cppcheck + Cppcheck @@ -3283,9 +3240,8 @@ The user interface language has been reset to English. Open the Preferences-dial そのため言語を 英語にリセットします。設定ダイアログから利用可能な言語を選択してください。 - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_ka.ts b/gui/cppcheck_ka.ts index 52c0657f646..00239743df0 100644 --- a/gui/cppcheck_ka.ts +++ b/gui/cppcheck_ka.ts @@ -96,9 +96,8 @@ Parameters: -l(line) (file) აირჩიეთ აპლიკაცია - Cppcheck - Cppcheck + Cppcheck @@ -167,10 +166,8 @@ Parameters: -l(line) (file) ვერ ვიპოვე ფაილი: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -201,9 +198,8 @@ Parameters: -l(line) (file) დახმარების ფაილი '%1' ვერ ვიპოვე - Cppcheck - Cppcheck + Cppcheck @@ -323,11 +319,8 @@ Parameters: -l(line) (file) ბიბლიოთეკის ფაილის გახსნა - - - Cppcheck - Cppcheck + Cppcheck @@ -464,23 +457,8 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -993,29 +971,16 @@ Parameters: -l(line) (file) ნორმალური - Misra C - Misra C + Misra C - - Misra C++ 2008 - - - - Cert C - Cert C + Cert C - Cert C++ - Cert C++ - - - - Misra C++ 2023 - + Cert C++ @@ -1273,14 +1238,12 @@ This is probably because the settings were changed between the Cppcheck versions მონაცემთა ბაზის კომპილაცია - Visual Studio - Visual Studio + Visual Studio - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -1566,29 +1529,24 @@ Options: საკუთარი - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit ANSI + Windows 32-bit ANSI - Windows 32-bit Unicode - Windows 32-bit Unicode + Windows 32-bit Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -1977,14 +1935,12 @@ Options: შეცდომებზე ნადირობა (ფასიანი) - Clang analyzer - Clang-ის ანალიზატორი + Clang-ის ანალიზატორი - Clang-tidy - Clang-tidy + Clang-tidy @@ -2025,9 +1981,8 @@ Options: Clang-tidy (ვერ ვიპოვე) - Visual Studio - Visual Studio + Visual Studio @@ -2035,9 +1990,8 @@ Options: მონაცემთა ბაზის კომპილაცია - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -2316,11 +2270,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2451,10 +2400,8 @@ Options: ჭდის გარეშე - - Cppcheck - Cppcheck + Cppcheck @@ -2555,10 +2502,8 @@ Please check the application path and parameters are correct. %p% (შემოწმებულია %1 ფაილი %2-დან) - - Cppcheck - Cppcheck + Cppcheck @@ -3236,9 +3181,8 @@ The user interface language has been reset to English. Open the Preferences-dial მომხმარებლის ინტერფეისი ინგლისურზე გადაირთო. გახსენით მორგების დიალოგი, რომ ხელმისაწვდომი ენებიდან სასურველი აირჩიოთ. - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_ko.ts b/gui/cppcheck_ko.ts index 611eede0491..eef9ffac818 100644 --- a/gui/cppcheck_ko.ts +++ b/gui/cppcheck_ko.ts @@ -106,9 +106,8 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: 뷰어 프로그램 선택 - Cppcheck - Cppcheck + Cppcheck @@ -124,10 +123,8 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: 파일 찾기 실패: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -158,9 +155,8 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - Cppcheck - Cppcheck + Cppcheck @@ -280,11 +276,8 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: - - - Cppcheck - Cppcheck + Cppcheck @@ -420,23 +413,8 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -710,31 +688,6 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1415,16 +1368,6 @@ Do you want to stop the analysis and exit Cppcheck? Compile database - - - Visual Studio - - - - - Borland C++ Builder 6 - - Current results will be cleared. @@ -1470,29 +1413,24 @@ Do you want to proceed? Platforms - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit ANSI + Windows 32-bit ANSI - Windows 32-bit Unicode - Windows 32-bit Unicode + Windows 32-bit Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -1699,16 +1637,6 @@ Do you want to proceed? Bug hunting - - - Clang analyzer - - - - - Clang-tidy - - @@ -1977,21 +1905,11 @@ Do you want to proceed? MISRA rule texts file (%1) - - - Visual Studio - - Compile database - - - Borland C++ Builder 6 - - QObject @@ -2220,11 +2138,6 @@ Do you want to proceed? Tags - - - CWE - - QPlatformTheme @@ -2316,10 +2229,8 @@ Do you want to proceed? 숨기기 - - Cppcheck - Cppcheck + Cppcheck @@ -2443,10 +2354,8 @@ Please check the application path and parameters are correct. %p% (%2 중 %1 파일 검사됨) - - Cppcheck - Cppcheck + Cppcheck @@ -3118,9 +3027,8 @@ The user interface language has been reset to English. Open the Preferences-dial 언어가 영어로 초기화 됐습니다. 설정창을 열어서 설정 가능한 언어를 선택하세요. - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_nl.ts b/gui/cppcheck_nl.ts index 7c58587662b..6a877a34909 100644 --- a/gui/cppcheck_nl.ts +++ b/gui/cppcheck_nl.ts @@ -106,9 +106,8 @@ Parameters: -l(lijn) (bestand) Selecteer applicatie - Cppcheck - Cppcheck + Cppcheck @@ -126,10 +125,8 @@ Parameters: -l(lijn) (bestand) Kon het bestand niet vinden: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -160,9 +157,8 @@ Parameters: -l(lijn) (bestand) - Cppcheck - Cppcheck + Cppcheck @@ -282,11 +278,8 @@ Parameters: -l(lijn) (bestand) - - - Cppcheck - Cppcheck + Cppcheck @@ -424,23 +417,8 @@ Parameters: -l(lijn) (bestand) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -952,31 +930,6 @@ Parameters: -l(lijn) (bestand) Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1227,16 +1180,6 @@ Dit is waarschijnlijk omdat de instellingen zijn gewijzigd tussen de versies van Compile database - - - Visual Studio - - - - - Borland C++ Builder 6 - - Select files to analyze @@ -1493,31 +1436,6 @@ Options: Native - - - Unix 32-bit - - - - - Unix 64-bit - - - - - Windows 32-bit ANSI - - - - - Windows 32-bit Unicode - - - - - Windows 64-bit - - ProjectFile @@ -1904,16 +1822,6 @@ Options: Bug hunting (Premium) - - - Clang analyzer - - - - - Clang-tidy - - Defines: @@ -1952,21 +1860,11 @@ Options: Clang-tidy (not found) - - - Visual Studio - - Compile database - - - Borland C++ Builder 6 - - Import Project @@ -2244,11 +2142,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2375,10 +2268,8 @@ Options: - - Cppcheck - Cppcheck + Cppcheck @@ -2470,10 +2361,8 @@ Gelieve te controleren of de het pad en de parameters correct zijn.%p% (%1 van %2 bestanden gecontroleerd) - - Cppcheck - Cppcheck + Cppcheck @@ -3143,9 +3032,8 @@ The user interface language has been reset to English. Open the Preferences-dial De gebruikerstaal is gereset naar Engels. Open het dialoogvenster om een van de beschikbare talen te selecteren. - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_ru.ts b/gui/cppcheck_ru.ts index a6608d90f7d..cd1a4c4d0ce 100644 --- a/gui/cppcheck_ru.ts +++ b/gui/cppcheck_ru.ts @@ -106,9 +106,8 @@ Parameters: -l(line) (file) Выберите приложение - Cppcheck - Cppcheck + Cppcheck @@ -126,10 +125,8 @@ Parameters: -l(line) (file) Невозможно найти файл: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -160,9 +157,8 @@ Parameters: -l(line) (file) - Cppcheck - Cppcheck + Cppcheck @@ -282,11 +278,8 @@ Parameters: -l(line) (file) Открыть файл библиотеки - - - Cppcheck - Cppcheck + Cppcheck @@ -424,23 +417,8 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -952,31 +930,6 @@ Parameters: -l(line) (file) Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1235,14 +1188,12 @@ This is probably because the settings were changed between the Cppcheck versions - Visual Studio - Visual Studio + Visual Studio - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -1525,29 +1476,24 @@ Options: - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit ANSI + Windows 32-bit ANSI - Windows 32-bit Unicode - Windows 32-bit Unicode + Windows 32-bit Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -1939,16 +1885,6 @@ Options: Bug hunting (Premium) - - - Clang analyzer - - - - - Clang-tidy - - Defines: @@ -1988,9 +1924,8 @@ Options: Clang-tidy (не найден) - Visual Studio - Visual Studio + Visual Studio @@ -1998,9 +1933,8 @@ Options: - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -2279,11 +2213,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2414,10 +2343,8 @@ Options: Тег отсутствует - - Cppcheck - Cppcheck + Cppcheck @@ -2515,10 +2442,8 @@ Please check the application path and parameters are correct. %p% (%1 из %2 файлов проверено) - - Cppcheck - Cppcheck + Cppcheck @@ -3192,9 +3117,8 @@ The user interface language has been reset to English. Open the Preferences-dial Язык пользовательского интерфейса был сброшен на английский. Откройте Настройки-диалог для выбора любого из доступных языков. - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_sr.ts b/gui/cppcheck_sr.ts index 07e8059f724..ebfe46f5ced 100644 --- a/gui/cppcheck_sr.ts +++ b/gui/cppcheck_sr.ts @@ -96,9 +96,8 @@ Parameters: -l(line) (file) Select viewer application - Cppcheck - Cppcheck + Cppcheck @@ -114,10 +113,8 @@ Parameters: -l(line) (file) Could not find the file: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -148,9 +145,8 @@ Parameters: -l(line) (file) - Cppcheck - Cppcheck + Cppcheck @@ -270,11 +266,8 @@ Parameters: -l(line) (file) - - - Cppcheck - Cppcheck + Cppcheck @@ -412,23 +405,8 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -940,31 +918,6 @@ Parameters: -l(line) (file) Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1212,16 +1165,6 @@ This is probably because the settings were changed between the Cppcheck versions Compile database - - - Visual Studio - - - - - Borland C++ Builder 6 - - Select files to analyze @@ -1474,29 +1417,24 @@ Options: - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit ANSI + Windows 32-bit ANSI - Windows 32-bit Unicode - Windows 32-bit Unicode + Windows 32-bit Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -1884,16 +1822,6 @@ Options: Bug hunting (Premium) - - - Clang analyzer - - - - - Clang-tidy - - Defines: @@ -1932,21 +1860,11 @@ Options: Clang-tidy (not found) - - - Visual Studio - - Compile database - - - Borland C++ Builder 6 - - Import Project @@ -2222,11 +2140,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2345,10 +2258,8 @@ Options: - - Cppcheck - Cppcheck + Cppcheck @@ -2432,10 +2343,8 @@ Please check the application path and parameters are correct. - - Cppcheck - Cppcheck + Cppcheck @@ -3096,9 +3005,8 @@ The user interface language has been reset to English. Open the Preferences-dial - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_sv.ts b/gui/cppcheck_sv.ts index 4b8164d7775..43d6886afc0 100644 --- a/gui/cppcheck_sv.ts +++ b/gui/cppcheck_sv.ts @@ -106,9 +106,8 @@ Parametrar: -l(line) (file) Välj program - Cppcheck - Cppcheck + Cppcheck @@ -126,10 +125,8 @@ Parametrar: -l(line) (file) Kunde inte hitta filen: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -160,9 +157,8 @@ Parametrar: -l(line) (file) - Cppcheck - Cppcheck + Cppcheck @@ -282,11 +278,8 @@ Parametrar: -l(line) (file) Öppna Library fil - - - Cppcheck - Cppcheck + Cppcheck @@ -430,23 +423,8 @@ Exempel: MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -959,31 +937,6 @@ Exempel: Normal - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1242,14 +1195,8 @@ En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. - Visual Studio - Visual Studio - - - - Borland C++ Builder 6 - + Visual Studio @@ -1530,29 +1477,24 @@ Options: Native - Unix 32-bit - Unix 32-bit + Unix 32-bit - Unix 64-bit - Unix 64-bit + Unix 64-bit - Windows 32-bit ANSI - Windows 32-bit ANSI + Windows 32-bit ANSI - Windows 32-bit Unicode - Windows 32-bit Unicode + Windows 32-bit Unicode - Windows 64-bit - Windows 64-bit + Windows 64-bit @@ -1941,14 +1883,12 @@ Options: - Clang analyzer - Clang analyzer + Clang analyzer - Clang-tidy - Clang-tidy + Clang-tidy @@ -2025,20 +1965,14 @@ Options: Välj mapp att analysera - Visual Studio - Visual Studio + Visual Studio Compile database - - - Borland C++ Builder 6 - - Import Project @@ -2280,11 +2214,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2415,10 +2344,8 @@ Options: Ingen tag - - Cppcheck - Cppcheck + Cppcheck @@ -2519,10 +2446,8 @@ Kontrollera att sökvägen och parametrarna är korrekta. %p% (%1 av %2 filer analyserade) - - Cppcheck - Cppcheck + Cppcheck @@ -3196,9 +3121,8 @@ The user interface language has been reset to English. Open the Preferences-dial Språket har nollställts till Engelska. Öppna Preferences och välj något av de tillgängliga språken. - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_zh_CN.ts b/gui/cppcheck_zh_CN.ts index 5860c842a16..5ecaa17a91b 100644 --- a/gui/cppcheck_zh_CN.ts +++ b/gui/cppcheck_zh_CN.ts @@ -105,9 +105,8 @@ Parameters: -l(line) (file) 选择查看应用程序 - Cppcheck - Cppcheck + Cppcheck @@ -123,10 +122,8 @@ Parameters: -l(line) (file) 无法找到文件: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -157,9 +154,8 @@ Parameters: -l(line) (file) 帮助文件 '%1' 未找到 - Cppcheck - Cppcheck + Cppcheck @@ -279,11 +275,8 @@ Parameters: -l(line) (file) 打开库文件 - - - Cppcheck - Cppcheck + Cppcheck @@ -431,23 +424,8 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -990,31 +968,6 @@ Parameters: -l(line) (file) Normal 常规 - - - Misra C - - - - - Misra C++ 2008 - - - - - Cert C - - - - - Cert C++ - - - - - Misra C++ 2023 - - Autosar @@ -1242,14 +1195,12 @@ Analysis is stopped. Compile database - Visual Studio - Visual Studio + Visual Studio - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -1531,31 +1482,6 @@ Options: Native 本地 - - - Unix 32-bit - - - - - Unix 64-bit - - - - - Windows 32-bit ANSI - - - - - Windows 32-bit Unicode - - - - - Windows 64-bit - - ProjectFile @@ -1947,14 +1873,12 @@ Options: - Clang analyzer - Clang analyzer + Clang analyzer - Clang-tidy - Clang-tidy + Clang-tidy @@ -1995,9 +1919,8 @@ Options: Clang-tidy (未找到) - Visual Studio - Visual Studio + Visual Studio @@ -2005,9 +1928,8 @@ Options: Compile database - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -2284,11 +2206,6 @@ Options: Tags - - - CWE - - QPlatformTheme @@ -2419,10 +2336,8 @@ Options: 取消标记 - - Cppcheck - Cppcheck + Cppcheck @@ -2549,10 +2464,8 @@ Please check the application path and parameters are correct. %p% (%2 个文件已检查 %1 个) - - Cppcheck - Cppcheck + Cppcheck @@ -3204,9 +3117,8 @@ The user interface language has been reset to English. Open the Preferences-dial 用户界面语言已被重置为英语。打开“首选项”对话框,选择任何可用的语言。 - Cppcheck - Cppcheck + Cppcheck diff --git a/gui/cppcheck_zh_TW.ts b/gui/cppcheck_zh_TW.ts index 841650ba5b1..3c25925c207 100644 --- a/gui/cppcheck_zh_TW.ts +++ b/gui/cppcheck_zh_TW.ts @@ -95,9 +95,8 @@ Parameters: -l(line) (file) 選取檢視器應用程式 - Cppcheck - Cppcheck + Cppcheck @@ -128,10 +127,8 @@ Parameters: -l(line) (file) 無法找到檔案: %1 - - Cppcheck - Cppcheck + Cppcheck @@ -162,9 +159,8 @@ Parameters: -l(line) (file) 找不到幫助檔 '%1' - Cppcheck - Cppcheck + Cppcheck @@ -284,11 +280,8 @@ Parameters: -l(line) (file) 開啟程式庫檔案 - - - Cppcheck - Cppcheck + Cppcheck @@ -424,23 +417,8 @@ Parameters: -l(line) (file) MainWindow - - - - - - - - - - - - - - - Cppcheck - Cppcheck + Cppcheck @@ -974,29 +952,12 @@ Parameters: -l(line) (file) - - Misra C - - - - Misra C++ 2008 - Misra C++ 2008 - - - - Cert C - - - - - Cert C++ - + Misra C++ 2008 - Misra C++ 2023 - Misra C++ 2023 + Misra C++ 2023 @@ -1083,14 +1044,12 @@ This is probably because the settings were changed between the Cppcheck versions 編譯資料庫 - Visual Studio - Visual Studio + Visual Studio - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -1485,29 +1444,24 @@ Do you want to remove the file from the recently used projects -list? 原生 - Unix 32-bit - Unix 32 位元 + Unix 32 位元 - Unix 64-bit - Unix 64 位元 + Unix 64 位元 - Windows 32-bit ANSI - Windows 32 位元 ANSI + Windows 32 位元 ANSI - Windows 32-bit Unicode - Windows 32 位元 Unicode + Windows 32 位元 Unicode - Windows 64-bit - Windows 64 位元 + Windows 64 位元 @@ -1906,14 +1860,12 @@ Do you want to remove the file from the recently used projects -list? 外部工具 - Clang-tidy - Clang-tidy + Clang-tidy - Clang analyzer - Clang 分析器 + Clang 分析器 @@ -1939,9 +1891,8 @@ Do you want to remove the file from the recently used projects -list? 選取 Cppcheck 建置目錄 - Visual Studio - Visual Studio + Visual Studio @@ -1949,9 +1900,8 @@ Do you want to remove the file from the recently used projects -list? 編譯資料庫 - Borland C++ Builder 6 - Borland C++ Builder 6 + Borland C++ Builder 6 @@ -2237,11 +2187,6 @@ Do you want to remove the file from the recently used projects -list? Tags - - - CWE - - QPlatformTheme @@ -2362,10 +2307,8 @@ Do you want to remove the file from the recently used projects -list? 取消標記 - - Cppcheck - Cppcheck + Cppcheck @@ -2479,10 +2422,8 @@ Please check the application path and parameters are correct. - - Cppcheck - Cppcheck + Cppcheck @@ -3115,11 +3056,6 @@ To toggle what kind of errors are shown, open view menu. The user interface language has been reset to English. Open the Preferences-dialog to select any of the available languages. - - - Cppcheck - - TxtReport diff --git a/gui/fileviewdialog.cpp b/gui/fileviewdialog.cpp index 3f66f008678..9d453519450 100644 --- a/gui/fileviewdialog.cpp +++ b/gui/fileviewdialog.cpp @@ -54,7 +54,7 @@ void FileViewDialog::loadTextFile(const QString &filename, QTextEdit *edit) msg = msg.arg(filename); QMessageBox msgbox(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", msg, QMessageBox::Ok, this); @@ -68,7 +68,7 @@ void FileViewDialog::loadTextFile(const QString &filename, QTextEdit *edit) msg = msg.arg(filename); QMessageBox msgbox(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", msg, QMessageBox::Ok, this); diff --git a/gui/helpdialog.cpp b/gui/helpdialog.cpp index 78ac1e0e635..bef304c5471 100644 --- a/gui/helpdialog.cpp +++ b/gui/helpdialog.cpp @@ -84,7 +84,7 @@ HelpDialog::HelpDialog(QWidget *parent) : if (helpFile.isEmpty()) { const QString msg = tr("Helpfile '%1' was not found").arg("online-help.qhc"); QMessageBox msgBox(QMessageBox::Warning, - tr("Cppcheck"), + "Cppcheck", msg, QMessageBox::Ok, this); diff --git a/gui/librarydialog.cpp b/gui/librarydialog.cpp index 3199af9a975..147363a3a25 100644 --- a/gui/librarydialog.cpp +++ b/gui/librarydialog.cpp @@ -107,7 +107,7 @@ void LibraryDialog::openCfg() QFile file(selectedFile); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox msg(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("Cannot open file %1.").arg(selectedFile), QMessageBox::Ok, this); @@ -119,7 +119,7 @@ void LibraryDialog::openCfg() const QString errmsg = tempdata.open(file); if (!errmsg.isNull()) { QMessageBox msg(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("Failed to load %1. %2.").arg(selectedFile).arg(errmsg), QMessageBox::Ok, this); @@ -156,7 +156,7 @@ void LibraryDialog::saveCfg() mUi->buttonSave->setEnabled(false); } else { QMessageBox msg(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("Cannot save file %1.").arg(mFileName), QMessageBox::Ok, this); diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index bf73828bed4..31f124bc5b0 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -456,7 +456,7 @@ void MainWindow::loadSettings() "Please check (and fix) the editor application settings, otherwise the editor " "program might not start correctly."); QMessageBox msgBox(QMessageBox::Warning, - tr("Cppcheck"), + "Cppcheck", msg, QMessageBox::Ok, this); @@ -666,7 +666,7 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, c if (fileNames.isEmpty()) { QMessageBox msg(QMessageBox::Warning, - tr("Cppcheck"), + "Cppcheck", tr("No suitable files found to analyze!"), QMessageBox::Ok, this); @@ -751,7 +751,7 @@ QStringList MainWindow::selectFilesToAnalyze(QFileDialog::FileMode mode) { if (mProjectFile) { QMessageBox msgBox(this); - msgBox.setWindowTitle(tr("Cppcheck")); + msgBox.setWindowTitle("Cppcheck"); const QString msg(tr("You must close the project file before selecting new files or directories!")); msgBox.setText(msg); msgBox.setIcon(QMessageBox::Critical); @@ -768,8 +768,8 @@ QStringList MainWindow::selectFilesToAnalyze(QFileDialog::FileMode mode) QMap filters; filters[tr("C/C++ Source")] = FileList::getDefaultFilters().join(" "); filters[tr("Compile database")] = compile_commands_json; - filters[tr("Visual Studio")] = "*.sln *.slnx *.vcxproj"; - filters[tr("Borland C++ Builder 6")] = "*.bpr"; + filters["Visual Studio"] = "*.sln *.slnx *.vcxproj"; + filters["Borland C++ Builder 6"] = "*.bpr"; QString lastFilter = mSettings->value(SETTINGS_LAST_ANALYZE_FILES_FILTER).toString(); selected = QFileDialog::getOpenFileNames(this, tr("Select files to analyze"), @@ -857,7 +857,7 @@ void MainWindow::analyzeDirectory() if (projFiles.size() == 1) { // If one project file found, suggest loading it QMessageBox msgBox(this); - msgBox.setWindowTitle(tr("Cppcheck")); + msgBox.setWindowTitle("Cppcheck"); const QString msg(tr("Found project file: %1\n\nDo you want to " "load this project file instead?").arg(projFiles[0])); msgBox.setText(msg); @@ -879,7 +879,7 @@ void MainWindow::analyzeDirectory() // If multiple project files found inform that there are project // files also available. QMessageBox msgBox(this); - msgBox.setWindowTitle(tr("Cppcheck")); + msgBox.setWindowTitle("Cppcheck"); const QString msg(tr("Found project files from the directory.\n\n" "Do you want to proceed analysis without " "using any of these project files?")); @@ -1466,7 +1466,7 @@ void MainWindow::openResults() { if (mUI->mResults->hasResults()) { QMessageBox msgBox(this); - msgBox.setWindowTitle(tr("Cppcheck")); + msgBox.setWindowTitle("Cppcheck"); const QString msg(tr("Current results will be cleared.\n\n" "Opening a new XML file will clear current results.\n" "Do you want to proceed?")); @@ -1591,7 +1591,7 @@ void MainWindow::closeEvent(QCloseEvent *event) "Do you want to stop the analysis and exit Cppcheck?")); QMessageBox msg(QMessageBox::Warning, - tr("Cppcheck"), + "Cppcheck", text, QMessageBox::Yes | QMessageBox::No, this); @@ -1886,7 +1886,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis buildDir = inf.canonicalPath() + '/' + buildDir; if (!QDir(buildDir).exists()) { QMessageBox msg(QMessageBox::Question, - tr("Cppcheck"), + "Cppcheck", tr("Build dir '%1' does not exist, create it?").arg(buildDir), QMessageBox::Yes | QMessageBox::No, this); @@ -1894,7 +1894,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis QDir().mkpath(buildDir); } else if (!projectFile->getAddons().isEmpty()) { QMessageBox m(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("To check the project using addons, you need a build directory."), QMessageBox::Ok, this); @@ -1949,7 +1949,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis if (!errorMessage.isEmpty()) { QMessageBox msg(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("Failed to import '%1': %2\n\nAnalysis is stopped.").arg(prjfile).arg(errorMessage), QMessageBox::Ok, this); @@ -1958,7 +1958,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis } } catch (InternalError &e) { QMessageBox msg(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("Failed to import '%1' (%2), analysis is stopped").arg(prjfile).arg(QString::fromStdString(e.errorMessage)), QMessageBox::Ok, this); @@ -2030,7 +2030,7 @@ void MainWindow::editProjectFile() { if (!mProjectFile) { QMessageBox msg(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("No project file loaded"), QMessageBox::Ok, this); @@ -2118,7 +2118,7 @@ void MainWindow::openRecentProject() "used projects -list?").arg(project)); QMessageBox msg(QMessageBox::Warning, - tr("Cppcheck"), + "Cppcheck", text, QMessageBox::Yes | QMessageBox::No, this); diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index 1f66d1a582a..16577224874 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -23,7 +23,7 @@ - Cppcheck + Cppcheck @@ -684,7 +684,7 @@ :/cppcheck-gui.png:/cppcheck-gui.png - Cppcheck + Cppcheck Show Cppcheck results @@ -992,7 +992,7 @@ true - Misra C + Misra C @@ -1000,7 +1000,7 @@ true - Misra C++ 2008 + Misra C++ 2008 @@ -1008,7 +1008,7 @@ true - Cert C + Cert C @@ -1016,7 +1016,7 @@ true - Cert C++ + Cert C++ @@ -1024,7 +1024,7 @@ true - Misra C++ 2023 + Misra C++ 2023 diff --git a/gui/platforms.cpp b/gui/platforms.cpp index 77683a6ea09..27504006477 100644 --- a/gui/platforms.cpp +++ b/gui/platforms.cpp @@ -36,11 +36,11 @@ void Platforms::add(const QString &title, Platform::Type platform) void Platforms::init() { add(tr("Native"), Platform::Type::Native); - add(tr("Unix 32-bit"), Platform::Type::Unix32); - add(tr("Unix 64-bit"), Platform::Type::Unix64); - add(tr("Windows 32-bit ANSI"), Platform::Type::Win32A); - add(tr("Windows 32-bit Unicode"), Platform::Type::Win32W); - add(tr("Windows 64-bit"), Platform::Type::Win64); + add("Unix 32-bit", Platform::Type::Unix32); + add("Unix 64-bit", Platform::Type::Unix64); + add("Windows 32-bit ANSI", Platform::Type::Win32A); + add("Windows 32-bit Unicode", Platform::Type::Win32W); + add("Windows 64-bit", Platform::Type::Win64); } int Platforms::getCount() const diff --git a/gui/projectfile.ui b/gui/projectfile.ui index 84a1d6e40ec..9f7ad91fa8f 100644 --- a/gui/projectfile.ui +++ b/gui/projectfile.ui @@ -1010,14 +1010,14 @@ - Clang-tidy + Clang-Tidy - Clang analyzer + Clang Static Analyzer diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index e156f3dfe3b..72e3d651471 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -624,9 +624,9 @@ void ProjectFileDialog::browseImportProject() const QFileInfo inf(mProjectFile->getFilename()); const QDir &dir = inf.absoluteDir(); QMap filters; - filters[tr("Visual Studio")] = "*.sln *.slnx *.vcxproj"; + filters["Visual Studio"] = "*.sln *.slnx *.vcxproj"; filters[tr("Compile database")] = "compile_commands.json"; - filters[tr("Borland C++ Builder 6")] = "*.bpr"; + filters["Borland C++ Builder 6"] = "*.bpr"; QString fileName = QFileDialog::getOpenFileName(this, tr("Import Project"), dir.canonicalPath(), toFilterString(filters)); diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index fc70fdb84af..ed8b3c7412e 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -122,7 +122,7 @@ static QStringList getLabels() { QObject::tr("Rule"), QObject::tr("Since date"), QObject::tr("Tags"), - QObject::tr("CWE")}; + "CWE"}; } static Severity getSeverity(ReportType reportType, const ErrorItem& errorItem) { @@ -741,7 +741,7 @@ void ResultsTree::startApplication(const ResultItem *target, int application) //If there are no applications specified, tell the user about it if (mApplications->getApplicationCount() == 0) { QMessageBox msg(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("No editor application configured.\n\n" "Configure the editor application for Cppcheck in preferences/Applications."), QMessageBox::Ok, @@ -755,7 +755,7 @@ void ResultsTree::startApplication(const ResultItem *target, int application) if (application == -1) { QMessageBox msg(QMessageBox::Critical, - tr("Cppcheck"), + "Cppcheck", tr("No default editor application selected.\n\n" "Please select the default editor application in preferences/Applications."), QMessageBox::Ok, diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index 496c0793157..55f673ab80c 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -345,7 +345,7 @@ void ResultsView::checkingFinished() //Tell user that we found no errors if (!hasResults()) { QMessageBox msg(QMessageBox::Information, - tr("Cppcheck"), + "Cppcheck", tr("No errors found."), QMessageBox::Ok, this); @@ -356,7 +356,7 @@ void ResultsView::checkingFinished() QString text = tr("Errors were found, but they are configured to be hidden.\n" \ "To toggle what kind of errors are shown, open view menu."); QMessageBox msg(QMessageBox::Information, - tr("Cppcheck"), + "Cppcheck", text, QMessageBox::Ok, this); diff --git a/gui/translationhandler.cpp b/gui/translationhandler.cpp index d8160525856..14faedc04a2 100644 --- a/gui/translationhandler.cpp +++ b/gui/translationhandler.cpp @@ -133,7 +133,7 @@ bool TranslationHandler::setLanguage(const QString &code) "the Preferences-dialog to select any of the available " "languages.").arg(error)); QMessageBox msgBox(QMessageBox::Warning, - tr("Cppcheck"), + "Cppcheck", msg, QMessageBox::Ok); msgBox.exec(); From 37b5e958a2bc9380594c9270620ee38adde1b0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 17 Jun 2026 10:28:29 +0200 Subject: [PATCH 180/493] removed usage of `#file`/`#endfile` (#7951) --- lib/cppcheck.cpp | 8 --- test/cli/other_test.py | 111 ++++++++++++++++++++++++++++++++++++ test/testpreprocessor.cpp | 91 +++++++++++++---------------- test/testtokenize.cpp | 35 ++++++------ test/testunusedprivfunc.cpp | 39 ------------- 5 files changed, 168 insertions(+), 116 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index da078e5eb20..b7ab1f99039 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1136,15 +1136,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str codeWithoutCfg = preprocessor.getcode(currentConfig, files, true); }); - if (startsWith(codeWithoutCfg,"#file")) - codeWithoutCfg.insert(0U, "//"); std::string::size_type pos = 0; - while ((pos = codeWithoutCfg.find("\n#file",pos)) != std::string::npos) - codeWithoutCfg.insert(pos+1U, "//"); - pos = 0; - while ((pos = codeWithoutCfg.find("\n#endfile",pos)) != std::string::npos) - codeWithoutCfg.insert(pos+1U, "//"); - pos = 0; while ((pos = codeWithoutCfg.find(Preprocessor::macroChar,pos)) != std::string::npos) codeWithoutCfg[pos] = ' '; mErrorLogger.reportOut(codeWithoutCfg, Color::Reset); diff --git a/test/cli/other_test.py b/test/cli/other_test.py index f788a7d21c8..c79fd0c8e50 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4240,6 +4240,117 @@ def test_no_valid_configuration(tmp_path): ] +# The implementation for "A::a" is missing - so don't check if "A::b" is used or not +def test_unused_private_function_incomplete_impl(tmpdir): + test_inc = os.path.join(tmpdir, 'test.h') + with open(test_inc, 'wt') as f: + f.write( +""" +class A +{ +public: + A(); + void a(); +private: + void b(); +}; +""") + + test_file = os.path.join(tmpdir, 'test.cpp') + with open(test_file, 'wt') as f: + f.write( +""" +#include "test.h" + +A::A() { } +void A::b() { } +""") + + args = [ + '-q', + '--template=simple', + '--enable=style', + '--suppress=functionStatic', # we do not care about this - this was converted from TestUnusedPrivateFunction + test_file + ] + + ret, stdout, stderr = cppcheck(args) + assert stdout == '' + assert stderr.splitlines() == [] + assert ret == 0, stdout + + +def test_unused_private_function_multi_file(tmpdir): # ticket #2567 + test_inc = os.path.join(tmpdir, 'test.h') + with open(test_inc, 'wt') as f: + f.write( +""" +struct Fred +{ + Fred() + { + Init(); + } +private: + void Init(); +}; +""") + + test_file = os.path.join(tmpdir, 'test.cpp') + with open(test_file, 'wt') as f: + f.write( +""" +#include "test.h" + +void Fred::Init() +{ +} +""") + + args = [ + '-q', + '--template=simple', + '--enable=style', + '--suppress=functionStatic', # we do not care about this - this was converted from TestUnusedPrivateFunction + test_file + ] + + ret, stdout, stderr = cppcheck(args) + assert stdout == '' + assert stderr.splitlines() == [] + assert ret == 0, stdout + + +def test_missing_doublequote_include(tmpdir): + test_inc = os.path.join(tmpdir, 'abc.h') + with open(test_inc, 'wt') as f: + f.write( +''' +#define a +" +''') + + test_file = os.path.join(tmpdir, 'test.cpp') + with open(test_file, 'wt') as f: + f.write( +""" +#include "abc.h" +""") + + args = [ + '-q', + '--template=simple', + test_file + ] + + ret, stdout, stderr = cppcheck(args) + assert stdout == '' + assert stderr.splitlines() == [ + f"{test_inc}:3:1: error: No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [syntaxError]" + ] + assert ret == 0, stdout + + def test_no_valid_configuration_check_config(tmp_path): test_file = tmp_path / 'test.c' with open(test_file, "w") as f: diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 7e01f6f233b..b90a879738d 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -50,13 +50,14 @@ class TestPreprocessor : public TestFixture { TestPreprocessor() : TestFixture("TestPreprocessor") {} private: + #define expandMacros(...) expandMacros_(__FILE__, __LINE__, __VA_ARGS__) template - std::string expandMacros(const char (&code)[size], ErrorLogger &errorLogger) const { + std::string expandMacros_(const char* file, int line, const char (&code)[size], ErrorLogger &errorLogger) const { simplecpp::OutputList outputList; std::vector files; simplecpp::TokenList tokens1 = simplecpp::TokenList(code, files, "file.cpp", &outputList); Preprocessor p(tokens1, settingsDefault, errorLogger, Path::identify(tokens1.getFiles()[0], false)); - ASSERT(p.loadFiles(files)); + ASSERT_LOC(p.loadFiles(files), file, line); simplecpp::TokenList tokens2 = p.preprocess("", files, outputList); (void)p.reportOutput(outputList, true); return tokens2.stringify(); @@ -140,7 +141,7 @@ class TestPreprocessor : public TestFixture { cfgs = preprocessor.getConfigs(); for (const std::string & config : cfgs) { try { - const bool writeLocations = (strstr(code, "#file") != nullptr) || (strstr(code, "#include") != nullptr); + const bool writeLocations = (strstr(code, "#include") != nullptr); cfgcode[config] = preprocessor.getcode(config, files, writeLocations); } catch (const simplecpp::Output &) { cfgcode[config] = ""; @@ -392,7 +393,7 @@ class TestPreprocessor : public TestFixture { std::vector files; simplecpp::OutputList outputList; simplecpp::TokenList tokens(code,files,"test.c",&outputList); - Preprocessor preprocessor(tokens, settings, *this, Standards::Language::C); // TODO: do we need to consider #file? + Preprocessor preprocessor(tokens, settings, *this, Standards::Language::C); ASSERT(preprocessor.loadFiles(files)); ASSERT(!preprocessor.reportOutput(outputList, true)); preprocessor.removeComments(); @@ -407,7 +408,7 @@ class TestPreprocessor : public TestFixture { std::size_t getHash(const char (&code)[size]) { std::vector files; simplecpp::TokenList tokens(code,files,"test.c"); - Preprocessor preprocessor(tokens, settingsDefault, *this, Standards::Language::C); // TODO: do we need to consider #file? + Preprocessor preprocessor(tokens, settingsDefault, *this, Standards::Language::C); ASSERT(preprocessor.loadFiles(files)); preprocessor.removeComments(); return preprocessor.calculateHash(""); @@ -472,16 +473,19 @@ class TestPreprocessor : public TestFixture { void error4() { // In included file { + ScopedFile header("ab.h", "#error hello world!\n"); const auto settings = dinit(Settings, $.userDefines = "TEST"); - const char code[] = "#file \"ab.h\"\n#error hello world!\n#endfile"; + const char code[] = "#include \"ab.h\""; (void)getcodeforcfg(settings, *this, code, "TEST", "test.c"); ASSERT_EQUALS("[ab.h:1:2]: (error) #error hello world! [preprocessorErrorDirective]\n", errout_str()); } // After including a file { + ScopedFile header("ab.h", ""); const auto settings = dinit(Settings, $.userDefines = "TEST"); - const char code[] = "#file \"ab.h\"\n\n#endfile\n#error aaa"; + const char code[] = "#include \"ab.h\"\n" + "#error aaa"; (void)getcodeforcfg(settings, *this, code, "TEST", "test.c"); ASSERT_EQUALS("[test.c:2:2]: (error) #error aaa [preprocessorErrorDirective]\n", errout_str()); } @@ -584,35 +588,35 @@ class TestPreprocessor : public TestFixture { } void includeguard1() { + ScopedFile header("abc.h", + "#ifndef abcH\n" + "#define abcH\n" + "#endif\n"); // Handling include guards.. - const char filedata[] = "#file \"abc.h\"\n" - "#ifndef abcH\n" - "#define abcH\n" - "#endif\n" - "#endfile\n" + const char filedata[] = "#include \"abc.h\"\n" "#ifdef ABC\n" "#endif"; ASSERT_EQUALS("\nABC=ABC\n", getConfigsStr(filedata)); } void includeguard2() { + ScopedFile header("abc.h", + "foo\n" + "#ifdef ABC\n" + "\n" + "#endif\n"); // Handling include guards.. - const char filedata[] = "#file \"abc.h\"\n" - "foo\n" - "#ifdef ABC\n" - "\n" - "#endif\n" - "#endfile\n"; + const char filedata[] = "#include \"abc.h\"\n"; ASSERT_EQUALS("\nABC=ABC\n", getConfigsStr(filedata)); } void ifdefwithfile() { + ScopedFile header("abc.h", "class A{};/*\n\n\n\n\n\n\n*/\n"); + // Handling include guards.. const char filedata[] = "#ifdef ABC\n" - "#file \"abc.h\"\n" - "class A{};/*\n\n\n\n\n\n\n*/\n" - "#endfile\n" + "#include \"abc.h\"\n" "#endif\n" "int main() {}\n"; @@ -1576,22 +1580,9 @@ class TestPreprocessor : public TestFixture { } { - const char filedata[] = "#file \"abc.h\"\n" - "#define a\n" - "\"\n" - "#endfile\n"; - - // expand macros.. - const std::string actual(expandMacros(filedata, *this)); - - ASSERT_EQUALS("", actual); - ASSERT_EQUALS("[abc.h:2:1]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported. [syntaxError]\n", errout_str()); - } - - { - const char filedata[] = "#file \"abc.h\"\n" - "#define a\n" - "#endfile\n" + ScopedFile header("abc.h", + "#define a\n"); + const char filedata[] = "#include \"abc.h\"\n" "\"\n"; // expand macros.. @@ -2286,14 +2277,14 @@ class TestPreprocessor : public TestFixture { } void getConfigs7e() { + ScopedFile header("test.h", + "#ifndef test_h\n" + "#define test_h\n" + "#ifdef ABC\n" + "#endif\n" + "#endif\n"); const char filedata[] = "#ifdef ABC\n" - "#file \"test.h\"\n" - "#ifndef test_h\n" - "#define test_h\n" - "#ifdef ABC\n" - "#endif\n" - "#endif\n" - "#endfile\n" + "#include \"test.h\"\n" "#endif\n"; ASSERT_EQUALS("\nABC=ABC\n", getConfigsStr(filedata)); } @@ -2315,12 +2306,12 @@ class TestPreprocessor : public TestFixture { } void getConfigs11() { // #9832 - include guards - const char filedata[] = "#file \"test.h\"\n" - "#if !defined(test_h)\n" - "#define test_h\n" - "123\n" - "#endif\n" - "#endfile\n"; + ScopedFile header("test.h", + "#if !defined(test_h)\n" + "#define test_h\n" + "123\n" + "#endif\n"); + const char filedata[] = "#include \"test.h\"\n"; ASSERT_EQUALS("\n", getConfigsStr(filedata)); } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b1e3e87cdcf..6e5ea0f785f 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8848,14 +8848,11 @@ class TestTokenizer : public TestFixture { } void testDirectiveIncludeLocations() { + ScopedFile inc1("inc1.h", "#define macro2 val\n#include \"inc2.h\"\n#define macro4 val\n"); + ScopedFile inc2("inc2.h", "#define macro3 val\n"); + // TODO: preprocess? const char filedata[] = "#define macro1 val\n" - "#file \"inc1.h\"\n" - "#define macro2 val\n" - "#file \"inc2.h\"\n" - "#define macro3 val\n" - "#endfile\n" - "#define macro4 val\n" - "#endfile\n" + "#include \"inc1.h\"\n" "#define macro5 val\n"; const char dumpdata[] = " \n" " \n" @@ -8866,8 +8863,14 @@ class TestTokenizer : public TestFixture { " \n" " \n" " \n" - " \n" - " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" " \n" @@ -8877,14 +8880,8 @@ class TestTokenizer : public TestFixture { " \n" " \n" " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + " \n" + " \n" " \n" " \n" " \n" @@ -8892,10 +8889,10 @@ class TestTokenizer : public TestFixture { " \n" " \n" " \n" - " \n" + " \n" " \n" " \n" - " \n" + " \n" " \n" " \n" " \n" diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 4a2a6ca1894..09f8c21d102 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -58,7 +58,6 @@ class TestUnusedPrivateFunction : public TestFixture { TEST_CASE(classInClass); TEST_CASE(sameFunctionNames); - TEST_CASE(incompleteImplementation); TEST_CASE(derivedClass); // skip warning for derived classes. It might be a virtual function. @@ -76,7 +75,6 @@ class TestUnusedPrivateFunction : public TestFixture { TEST_CASE(testDoesNotIdentifyMethodAsMiddleFunctionArgument); TEST_CASE(testDoesNotIdentifyMethodAsLastFunctionArgument); - TEST_CASE(multiFile); TEST_CASE(unknownBaseTemplate); // ticket #2580 TEST_CASE(hierarchy_loop); // ticket 5590 @@ -482,24 +480,6 @@ class TestUnusedPrivateFunction : public TestFixture { ASSERT_EQUALS("", errout_str()); } - void incompleteImplementation() { - // The implementation for "A::a" is missing - so don't check if - // "A::b" is used or not - check("#file \"test.h\"\n" - "class A\n" - "{\n" - "public:\n" - " A();\n" - " void a();\n" - "private:\n" - " void b();\n" - "};\n" - "#endfile\n" - "A::A() { }\n" - "void A::b() { }"); - ASSERT_EQUALS("", errout_str()); - } - void derivedClass() { // skip warning in derived classes in case the base class is invisible check("class derived : public base\n" @@ -780,25 +760,6 @@ class TestUnusedPrivateFunction : public TestFixture { ASSERT_EQUALS("", errout_str()); } - void multiFile() { // ticket #2567 - check("#file \"test.h\"\n" - "struct Fred\n" - "{\n" - " Fred()\n" - " {\n" - " Init();\n" - " }\n" - "private:\n" - " void Init();\n" - "};\n" - "#endfile\n" - "void Fred::Init()\n" - "{\n" - "}"); - - ASSERT_EQUALS("", errout_str()); - } - void unknownBaseTemplate() { // ticket #2580 check("class Bla : public Base2 {\n" "public:\n" From 54b482c09bb9848343f6e30f6b0bd3814f9bcfcc Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:24:55 +0200 Subject: [PATCH 181/493] Fix #14374 FP missingReturn with std::throw_with_nested() (#8638) --- cfg/std.cfg | 6 ++++++ test/cfg/std.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/cfg/std.cfg b/cfg/std.cfg index 245142c091d..4662d0a4632 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -8814,6 +8814,12 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
+ + + + true + + malloc,std::malloc calloc,std::calloc diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 77c9d99cd5d..850dd74b997 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -5379,3 +5379,13 @@ int containerOutOfBounds_std_initializer_list() { // #14340 int i = *x.end(); return i + containerOutOfBounds_std_initializer_list_access(x); } + +int* missingReturn_std_throw_with_nested() { // #14374 + try { + int* p = new int(); + return p; + } + catch (...) { + std::throw_with_nested(std::runtime_error("xyz")); + } +} From c903d68fdc7ca57da42ad0d0c1d33293f7d2d84b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Jun 2026 12:20:02 +0200 Subject: [PATCH 182/493] Fix #13855 useStlAlgorithm might lack column information (#8627) --- lib/tokenize.cpp | 1 + test/teststl.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 59da46a0b28..f97057ddb0f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7003,6 +7003,7 @@ Token *Tokenizer::simplifyAddBracesPair(Token *tok, bool commandWithCondition) tokAfterCondition->previous()->insertToken("{"); Token * tokOpenBrace=tokAfterCondition->previous(); + tokOpenBrace->column(tokAfterCondition->column()); tokEnd->insertToken("}"); Token * tokCloseBrace=tokEnd->next(); diff --git a/test/teststl.cpp b/test/teststl.cpp index 51fab0e6021..2060a5cfd2b 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -613,7 +613,7 @@ class TestStl : public TestFixture { " return i;\n" " return 0;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:8:0]: style: Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:8:13]: style: Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); checkNormal("bool g();\n" "int f(int x) {\n" @@ -626,7 +626,7 @@ class TestStl : public TestFixture { " return i;\n" " return 0;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:8:0]: style: Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:8:13]: style: Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); checkNormal("bool g();\n" "void f(int x) {\n" @@ -5260,7 +5260,7 @@ class TestStl : public TestFixture { " return s.erase(it);\n" " return s.end();\n" "}\n"); - ASSERT_EQUALS("[test.cpp:3:0]: (style) Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:9]: (style) Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); // #11381 check("int f(std::map& map) {\n" @@ -5953,7 +5953,7 @@ class TestStl : public TestFixture { " v1.erase(it1);\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:9:0]: (style) Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:9:17]: (style) Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); check("bool f(const std::set& set, const std::string& f) {\n" // #11595 " for (const std::string& s : set) {\n" From 717566c1e2f262ddf266d54d3afaa42aed3a1022 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Jun 2026 12:21:05 +0200 Subject: [PATCH 183/493] Partial fix for #14810 FN constVariablePointer (cbegin() called on container) (#8619) Co-authored-by: chrchr-github --- lib/library.cpp | 2 ++ test/testother.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/lib/library.cpp b/lib/library.cpp index 7520944d8ad..2a198001d3c 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -1781,6 +1781,8 @@ bool Library::isFunctionConst(const Token *ftok) const const Yield yield = astContainerYield(ftok->astParent()->astOperand1(), *this); if (yield == Yield::EMPTY || yield == Yield::SIZE || yield == Yield::BUFFER_NT) return true; + if ((yield == Yield::START_ITERATOR || yield == Yield::END_ITERATOR) && ftok->str()[0] == 'c') + return true; } return false; } diff --git a/test/testother.cpp b/test/testother.cpp index c8a95c9882b..eb8f9dfe8ef 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4867,6 +4867,11 @@ class TestOther : public TestFixture { ASSERT_EQUALS("[test.cpp:1:12]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:1:20]: (style) Parameter 'q' can be declared as pointer to const [constParameterPointer]\n", errout_str()); + + check("int f(std::vector* p) {\n" // #14810 + " return *p->cbegin();\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:1:25]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); } void constArray() { From af63e5fbad20993997279a9b73256c9dc2f3095d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Jun 2026 13:42:54 +0200 Subject: [PATCH 184/493] Fix #14783 / #14784 FN unusedVariable with templated type (default constructor, regression) (#8574) Co-authored-by: chrchr-github --- lib/checkunusedvar.cpp | 4 ---- test/testunusedvar.cpp | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index fcc8746c30e..8ed249f05e2 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1155,10 +1155,6 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage_iterateScopes(const Scope* c variables.read(tok2->varId(), tok); } } - } else if (tok->variable() && tok->variable()->isClass() && tok->variable()->type() && - (tok->variable()->type()->needInitialization == Type::NeedInitialization::False) && - tok->strAt(1) == ";") { - variables.write(tok->varId(), tok); } } } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 2efe658b52e..03ef0a14a83 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -7083,6 +7083,24 @@ class TestUnusedVar : public TestFixture { " S<0> s;\n" "}\n"); ASSERT_EQUALS("[test.cpp:6:10]: (style) Unused variable: s [unusedVariable]\n", errout_str()); + + functionVariableUsage("template \n" // #14783 + "struct A {\n" + " A() = default;\n" + "};\n" + "void f() {\n" + " A a;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6:12]: (style) Unused variable: a [unusedVariable]\n", errout_str()); + + functionVariableUsage("template \n" // #14784 + "struct A {\n" + " A() {}\n" + "};\n" + "void f() {\n" + " A a;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6:12]: (style) Unused variable: a [unusedVariable]\n", errout_str()); } void localvarFuncPtr() { @@ -7171,6 +7189,7 @@ class TestUnusedVar : public TestFixture { "void f() {\n" " Y y;\n" "}"); // #4695 + ASSERT_EQUALS("[test.cpp:6:7]: (style) Unused variable: y [unusedVariable]\n", errout_str()); } void crash3() { From 2538dcde482f91719b2c3e3ea7db508d6d3bf5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ramner=C3=B6?= Date: Wed, 17 Jun 2026 18:43:39 +0200 Subject: [PATCH 185/493] updated readme to direct vs code users to cppcheck official extension [skip ci] (#8657) --- readme.md | 66 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 64 deletions(-) diff --git a/readme.md b/readme.md index 512a1ec1110..6671fdd4827 100644 --- a/readme.md +++ b/readme.md @@ -108,71 +108,9 @@ If you do not wish to use the Visual Studio IDE, you can compile Cppcheck from t msbuild cppcheck.sln ``` -### VS Code (on Windows) - -Install MSYS2 to get GNU toolchain with g++ and gdb (). -Create a `settings.json` file in the `.vscode` folder with the following content (adjust path as necessary): - -```json -{ - "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe", - "terminal.integrated.shellArgs.windows": [ - "--login", - ], - "terminal.integrated.env.windows": { - "CHERE_INVOKING": "1", - "MSYSTEM": "MINGW64", - } -} -``` +### VS Code -Run `make` in the terminal to build Cppcheck. - -For debugging create a `launch.json` file in the `.vscode` folder with the following content, which covers configuration for debugging Cppcheck and `misra.py`: - -```json -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "cppcheck", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/cppcheck.exe", - "args": [ - "--dump", - "${workspaceFolder}/addons/test/misra/misra-test.c" - ], - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "externalConsole": true, - "MIMode": "gdb", - "miDebuggerPath": "C:/msys64/mingw64/bin/gdb.exe", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ] - }, - { - "name": "misra.py", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/addons/misra.py", - "console": "integratedTerminal", - "args": [ - "${workspaceFolder}/addons/test/misra/misra-test.c.dump" - ] - } - ] -} -``` +Cppcheck Official is an extension officially supported by the cppcheck team allowing you to easily use cppcheck in VS Code. You can find it in VS Code Marketplace through the extension tab in your IDE. For instructions on how to set it up and use it, see the readme on the github page: ### Qt Creator + MinGW From 93bc25196f2b296b976bdf9a5ca1540ea97179b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Thu, 18 Jun 2026 19:24:38 +0200 Subject: [PATCH 186/493] Fix #13628 FP: accessMoved with ternary (#8645) When std::move(x) is only in the true branch of a ternary operator, endOfFunctionCall was left pointing at the first token of the false branch, causing valueFlowForward to tag it as always-moved and report a spurious warning on the ? token. Fix by advancing past the entire false-branch subtree using nextAfterAstRightmostLeaf before starting propagation. --------- Signed-off-by: Francois Berder --- lib/valueflow.cpp | 7 +++++-- test/testother.cpp | 12 ++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 68e989c0738..fb9f6dda7a1 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3296,8 +3296,11 @@ static void valueFlowAfterMove(const TokenList& tokenlist, const SymbolDatabase& ternaryColon = ternaryColon->astParent(); if (Token::simpleMatch(ternaryColon, ":")) { endOfFunctionCall = ternaryColon->astOperand2(); - if (Token::simpleMatch(endOfFunctionCall, "(")) - endOfFunctionCall = endOfFunctionCall->link(); + Token* next = nextAfterAstRightmostLeaf(endOfFunctionCall); + if (next) + endOfFunctionCall = next; + else + endOfFunctionCall = endOfFunctionCall->next(); } } ValueFlow::Value value; diff --git a/test/testother.cpp b/test/testother.cpp index eb8f9dfe8ef..a24209fd4f1 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -12866,6 +12866,18 @@ class TestOther : public TestFixture { " h(b ? h(gA(5, std::move(s))) : h(gB(7, std::move(s))));\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("int cb(std::string);\n" // #13628 + "void f(bool b, std::string s1) {\n" + " std::string s2 = b ? cb(std::move(s1)) : s1;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("int cb(std::string);\n" + "void f(bool b, std::string s1) {\n" + " std::string s2 = b ? cb(std::move(s1)) : s1 + s1;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void movePointerAlias() From 3be9d35fb5d79c10cd0b591020e4f4f29dc9ee50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 19 Jun 2026 14:56:41 +0200 Subject: [PATCH 187/493] Fix #14863 (tokenizer: add token flag when braces are inserted during simplifications and publish in dumpfile) (#8664) --- lib/checkother.cpp | 4 ++-- lib/token.h | 19 ++++++++++++++----- lib/tokenize.cpp | 11 ++++++++--- test/testtokenize.cpp | 12 ++++++++++++ 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 551c3a47543..9b9d40a777e 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1289,7 +1289,7 @@ void CheckOtherImpl::checkVariableScope() tok = tok->link(); // parse else if blocks.. - } else if (Token::simpleMatch(tok, "else { if (") && tok->next()->isSimplifiedScope() && Token::simpleMatch(tok->linkAt(3), ") {")) { + } else if (Token::simpleMatch(tok, "else { if (") && tok->next()->isInsertedBrace() && Token::simpleMatch(tok->linkAt(3), ") {")) { tok = tok->next(); } else if (tok->varId() == var->declarationId() || tok->str() == "goto") { reduce = false; @@ -1415,7 +1415,7 @@ bool CheckOtherImpl::checkInnerScope(const Token *tok, const Variable* var, bool if (scope->type == ScopeType::eSwitch) return false; // Used in outer switch scope - unsafe or impossible to reduce scope - if (scope->bodyStart && scope->bodyStart->isSimplifiedScope()) + if (scope->bodyStart && scope->bodyStart->isSimplifiedIfInitStmt()) return false; // simplified if/for/switch init statement } if (var->isArrayOrPointer()) { diff --git a/lib/token.h b/lib/token.h index ca945fcab22..3328af31fa0 100644 --- a/lib/token.h +++ b/lib/token.h @@ -732,11 +732,11 @@ class CPPCHECKLIB Token { setFlag(fIsTemplate, b); } - bool isSimplifiedScope() const { - return getFlag(fIsSimplifedScope); + bool isSimplifiedIfInitStmt() const { + return getFlag(fIsSimplifiedIfInitStmt); } - void isSimplifiedScope(bool b) { - setFlag(fIsSimplifedScope, b); + void isSimplifiedIfInitStmt(bool b) { + setFlag(fIsSimplifiedIfInitStmt, b); } bool isFinalType() const { @@ -767,6 +767,14 @@ class CPPCHECKLIB Token { setFlag(fIsAnonymous, b); } + bool isInsertedBrace() const { + return getFlag(fIsInsertedBrace); + } + Token* isInsertedBrace(bool b) { + setFlag(fIsInsertedBrace, b); + return this; + } + // cppcheck-suppress unusedFunction bool isBitfield() const { return mImpl->mBits >= 0; @@ -1498,7 +1506,7 @@ class CPPCHECKLIB Token { fIsImplicitInt = (1ULL << 33), // Is "int" token implicitly added? fIsInline = (1ULL << 34), // Is this a inline type fIsTemplate = (1ULL << 35), - fIsSimplifedScope = (1ULL << 36), // scope added when simplifying e.g. if (int i = ...; ...) + fIsSimplifiedIfInitStmt = (1ULL << 36), // simplified if/switch/while init statement e.g. if (int i = ...; ...) => { int i = ...; if (..) .. } fIsRemovedVoidParameter = (1ULL << 37), // A void function parameter has been removed fIsIncompleteConstant = (1ULL << 38), fIsRestrict = (1ULL << 39), // Is this a restrict pointer type @@ -1508,6 +1516,7 @@ class CPPCHECKLIB Token { fIsInitComma = (1ULL << 43), // Is this comma located inside some {..}. i.e: {1,2,3,4} fIsInitBracket = (1ULL << 44), // Is this bracket used as a part of variable initialization i.e: int a{5}, b(2); fIsAnonymous = (1ULL << 45), // Is this a token added for an unnamed member + fIsInsertedBrace = (1ULL << 46), // brace added when simplifying e.g. if (x) f(); => if (x) { f(); } }; enum : std::uint8_t { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f97057ddb0f..a8f675bbc97 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6218,6 +6218,8 @@ void Tokenizer::dump(std::ostream &out) const } if (tok->isRemovedVoidParameter()) outs += " isRemovedVoidParameter=\"true\""; + if (tok->isInsertedBrace()) + outs += " isInsertedBrace=\"true\""; if (tok->isSplittedVarDeclComma()) outs += " isSplittedVarDeclComma=\"true\""; if (tok->isSplittedVarDeclEq()) @@ -7004,10 +7006,12 @@ Token *Tokenizer::simplifyAddBracesPair(Token *tok, bool commandWithCondition) tokAfterCondition->previous()->insertToken("{"); Token * tokOpenBrace=tokAfterCondition->previous(); tokOpenBrace->column(tokAfterCondition->column()); + tokOpenBrace->isInsertedBrace(true); tokEnd->insertToken("}"); Token * tokCloseBrace=tokEnd->next(); tokCloseBrace->column(tokEnd->column()); + tokCloseBrace->isInsertedBrace(true); Token::createMutualLinks(tokOpenBrace,tokCloseBrace); tokBracesEnd=tokCloseBrace; @@ -8038,8 +8042,8 @@ void Tokenizer::elseif() if (Token::Match(tok2, "}|;")) { if (tok2->next() && tok2->strAt(1) != "else") { - tok->insertToken("{")->isSimplifiedScope(true); - tok2->insertToken("}")->isSimplifiedScope(true); + tok->insertToken("{")->isInsertedBrace(true); + tok2->insertToken("}")->isInsertedBrace(true); Token::createMutualLinks(tok->next(), tok2->next()); break; } @@ -8105,7 +8109,8 @@ void Tokenizer::simplifyIfSwitchForInit() tok->str("{"); endscope->insertToken("}"); Token::createMutualLinks(tok, endscope->next()); - tok->isSimplifiedScope(true); + tok->isInsertedBrace(true); + tok->isSimplifiedIfInitStmt(true); } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 6e5ea0f785f..e56ffa3d8bb 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -140,6 +140,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(whileAddBraces); TEST_CASE(whileAddBracesLabels); + TEST_CASE(whileAddBracesDump); TEST_CASE(doWhileAddBraces); TEST_CASE(doWhileAddBracesLabels); @@ -1532,6 +1533,17 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("", filter_valueflow(errout_str())); } + void whileAddBracesDump() { + const char code[] = "void f(){while(a);}"; + SimpleTokenizer tokenizer(settingsDefault, *this, false); + ASSERT(tokenizer.tokenize(code)); + ASSERT(Token::simpleMatch(tokenizer.tokens(), "void f ( ) { while ( a ) { ; } }")); + std::ostringstream ostr; + tokenizer.dump(ostr); + const std::string dump = ostr.str(); + ASSERT(dump.find("isInsertedBrace=\"true\"") != std::string::npos); + } + void doWhileAddBraces() { { const char code[] = "{do ; while (0);}"; From d45d90792b2414ff7e3ec0a3069fac1d6bd3c89f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 19 Jun 2026 19:15:05 +0200 Subject: [PATCH 188/493] Fix #14853 FP funcArgNamesDifferentUnnamed with function pointer argument (#8655) Co-authored-by: chrchr-github --- lib/checkother.cpp | 2 +- test/testother.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 9b9d40a777e..d69cfa7830a 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4052,7 +4052,7 @@ void CheckOtherImpl::checkFuncArgNamesDifferent() break; } // skip over templates and arrays - if (decl->link() && !Token::Match(decl, "[()]")) + if (decl->link() && precedes(decl, decl->link()) && !Token::Match(decl, "( [*&]")) decl = decl->link(); else if (decl->varId()) declarations[j] = decl; diff --git a/test/testother.cpp b/test/testother.cpp index a24209fd4f1..4215a3b3449 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -12976,6 +12976,10 @@ class TestOther : public TestFixture { check("void f(void (*fp)(), int x);\n" // #14847 "void f(void (*fp)(), int x) {}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f(void (*fp)(int a, int b), int b);\n" // #14853 + "void f(void (*fp)(int a, int b), int b) {}\n"); + ASSERT_EQUALS("", errout_str()); } void funcArgOrderDifferent() { From fb388e69bcfd9117e77289e8386daaaab9be9fea Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 19 Jun 2026 19:39:29 +0200 Subject: [PATCH 189/493] Fix #14812 FN useStlAlgorithm with std::set (#8629) Co-authored-by: chrchr-github --- gui/checkstatistics.cpp | 10 +++++----- lib/checkother.cpp | 1 + lib/checkstl.cpp | 9 ++++----- lib/symboldatabase.cpp | 4 ++-- lib/templatesimplifier.cpp | 1 + test/cfg/boost.cpp | 1 + test/teststl.cpp | 8 ++++++++ tools/dmake/dmake.cpp | 1 + 8 files changed, 23 insertions(+), 12 deletions(-) diff --git a/gui/checkstatistics.cpp b/gui/checkstatistics.cpp index 612e79da63b..830f5eb6b4e 100644 --- a/gui/checkstatistics.cpp +++ b/gui/checkstatistics.cpp @@ -109,10 +109,10 @@ unsigned CheckStatistics::getCount(const QString &tool, ShowTypes::ShowType type QStringList CheckStatistics::getTools() const { QSet ret; - for (const QString& tool: mStyle.keys()) ret.insert(tool); - for (const QString& tool: mWarning.keys()) ret.insert(tool); - for (const QString& tool: mPerformance.keys()) ret.insert(tool); - for (const QString& tool: mPortability.keys()) ret.insert(tool); - for (const QString& tool: mError.keys()) ret.insert(tool); + std::copy(mStyle.keyBegin(), mStyle.keyEnd(), std::inserter(ret, ret.end())); + std::copy(mWarning.keyBegin(), mWarning.keyEnd(), std::inserter(ret, ret.end())); + std::copy(mPerformance.keyBegin(), mPerformance.keyEnd(), std::inserter(ret, ret.end())); + std::copy(mPortability.keyBegin(), mPortability.keyEnd(), std::inserter(ret, ret.end())); + std::copy(mError.keyBegin(), mError.keyEnd(), std::inserter(ret, ret.end())); return ret.values(); } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d69cfa7830a..a45dfdf672e 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4586,6 +4586,7 @@ void CheckOtherImpl::checkUnionZeroInit() std::unordered_map unionsByScopeId; const std::vector unions = parseUnions(*symbolDatabase, mSettings); for (const Union &u : unions) { + // cppcheck-suppress useStlAlgorithm - std::transform is cumbersome unionsByScopeId.emplace(u.scope, u); } diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index c8fcca48f1a..f499bb03b91 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -3116,19 +3116,18 @@ void CheckStlImpl::useStlAlgorithm() bool useLoopVarInMemCall; const Token *memberAccessTok = singleMemberCallInScope(bodyTok, loopVar->varId(), useLoopVarInMemCall, mSettings); if (memberAccessTok && loopType == LoopType::RANGE) { - const Token *memberCallTok = memberAccessTok->astOperand2(); const int contVarId = memberAccessTok->astOperand1()->varId(); if (contVarId == loopVar->varId()) continue; - if (memberCallTok->str() == "push_back" || - memberCallTok->str() == "push_front" || - memberCallTok->str() == "emplace_back") { + using Action = Library::Container::Action; + const auto action = astContainerAction(memberAccessTok->astOperand1(), mSettings.library); + if (contains({Action::PUSH, Action::INSERT}, action)) { std::string algo; if (useLoopVarInMemCall) algo = "std::copy"; else algo = "std::transform"; - useStlAlgorithmError(memberCallTok, algo); + useStlAlgorithmError(memberAccessTok->astOperand2(), algo); } continue; } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4b923a328ca..ba5c31d1f47 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1246,6 +1246,7 @@ void SymbolDatabase::createSymbolDatabaseSetTypePointers() { std::unordered_set typenames; for (const Type &t : typeList) { + // cppcheck-suppress useStlAlgorithm - std::transform is cumbersome typenames.insert(t.name()); } @@ -4599,8 +4600,7 @@ void SymbolDatabase::printXml(std::ostream &out) const } // Variables.. - for (const Variable *var : mVariableList) - variables.insert(var); + std::copy(mVariableList.begin(), mVariableList.end(), std::inserter(variables, variables.end())); outs += " \n"; for (const Variable *var : variables) { if (!var) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 9c8c8fdde9a..2672e66c263 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -3916,6 +3916,7 @@ void TemplateSimplifier::simplifyTemplates(const std::time_t maxtime) std::unordered_map nameOrdinal; int ordinal = 0; for (const auto& decl : mTemplateDeclarations) { + // cppcheck-suppress useStlAlgorithm - std::transform is cumbersome nameOrdinal.emplace(decl.fullName(), ordinal++); } diff --git a/test/cfg/boost.cpp b/test/cfg/boost.cpp index 2cc4b288cce..27fae71b499 100644 --- a/test/cfg/boost.cpp +++ b/test/cfg/boost.cpp @@ -157,6 +157,7 @@ void test_BOOST_FOREACH_5() { std::set data; BOOST_FOREACH(const int& i, get_data()) + // cppcheck-suppress useStlAlgorithm data.insert(i); } diff --git a/test/teststl.cpp b/test/teststl.cpp index 2060a5cfd2b..b7a29b2a11a 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -5661,6 +5661,14 @@ class TestStl : public TestFixture { "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); + + check("void f(const std::vector& v) {\n" // #14812 + " std::set s;\n" + " for (const std::string& a : v) {\n" + " s.insert(a);\n" + " }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:11]: (style) Consider using std::copy algorithm instead of a raw loop. [useStlAlgorithm]\n", errout_str()); } void loopAlgoIncrement() { diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index a434c710631..eaf0a727646 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -297,6 +297,7 @@ static std::vector prioritizelib(const std::vector& li std::map priorities; std::size_t prio = libfiles.size(); for (const auto &l : libfiles) { + // cppcheck-suppress useStlAlgorithm - std::transform is cumbersome priorities.emplace(l, prio--); } priorities["lib/valueflow.cpp"] = 1000; From 731ef86c9e1034336854ab858986c400941a9f0f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 19 Jun 2026 19:46:54 +0200 Subject: [PATCH 190/493] Fix #11861 Syntax Error: AST broken for C++20 ranges (#8644) Co-authored-by: chrchr-github --- lib/tokenlist.cpp | 2 ++ test/testtokenize.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index f98335badb7..5921621fed2 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1696,6 +1696,8 @@ static Token * createAstAtToken(Token *tok) tok->next()->astOperand1(tok); tok->next()->astOperand2(colon); + createAstAtTokenInner(colon, tok->linkAt(1), cpp); + return decl; } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index e56ffa3d8bb..8a6a9353707 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6701,6 +6701,7 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("foria:( asize.(", testAst("for(decltype(a.size()) i:a);")); ASSERT_EQUALS("forec0{([,(:( fb.return", testAst("for (auto e : c(0, [](auto f) { return f->b; }));")); // #10802 ASSERT_EQUALS("forvar1{;;(", testAst("for(int var{1};;)")); // #12867 + ASSERT_EQUALS("forxg{([(:( si.return", testAst("for (auto [x] : g([](S s) { return s.i; })) {}")); // #11861 // for with initializer (c++20) ASSERT_EQUALS("forab=ca:;(", testAst("for(a=b;int c:a)")); From bf099d1d152456e3372e9301e2d4a821689b0ff3 Mon Sep 17 00:00:00 2001 From: Jonny Date: Sat, 20 Jun 2026 15:00:03 +0100 Subject: [PATCH 191/493] Fix #14854 (import project: Handle forced include files from compilation database projects) (#8641) --- .github/workflows/selfcheck.yml | 2 +- lib/cppcheck.cpp | 1 + lib/filesettings.h | 1 + lib/importproject.cpp | 5 +++++ test/testimportproject.cpp | 19 +++++++++++++++++++ 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 6bd87f9243f..6d100c4ddc8 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -121,7 +121,7 @@ jobs: - name: Self check (unusedFunction / no test / no gui) run: | - supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1666 --suppress=unusedFunction:lib/importproject.cpp:1690" + supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1671 --suppress=unusedFunction:lib/importproject.cpp:1695" ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs env: DISABLE_VALUEFLOW: 1 diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index b7ab1f99039..9a3e2e2a053 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -825,6 +825,7 @@ unsigned int CppCheck::check(const FileSettings &fs) else tempSettings.userDefines += fs.cppcheckDefines(); tempSettings.includePaths = fs.includePaths; + tempSettings.userIncludes.insert(tempSettings.userIncludes.end(), fs.forcedIncludes.cbegin(), fs.forcedIncludes.cend()); tempSettings.userUndefs.insert(fs.undefs.cbegin(), fs.undefs.cend()); if (fs.standard.find("++") != std::string::npos) tempSettings.standards.setCPP(fs.standard); diff --git a/lib/filesettings.h b/lib/filesettings.h index 183e38708fd..0b4f15dd7e1 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -148,6 +148,7 @@ struct CPPCHECKLIB FileSettings { } std::set undefs; std::list includePaths; + std::list forcedIncludes; // only used by clang mode std::list systemIncludePaths; std::string standard; diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 0bcda5a43bf..2d63fa8bbb7 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -149,6 +149,11 @@ void ImportProject::parseArgs(FileSettings &fs, const std::vector & continue; } + if (!(optArg = getOptArg({ "-include", "/FI", "-FI" }, i)).empty()) { + fs.forcedIncludes.push_back(std::move(optArg)); + continue; + } + if (!(optArg = getOptArg({ "-D", "/D" }, i)).empty()) { defs += optArg + ";"; continue; diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index 88ca2fe75b7..c9889445c3c 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -73,6 +73,7 @@ class TestImportProject : public TestFixture { TEST_CASE(importCompileCommands13); // #13333: duplicate file entries TEST_CASE(importCompileCommands14); // #14156 TEST_CASE(importCompileCommands15); // #14306 + TEST_CASE(importCompileCommandsForcedInclude); // -include / /FI force-include TEST_CASE(importCompileCommandsArgumentsSection); // Handle arguments section TEST_CASE(importCompileCommandsNoCommandSection); // gracefully handles malformed json TEST_CASE(importCompileCommandsDirectoryMissing); // 'directory' field missing @@ -436,6 +437,24 @@ class TestImportProject : public TestFixture { ASSERT_EQUALS("C:/Users/abcd/efg/hijk/path/123/", fs.includePaths.front()); } + void importCompileCommandsForcedInclude() const { // -include / /FI force-include + REDIRECT; + constexpr char json[] = + R"([{ + "file": "/x/a.c", + "directory": "/x", + "command": "cc -include prefix.h /FIplatform.h -c a.c" + }])"; + std::istringstream istr(json); + TestImporter importer; + ASSERT_EQUALS(true, importer.importCompileCommands(istr)); + ASSERT_EQUALS(1, importer.fileSettings.size()); + const FileSettings &fs = importer.fileSettings.front(); + ASSERT_EQUALS(2, fs.forcedIncludes.size()); + ASSERT_EQUALS("prefix.h", fs.forcedIncludes.front()); // gcc/clang -include + ASSERT_EQUALS("platform.h", fs.forcedIncludes.back()); // MSVC/clang-cl /FI + } + void importCompileCommandsArgumentsSection() const { REDIRECT; constexpr char json[] = "[ { \"directory\": \"/tmp/\"," From 30ec6e1970b3f113de2bc95865cf02ba5c2d8535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 20 Jun 2026 16:02:10 +0200 Subject: [PATCH 192/493] AUTHORS: Add JonnyPtn [skip ci] (#8666) --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 874ff59748b..b505b682708 100644 --- a/AUTHORS +++ b/AUTHORS @@ -206,6 +206,7 @@ Jonathan Clohessy Jonathan Haehne Jonathan Neuschäfer Jonathan Thackray +Jonny Paton José Martins Jose Roquette Joshua Beck From 907f9a46060151139eb909abf1bc414a336390cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 20 Jun 2026 18:44:08 +0200 Subject: [PATCH 193/493] Fix #14850 (Compilation fails on oraclelinux:8 (g++ 8.5.0 released in 2021)) (#8654) --- lib/checks.h | 2 +- lib/settings.cpp | 4 ++-- lib/settings.h | 14 ++++++++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/checks.h b/lib/checks.h index ec4a78c2008..9c053b81405 100644 --- a/lib/checks.h +++ b/lib/checks.h @@ -29,6 +29,6 @@ namespace CheckInstances { /** List of registered check classes. This is used by Cppcheck to run checks and generate documentation */ CPPCHECKLIB const std::list& get(); -}; +} #endif // checksH diff --git a/lib/settings.cpp b/lib/settings.cpp index 95d4c4e953b..c0539bbeaba 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -79,8 +79,8 @@ Settings::~Settings() = default; Settings::Settings(const Settings&) = default; Settings & Settings::operator=(const Settings &) = default; -Settings::Settings(Settings&&) noexcept = default; -Settings & Settings::operator=(Settings &&) noexcept = default; +Settings::Settings(Settings&&) CPPCHECK_NOEXCEPT = default; +Settings & Settings::operator=(Settings &&) CPPCHECK_NOEXCEPT = default; std::string Settings::loadCppcheckCfg(Settings& settings, Suppressions& suppressions, bool debug) { diff --git a/lib/settings.h b/lib/settings.h index 04ddb9adb9a..4a73f35039b 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -94,6 +94,16 @@ class SimpleEnableGroup { }; +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 9 +// Hack to workaround GCC bug. +// Details: https://trac.cppcheck.net/ticket/14850 +// seen on g++ before 10.x +#define CPPCHECK_NOEXCEPT +#else +#define CPPCHECK_NOEXCEPT noexcept +#endif + + /** * @brief This is just a container for general settings so that we don't need * to pass individual values to functions or constructors now or in the @@ -113,8 +123,8 @@ class CPPCHECKLIB WARN_UNUSED Settings { Settings(const Settings&); Settings& operator=(const Settings&); - Settings(Settings&&) noexcept; - Settings& operator=(Settings&&) noexcept; + Settings(Settings&&) CPPCHECK_NOEXCEPT; + Settings& operator=(Settings&&) CPPCHECK_NOEXCEPT; static std::string loadCppcheckCfg(Settings& settings, Suppressions& suppressions, bool debug = false); From 31222058d3a70f824c08f3b9f92381874800ffd8 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 20 Jun 2026 19:25:43 +0200 Subject: [PATCH 194/493] Refs #9173: Fix FN bufferAccessOutOfBounds (memset on array, &a[0]) (#8656) --- lib/checkbufferoverrun.cpp | 10 +++++++++- test/testbufferoverrun.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index d278208fcc3..8be9b508849 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -556,8 +556,16 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons { if (!bufTok->valueType()) return ValueFlow::Value(-1); - if (bufTok->isUnaryOp("&")) + + if (bufTok->isUnaryOp("&")) { bufTok = bufTok->astOperand1(); + if (Token::simpleMatch(bufTok, "[")) { + const Token* index = bufTok->astOperand2(); + if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0)) + return ValueFlow::Value(-1); + bufTok = bufTok->astOperand1(); + } + } const Variable *var = bufTok->variable(); if (!var || var->dimensions().empty()) { diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 23e55748ce6..1a03ca336f8 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -227,6 +227,7 @@ class TestBufferOverrun : public TestFixture { TEST_CASE(buffer_overrun_35); //#2304 TEST_CASE(buffer_overrun_36); TEST_CASE(buffer_overrun_37); + TEST_CASE(buffer_overrun_38); TEST_CASE(buffer_overrun_errorpath); TEST_CASE(buffer_overrun_bailoutIfSwitch); // ticket #2378 : bailoutIfSwitch TEST_CASE(buffer_overrun_function_array_argument); @@ -3507,6 +3508,39 @@ class TestBufferOverrun : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void buffer_overrun_38() { // #9173 + check("void f() {\n" + " int a[10];\n" + " memset(&a[0], 0, 20 * sizeof(int));\n" + "}\n" + "void g() {\n" + " int a[10];\n" + " memset(&a[0], 0, 10 * sizeof(int));\n" + "}\n" + "void h() {\n" + " int a[10];\n" + " memset(&a[5], 0, 5 * sizeof(int));\n" + "}\n" + "void i() {\n" + " int a[10][10];\n" + " memset(&a[0][0], 0, 100 * sizeof(int));\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[0] [bufferAccessOutOfBounds]\n", errout_str()); + + check("void f() {\n" + " int a[10];\n" + " memset(&a[5], 0, 10 * sizeof(int));\n" + "}\n" + "void g() {\n" + " int a[1][1];\n" + " memset(&a[0][0], 0, 10 * sizeof(int));\n" + "}\n"); + TODO_ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[5] [bufferAccessOutOfBounds]\n" + "[test.cpp:7:12]: (error) Buffer is accessed out of bounds: &a[0][0] [bufferAccessOutOfBounds]\n", + "", + errout_str()); + } + void buffer_overrun_errorpath() { setMultiline(); Settings s = settings0; From 49f7cd2853f9bc2f1d2c964a4c19addfdb776bf9 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 20 Jun 2026 19:26:39 +0200 Subject: [PATCH 195/493] Fix #14848 FP compareValueOutOfTypeRangeError and knownConditionTrueFalse with unsigned arithmetic (#8658) Co-authored-by: chrchr-github --- lib/vf_settokenvalue.cpp | 2 +- test/testvalueflow.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index fe94225083b..315f4a40129 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -613,7 +613,7 @@ namespace ValueFlow } // unary minus - else if (parent->isUnaryOp("-")) { + else if (parent->isUnaryOp("-") && !astIsUnsigned(parent)) { for (const Value &val : tok->values()) { if (!val.isIntValue() && !val.isFloatValue()) continue; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 247d2ae6012..8305a63bc56 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1269,6 +1269,12 @@ class TestValueFlow : public TestFixture { ASSERT_EQUALS(1U, values.size()); ASSERT_EQUALS(-10, values.back().intvalue); + code = "bool f(unsigned a) {\n" // #14848 + " bool x = -a < 1;\n" + " return x;\n" + "}"; + ASSERT_EQUALS(false, testValueOfXKnown(code, 3U, 1)); + // Logical and code = "void f(bool b) {\n" " bool x = false && b;\n" From d7bcdb595797b6f31504ad805a7dd795b6e52bb4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 22 Jun 2026 12:53:33 +0200 Subject: [PATCH 196/493] Fix #14809 FP syntaxError for typedef involving std::size_t (#8618) `size_t` is a platform type and will be simplified anyway, this is tested here: https://github.com/cppcheck-opensource/cppcheck/blob/e1053dba3b0988dc828d7a9c4b2a8f6c9866035b/test/testtokenize.cpp#L9012 --------- Co-authored-by: chrchr-github --- lib/token.cpp | 1 - test/testtoken.cpp | 17 ----------------- test/testtokenize.cpp | 2 ++ test/testvarid.cpp | 2 +- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index 2b30419b9df..7e19106e1b0 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -204,7 +204,6 @@ static const std::unordered_set stdTypes = { "bool" , "int" , "long" , "short" - , "size_t" , "void" , "wchar_t" , "signed" diff --git a/test/testtoken.cpp b/test/testtoken.cpp index 83a514eb963..92c111c810c 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -1059,7 +1059,6 @@ class TestToken : public TestFixture { standard_types.emplace_back("long"); standard_types.emplace_back("float"); standard_types.emplace_back("double"); - standard_types.emplace_back("size_t"); for (auto test_op = standard_types.cbegin(); test_op != standard_types.cend(); ++test_op) { auto tokensFrontBack = std::make_shared(); @@ -1484,13 +1483,6 @@ class TestToken : public TestFixture { tok.str("char"); // not treated as keyword in TokenList::isKeyword() assert_tok(&tok, Token::Type::eType, /*l=*/ false, /*std=*/ true); } - { - TokenList list_c{settingsDefault, Standards::Language::C}; - auto tokensFrontBack = std::make_shared(); - Token tok(list_c, std::move(tokensFrontBack)); - tok.str("size_t"); // not treated as keyword in TokenList::isKeyword() - assert_tok(&tok, Token::Type::eType, /*l=*/ false, /*std=*/ true); - } } void update_property_info_etype_cpp() const @@ -1502,21 +1494,12 @@ class TestToken : public TestFixture { tok.str("bool"); // not treated as keyword in TokenList::isKeyword() assert_tok(&tok, Token::Type::eType, /*l=*/ false, /*std=*/ true); } - { - TokenList list_cpp{settingsDefault, Standards::Language::CPP}; - auto tokensFrontBack = std::make_shared(); - Token tok(list_cpp, std::move(tokensFrontBack)); - tok.str("size_t"); - assert_tok(&tok, Token::Type::eType, /*l=*/ false, /*std=*/ true); - } } void update_property_info_replace() const // #13743 { auto tokensFrontBack = std::make_shared(); Token tok(list, std::move(tokensFrontBack)); - tok.str("size_t"); - assert_tok(&tok, Token::Type::eType, false, true); tok.str("long"); assert_tok(&tok, Token::Type::eType, false, true); } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 8a6a9353707..167d5411553 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -7893,6 +7893,8 @@ class TestTokenizer : public TestFixture { "}\n")); ignore_errout(); + + ASSERT_EQUALS(";", tokenizeAndStringify("typedef std::size_t size_t;\n")); // #14809 } diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 941b5812678..c8d16bc89a5 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -2841,7 +2841,7 @@ class TestVarID : public TestFixture { void varid_using() { // #3648 const char code[] = "using std::size_t;"; - const char expected[] = "1: using unsigned long ;\n"; + const char expected[] = "1: ;\n"; ASSERT_EQUALS(expected, tokenize(code)); } From d833b6b276af306ffdef18eda4199589ac26bb10 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:44:36 +0200 Subject: [PATCH 197/493] Fix #12520 FN mismatchingContainers/iterators3 with temporary containers and erase (#8665) --- lib/checkstl.cpp | 6 ++++-- test/teststl.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index f499bb03b91..3e08fe04ed6 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -637,12 +637,14 @@ void CheckStlImpl::iterators() void CheckStlImpl::mismatchingContainerIteratorError(const Token* containerTok, const Token* iterTok, const Token* containerTok2) { const std::string container(containerTok ? containerTok->expressionString() : std::string("v1")); + const std::string containerTemp(isTemporary(containerTok, &mSettings.library) ? " temporary " : " "); const std::string container2(containerTok2 ? containerTok2->expressionString() : std::string("v2")); + const std::string containerTemp2(isTemporary(containerTok2, &mSettings.library) ? " temporary " : " "); const std::string iter(iterTok ? iterTok->expressionString() : std::string("it")); reportError(containerTok, Severity::error, "mismatchingContainerIterator", - "Iterator '" + iter + "' referring to container '" + container2 + "' is used with container '" + container + "'.", + "Iterator '" + iter + "' referring to" + containerTemp2 + "container '" + container2 + "' is used with" + containerTemp + "container '" + container + "'.", CWE664, Certainty::normal); } @@ -884,7 +886,7 @@ void CheckStlImpl::mismatchingContainerIterator() const std::vector args = getArguments(ftok); const Library::Container * c = tok->valueType()->container; - const Library::Container::Action action = c->getAction(tok->strAt(2)); + const Library::Container::Action action = c->getAction(ftok->str()); const Token* iterTok = nullptr; if (action == Library::Container::Action::INSERT && args.size() == 2) { // Skip if iterator pair diff --git a/test/teststl.cpp b/test/teststl.cpp index b7a29b2a11a..35941f6422c 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -2345,6 +2345,15 @@ class TestStl : public TestFixture { " } \n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("std::string g1();\n" // #12520 + "const std::string& g2();\n" + "void f() {\n" + " g1().erase(g1().begin());\n" + " g2().erase(g2().begin());\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:7]: (error) Iterator 'g1().begin()' referring to temporary container 'g1()' is used with temporary container 'g1()'. [mismatchingContainerIterator]\n", + errout_str()); } void eraseIteratorOutOfBounds() { From ed596da1dc32b29d19573cae722e8fcb730c56c6 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:19:55 +0200 Subject: [PATCH 198/493] Fix #14817 FN constParameterPointer for constructor initializing array (regression) , add test for #11471 (#8637) Co-authored-by: chrchr-github --- lib/astutils.cpp | 2 ++ test/testother.cpp | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 8dfd03596d3..7af806508fd 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2592,6 +2592,8 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti if (const Variable* var = tok->variable()) { if (tok == var->nameToken() && (!var->isReference() || (var->isConst() && var->type() == tok1->type())) && (!var->isClass() || (var->valueType() && var->valueType()->container))) // const ref or passed to (copy) ctor return false; + if (var->isArray() && var->valueType() && var->valueType()->pointer == 0 && var->valueType()->isPrimitive()) + return false; } std::vector args = getArgumentVars(tok, argnr); diff --git a/test/testother.cpp b/test/testother.cpp index 4215a3b3449..1d69cf6763e 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4872,6 +4872,28 @@ class TestOther : public TestFixture { " return *p->cbegin();\n" "}\n"); ASSERT_EQUALS("[test.cpp:1:25]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); + + check("struct S {\n" // #14817 + " explicit S(int *a) : m{ a[0], a[1] } {}\n" + " int m[2];\n" + "}" + "struct T {\n" + " explicit T(int *a) : m{ &a[0], &a[1] } {}\n" + " int* m[2];\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:2:21]: (style) Parameter 'a' can be declared as pointer to const [constParameterPointer]\n", + errout_str()); + + check("class A {\n" // #11471 + "public:\n" + " A(const int& i, int) : m_i(&i) {}\n" + " const int* m_i;\n" + "};\n" + "A f(int& s) {\n" + " return A(s, 0);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6:10]: (style) Parameter 's' can be declared as reference to const [constParameterReference]\n", + errout_str()); } void constArray() { From a709c8664ee156fd0f3c5b286cc0eb58a3c15de9 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:39:23 +0200 Subject: [PATCH 199/493] Fix #14860 FP sizeofwithsilentarraypointer with std::array (#8661) --- lib/checksizeof.cpp | 2 +- test/testsizeof.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index b9c495733e0..2d9012078a6 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -87,7 +87,7 @@ void CheckSizeofImpl::checkSizeofForArrayParameter() } const Variable *var = varTok->variable(); - if (var && var->isArray() && var->isArgument() && !var->isReference()) + if (var && var->isArray() && var->isArgument() && !var->isReference() && !(var->isStlType() && var->getTypeName() == "std::array")) sizeofForArrayParameterError(tok); } } diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index 9337252f92c..f955242019f 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -334,6 +334,14 @@ class TestSizeof : public TestFixture { "}"); ASSERT_EQUALS("", errout_str()); + check("int f(std::array a) {\n" // #14860 + " return sizeof(a);\n" + "}\n" + "int g(std::string a[2]) {\n" + " return sizeof(a);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:12]: (warning) Using 'sizeof' on array given as function argument returns size of a pointer. [sizeofwithsilentarraypointer]\n", + errout_str()); } void sizeofForNumericParameter() { From e0014e1b023442e9c0e15609658a910c41436356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Tue, 23 Jun 2026 08:58:20 +0200 Subject: [PATCH 200/493] fixed some `-Wsign-compare` compiler warnings (#8280) --- lib/analyzerinfo.cpp | 2 +- lib/analyzerinfo.h | 2 +- lib/check64bit.cpp | 12 ++++++------ lib/checkbufferoverrun.cpp | 4 ++-- lib/checkclass.cpp | 6 +++--- lib/checkfunctions.cpp | 2 +- lib/checkleakautovar.cpp | 2 +- lib/checknullpointer.cpp | 6 +++--- lib/checkother.cpp | 12 ++++++------ lib/checkother.h | 2 +- lib/checkstl.cpp | 8 ++++---- lib/clangimport.cpp | 10 +++++----- lib/ctu.cpp | 18 +++++++++--------- lib/ctu.h | 10 +++++----- lib/errorlogger.h | 2 +- lib/fwdanalysis.cpp | 4 ++-- lib/programmemory.cpp | 2 +- lib/reverseanalyzer.cpp | 2 +- lib/symboldatabase.cpp | 18 +++++++++--------- lib/symboldatabase.h | 12 ++++++------ lib/templatesimplifier.cpp | 6 +++--- lib/token.cpp | 6 +++--- lib/valueflow.cpp | 4 ++-- 23 files changed, 76 insertions(+), 76 deletions(-) diff --git a/lib/analyzerinfo.cpp b/lib/analyzerinfo.cpp index 6f919ec3651..36803b897b1 100644 --- a/lib/analyzerinfo.cpp +++ b/lib/analyzerinfo.cpp @@ -126,7 +126,7 @@ std::string AnalyzerInformation::skipAnalysis(const tinyxml2::XMLDocument &analy return ""; } -std::string AnalyzerInformation::getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg, int fsFileId) +std::string AnalyzerInformation::getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg, size_t fsFileId) { std::string line; while (std::getline(filesTxt,line)) { diff --git a/lib/analyzerinfo.h b/lib/analyzerinfo.h index d2a83c747c3..75674a22f82 100644 --- a/lib/analyzerinfo.h +++ b/lib/analyzerinfo.h @@ -87,7 +87,7 @@ class CPPCHECKLIB AnalyzerInformation { protected: static std::string getFilesTxt(const std::list &sourcefiles, const std::list &fileSettings); - static std::string getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg, int fsFileId); + static std::string getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg, size_t fsFileId); static std::string skipAnalysis(const tinyxml2::XMLDocument &analyzerInfoDoc, std::size_t hash, std::list &errors); diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index 345d66d9846..174237eef5a 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -90,11 +90,11 @@ void Check64BitPortabilityImpl::pointerassignment() if (!returnType) continue; - if (retPointer && !returnType->typeScope && returnType->pointer == 0U) + if (retPointer && !returnType->typeScope && returnType->pointer == 0) returnIntegerError(tok); if (!retPointer) { - bool warn = returnType->pointer >= 1U; + bool warn = returnType->pointer >= 1; if (!warn) { const Token* tok2 = tok->astOperand1(); while (tok2 && tok2->isCast()) @@ -119,17 +119,17 @@ void Check64BitPortabilityImpl::pointerassignment() continue; // Assign integer to pointer.. - if (lhstype->pointer >= 1U && + if (lhstype->pointer >= 1 && !tok->astOperand2()->isNumber() && - rhstype->pointer == 0U && + rhstype->pointer == 0 && rhstype->originalTypeName.empty() && rhstype->type == ValueType::Type::INT && !isFunctionPointer(tok->astOperand1())) assignmentIntegerToAddressError(tok); // Assign pointer to integer.. - if (rhstype->pointer >= 1U && - lhstype->pointer == 0U && + if (rhstype->pointer >= 1 && + lhstype->pointer == 0 && lhstype->originalTypeName.empty() && lhstype->isIntegral() && lhstype->type >= ValueType::Type::CHAR && diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 8be9b508849..879ade5f21f 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -654,7 +654,7 @@ void CheckBufferOverrunImpl::bufferOverflow() if (!mSettings.library.hasminsize(tok)) continue; const std::vector args = getArguments(tok); - for (int argnr = 0; argnr < args.size(); ++argnr) { + for (size_t argnr = 0; argnr < args.size(); ++argnr) { if (!args[argnr]->valueType() || args[argnr]->valueType()->pointer == 0) continue; const std::vector *minsizes = mSettings.library.argminsizes(tok, argnr + 1); @@ -846,7 +846,7 @@ void CheckBufferOverrunImpl::argumentSize() // If argument is '%type% a[num]' then check bounds against num const Function *callfunc = tok->function(); const std::vector callargs = getArguments(tok); - for (nonneg int paramIndex = 0; paramIndex < callargs.size() && paramIndex < callfunc->argCount(); ++paramIndex) { + for (size_t paramIndex = 0; paramIndex < callargs.size() && paramIndex < callfunc->argCount(); ++paramIndex) { const Variable* const argument = callfunc->getArgumentVar(paramIndex); if (!argument || !argument->nameToken() || !argument->isArray()) continue; diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 7d3fa5c51ec..ce96849ca27 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2414,7 +2414,7 @@ bool CheckClassImpl::isMemberFunc(const Scope *scope, const Token *tok) for (const Function &func : scope->functionList) { if (func.name() == tok->str()) { const Token* tok2 = tok->tokAt(2); - int argsPassed = tok2->str() == ")" ? 0 : 1; + size_t argsPassed = tok2->str() == ")" ? 0 : 1; for (;;) { tok2 = tok2->nextArgument(); if (tok2) @@ -2511,9 +2511,9 @@ bool CheckClassImpl::checkConstFunc(const Scope *scope, const Function *func, Me if (const Function* f = funcTok->function()) { // check known function const std::vector args = getArguments(funcTok); - const auto argMax = std::min(args.size(), f->argCount()); + const auto argMax = std::min(args.size(), f->argCount()); - for (nonneg int argIndex = 0; argIndex < argMax; ++argIndex) { + for (size_t argIndex = 0; argIndex < argMax; ++argIndex) { const Variable* const argVar = f->getArgumentVar(argIndex); if (!argVar || ((argVar->isArrayOrPointer() || argVar->isReference()) && !(argVar->valueType() && argVar->valueType()->isConst(argVar->valueType()->pointer)))) { // argument might be modified diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index d04f9d9cc1d..23db248816d 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -116,7 +116,7 @@ void CheckFunctionsImpl::invalidFunctionUsage() continue; const Token * const functionToken = tok; const std::vector arguments = getArguments(tok); - for (int argnr = 1; argnr <= arguments.size(); ++argnr) { + for (size_t argnr = 1; argnr <= arguments.size(); ++argnr) { const Token * const argtok = arguments[argnr-1]; // check ... diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 2fd16e85eaa..9049d56e7ff 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -392,7 +392,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, }); }); if (hasOutParam) { - for (int i = 0; i < args.size(); i++) { + for (size_t i = 0; i < args.size(); i++) { if (!argChecks.count(i + 1)) continue; const ArgumentChecks argCheck = argChecks.at(i + 1); diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 9790f7f2724..ac56f19eb09 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -49,7 +49,7 @@ static const CWE CWE_INCORRECT_CALCULATION(682U); //--------------------------------------------------------------------------- -static bool checkNullpointerFunctionCallPlausibility(const Function* func, unsigned int arg) +static bool checkNullpointerFunctionCallPlausibility(const Function* func, size_t arg) { return !func || (func->argCount() >= arg && func->getArgumentVar(arg - 1) && func->getArgumentVar(arg - 1)->isPointer()); } @@ -61,7 +61,7 @@ std::list CheckNullPointerImpl::parseFunctionCall(const Token &tok const std::vector args = getArguments(&tok); std::list var; - for (int argnr = 1; argnr <= args.size(); ++argnr) { + for (size_t argnr = 1; argnr <= args.size(); ++argnr) { const Token *param = args[argnr - 1]; if ((!checkNullArg || library.isnullargbad(&tok, argnr)) && checkNullpointerFunctionCallPlausibility(tok.function(), argnr)) var.push_back(param); @@ -370,7 +370,7 @@ void CheckNullPointerImpl::nullConstantDereference() else if (Token::Match(tok->previous(), "::|. %name% (")) { const std::vector &args = getArguments(tok); - for (int argnr = 0; argnr < args.size(); ++argnr) { + for (size_t argnr = 0; argnr < args.size(); ++argnr) { const Token *argtok = args[argnr]; if (!argtok->hasKnownIntValue()) continue; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index a45dfdf672e..5ed3473c8a7 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3313,7 +3313,7 @@ static bool constructorTakesReference(const Scope * const classScope) { return std::any_of(classScope->functionList.begin(), classScope->functionList.end(), [&](const Function& constructor) { if (constructor.isConstructor()) { - for (int argnr = 0U; argnr < constructor.argCount(); argnr++) { + for (size_t argnr = 0U; argnr < constructor.argCount(); argnr++) { const Variable * const argVar = constructor.getArgumentVar(argnr); if (argVar && argVar->isReference()) { return true; @@ -4036,7 +4036,7 @@ void CheckOtherImpl::checkFuncArgNamesDifferent() std::vector declarations(function->argCount()); std::vector definitions(function->argCount()); const Token * decl = function->argDef->next(); - for (int j = 0; j < function->argCount(); ++j) { + for (size_t j = 0; j < function->argCount(); ++j) { // get the definition const Variable * variable = function->getArgumentVar(j); if (variable) { @@ -4064,11 +4064,11 @@ void CheckOtherImpl::checkFuncArgNamesDifferent() // check for different argument order if (warning) { bool order_different = false; - for (int j = 0; j < function->argCount(); ++j) { + for (size_t j = 0; j < function->argCount(); ++j) { if (!declarations[j] || !definitions[j] || declarations[j]->str() == definitions[j]->str()) continue; - for (int k = 0; k < function->argCount(); ++k) { + for (size_t k = 0; k < function->argCount(); ++k) { if (j != k && definitions[k] && declarations[j]->str() == definitions[k]->str()) { order_different = true; break; @@ -4082,7 +4082,7 @@ void CheckOtherImpl::checkFuncArgNamesDifferent() } // check for different argument names if (style && inconclusive) { - for (int j = 0; j < function->argCount(); ++j) { + for (size_t j = 0; j < function->argCount(); ++j) { const bool warn = (declarations[j] != nullptr) != (definitions[j] != nullptr) || (declarations[j] && definitions[j] && declarations[j]->str() != definitions[j]->str()); if (warn) @@ -4092,7 +4092,7 @@ void CheckOtherImpl::checkFuncArgNamesDifferent() } } -void CheckOtherImpl::funcArgNamesDifferent(const std::string & functionName, nonneg int index, +void CheckOtherImpl::funcArgNamesDifferent(const std::string & functionName, size_t index, const Token* declaration, const Token* definition) { std::list tokens = { declaration,definition }; diff --git a/lib/checkother.h b/lib/checkother.h index 7f21ffc00f8..759a4d23e7b 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -316,7 +316,7 @@ class CPPCHECKLIB CheckOtherImpl : public CheckImpl { void unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef); void unknownEvaluationOrder(const Token* tok, bool isUnspecifiedBehavior = false); void accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive); - void funcArgNamesDifferent(const std::string & functionName, nonneg int index, const Token* declaration, const Token* definition); + void funcArgNamesDifferent(const std::string & functionName, size_t index, const Token* declaration, const Token* definition); void funcArgOrderDifferent(const std::string & functionName, const Token * declaration, const Token * definition, const std::vector & declarations, const std::vector & definitions); void shadowError(const Token *shadows, const std::string &shadowsType, const Token *shadowed, const std::string &shadowedType); void knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value, const std::string &varexpr, bool isVariableExpressionHidden); diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 3e08fe04ed6..6c4e5a7a22c 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -830,7 +830,7 @@ void CheckStlImpl::mismatchingContainers() // Group args together by container std::map> containers; - for (int argnr = 1; argnr <= args.size(); ++argnr) { + for (size_t argnr = 1; argnr <= args.size(); ++argnr) { const Library::ArgumentChecks::IteratorInfo *i = mSettings.library.getArgIteratorInfo(ftok, argnr); if (!i) continue; @@ -1435,7 +1435,7 @@ void CheckStlImpl::eraseCheckLoopVar(const Scope &scope, const Variable *var) if (Token::Match(tok->astParent(), "=|return")) continue; // Iterator is invalid.. - int indentlevel = 0U; + int indentlevel = 0; const Token *tok2 = tok->link(); for (; tok2 != scope.bodyEnd; tok2 = tok2->next()) { if (tok2->str() == "{") { @@ -1443,7 +1443,7 @@ void CheckStlImpl::eraseCheckLoopVar(const Scope &scope, const Variable *var) continue; } if (tok2->str() == "}") { - if (indentlevel > 0U) + if (indentlevel > 0) --indentlevel; else if (Token::simpleMatch(tok2, "} else {")) tok2 = tok2->linkAt(2); @@ -3295,7 +3295,7 @@ void CheckStlImpl::knownEmptyContainer() if (args.empty()) continue; - for (int argnr = 1; argnr <= args.size(); ++argnr) { + for (size_t argnr = 1; argnr <= args.size(); ++argnr) { const Library::ArgumentChecks::IteratorInfo *i = mSettings.library.getArgIteratorInfo(tok, argnr); if (!i) continue; diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 417e94e8798..98c0e700d83 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -140,7 +140,7 @@ static std::vector splitString(const std::string &line) pos2 = line.find('\"', pos1+1); else if (line[pos1] == '\'') { pos2 = line.find('\'', pos1+1); - if (pos2 < static_cast(line.size()) - 3 && line.compare(pos2, 3, "\':\'", 0, 3) == 0) + if (pos2 < line.size() - 3 && line.compare(pos2, 3, "\':\'", 0, 3) == 0) pos2 = line.find('\'', pos2 + 3); } else { pos2 = pos1; @@ -357,7 +357,7 @@ namespace clangimport { /** * @throws InternalError thrown if index is out of bounds */ - AstNodePtr getChild(int c) { + AstNodePtr getChild(size_t c) { if (c >= children.size()) { std::ostringstream err; err << "ClangImport: AstNodePtr::getChild(" << c << ") out of bounds. children.size=" << children.size() << " " << nodeType; @@ -509,7 +509,7 @@ void clangimport::AstNode::dumpAst(int num, int indent) const for (const auto& tok: mExtTokens) std::cout << " " << tok; std::cout << std::endl; - for (int c = 0; c < children.size(); ++c) { + for (size_t c = 0; c < children.size(); ++c) { if (children[c]) children[c]->dumpAst(c, indent + 2); else @@ -1432,7 +1432,7 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList) function->nestedIn = nestedIn; function->argDef = par1; // Function arguments - for (int i = 0; i < children.size(); ++i) { + for (size_t i = 0; i < children.size(); ++i) { AstNodePtr child = children[i]; if (child->nodeType != ParmVarDecl) continue; @@ -1657,7 +1657,7 @@ void clangimport::parseClangAstDump(Tokenizer &tokenizer, std::istream &f) continue; } - const int level = (pos1 - 1) / 2; + const size_t level = (pos1 - 1) / 2; if (level == 0 || level > tree.size()) continue; diff --git a/lib/ctu.cpp b/lib/ctu.cpp index fee3acb85ae..feef065d3ac 100644 --- a/lib/ctu.cpp +++ b/lib/ctu.cpp @@ -280,11 +280,11 @@ std::list CTU::loadUnsafeUsageListFromXml(const tiny return ret; } -static int isCallFunction(const Scope *scope, int argnr, const Token *&tok) +static size_t isCallFunction(const Scope *scope, size_t argnr, const Token *&tok) { const Variable * const argvar = scope->function->getArgumentVar(argnr); if (!argvar->isPointer()) - return -1; + return 0; for (const Token *tok2 = scope->bodyStart; tok2 != scope->bodyEnd; tok2 = tok2->next()) { if (tok2->variable() != argvar) continue; @@ -306,7 +306,7 @@ static int isCallFunction(const Scope *scope, int argnr, const Token *&tok) tok = prev->previous(); return argnr2; } - return -1; + return 0; } @@ -330,7 +330,7 @@ const CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer) if (!tokFunction) continue; const std::vector args(getArguments(tok->previous())); - for (int argnr = 0; argnr < args.size(); ++argnr) { + for (size_t argnr = 0; argnr < args.size(); ++argnr) { const Token *argtok = args[argnr]; if (!argtok) continue; @@ -427,9 +427,9 @@ const CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer) } // Nested function calls - for (int argnr = 0; argnr < scopeFunction->argCount(); ++argnr) { + for (size_t argnr = 0; argnr < scopeFunction->argCount(); ++argnr) { const Token *tok; - const int argnr2 = isCallFunction(&scope, argnr, tok); + const size_t argnr2 = isCallFunction(&scope, argnr, tok); if (argnr2 > 0) { FileInfo::NestedCall nestedCall(tokenizer, scopeFunction, tok); nestedCall.myArgNr = argnr + 1; @@ -442,7 +442,7 @@ const CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer) return fileInfo; } -static std::vector> getUnsafeFunction(const Settings &settings, const Scope *scope, int argnr, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *value)) +static std::vector> getUnsafeFunction(const Settings &settings, const Scope *scope, size_t argnr, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *value)) { std::vector> ret; const Variable * const argvar = scope->function->getArgumentVar(argnr); @@ -487,7 +487,7 @@ std::list CTU::getUnsafeUsage(const Tokenizer &token const Function *const function = scope.function; // "Unsafe" functions unconditionally reads data before it is written.. - for (int argnr = 0; argnr < function->argCount(); ++argnr) { + for (size_t argnr = 0; argnr < function->argCount(); ++argnr) { for (const std::pair &v : getUnsafeFunction(settings, &scope, argnr, isUnsafeUsage)) { const Token *tok = v.first; const MathLib::bigint val = v.second.value; @@ -500,7 +500,7 @@ std::list CTU::getUnsafeUsage(const Tokenizer &token } static bool findPath(const std::string &callId, - nonneg int callArgNr, + size_t callArgNr, MathLib::bigint unsafeValue, CTU::FileInfo::InvalidValueType invalidValue, const std::map> &callsMap, diff --git a/lib/ctu.h b/lib/ctu.h index 60120064284..76baff21b9f 100644 --- a/lib/ctu.h +++ b/lib/ctu.h @@ -79,14 +79,14 @@ namespace CTU { struct UnsafeUsage { UnsafeUsage() = default; - UnsafeUsage(std::string myId, nonneg int myArgNr, std::string myArgumentName, Location location, MathLib::bigint value) + UnsafeUsage(std::string myId, size_t myArgNr, std::string myArgumentName, Location location, MathLib::bigint value) : myId(std::move(myId)) , myArgNr(myArgNr) , myArgumentName(std::move(myArgumentName)) , location(std::move(location)) , value(value) {} std::string myId; - nonneg int myArgNr{}; + size_t myArgNr{}; std::string myArgumentName; Location location; MathLib::bigint value{}; @@ -96,14 +96,14 @@ namespace CTU { class CallBase { public: CallBase() = default; - CallBase(std::string callId, int callArgNr, std::string callFunctionName, Location loc) + CallBase(std::string callId, size_t callArgNr, std::string callFunctionName, Location loc) : callId(std::move(callId)), callArgNr(callArgNr), callFunctionName(std::move(callFunctionName)), location(std::move(loc)) {} CallBase(const Tokenizer &tokenizer, const Token *callToken); virtual ~CallBase() = default; CallBase(const CallBase&) = default; std::string callId; - int callArgNr{}; + size_t callArgNr{}; std::string callFunctionName; Location location; protected: @@ -138,7 +138,7 @@ namespace CTU { bool loadFromXml(const tinyxml2::XMLElement *xmlElement); std::string myId; - nonneg int myArgNr{}; + size_t myArgNr{}; }; std::list functionCalls; diff --git a/lib/errorlogger.h b/lib/errorlogger.h index d739cb3fbf9..daf683bd0a3 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -88,7 +88,7 @@ class CPPCHECKLIB ErrorMessage { std::string stringify(bool addcolumn = false) const; unsigned int fileIndex; - int line; // negative value means "no line" + int line; // negative value means "no line" - TODO: actually 0 means no line - lines from simplecpp are unsigned unsigned int column; const std::string& getinfo() const { diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index ddcbbbd1fa9..07ba7cc2e59 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -289,7 +289,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * ftok = ftok->astParent(); if (ftok && Token::Match(ftok->previous(), "%name% (")) { const std::vector args = getArguments(ftok); - int argnr = 0; + size_t argnr = 0; while (argnr < args.size() && args[argnr] != parent) argnr++; if (argnr < args.size()) { @@ -469,7 +469,7 @@ bool FwdAnalysis::possiblyAliased(const Token *expr, const Token *startToken) co if (Token::Match(tok, "%name% (") && !Token::Match(tok, "if|while|for")) { // Is argument passed by reference? const std::vector args = getArguments(tok); - for (int argnr = 0; argnr < args.size(); ++argnr) { + for (size_t argnr = 0; argnr < args.size(); ++argnr) { if (!Token::Match(args[argnr], "%name%|.|::")) continue; if (tok->function() && tok->function()->getArgumentVar(argnr) && !tok->function()->getArgumentVar(argnr)->isReference() && !tok->function()->isConst()) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index e1f40de277e..b86ca2d8812 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1552,7 +1552,7 @@ namespace { return unknown(); const MathLib::bigint index = rhs.intvalue; if (index >= 0 && index < strValue.size()) - return ValueFlow::Value{strValue[static_cast(index)]}; + return ValueFlow::Value{strValue[index]}; if (index == strValue.size()) return ValueFlow::Value{}; } else if (Token::Match(expr, "%cop%") && expr->astOperand1() && expr->astOperand2()) { diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 4afd2556a24..38aea656bf0 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -204,7 +204,7 @@ namespace { void traverse(Token* start, const Token* end = nullptr) { if (start == end) return; - std::size_t i = start->index(); + nonneg int i = start->index(); for (Token* tok = start->previous(); succeeds(tok, end); tok = tok->previous()) { if (tok->index() >= i) throw InternalError(tok, "Cyclic reverse analysis."); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index ba5c31d1f47..14fc1b7cdf2 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2174,7 +2174,7 @@ namespace { { if (const Scope* scope = var->nameToken()->scope()) { auto it = std::find_if(scope->functionList.begin(), scope->functionList.end(), [&](const Function& function) { - for (nonneg int arg = 0; arg < function.argCount(); ++arg) { + for (size_t arg = 0; arg < function.argCount(); ++arg) { if (var == function.getArgumentVar(arg)) return true; } @@ -4537,7 +4537,7 @@ void SymbolDatabase::printXml(std::ostream &out) const outs += "/>\n"; else { outs += ">\n"; - for (unsigned int argnr = 0; argnr < function->argCount(); ++argnr) { + for (size_t argnr = 0; argnr < function->argCount(); ++argnr) { const Variable *arg = function->getArgumentVar(argnr); outs += " & matches) const +void Scope::findFunctionInBase(const Token* tok, size_t args, std::vector & matches) const { if (isClassOrStruct() && definedType && !definedType->derivedFrom.empty()) { const std::vector &derivedFrom = definedType->derivedFrom; @@ -7049,7 +7049,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const return; } - if (parent->str() == "[" && (!parent->isCpp() || parent->astOperand1() == tok) && valuetype.pointer > 0U && !Token::Match(parent->previous(), "[{,]")) { + if (parent->str() == "[" && (!parent->isCpp() || parent->astOperand1() == tok) && valuetype.pointer > 0 && !Token::Match(parent->previous(), "[{,]")) { const Token *op1 = parent->astOperand1(); while (op1 && op1->str() == "[") op1 = op1->astOperand1(); @@ -7061,7 +7061,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const setValueType(parent, vt); return; } - if (Token::Match(parent->tokAt(-1), "%name% (") && !parent->tokAt(-1)->isKeyword() && parent->astOperand1() == tok && valuetype.pointer > 0U) { + if (Token::Match(parent->tokAt(-1), "%name% (") && !parent->tokAt(-1)->isKeyword() && parent->astOperand1() == tok && valuetype.pointer > 0) { ValueType vt(valuetype); vt.pointer -= 1U; setValueType(parent, vt); @@ -7074,7 +7074,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const setValueType(parent, vt); return; } - if (parent->str() == "*" && !parent->astOperand2() && valuetype.pointer > 0U) { + if (parent->str() == "*" && !parent->astOperand2() && valuetype.pointer > 0) { ValueType vt(valuetype); vt.pointer -= 1U; setValueType(parent, vt); @@ -7107,7 +7107,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const return; } } - if (parent->str() == "*" && Token::simpleMatch(parent->astOperand2(), "[") && valuetype.pointer > 0U) { + if (parent->str() == "*" && Token::simpleMatch(parent->astOperand2(), "[") && valuetype.pointer > 0) { const Token *op1 = parent->astOperand2()->astOperand1(); while (op1 && op1->str() == "[") op1 = op1->astOperand1(); @@ -8714,7 +8714,7 @@ std::string ValueType::str() const } else if (type == ValueType::Type::SMART_POINTER && smartPointer) { ret += " smart-pointer(" + smartPointer->name + ")"; } - for (unsigned int p = 0; p < pointer; p++) { + for (nonneg int p = 0; p < pointer; p++) { ret += " *"; if (constness & (2 << p)) ret += " const"; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index a4a07fd2083..166f228ad99 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -767,14 +767,14 @@ class CPPCHECKLIB Function { std::string fullName() const; - nonneg int argCount() const { + size_t argCount() const { return argumentList.size(); } - nonneg int minArgCount() const { + size_t minArgCount() const { return argumentList.size() - initArgCount; } - const Variable* getArgumentVar(nonneg int num) const; - nonneg int initializedArgCount() const { + const Variable* getArgumentVar(size_t num) const; + size_t initializedArgCount() const { return initArgCount; } /** @@ -928,7 +928,7 @@ class CPPCHECKLIB Function { const Scope* functionScope{}; ///< scope of function body const Scope* nestedIn{}; ///< Scope the function is declared in std::list argumentList; ///< argument list, must remain list due to clangimport usage! - nonneg int initArgCount{}; ///< number of args with default values + size_t initArgCount{}; ///< number of args with default values FunctionType type = FunctionType::eFunction; ///< constructor, destructor, ... const Token* noexceptArg{}; ///< noexcept token const Token* throwArg{}; ///< throw token @@ -1209,7 +1209,7 @@ class CPPCHECKLIB Scope { */ bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; - void findFunctionInBase(const Token* tok, nonneg int args, std::vector & matches) const; + void findFunctionInBase(const Token* tok, size_t args, std::vector & matches) const; /** @brief initialize varlist */ void getVariableList(const Token *start, const Token *end); diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 2672e66c263..4051b05c204 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -2258,7 +2258,7 @@ void TemplateSimplifier::expandTemplate( Token::Match(tok3->next()->findClosingBracket(), ">|>>")) { const Token *closingBracket = tok3->next()->findClosingBracket(); if (Token::simpleMatch(closingBracket->next(), "&")) { - int num = 0; + size_t num = 0; const Token *par = tok3->next(); while (num < typeParametersInDeclaration.size() && par != closingBracket) { const std::string pattern("[<,] " + typeParametersInDeclaration[num]->str() + " [,>]"); @@ -3041,7 +3041,7 @@ bool TemplateSimplifier::matchSpecialization( declToken->isSigned() != instToken->isSigned() || declToken->isUnsigned() != instToken->isUnsigned() || declToken->isLong() != instToken->isLong()) { - int nr = 0; + size_t nr = 0; while (nr < templateParameters.size() && templateParameters[nr]->str() != declToken->str()) ++nr; @@ -3139,7 +3139,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( // locate template usage.. std::string::size_type numberOfTemplateInstantiations = mTemplateInstantiations.size(); - unsigned int recursiveCount = 0; + int recursiveCount = 0; bool instantiated = false; diff --git a/lib/token.cpp b/lib/token.cpp index 7e19106e1b0..d8b438c5073 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1330,10 +1330,10 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec std::string ret; - unsigned int lineNumber = mImpl->mLineNumber - (options.linenumbers ? 1U : 0U); + nonneg int lineNumber = mImpl->mLineNumber - (options.linenumbers ? 1 : 0); // cppcheck-suppress shadowFunction - TODO: fix this - unsigned int fileIndex = options.files ? ~0U : mImpl->mFileIndex; - std::map lineNumbers; + nonneg int fileIndex = options.files ? ~0U : mImpl->mFileIndex; + std::map lineNumbers; for (const Token *tok = this; tok != end; tok = tok->next()) { assert(tok && "end precedes token"); if (!tok) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index fb9f6dda7a1..9ff54a5c244 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2459,7 +2459,7 @@ static void valueFlowLifetimeFunction(Token *tok, const TokenList &tokenlist, Er const int returnContainer = settings.library.returnValueContainer(tok); if (returnContainer >= 0) { std::vector args = getArguments(tok); - for (int argnr = 1; argnr <= args.size(); ++argnr) { + for (size_t argnr = 1; argnr <= args.size(); ++argnr) { const Library::ArgumentChecks::IteratorInfo *i = settings.library.getArgIteratorInfo(tok, argnr); if (!i) continue; @@ -5758,7 +5758,7 @@ static void valueFlowFunctionDefaultParameter(const TokenList& tokenlist, const const Function* function = scope->function; if (!function) continue; - for (nonneg int arg = function->minArgCount(); arg < function->argCount(); arg++) { + for (size_t arg = function->minArgCount(); arg < function->argCount(); arg++) { const Variable* var = function->getArgumentVar(arg); if (var && var->hasDefault() && Token::Match(var->nameToken(), "%var% = %num%|%str%|%char%|%name% [,)]")) { const std::list &values = var->nameToken()->tokAt(2)->values(); From b587c7cf10ca5c1de8cdc00b8a55495fac1bda98 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 24 Jun 2026 08:19:23 +0200 Subject: [PATCH 201/493] Fix #14866 FP bufferAccessOutOfBounds with vector and gethostname() (#8667) Co-authored-by: chrchr-github --- lib/checkbufferoverrun.cpp | 2 +- test/testbufferoverrun.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 879ade5f21f..a98ba73429c 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -574,7 +574,7 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons return *value; } - if (!var || var->isPointer()) + if (!var || var->isPointer() || (astIsContainer(bufTok) && var->getTypeName() != "std::array")) return ValueFlow::Value(-1); const MathLib::bigint dim = std::accumulate(var->dimensions().cbegin(), var->dimensions().cend(), MathLib::bigint(1), [](MathLib::bigint i1, const Dimension &dim) { diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 1a03ca336f8..e1da77ccbfb 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3539,6 +3539,12 @@ class TestBufferOverrun : public TestFixture { "[test.cpp:7:12]: (error) Buffer is accessed out of bounds: &a[0][0] [bufferAccessOutOfBounds]\n", "", errout_str()); + + check("void f() {\n" // #14866 + " std::vector buf(25);\n" + " std::memset(&buf[0], 0, 25);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void buffer_overrun_errorpath() { From 6640a7ce56cd57a046907360fbbe320d2b1f5704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 24 Jun 2026 10:35:13 +0200 Subject: [PATCH 202/493] enabled `-Wshorten-64-to-32` Clang compiler warning (#8670) --- cmake/compileroptions.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/compileroptions.cmake b/cmake/compileroptions.cmake index aa7deb8552c..6343a8a5102 100644 --- a/cmake/compileroptions.cmake +++ b/cmake/compileroptions.cmake @@ -134,7 +134,6 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # TODO: fix and enable these warnings - or move to suppression list below add_compile_options_safe(-Wno-sign-conversion) add_compile_options_safe(-Wno-shadow-field-in-constructor) - add_compile_options_safe(-Wno-shorten-64-to-32) add_compile_options_safe(-Wno-implicit-int-conversion) add_compile_options_safe(-Wno-double-promotion) add_compile_options_safe(-Wno-shadow-field) From 887b5d2ff53031cc53ec76881caf27a6c74da005 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Thu, 25 Jun 2026 01:18:17 -0500 Subject: [PATCH 203/493] Fix issue 13682: false negative: nullPointerRedundantCheck (multiple conditions, regression) (#8669) Co-authored-by: Your Name --- .selfcheck_suppressions | 1 + lib/astutils.cpp | 4 -- lib/checkclass.cpp | 11 +++- lib/checkcondition.cpp | 2 +- lib/checkstl.cpp | 2 +- lib/forwardanalyzer.cpp | 2 +- lib/reverseanalyzer.cpp | 3 - lib/symboldatabase.cpp | 6 +- lib/tokenize.cpp | 2 +- lib/vf_analyzers.cpp | 30 +++++++-- test/testnullpointer.cpp | 134 +++++++++++++++++++++++++++++++++++++++ 11 files changed, 175 insertions(+), 22 deletions(-) diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index f21492e783a..402fdbeb75d 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -79,3 +79,4 @@ useStlAlgorithm:externals/simplecpp/simplecpp.cpp funcArgNamesDifferentUnnamed:externals/simplecpp/simplecpp.h missingMemberCopy:externals/simplecpp/simplecpp.h shadowFunction:externals/simplecpp/simplecpp.h +knownConditionTrueFalse:externals/simplecpp/simplecpp.cpp \ No newline at end of file diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 7af806508fd..8700d2d2cd9 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -495,8 +495,6 @@ bool isTemporary(const Token* tok, const Library* library, bool unknown) } return unknown; } - if (tok->isCast()) - return false; // Currying a function is unknown in cppcheck if (Token::simpleMatch(tok, "(") && Token::simpleMatch(tok->astOperand1(), "(")) return unknown; @@ -1543,8 +1541,6 @@ bool isUsedAsBool(const Token* const tok, const Settings& settings) return true; if (parent->isCast()) return !Token::simpleMatch(parent->astOperand1(), "dynamic_cast") && isUsedAsBool(parent, settings); - if (parent->isUnaryOp("*")) - return isUsedAsBool(parent, settings); if (Token::Match(parent, "==|!=") && tok->valueType() && tok->valueType()->pointer && tok->astSibling()->hasKnownIntValue() && tok->astSibling()->getKnownIntValue() == 0) return true; diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index ce96849ca27..b610e963d76 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -3452,9 +3452,14 @@ void CheckClassImpl::checkUselessOverride() if (isSameCode) { // bailout for shadowed members - if (!classScope->definedType || - !getDuplInheritedMembersRecursive(classScope->definedType, classScope->definedType, /*skipPrivate*/ false).empty() || - !getDuplInheritedMemberFunctionsRecursive(classScope->definedType, classScope->definedType, /*skipPrivate*/ false).empty()) + if (!getDuplInheritedMembersRecursive(classScope->definedType, + classScope->definedType, + /*skipPrivate*/ false) + .empty() || + !getDuplInheritedMemberFunctionsRecursive(classScope->definedType, + classScope->definedType, + /*skipPrivate*/ false) + .empty()) continue; uselessOverrideError(baseFunc, &func, true); continue; diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 72b61fd68b9..e77641f89e7 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -455,7 +455,7 @@ bool CheckConditionImpl::isOverlappingCond(const Token * const cond1, const Toke if (!num1->isNumber() || MathLib::isNegative(num1->str())) return false; - if (!Token::Match(cond2, "&|==") || !cond2->astOperand1() || !cond2->astOperand2()) + if (!Token::Match(cond2, "&|==") || !cond2->astOperand1()) return false; const Token *expr2 = cond2->astOperand1(); const Token *num2 = cond2->astOperand2(); diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 6c4e5a7a22c..6d97dffe3d2 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -549,7 +549,7 @@ void CheckStlImpl::iterators() } // Not different containers if a reference is used.. - if (containerToken && containerToken->variable() && containerToken->variable()->isReference()) { + if (containerToken->variable() && containerToken->variable()->isReference()) { const Token *nameToken = containerToken->variable()->nameToken(); if (Token::Match(nameToken, "%name% =")) { const Token *name1 = nameToken->tokAt(2); diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 0999a08d908..670db0b1090 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -782,7 +782,7 @@ namespace { } else if (thenBranch.check) { return Break(); } else { - if (analyzer->isConditional() && stopUpdates()) + if (stopOnCondition(condTok) && stopUpdates()) return Break(Analyzer::Terminate::Conditional); analyzer->assume(condTok, false); } diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 38aea656bf0..0c3c966f2b2 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -340,9 +340,6 @@ namespace { valueFlowGenericForward(condTok, analyzer, tokenlist, errorLogger, settings); else if (condAction.isRead()) break; - // If the condition modifies the variable then bail - if (condAction.isModified()) - break; tok = jumpToStart(tok->link()); continue; } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 14fc1b7cdf2..231a8ce009c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1043,10 +1043,8 @@ void SymbolDatabase::createSymbolDatabaseNeedInitialization() scope.definedType->needInitialization = Type::NeedInitialization::True; else if (!unknown) scope.definedType->needInitialization = Type::NeedInitialization::False; - else { - if (scope.definedType->needInitialization == Type::NeedInitialization::Unknown) - unknowns++; - } + else + unknowns++; } } else if (scope.type == ScopeType::eUnion && scope.definedType->needInitialization == Type::NeedInitialization::Unknown) scope.definedType->needInitialization = Type::NeedInitialization::True; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index a8f675bbc97..7379957804f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2711,7 +2711,7 @@ namespace { { Token *tok1 = tok; - if (tok1 && tok1->str() != nameToken->str()) + if (!tok1 || tok1->str() != nameToken->str()) return false; // skip this using diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index a50a3b1d4a4..10efc6d6f39 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -1198,18 +1198,40 @@ struct SingleValueFlowAnalyzer : ValueFlowAnalyzer { bool stopOnCondition(const Token* condTok) const override { - if (value.isNonValue()) - return false; if (value.isImpossible()) return false; - if (isConditional() && !value.isKnown()) + // lifetime values must keep flowing to properly track aliases + if (value.isLifetimeValue()) + return false; + // 'conditional' flag (uninit, or lowered after a modifying branch): may depend on a + // condition that doesn't mention the variable -> stop + if (value.conditional && !value.isKnown()) return true; - if (value.isSymbolicValue()) + if (value.isNonValue()) return false; + if (value.isSymbolicValue()) + return isConditional() && !value.isKnown(); + // conditional via the originating 'condition' (e.g. possible null after 'if (p && ...)'): only flow + // if the condition references the value, else a correlation we can't follow (e.g. + // 'bool ok = (p != nullptr); if (!ok)') could make a later deref safe -> stop + if (value.condition && !value.isKnown() && !conditionReferencesValue(condTok)) + return true; ConditionState cs = analyzeCondition(condTok); return cs.isUnknownDependent(); } + // Does the condition mention the tracked value, either directly or through a symbolic alias? + bool conditionReferencesValue(const Token* condTok) const + { + return findAstNode(condTok, [&](const Token* tok) { + if (match(tok)) + return true; + return std::any_of(tok->values().cbegin(), tok->values().cend(), [&](const ValueFlow::Value& v) { + return v.isSymbolicValue() && !v.isImpossible() && v.tokvalue && match(v.tokvalue); + }); + }) != nullptr; + } + bool updateScope(const Token* endBlock, bool /*modified*/) const override { const Scope* scope = endBlock->scope(); if (!scope) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 99ece1c57fc..369c04a2101 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -143,6 +143,8 @@ class TestNullPointer : public TestFixture { TEST_CASE(nullpointer103); TEST_CASE(nullpointer104); // #13881 TEST_CASE(nullpointer105); // #13861 + TEST_CASE(nullpointer106); // #13682 + TEST_CASE(nullpointer107); // #13682 (FP/FN cases around guards that depend on the pointer indirectly) TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 @@ -2966,6 +2968,138 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void nullpointer106() // #13682 + { + // An unrelated condition between the null check and the dereference must not stop the analysis + check("struct S {\n" + " bool b;\n" + " bool f() const;\n" + "};\n" + "void f(const S* p, const S* o) {\n" + " const S* p1 = p;\n" + " if (p1 && p1->f())\n" + " return;\n" + " if (p == o)\n" + " return;\n" + " if (p1->b) {}\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:7:9] -> [test.cpp:11:9]: (warning) Either the condition 'p1' is redundant or there is possible null pointer dereference: p1. [nullPointerRedundantCheck]\n", + errout_str()); + } + + void nullpointer107() // #13682 - guards that depend on the pointer indirectly + { + // cached null-check 'ok'; guard 'if (!ok)' is safe -> no FP + check("struct S { void g(); bool f() const; };\n" + "void f(S* p) {\n" + " bool ok = (p != nullptr);\n" + " if (p && p->f())\n" + " return;\n" + " if (!ok)\n" + " return;\n" + " p->g();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // unrelated bool guard -> conservative, no FP + check("struct S { void g(); bool f() const; };\n" + "void f(S* p, bool valid) {\n" + " S* p1 = p;\n" + " if (p1 && p1->f())\n" + " return;\n" + " if (!valid)\n" + " return;\n" + " p1->g();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // guard on a different pointer -> no FP + check("struct S { void g(); bool f() const; };\n" + "void f(S* p, S* q) {\n" + " S* p1 = p;\n" + " if (p1 && p1->f())\n" + " return;\n" + " if (!q)\n" + " return;\n" + " p1->g();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // direct null guard on the alias -> no FP + check("struct S { void g(); bool f() const; };\n" + "void f(S* p) {\n" + " S* p1 = p;\n" + " if (p1 && p1->f())\n" + " return;\n" + " if (!p)\n" + " return;\n" + " p1->g();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // FN: 'if (ok)' => survivor has p==nullptr, but the cached 'ok' is not followed -> should warn + check("struct S { void g(); bool f() const; };\n" + "void f(S* p) {\n" + " bool ok = (p != nullptr);\n" + " if (p && p->f())\n" + " return;\n" + " if (ok)\n" + " return;\n" + " p->g();\n" + "}\n"); + TODO_ASSERT_EQUALS( + "[test.cpp:4:9] -> [test.cpp:8:5]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", + "", + errout_str()); + + // FN: sink(q) drops the q==p symbolic, so guard 'if (q)' is no longer seen to relate to p -> should warn + check("struct S { void g(); bool f() const; };\n" + "void sink(S*&);\n" + "void f(S* p) {\n" + " S* q = p;\n" + " if (p && p->f())\n" + " return;\n" + " sink(q);\n" + " if (q)\n" + " return;\n" + " p->g();\n" + "}\n"); + TODO_ASSERT_EQUALS( + "[test.cpp:5:9] -> [test.cpp:10:5]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", + "", + errout_str()); + + // a conditional modification makes ProgramMemory drop the guard (FP-prone) -> must stay quiet: + // alias 'q==p' re-assigned to p under a condition + check("struct S { void g(); bool f() const; };\n" + "void f(S* p, bool c) {\n" + " S* q = p;\n" + " if (p && p->f())\n" + " return;\n" + " if (c)\n" + " q = p;\n" + " if (!q)\n" + " return;\n" + " p->g();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // cached 'ok' refreshed under a condition + check("struct S { void g(); bool f() const; };\n" + "void f(S* p, bool c) {\n" + " bool ok = (p != nullptr);\n" + " if (p && p->f())\n" + " return;\n" + " if (c)\n" + " ok = (p != nullptr);\n" + " if (!ok)\n" + " return;\n" + " p->g();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void nullpointer_addressOf() { // address of check("void f() {\n" " struct X *x = 0;\n" From d8eaa524f24c9269bab520ad187decdc6a58c5a9 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:15:49 +0200 Subject: [PATCH 204/493] Fix #13678 FN constParameterPointer (calling const function on struct member) (#8624) --- lib/checkother.cpp | 13 ++++++++----- lib/checkunusedvar.cpp | 4 ++-- test/testother.cpp | 12 ++++++++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 5ed3473c8a7..21657cfd9fd 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1945,13 +1945,16 @@ void CheckOtherImpl::checkConstPointer() if (deref == MEMBER) { if (!gparent) continue; - if (parent->astOperand2()) { - if (parent->astOperand2()->function() && parent->astOperand2()->function()->isConst()) + const Token* funcParent = parent; + while (Token::simpleMatch(funcParent->astParent(), ".")) + funcParent = funcParent->astParent(); + if (funcParent->astOperand2()) { + if (funcParent->astOperand2()->function() && funcParent->astOperand2()->function()->isConst()) continue; - if (mSettings.library.isFunctionConst(parent->astOperand2())) + if (mSettings.library.isFunctionConst(funcParent->astOperand2())) continue; - if (parent->astOperand2()->varId()) { - if (gparent->str() == "?" && astIsLHS(parent)) + if (funcParent->astOperand2()->varId()) { + if (gparent->str() == "?" && astIsLHS(funcParent)) continue; } } diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 8ed249f05e2..fe85260fc8d 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -249,7 +249,7 @@ void Variables::clearAliases(nonneg int varid) void Variables::eraseAliases(nonneg int varid) { - VariableUsage *usage = find(varid); + const VariableUsage *usage = find(varid); if (usage) { for (auto aliases = usage->_aliases.cbegin(); aliases != usage->_aliases.cend(); ++aliases) @@ -329,7 +329,7 @@ void Variables::write(nonneg int varid, const Token* tok) void Variables::writeAliases(nonneg int varid, const Token* tok) { - VariableUsage *usage = find(varid); + const VariableUsage *usage = find(varid); if (usage) { for (auto aliases = usage->_aliases.cbegin(); aliases != usage->_aliases.cend(); ++aliases) { diff --git a/test/testother.cpp b/test/testother.cpp index 1d69cf6763e..b8134623a37 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4894,6 +4894,18 @@ class TestOther : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:6:10]: (style) Parameter 's' can be declared as reference to const [constParameterReference]\n", errout_str()); + + check("struct S { std::string a; };\n" // #13678 + "struct T { S s; };\n" + "bool f(S* s) {\n" + " return s->a.empty();\n" + "}\n" + "bool g(T* t) {\n" + " return t->s.a.empty();\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:11]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n" + "[test.cpp:6:11]: (style) Parameter 't' can be declared as pointer to const [constParameterPointer]\n", + errout_str()); } void constArray() { From b37e6b85e5b1655a6b379d0f76446fd940be4371 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:49:13 +0200 Subject: [PATCH 205/493] Add test for #13099 (#8674) --- test/testother.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/testother.cpp b/test/testother.cpp index b8134623a37..60323b3395b 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4906,6 +4906,14 @@ class TestOther : public TestFixture { ASSERT_EQUALS("[test.cpp:3:11]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:6:11]: (style) Parameter 't' can be declared as pointer to const [constParameterPointer]\n", errout_str()); + + check("struct S { int i; };\n" // #13099 + "double f(S * s, int n, int a, int b, double* p) {\n" + " return (s + (n * (a + 1) + b))->i / *(p + b);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:14]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n" + "[test.cpp:2:46]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", + errout_str()); } void constArray() { From 86f4c91741690386cd5917ccd8120624d9473ad5 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 26 Jun 2026 08:32:09 +0200 Subject: [PATCH 206/493] Fix #14864 FN knownConditionTrueFalse with default initialized user type pointer (#8672) --- lib/valueflow.cpp | 2 ++ test/testvalueflow.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 9ff54a5c244..f934d8496d6 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4099,6 +4099,8 @@ static bool isVariableInit(const Token *tok) return false; if (var->nameToken() != tok->astOperand1()) return false; + if (var->isPointer()) + return true; const ValueType* vt = var->valueType(); if (!vt) return false; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 8305a63bc56..7fa28855eb1 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3188,6 +3188,18 @@ class TestValueFlow : public TestFixture { " return x;\n" "}\n"; ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, -1)); + + code = "A* f() {\n" // #14864 + " A* x{};\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 0)); + + code = "A* f() {\n" + " A* x{ nullptr };\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 0)); } void valueFlowAfterSwap() From 7d5a54cc6e62c86fc38ae57e1834f45cce9709a3 Mon Sep 17 00:00:00 2001 From: Gilmar Santos Jr Date: Tue, 30 Jun 2026 13:30:12 -0300 Subject: [PATCH 207/493] Fix #14877: heap-use-after-free in Tokenizer::simplifyUsing() (#8679) In a large codebase, constructs like `using C = struct C { C() {} };` lead to errors such as `Code.cpp:0:0: error: Bailing out from analysis: Checking file failed: out of memory [internalError]`. When compiling cppcheck using clang 22's address sanitizer, the analysis terminates with the following messages: ``` ================================================================= ==1390963==ERROR: AddressSanitizer: heap-use-after-free on address 0x7c985f8ff900 at pc 0x55dcbe530972 bp 0x7ffd79cf5010 sp 0x7ffd79cf5008 READ of size 8 at 0x7c985f8ff900 thread T0 #0 0x55dcbe530971 in std::__cxx11::basic_string, std::allocator>::size() const /usr/include/c++/bits/basic_string.h:1165:19 #1 0x55dcbe53c624 in std::__cxx11::basic_string, std::allocator>::length() const /usr/include/c++/bits/basic_string.h:1176:16 #2 0x55dcbe54f8d6 in std::__cxx11::basic_string, std::allocator>::_M_assign(std::__cxx11::basic_string, std::allocator> const&) /usr/include/c++/bits/basic_string.tcc:313:36 #3 0x55dcbe54f7f0 in std::__cxx11::basic_string, std::allocator>::assign(std::__cxx11::basic_string, std::allocator> const&) /usr/include/c++/bits/basic_string.h:1771:8 #4 0x55dcbe54f7bc in std::__cxx11::basic_string, std::allocator>::operator=(std::__cxx11::basic_string, std::allocator> const&) /usr/include/c++/bits/basic_string.h:906:15 #5 0x55dcbe635d19 in Tokenizer::simplifyUsing() ./src/cppcheck/lib/tokenize.cpp:3214:32 #6 0x55dcbe6470b3 in Tokenizer::simplifyTokenList1(char const*) ./src/cppcheck/lib/tokenize.cpp:5910:12 #7 0x55dcbe643cb8 in Tokenizer::simplifyTokens1(std::__cxx11::basic_string, std::allocator> const&, int) ./src/cppcheck/lib/tokenize.cpp:3527:14 #8 0x55dcbedb37e7 in CppCheck::checkInternal(FileWithDetails const&, std::__cxx11::basic_string, std::allocator> const&, std::function, std::allocator>, std::allocator, std::allocator>>>&, std::__cxx11::list>*)> const&) ./src/cppcheck/lib/cppcheck.cpp:1203:32 #9 0x55dcbeda7bf4 in CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string, std::allocator> const&) ./src/cppcheck/lib/cppcheck.cpp:898:12 #10 0x55dcbeda7862 in CppCheck::check(FileWithDetails const&) ./src/cppcheck/lib/cppcheck.cpp:802:23 #11 0x55dcbf294ce0 in SingleExecutor::check() ./src/cppcheck/cli/singleexecutor.cpp:52:29 #12 0x55dcbf23cf66 in CppCheckExecutor::check_internal(Settings const&, Suppressions&) const ./src/cppcheck/cli/cppcheckexecutor.cpp:453:32 #13 0x55dcbf23c4fc in CppCheckExecutor::check_wrapper(Settings const&, Suppressions&) ./src/cppcheck/cli/cppcheckexecutor.cpp:295:12 #14 0x55dcbf23c1af in CppCheckExecutor::check(int, char const* const*) ./src/cppcheck/cli/cppcheckexecutor.cpp:280:21 #15 0x55dcbf23b67d in main ./src/cppcheck/cli/main.cpp:71:17 #16 0x7fe8606517e4 in __libc_start_main (/lib64/libc.so.6+0x3a7e4) (BuildId: b81415c1738806b536fb1599d7af2d15bf6a86b7) #17 0x55dcbe317bed in _start (./src/cppcheck/build/bin/cppcheck+0x4bbbed) 0x7c985f8ff900 is located 32 bytes inside of 112-byte region [0x7c985f8ff8e0,0x7c985f8ff950) freed by thread T0 here: #0 0x55dcbe4642ba in operator delete(void*) /usr/local/src/conda/compiler-rt-packages-22.1.8/compiler-rt/lib/asan/asan_new_delete.cpp:177:44 #1 0x55dcbf144bd0 in Token::deleteNext(int) ./src/cppcheck/lib/token.cpp:281:9 #2 0x55dcbf145e2d in Token::deleteThis() ./src/cppcheck/lib/token.cpp:360:9 #3 0x55dcbe634c84 in Tokenizer::simplifyUsing() ./src/cppcheck/lib/tokenize.cpp:3086:18 #4 0x55dcbe6470b3 in Tokenizer::simplifyTokenList1(char const*) ./src/cppcheck/lib/tokenize.cpp:5910:12 #5 0x55dcbe643cb8 in Tokenizer::simplifyTokens1(std::__cxx11::basic_string, std::allocator> const&, int) ./src/cppcheck/lib/tokenize.cpp:3527:14 #6 0x55dcbedb37e7 in CppCheck::checkInternal(FileWithDetails const&, std::__cxx11::basic_string, std::allocator> const&, std::function, std::allocator>, std::allocator, std::allocator>>>&, std::__cxx11::list>*)> const&) ./src/cppcheck/lib/cppcheck.cpp:1203:32 #7 0x55dcbeda7bf4 in CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string, std::allocator> const&) ./src/cppcheck/lib/cppcheck.cpp:898:12 #8 0x55dcbeda7862 in CppCheck::check(FileWithDetails const&) ./src/cppcheck/lib/cppcheck.cpp:802:23 #9 0x55dcbf294ce0 in SingleExecutor::check() ./src/cppcheck/cli/singleexecutor.cpp:52:29 #10 0x55dcbf23cf66 in CppCheckExecutor::check_internal(Settings const&, Suppressions&) const ./src/cppcheck/cli/cppcheckexecutor.cpp:453:32 #11 0x55dcbf23c4fc in CppCheckExecutor::check_wrapper(Settings const&, Suppressions&) ./src/cppcheck/cli/cppcheckexecutor.cpp:295:12 #12 0x55dcbf23c1af in CppCheckExecutor::check(int, char const* const*) ./src/cppcheck/cli/cppcheckexecutor.cpp:280:21 #13 0x55dcbf23b67d in main ./src/cppcheck/cli/main.cpp:71:17 #14 0x7fe8606517e4 in __libc_start_main (/lib64/libc.so.6+0x3a7e4) (BuildId: b81415c1738806b536fb1599d7af2d15bf6a86b7) previously allocated by thread T0 here: #0 0x55dcbe4638aa in operator new(unsigned long) /usr/local/src/conda/compiler-rt-packages-22.1.8/compiler-rt/lib/asan/asan_new_delete.cpp:109:35 #1 0x55dcbf14fb4a in Token::insertToken(std::__cxx11::basic_string, std::allocator> const&, bool) ./src/cppcheck/lib/token.cpp:1069:20 #2 0x55dcbe758b2e in Token::insertToken(std::__cxx11::basic_string, std::allocator> const&) ./src/cppcheck/lib/token.h:991:16 #3 0x55dcbf18de6e in TokenList::createTokens(simplecpp::TokenList&&) ./src/cppcheck/lib/tokenlist.cpp:392:37 #4 0x55dcbedc8c03 in CppCheck::checkInternal(FileWithDetails const&, std::__cxx11::basic_string, std::allocator> const&, std::function, std::allocator>, std::allocator, std::allocator>>>&, std::__cxx11::list>*)> const&)::$_2::operator()() const ./src/cppcheck/lib/cppcheck.cpp:1157:35 #5 0x55dcbedb9322 in void Timer::run, std::allocator> const&, std::function, std::allocator>, std::allocator, std::allocator>>>&, std::__cxx11::list>*)> const&)::$_2>(std::__cxx11::basic_string, std::allocator>, TimerResultsIntf*, CppCheck::checkInternal(FileWithDetails const&, std::__cxx11::basic_string, std::allocator> const&, std::function, std::allocator>, std::allocator, std::allocator>>>&, std::__cxx11::list>*)> const&)::$_2 const&) ./src/cppcheck/lib/timer.h:77:9 #6 0x55dcbedb2f65 in CppCheck::checkInternal(FileWithDetails const&, std::__cxx11::basic_string, std::allocator> const&, std::function, std::allocator>, std::allocator, std::allocator>>>&, std::__cxx11::list>*)> const&) ./src/cppcheck/lib/cppcheck.cpp:1152:17 #7 0x55dcbeda7bf4 in CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string, std::allocator> const&) ./src/cppcheck/lib/cppcheck.cpp:898:12 #8 0x55dcbeda7862 in CppCheck::check(FileWithDetails const&) ./src/cppcheck/lib/cppcheck.cpp:802:23 #9 0x55dcbf294ce0 in SingleExecutor::check() ./src/cppcheck/cli/singleexecutor.cpp:52:29 #10 0x55dcbf23cf66 in CppCheckExecutor::check_internal(Settings const&, Suppressions&) const ./src/cppcheck/cli/cppcheckexecutor.cpp:453:32 #11 0x55dcbf23c4fc in CppCheckExecutor::check_wrapper(Settings const&, Suppressions&) ./src/cppcheck/cli/cppcheckexecutor.cpp:295:12 #12 0x55dcbf23c1af in CppCheckExecutor::check(int, char const* const*) ./src/cppcheck/cli/cppcheckexecutor.cpp:280:21 #13 0x55dcbf23b67d in main ./src/cppcheck/cli/main.cpp:71:17 #14 0x7fe8606517e4 in __libc_start_main (/lib64/libc.so.6+0x3a7e4) (BuildId: b81415c1738806b536fb1599d7af2d15bf6a86b7) SUMMARY: AddressSanitizer: heap-use-after-free ./src/cppcheck/lib/tokenize.cpp:3214:32 in Tokenizer::simplifyUsing() Shadow bytes around the buggy address: 0x7c985f8ff680: fd fa fa fa fa fa fa fa fa fa fd fd fd fd fd fd 0x7c985f8ff700: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa 0x7c985f8ff780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa 0x7c985f8ff800: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00 0x7c985f8ff880: 00 00 00 fa fa fa fa fa fa fa fa fa fd fd fd fd =>0x7c985f8ff900:[fd]fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa 0x7c985f8ff980: fa fa fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x7c985f8ffa00: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x7c985f8ffa80: fd fd fd fd fd fd fa fa fa fa fa fa fa fa 00 00 0x7c985f8ffb00: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa 0x7c985f8ffb80: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==1390963==ABORTING ``` The proposed fix avoids storing a reference to a memory area that will eventually be deallocated before the reference is used. --- AUTHORS | 1 + lib/tokenize.cpp | 5 ++--- test/testsimplifyusing.cpp | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index b505b682708..19cbe734d2e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -156,6 +156,7 @@ Gerhard Zlabinger Gerik Rhoden Gianfranco Costamagna Gianluca Scacco +Gilmar Santos Jr Gleydson Soares Goncalo Mao-Cheia Goran Džaferi diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7379957804f..2d248f2cbd2 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3015,7 +3015,6 @@ bool Tokenizer::simplifyUsing() Token::Match(tok->linkAt(2), "] ] = ::| %name%"))))) continue; - const std::string& name = tok->strAt(1); const Token *nameToken = tok->next(); std::string scope = currentScope->fullName; Token *usingStart = tok; @@ -3064,7 +3063,7 @@ bool Tokenizer::simplifyUsing() if (!hasName) { std::string newName; if (structEnd->strAt(2) == ";") - newName = name; + newName = nameToken->str(); else newName = "Unnamed" + std::to_string(mUnnamedCount++); TokenList::copyTokens(structEnd->next(), tok, start); @@ -3211,7 +3210,7 @@ bool Tokenizer::simplifyUsing() if (!isTypedefInfoAdded && Token::Match(tok1, "%name% (")) { isTypedefInfoAdded = true; TypedefInfo usingInfo; - usingInfo.name = name; + usingInfo.name = nameToken->str(); usingInfo.filename = list.file(nameToken); usingInfo.lineNumber = nameToken->linenr(); usingInfo.column = nameToken->column(); diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index 7359613510f..0d09fa37b12 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -98,6 +98,7 @@ class TestSimplifyUsing : public TestFixture { TEST_CASE(simplifyUsing10335); TEST_CASE(simplifyUsing10720); TEST_CASE(simplifyUsing13873); // function declaration + TEST_CASE(simplifyUsing14877); TEST_CASE(scopeInfo1); TEST_CASE(scopeInfo2); @@ -1667,6 +1668,12 @@ class TestSimplifyUsing : public TestFixture { ASSERT_EQUALS("namespace NS1 { void * f ( ) ; }", tok(code3)); } + void simplifyUsing14877() { + const char code[] = "using C = struct C { C() {} };"; + const char expected[] = "struct C { C ( ) { } } ;"; + ASSERT_EQUALS(expected, tok(code)); + } + void scopeInfo1() { const char code[] = "struct A {\n" " enum class Mode { UNKNOWN, ENABLED, NONE, };\n" From 7d0d721d489d0380ce5aefd67f3e64f5af8d9e2a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 1 Jul 2026 08:25:30 +0200 Subject: [PATCH 208/493] Fix #14876 Nullptr dereference in usingMatch() (#8678) Root cause is here: https://github.com/cppcheck-opensource/cppcheck/blob/86f4c91741690386cd5917ccd8120624d9473ad5/lib/tokenize.cpp#L3108 Co-authored-by: chrchr-github --- lib/tokenize.cpp | 3 +++ test/testsimplifyusing.cpp | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 2d248f2cbd2..b29e807b8b5 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2720,6 +2720,9 @@ namespace { return false; } + if (!tok->tokAt(-1)) + return false; + // skip other using with this name if (tok1->strAt(-1) == "using") { // fixme: this is wrong diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index 0d09fa37b12..160f80762a8 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -77,6 +77,7 @@ class TestSimplifyUsing : public TestFixture { TEST_CASE(simplifyUsing37); TEST_CASE(simplifyUsing38); TEST_CASE(simplifyUsing39); + TEST_CASE(simplifyUsing40); TEST_CASE(simplifyUsing8970); TEST_CASE(simplifyUsing8971); @@ -940,6 +941,13 @@ class TestSimplifyUsing : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void simplifyUsing40() { + const char code[] = "uint8_t f();\n" // #14876 + "using ::std::uint8_t;"; + const char expected[] = "uint8_t f ( ) ;"; + ASSERT_EQUALS(expected, tok(code)); + } + void simplifyUsing8970() { const char code[] = "using V = std::vector;\n" "struct A {\n" From 186a7a9eeccc2968d9730aa0b5bc2d189b9b953d Mon Sep 17 00:00:00 2001 From: William Jakobsson <50847546+wjakobsson@users.noreply.github.com> Date: Wed, 1 Jul 2026 15:01:54 +0200 Subject: [PATCH 209/493] Fix --premium-license CLI parsing problem with space in path (#8683) --- cli/cmdlineparser.cpp | 5 ++++- test/testcmdlineparser.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 1ad0863d96d..f2d2254f833 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -1159,7 +1159,10 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a if (!parseNumberArg(argv[i], 31, tmp, true)) return Result::Fail; } - mSettings.premiumArgs += "--" + p; + if (p.find(' ') != std::string::npos) + mSettings.premiumArgs += "\"--" + p + "\""; + else + mSettings.premiumArgs += "--" + p; if (isCodingStandard) { // All checkers related to the coding standard should be enabled. The coding standards // do not all undefined behavior or portability issues. diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 3b88e050f82..326b7ad613d 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -262,6 +262,7 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(premiumOptionsMetrics); TEST_CASE(premiumOptionsCertCIntPrecision); TEST_CASE(premiumOptionsLicenseFile); + TEST_CASE(premiumOptionsLicenseFilePathWithSpace); TEST_CASE(premiumOptionsInvalid1); TEST_CASE(premiumOptionsInvalid2); TEST_CASE(premiumSafety); @@ -1642,6 +1643,14 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS("--license-file=file.lic", settings->premiumArgs); } + void premiumOptionsLicenseFilePathWithSpace() { + REDIRECT; + asPremium(); + const char * const argv[] = {"cppcheck", "--premium-license-file=license folder/file.lic", "file.c"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); + ASSERT_EQUALS("\"--license-file=license folder/file.lic\"", settings->premiumArgs); + } + void premiumOptionsInvalid1() { REDIRECT; asPremium(); From 47d4f68f5e9a1c2c86f48f9f06b430233cb9476f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 1 Jul 2026 22:21:59 +0200 Subject: [PATCH 210/493] Fix #12428 FN objectIndex when accessing struct member (#8676) --- lib/checkbufferoverrun.cpp | 6 ++++-- test/testbufferoverrun.cpp | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index a98ba73429c..496ca6905a1 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1086,9 +1086,11 @@ void CheckBufferOverrunImpl::objectIndex() std::vector values = ValueFlow::getLifetimeObjValues(obj, false, -1); for (const ValueFlow::Value& v:values) { - if (v.lifetimeKind != ValueFlow::Value::LifetimeKind::Address) + if (v.lifetimeKind != ValueFlow::Value::LifetimeKind::Address && v.lifetimeKind != ValueFlow::Value::LifetimeKind::Object) continue; - const Variable *var = v.tokvalue->variable(); + const Token* varTok = nextAfterAstRightmostLeaf(v.tokvalue->astParent()); + varTok = varTok ? varTok->previous() : nullptr; + const Variable *var = varTok ? varTok->variable() : nullptr; if (!var) continue; if (var->isReference()) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index e1da77ccbfb..e51a1708389 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -5857,7 +5857,9 @@ class TestBufferOverrun : public TestFixture { " (void)y[1];\n" " (void)y[2];\n" "}\n"); - TODO_ASSERT_EQUALS("error", "", errout_str()); + ASSERT_EQUALS("[test.cpp:7:20] -> [test.cpp:9:12]: (error) The address of variable 's.a' is accessed at non-zero index. [objectIndex]\n" + "[test.cpp:7:20] -> [test.cpp:10:12]: (error) The address of variable 's.a' is accessed at non-zero index. [objectIndex]\n", + errout_str()); } void checkPipeParameterSize() { // #3521 From 56a055d5ab0d28a47f65bd14893f8155f2735fa4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 1 Jul 2026 22:26:45 +0200 Subject: [PATCH 211/493] Refs #14859: Fix sizeof calculation for std::array (#8671) Co-authored-by: chrchr-github --- lib/symboldatabase.cpp | 14 +++++++++----- lib/vf_common.cpp | 10 ++++++++-- test/testvalueflow.cpp | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 231a8ce009c..bbf6cc8ce52 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -8476,7 +8476,7 @@ namespace { } template -static Result accumulateStructMembers(const Scope* scope, F f, ValueType::Accuracy accuracy) +static Result accumulateStructMembers(const Scope* scope, F f, ValueType::Accuracy accuracy, const Settings& settings) { size_t total = 0; std::set anonScopes; @@ -8495,6 +8495,10 @@ static Result accumulateStructMembers(const Scope* scope, F f, ValueType::Accura if (ret.second) total = f(total, *vt, dim, bits); } + else if (vt->container && vt->container->startPattern == "std :: array <") { + const ValueType vtElement = ValueType::parseDecl(vt->containerTypeToken, settings); + total = f(total, vtElement, dim, bits); + } else total = f(total, *vt, dim, bits); } @@ -8534,12 +8538,12 @@ static size_t getAlignOf(const ValueType& vt, const Settings& settings, ValueTyp size_t a = getAlignOf(vt2, settings, accuracy, ValueType::SizeOf::Pointer, ++maxRecursion); return std::max(max, a); }; - Result result = accumulateStructMembers(vt.typeScope, accHelper, accuracy); + Result result = accumulateStructMembers(vt.typeScope, accHelper, accuracy, settings); size_t total = result.total; if (const Type* dt = vt.typeScope->definedType) { total = std::accumulate(dt->derivedFrom.begin(), dt->derivedFrom.end(), total, [&](size_t v, const Type::BaseInfo& bi) { if (bi.type && bi.type->classScope) - v += accumulateStructMembers(bi.type->classScope, accHelper, accuracy).total; + v += accumulateStructMembers(bi.type->classScope, accHelper, accuracy, settings).total; return v; }); } @@ -8627,14 +8631,14 @@ size_t ValueType::getSizeOf( const Settings& settings, Accuracy accuracy, SizeOf } return typeScope->type == ScopeType::eUnion ? std::max(total, n) : total + padding + n; }; - Result result = accumulateStructMembers(typeScope, accHelper, accuracy); + Result result = accumulateStructMembers(typeScope, accHelper, accuracy, settings); size_t total = result.total; if (currentBitCount > 0) total += currentBitfieldAlloc; if (const ::Type* dt = typeScope->definedType) { total = std::accumulate(dt->derivedFrom.begin(), dt->derivedFrom.end(), total, [&](size_t v, const ::Type::BaseInfo& bi) { if (bi.type && bi.type->classScope) - v += accumulateStructMembers(bi.type->classScope, accHelper, accuracy).total; + v += accumulateStructMembers(bi.type->classScope, accHelper, accuracy, settings).total; return v; }); } diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index 56f928bcbd8..b4bd756d05e 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -165,7 +165,8 @@ namespace ValueFlow if (obj && !obj->isLiteral() && obj->valueType() && (obj->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions (obj->variable() && !obj->variable()->isArray())) && - !obj->valueType()->isEnum()) { // <- TODO this is a bailout, handle enum with non-int types + !obj->valueType()->isEnum() && // <- TODO this is a bailout, handle enum with non-int types + !(obj->valueType()->container && obj->valueType()->container->startPattern == "std :: array <")) { const auto ptrPointee = obj->valueType()->pointer > 0 ? ValueType::SizeOf::Pointer : ValueType::SizeOf::Pointee; const size_t sz = obj->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ptrPointee); if (sz) { @@ -246,7 +247,12 @@ namespace ValueFlow if (var->type()->classScope && var->type()->classScope->enumType) size = getSizeOfType(var->type()->classScope->enumType, settings); } else if (var->valueType()) { - size = var->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); + if (var->valueType()->container && var->valueType()->container->startPattern == "std :: array <") { + const ValueType vtElement = ValueType::parseDecl(var->valueType()->containerTypeToken, settings); + size = vtElement.getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); + } + else + size = var->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); } else if (!var->type()) { size = getSizeOfType(var->typeStartToken(), settings); } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 7fa28855eb1..c015664554a 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1812,6 +1812,20 @@ class TestValueFlow : public TestFixture { ASSERT_EQUALS(1U, values.size()); ASSERT_EQUALS(2 * settings.platform.sizeof_pointer, values.back().intvalue); ASSERT_EQUALS_ENUM(ValueFlow::Value::ValueKind::Known, values.back().valueKind); + + code = "struct S { std::array a; };\n" + "x = sizeof(S);\n"; + values = tokenValues(code, "( S"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(3 * settings.platform.sizeof_int, values.back().intvalue); + ASSERT_EQUALS_ENUM(ValueFlow::Value::ValueKind::Known, values.back().valueKind); + + code = "std::array a;\n" + "x = sizeof(a);\n"; + values = tokenValues(code, "( a"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(3 * settings.platform.sizeof_int, values.back().intvalue); + ASSERT_EQUALS_ENUM(ValueFlow::Value::ValueKind::Known, values.back().valueKind); } void valueFlowComma() From 9162aa7fb9d54b79e5abc0f3ebd441a2dfa7e7e5 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 2 Jul 2026 08:25:18 +0200 Subject: [PATCH 212/493] Fix #14878 fuzzing crash (null-pointer-use) in Tokenizer::simplifyUsing() (#8682) --- lib/tokenize.cpp | 2 ++ .../fuzz-crash/crash-42dad53b40278386e4ebd224813e26541cc725f1 | 1 + 2 files changed, 3 insertions(+) create mode 100644 test/cli/fuzz-crash/crash-42dad53b40278386e4ebd224813e26541cc725f1 diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b29e807b8b5..61719f5291d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3470,6 +3470,8 @@ bool Tokenizer::simplifyUsing() skip = true; simplifyUsingError(usingStart, usingEnd); } + if (!after) + syntaxError(tok1); tok1 = after->previous(); } diff --git a/test/cli/fuzz-crash/crash-42dad53b40278386e4ebd224813e26541cc725f1 b/test/cli/fuzz-crash/crash-42dad53b40278386e4ebd224813e26541cc725f1 new file mode 100644 index 00000000000..3a9abbf229f --- /dev/null +++ b/test/cli/fuzz-crash/crash-42dad53b40278386e4ebd224813e26541cc725f1 @@ -0,0 +1 @@ +using C=C*;C{{}} From 449ee2413ae26b1c31c28752efa7b2e1636ac8a5 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 2 Jul 2026 08:28:11 +0200 Subject: [PATCH 213/493] Fix #13944 FN constParameterPointer in method in derived class (#8673) https://github.com/cppcheck-opensource/cppcheck/pull/8240 seems to have stalled. Co-authored-by: ceJce --------- Co-authored-by: chrchr-github --- lib/checkother.cpp | 18 +++++++++++++----- lib/checkother.h | 2 +- test/testother.cpp | 12 ++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 21657cfd9fd..9dee8df7810 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2033,8 +2033,11 @@ void CheckOtherImpl::checkConstPointer() nonConstPointers.emplace(var); } for (const Variable *p: pointers) { + bool foundAllBaseClasses = true; if (p->isArgument()) { - if (!p->scope() || !p->scope()->function || p->scope()->function->isImplicitlyVirtual(true) || p->scope()->function->hasVirtualSpecifier()) + if (!p->scope() || !p->scope()->function || p->scope()->function->hasVirtualSpecifier()) + continue; + if (p->scope()->function->isImplicitlyVirtual(true, &foundAllBaseClasses) && foundAllBaseClasses) continue; if (p->isMaybeUnused()) continue; @@ -2051,12 +2054,12 @@ void CheckOtherImpl::checkConstPointer() continue; if (p->typeStartToken() && p->typeStartToken()->isSimplifiedTypedef() && !(Token::simpleMatch(p->typeEndToken(), "*") && !p->typeEndToken()->isSimplifiedTypedef())) continue; - constVariableError(p, p->isArgument() ? p->scope()->function : nullptr); + constVariableError(p, p->isArgument() ? p->scope()->function : nullptr, foundAllBaseClasses); } } } -void CheckOtherImpl::constVariableError(const Variable *var, const Function *function) +void CheckOtherImpl::constVariableError(const Variable *var, const Function *function, bool foundAllBaseClasses) { if (!var) { reportError(nullptr, Severity::style, "constParameter", "Parameter 'x' can be declared with const"); @@ -2069,13 +2072,18 @@ void CheckOtherImpl::constVariableError(const Variable *var, const Function *fun return; } - const std::string vartype(var->isArgument() ? "Parameter" : "Variable"); + std::string vartype(var->isArgument() ? "Parameter" : "Variable"); const std::string& varname(var->name()); const std::string ptrRefArray = var->isArray() ? "const array" : (var->isPointer() ? "pointer to const" : "reference to const"); ErrorPath errorPath; std::string id = "const" + vartype; - std::string message = "$symbol:" + varname + "\n" + vartype + " '$symbol' can be declared as " + ptrRefArray; + std::string message = "$symbol:" + varname + "\n"; + if (!foundAllBaseClasses) { + message += "Either there is a missing override/final keyword, or the "; + vartype[0] = std::tolower(vartype[0]); + } + message += vartype + " '$symbol' can be declared as " + ptrRefArray; errorPath.emplace_back(var->nameToken(), message); if (var->isArgument() && function && function->functionPointerUsage) { errorPath.emplace_front(function->functionPointerUsage, "You might need to cast the function pointer here"); diff --git a/lib/checkother.h b/lib/checkother.h index 759a4d23e7b..caf9f4a9e57 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -275,7 +275,7 @@ class CPPCHECKLIB CheckOtherImpl : public CheckImpl { void suspiciousFloatingPointCastError(const Token *tok); void invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt); void passedByValueError(const Variable* var, bool inconclusive, bool isRangeBasedFor = false); - void constVariableError(const Variable *var, const Function *function); + void constVariableError(const Variable *var, const Function *function, bool foundAllBaseClasses = true); void constStatementError(const Token *tok, const std::string &type, bool inconclusive); void signedCharArrayIndexError(const Token *tok); void unknownSignCharArrayIndexError(const Token *tok); diff --git a/test/testother.cpp b/test/testother.cpp index 60323b3395b..fa6899cf543 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4914,6 +4914,18 @@ class TestOther : public TestFixture { ASSERT_EQUALS("[test.cpp:2:14]: (style) Parameter 's' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:2:46]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); + + check("struct S : U {\n" // #13944 + " void f(int* p) const {\n" + " if (m == p) {}\n" + " }\n" + " void g(int* p) final {\n" + " if (m == p) {}\n" + " }\n" + " int* m;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:2:17]: (style) Either there is a missing override/final keyword, or the parameter 'p' can be declared as pointer to const [constParameterPointer]\n", + errout_str()); } void constArray() { From 161dcc1bb1161d28884ad054819cc79f9bdb5d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 2 Jul 2026 08:57:39 +0200 Subject: [PATCH 214/493] checkstl.cpp: small `LoopAnalyzer` cleanup (#8659) - pass `Settings` by reference - cleaned up `LoopAnalyzer` access - removed unnessary condition from `LoopAnalyzer::findAlgo()` - small `LoopAnalyzer::findAlgo()` cleanup --- lib/checkstl.cpp | 97 +++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 6d97dffe3d2..4c3b51ac5db 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2869,26 +2869,25 @@ static bool isTernaryAssignment(const Token* assignTok, nonneg int loopVarId, no namespace { struct LoopAnalyzer { - const Token* bodyTok = nullptr; - const Token* loopVar = nullptr; - const Settings* settings = nullptr; - std::set varsChanged; - - explicit LoopAnalyzer(const Token* tok, const Settings* psettings) - : bodyTok(tok->linkAt(1)->next()), settings(psettings) + private: + const Token* mBodyTok; + const Token* mLoopVar{}; + const Settings& mSettings; + std::set mVarsChanged; + + public: + explicit LoopAnalyzer(const Token* tok, const Settings& settings) + : mBodyTok(tok->linkAt(1)->next()), mSettings(settings) { const Token* splitTok = tok->next()->astOperand2(); if (Token::simpleMatch(splitTok, ":") && splitTok->previous()->varId() != 0) { - loopVar = splitTok->previous(); + mLoopVar = splitTok->previous(); } if (valid()) { findChangedVariables(); } } - bool isLoopVarChanged() const { - return varsChanged.count(loopVar->varId()) > 0; - } - + private: bool isModified(const Token* tok) const { if (tok->variable() && tok->variable()->isConst()) @@ -2896,11 +2895,11 @@ namespace { int n = 1 + (astIsPointer(tok) ? 1 : 0); for (int i = 0; i < n; i++) { bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, i, *settings, &inconclusive)) + if (isVariableChangedByFunctionCall(tok, i, mSettings, &inconclusive)) return true; if (inconclusive) return true; - if (isVariableChanged(tok, i, *settings)) + if (isVariableChanged(tok, i, mSettings)) return true; } return false; @@ -2909,7 +2908,7 @@ namespace { template void findTokens(Predicate pred, F f) const { - for (const Token* tok = bodyTok; precedes(tok, bodyTok->link()); tok = tok->next()) { + for (const Token* tok = mBodyTok; precedes(tok, mBodyTok->link()); tok = tok->next()) { if (pred(tok)) f(tok); } @@ -2918,7 +2917,7 @@ namespace { template const Token* findToken(Predicate pred) const { - for (const Token* tok = bodyTok; precedes(tok, bodyTok->link()); tok = tok->next()) { + for (const Token* tok = mBodyTok; precedes(tok, mBodyTok->link()); tok = tok->next()) { if (pred(tok)) return tok; } @@ -2933,58 +2932,56 @@ namespace { } bool valid() const { - return bodyTok && loopVar; + return mBodyTok && mLoopVar; } + public: std::string findAlgo() const { if (!valid()) return ""; - bool loopVarChanged = isLoopVarChanged(); - if (!loopVarChanged && varsChanged.empty()) { - if (hasGotoOrBreak()) - return ""; - bool alwaysTrue = true; - bool alwaysFalse = true; - auto hasReturn = [](const Token* tok) { - return Token::simpleMatch(tok, "return"); - }; - findTokens(hasReturn, [&](const Token* tok) { - const Token* returnTok = tok->astOperand1(); - if (!returnTok || !returnTok->hasKnownIntValue() || !astIsBool(returnTok)) { - alwaysTrue = false; - alwaysFalse = false; - return; - } - (returnTok->getKnownIntValue() ? alwaysTrue : alwaysFalse) &= true; - (returnTok->getKnownIntValue() ? alwaysFalse : alwaysTrue) &= false; - }); - if (alwaysTrue == alwaysFalse) - return ""; - if (alwaysTrue) - return "std::any_of"; - return "std::all_of or std::none_of"; - } - return ""; + if (!mVarsChanged.empty()) + return ""; + if (hasGotoOrBreak()) + return ""; + bool alwaysTrue = true; + bool alwaysFalse = true; + const auto hasReturn = [](const Token* tok) { + return Token::simpleMatch(tok, "return"); + }; + findTokens(hasReturn, [&](const Token* tok) { + const Token* returnTok = tok->astOperand1(); + if (!returnTok || !returnTok->hasKnownIntValue() || !astIsBool(returnTok)) { + alwaysTrue = false; + alwaysFalse = false; + return; + } + (returnTok->getKnownIntValue() ? alwaysTrue : alwaysFalse) &= true; + (returnTok->getKnownIntValue() ? alwaysFalse : alwaysTrue) &= false; + }); + if (alwaysTrue == alwaysFalse) + return ""; + if (alwaysTrue) + return "std::any_of"; + return "std::all_of or std::none_of"; } - + private: bool isLocalVar(const Variable* var) const { if (!var) return false; if (var->isPointer() || var->isReference()) return false; - if (var->declarationId() == loopVar->varId()) + if (var->declarationId() == mLoopVar->varId()) return false; const Scope* scope = var->scope(); - return scope && scope->isNestedIn(bodyTok->scope()); + return scope && scope->isNestedIn(mBodyTok->scope()); } - private: void findChangedVariables() { std::set vars; - for (const Token* tok = bodyTok; precedes(tok, bodyTok->link()); tok = tok->next()) { + for (const Token* tok = mBodyTok; precedes(tok, mBodyTok->link()); tok = tok->next()) { if (tok->varId() == 0) continue; if (vars.count(tok->varId()) > 0) @@ -2995,7 +2992,7 @@ namespace { } if (!isModified(tok)) continue; - varsChanged.insert(tok->varId()); + mVarsChanged.insert(tok->varId()); vars.insert(tok->varId()); } } @@ -3046,7 +3043,7 @@ void CheckStlImpl::useStlAlgorithm() continue; if (!Token::simpleMatch(tok->linkAt(1), ") {")) continue; - LoopAnalyzer a{tok, &mSettings}; + LoopAnalyzer a{tok, mSettings}; std::string algoName = a.findAlgo(); if (!algoName.empty()) { useStlAlgorithmError(tok, algoName); From ac061dac8a68c811300cf3c5201886a3c085e15f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 2 Jul 2026 14:36:20 +0200 Subject: [PATCH 215/493] Fix #14886 fuzzing crash (null-pointer-use) in SymbolDatabase::createSymbolDatabaseIncompleteVars() (#8685) --- lib/symboldatabase.cpp | 2 +- .../fuzz-crash/crash-60d6b7bc43d21f6a8ad8eb8cca551e45c31c6a32 | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test/cli/fuzz-crash/crash-60d6b7bc43d21f6a8ad8eb8cca551e45c31c6a32 diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index bbf6cc8ce52..b687c9f77a4 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1491,7 +1491,7 @@ void SymbolDatabase::createSymbolDatabaseEnums() void SymbolDatabase::createSymbolDatabaseIncompleteVars() { - for (Token* tok = mTokenizer.list.front(); tok != mTokenizer.list.back(); tok = tok->next()) { + for (Token* tok = mTokenizer.list.front(); precedes(tok, mTokenizer.list.back()); tok = tok->next()) { const Scope * scope = tok->scope(); if (!scope) continue; diff --git a/test/cli/fuzz-crash/crash-60d6b7bc43d21f6a8ad8eb8cca551e45c31c6a32 b/test/cli/fuzz-crash/crash-60d6b7bc43d21f6a8ad8eb8cca551e45c31c6a32 new file mode 100644 index 00000000000..4a60eb05b88 --- /dev/null +++ b/test/cli/fuzz-crash/crash-60d6b7bc43d21f6a8ad8eb8cca551e45c31c6a32 @@ -0,0 +1 @@ +ti(){using S}; From 3f2d60c4b72b5ab28ded6fc980341348643cc817 Mon Sep 17 00:00:00 2001 From: metsw24-max Date: Fri, 3 Jul 2026 12:52:50 +0530 Subject: [PATCH 216/493] Fix #14885 Shift by negative value in TemplateSimplifier::simplifyNumericalCalculations() (#8639) the value shift operators only reject a count >= bigint_bits, so MathLib::value::shiftLeft still left-shifts a negative value and both shiftLeft and shiftRight still shift by a negative count, which is undefined behaviour. it is reachable when folding a template argument like 0x8000000000000000 << 1 in simplifyNumericCalculations, since MathLib::isNegative only checks for a leading minus while a large hex literal parses to a negative bigint and the guard there lets it through. mirror the negative-operand check calculate.h already uses and return the operand unchanged, as is already done for oversized counts. ubsan flags the left shift at mathlib.cpp:272 on that input. --- AUTHORS | 1 + lib/mathlib.cpp | 4 ++-- test/testsimplifytemplate.cpp | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 19cbe734d2e..1a7543b0d93 100644 --- a/AUTHORS +++ b/AUTHORS @@ -369,6 +369,7 @@ Samuel Degrande Samuel Poláček Sandeep Dutta Savvas Etairidis +Sayed Kaif Scott Ehlert Scott Furry Seafarix Ltd. diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 403662f4df2..c7c055899fd 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -266,7 +266,7 @@ MathLib::value MathLib::value::shiftLeft(const MathLib::value &v) const if (!isInt() || !v.isInt()) throw InternalError(nullptr, "Shift operand is not integer"); MathLib::value ret(*this); - if (v.mIntValue >= MathLib::bigint_bits) { + if (v.mIntValue < 0 || v.mIntValue >= MathLib::bigint_bits || ret.mIntValue < 0) { return ret; } ret.mIntValue <<= v.mIntValue; @@ -278,7 +278,7 @@ MathLib::value MathLib::value::shiftRight(const MathLib::value &v) const if (!isInt() || !v.isInt()) throw InternalError(nullptr, "Shift operand is not integer"); MathLib::value ret(*this); - if (v.mIntValue >= MathLib::bigint_bits) { + if (v.mIntValue < 0 || v.mIntValue >= MathLib::bigint_bits) { return ret; } ret.mIntValue >>= v.mIntValue; diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index b28bc503869..6960b791426 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -320,6 +320,8 @@ class TestSimplifyTemplate : public TestFixture { TEST_CASE(templateArgPreserveType); // #13882 - type of template argument + TEST_CASE(template_shift_negative); // shift folding with a negative operand + TEST_CASE(dumpTemplateArgFrom); } @@ -6715,6 +6717,21 @@ class TestSimplifyTemplate : public TestFixture { tok(code)); } + void template_shift_negative() { + // a large hex literal is not negative as a string but parses to a negative + // bigint, so folding the shift in simplifyNumericCalculations would left-shift + // a negative value / shift by a negative count, both UB. the operand must be + // returned unchanged. parentheses are needed so the numeric folding is reached. + const char code[] = "template struct S { };\n" + "S<(0x8000000000000000 << 1)> s1;\n" + "S<(1 << 0x8000000000000000)> s2;\n" + "S<(1 >> 0x8000000000000000)> s3;"; + const char expected[] = "struct S<9223372036854775808U> ; struct S<1> ; " + "S<9223372036854775808U> s1 ; S<1> s2 ; S<1> s3 ; " + "struct S<9223372036854775808U> { } ; struct S<1> { } ;"; + ASSERT_EQUALS(expected, tok(code)); + } + void dumpTemplateArgFrom() { const char code[] = "template void foo(T t) {}\n" "foo(23);"; From ddab07631d6ef3ccff5dc4c93ae5ba8d3dd57c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Berder?= <18538310+francois-berder@users.noreply.github.com> Date: Fri, 3 Jul 2026 11:42:45 +0200 Subject: [PATCH 217/493] Fix #14826 valueflow: forward lifetimes through array and member subobjects (#8636) Signed-off-by: Francois Berder --- lib/valueflow.cpp | 39 ++++++++++++---- test/testautovariables.cpp | 93 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 8 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index f934d8496d6..7d25166bf99 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1952,6 +1952,35 @@ const Token* ValueFlow::getEndOfExprScope(const Token* tok, const Scope* default return end; } +static void getLhsLifetimeParentsImpl(const Token* lhs, const Library& library, std::vector& result) +{ + if (!lhs) + return; + + if (Token::simpleMatch(lhs, "[")) { + getLhsLifetimeParentsImpl(lhs->astOperand1(), library, result); + } else if (Token::simpleMatch(lhs, ".") && lhs->originalName() != "->") { + const Token* obj = lhs->astOperand1(); + if (Token::simpleMatch(obj, "[") && obj->exprId() > 0) + result.push_back(obj); + getLhsLifetimeParentsImpl(obj, library, result); + } else { + const Token* tok = getParentLifetime(lhs, library); + if (tok && tok->exprId() > 0) { + const Variable* var = tok->variable(); + if (!var || var->isLocal() || var->isArgument()) + result.push_back(tok); + } + } +} + +static std::vector getLhsLifetimeParents(const Token* lhs, const Library& library) +{ + std::vector result; + getLhsLifetimeParentsImpl(lhs, library, result); + return result; +} + static void valueFlowForwardLifetime(Token * tok, const TokenList &tokenlist, ErrorLogger &errorLogger, const Settings &settings) { // Forward lifetimes to constructed variable @@ -2004,14 +2033,8 @@ static void valueFlowForwardLifetime(Token * tok, const TokenList &tokenlist, Er if (val.lifetimeKind == ValueFlow::Value::LifetimeKind::Address) val.lifetimeKind = ValueFlow::Value::LifetimeKind::SubObject; } - // TODO: handle `[` - if (Token::simpleMatch(parent->astOperand1(), ".")) { - const Token* parentLifetime = - getParentLifetime(parent->astOperand1()->astOperand2(), settings.library); - if (parentLifetime && parentLifetime->exprId() > 0) { - valueFlowForward(nextExpression, endOfVarScope, parentLifetime, std::move(values), tokenlist, errorLogger, settings); - } - } + for (const Token *p : getLhsLifetimeParents(parent->astOperand1(), settings.library)) + valueFlowForward(nextExpression, endOfVarScope, p, values, tokenlist, errorLogger, settings); } // Constructor } else if (Token::simpleMatch(parent, "{") && !isScopeBracket(parent)) { diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 9fe3e126660..2867f147d81 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -4452,6 +4452,99 @@ class TestAutoVariables : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:5:14] -> [test.cpp:5:18] -> [test.cpp:6:7]: (error) Using pointer that is a temporary. [danglingTemporaryLifetime]\n", errout_str()); + + check("struct A { const int* data[2]; };\n" + "A g() {\n" + " int x = 0;\n" + " A a;\n" + " a.data[0] = &x;\n" + " return a;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:17] -> [test.cpp:3:9] -> [test.cpp:6:12]: (error) Returning object that points to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); + + check("struct A { const int* data[2]; };\n" + "A g() {\n" + " int x = 0;\n" + " A a[2];\n" + " a[0].data[0] = &x;\n" + " return a[0];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:20] -> [test.cpp:3:9] -> [test.cpp:6:13]: (error) Returning object that points to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); + + check("struct A { const int* data[2]; };\n" + "A* g() {\n" + " int x = 0;\n" + " static A arr[2];\n" + " arr[0].data[0] = &x;\n" + " return arr;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:22] -> [test.cpp:3:9] -> [test.cpp:6:12]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); + + check("struct A { const int* p; };\n" + "A g(int i) {\n" + " int x = 0;\n" + " A arr[2];\n" + " arr[i].p = &x;\n" + " return arr[i];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:16] -> [test.cpp:3:9] -> [test.cpp:6:15]: (error) Returning object that points to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); + + check("struct A { const int* p; };\n" + "A* g(int i) {\n" + " int x = 0;\n" + " static A arr[2];\n" + " arr[i].p = &x;\n" + " return arr;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:16] -> [test.cpp:3:9] -> [test.cpp:6:12]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); + + check("struct A { const int* p; };\n" + "struct B { A arr[2]; };\n" + "B g(int i) {\n" + " int x = 0;\n" + " B b;\n" + " b.arr[i].p = &x;\n" + " return b;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6:18] -> [test.cpp:4:9] -> [test.cpp:7:12]: (error) Returning object that points to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); + + check("struct A { const int* p; };\n" + "A* g() {\n" + " int x = 0;\n" + " static A a;\n" + " A* ap = &a;\n" + " ap->p = &x;\n" + " (*ap).p = &x;\n" + " return ap;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct A { int* a; int* b; };\n" + "static A g;\n" + "int* f() {\n" + " int x = 0;\n" + " g.a = &x;\n" + " return g.b;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:11] -> [test.cpp:4:9] -> [test.cpp:5:6]: (error) Non-local variable 'g.a' will use pointer to local variable 'x'. [danglingLifetime]\n", + errout_str()); + + check("struct A { int* a; int* b; };\n" + "static A g;\n" + "int* f() {\n" + " int x = 0;\n" + " g.a = &x;\n" + " return g.a;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:11] -> [test.cpp:4:9] -> [test.cpp:5:6]: (error) Non-local variable 'g.a' will use pointer to local variable 'x'. [danglingLifetime]\n" + "[test.cpp:5:11] -> [test.cpp:4:9] -> [test.cpp:6:13]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); } void danglingLifetimeClassMemberFunctions() From 04091bd597b5ec8bd2ee56f018cd628f9885d7c9 Mon Sep 17 00:00:00 2001 From: Robert Morin Date: Fri, 3 Jul 2026 05:48:23 -0400 Subject: [PATCH 218/493] Fix #14743 (New check: ftell() result is unspecified when file is opened in mode "t") (#8360) --- .gitignore | 1 + lib/checkio.cpp | 20 +++++++++++ lib/checkio.h | 1 + man/checkers/ftellTextModeFile.md | 56 +++++++++++++++++++++++++++++++ releasenotes.txt | 1 + test/testio.cpp | 17 ++++++++++ 6 files changed, 96 insertions(+) create mode 100644 man/checkers/ftellTextModeFile.md diff --git a/.gitignore b/.gitignore index 434203fe2a9..a821204bf2d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.gcno *.gch *.o +*.a *.pyc /cppcheck /cppcheck.exe diff --git a/lib/checkio.cpp b/lib/checkio.cpp index f632ca99e9e..c753dd80739 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -48,6 +48,7 @@ // CVE ID used: static const CWE CWE119(119U); // Improper Restriction of Operations within the Bounds of a Memory Buffer static const CWE CWE398(398U); // Indicator of Poor Code Quality +static const CWE CWE474(474U); // Use of Function with Inconsistent Implementations static const CWE CWE664(664U); // Improper Control of a Resource Through its Lifetime static const CWE CWE685(685U); // Function Call With Incorrect Number of Arguments static const CWE CWE686(686U); // Function Call With Incorrect Argument Type @@ -111,6 +112,8 @@ namespace { nonneg int op_indent{}; enum class AppendMode : std::uint8_t { UNKNOWN_AM, APPEND, APPEND_EX }; AppendMode append_mode = AppendMode::UNKNOWN_AM; + enum class ReadMode : std::uint8_t { READ_TEXT, READ_BIN }; + ReadMode read_mode = ReadMode::READ_BIN; std::string filename; explicit Filepointer(OpenMode mode_ = OpenMode::UNKNOWN_OM) : mode(mode_) {} @@ -183,6 +186,7 @@ void CheckIOImpl::checkFileUsage() } } else if (Token::Match(tok, "%name% (") && tok->previous() && (!tok->previous()->isName() || Token::Match(tok->previous(), "return|throw"))) { std::string mode; + bool isftell = false; const Token* fileTok = nullptr; const Token* fileNameTok = nullptr; Filepointer::Operation operation = Filepointer::Operation::NONE; @@ -266,6 +270,9 @@ void CheckIOImpl::checkFileUsage() fileTok = tok->tokAt(2); if ((tok->str() == "ungetc" || tok->str() == "ungetwc") && fileTok) fileTok = fileTok->nextArgument(); + else if (tok->str() == "ftell") { + isftell = true; + } operation = Filepointer::Operation::UNIMPORTANT; } else if (!Token::Match(tok, "if|for|while|catch|switch") && !mSettings.library.isFunctionConst(tok->str(), true)) { const Token* const end2 = tok->linkAt(1); @@ -321,10 +328,15 @@ void CheckIOImpl::checkFileUsage() f.append_mode = Filepointer::AppendMode::APPEND_EX; else f.append_mode = Filepointer::AppendMode::APPEND; + } + else if (mode.find('r') != std::string::npos && + mode.find('t') != std::string::npos) { + f.read_mode = Filepointer::ReadMode::READ_TEXT; } else f.append_mode = Filepointer::AppendMode::UNKNOWN_AM; f.mode_indent = indent; break; + case Filepointer::Operation::POSITIONING: if (f.mode == OpenMode::CLOSED) useClosedFileError(tok); @@ -357,6 +369,8 @@ void CheckIOImpl::checkFileUsage() case Filepointer::Operation::UNIMPORTANT: if (f.mode == OpenMode::CLOSED) useClosedFileError(tok); + if (isftell && f.read_mode == Filepointer::ReadMode::READ_TEXT && printPortability) + ftellFileError(tok); break; case Filepointer::Operation::UNKNOWN_OP: f.mode = OpenMode::UNKNOWN_OM; @@ -424,6 +438,12 @@ void CheckIOImpl::seekOnAppendedFileError(const Token *tok) "seekOnAppendedFile", "Repositioning operation performed on a file opened in append mode has no effect.", CWE398, Certainty::normal); } +void CheckIOImpl::ftellFileError(const Token *tok) +{ + reportError(tok, Severity::portability, + "ftellTextModeFile", "ftell() result is unspecified when file is opened in mode \"t\"", CWE474, Certainty::normal); +} + void CheckIOImpl::incompatibleFileOpenError(const Token *tok, const std::string &filename) { reportError(tok, Severity::warning, diff --git a/lib/checkio.h b/lib/checkio.h index dff49006bab..ae0ea242dab 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -128,6 +128,7 @@ class CPPCHECKLIB CheckIOImpl : public CheckImpl { void useClosedFileError(const Token *tok); void fcloseInLoopConditionError(const Token *tok, const std::string &varname); void seekOnAppendedFileError(const Token *tok); + void ftellFileError(const Token *tok); void incompatibleFileOpenError(const Token *tok, const std::string &filename); void invalidScanfError(const Token *tok); void wrongfeofUsage(const Token *tok); diff --git a/man/checkers/ftellTextModeFile.md b/man/checkers/ftellTextModeFile.md new file mode 100644 index 00000000000..6ca6653a6f2 --- /dev/null +++ b/man/checkers/ftellTextModeFile.md @@ -0,0 +1,56 @@ +# ftellModeTextFile + +**Message**: ftell() result is unspecified when file is opened in mode "t".
+**Category**: Portability
+**Severity**: Style
+**Language**: C/C++ + +## Description + +This checker detects the use of ftell() on a file open in text (or translate) mode. The text mode is not consistent + in between Linux and Windows system and may cause ftell() to return the wrong offset inside a text file. + +See section 7.21.9.4p2 of the C11 standard regarding the ftell function states for a text stream: + +- For a text stream, its file position indicator contains unspecified information, usable by the fseek function for returning the file position indicator for the stream to its position at the time of the ftell call; the difference between two such return values is not necessarily a meaningful measure of the number of characters written or read. + +This warning helps improve code quality by: +- Making the intent clear that the use of ftell() in "t" mode may cause portability problem. + +## Motivation + +This checker improves portability accross system. + +## How to fix + +According to C11, the file must be opened in binary mode 'b' to prevent this problem. + +Before: +```cpp + FILE *f = fopen("Example.txt", "rt"); + if (f) + { + fseek(f, 0, SEEK_END); + printf( "File size %d\n", ftell(f)); + fclose(f); + } + +``` + +After: +```cpp + + FILE *f = fopen("Example.txt", "rb"); + if (f) + { + fseek(f, 0, SEEK_END); + printf( "File size %d\n", ftell(f)); + fclose(f); + } + +``` + +## Notes + +See https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=msvc-170 + diff --git a/releasenotes.txt b/releasenotes.txt index 2141c34f001..0ca26f2374a 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -6,6 +6,7 @@ Major bug fixes & crashes: New checks: - Warn when feof() is used as a while loop condition (wrongfeofUsage). +- ftell() result is unspecified when file is opened in mode "t". C/C++ support: - diff --git a/test/testio.cpp b/test/testio.cpp index adfb6e31daf..f90773d4cf4 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -44,6 +44,7 @@ class TestIO : public TestFixture { TEST_CASE(fileIOwithoutPositioning); TEST_CASE(seekOnAppendedFile); TEST_CASE(fflushOnInputStream); + TEST_CASE(ftellCompatibility); TEST_CASE(incompatibleFileOpen); TEST_CASE(testWrongfeofUsage); // #958 @@ -728,6 +729,22 @@ class TestIO : public TestFixture { ASSERT_EQUALS("", errout_str()); // #6566 } + void ftellCompatibility() { + + check("void foo() {\n" + " FILE *f = fopen(\"\", \"rt\");\n" + " if (f)\n" + " {\n" + " extern long position;\n" + " fseek(f, 0, SEEK_END);\n" + " position = ftell(f);\n" + " fclose(f);\n" + " }\n" + "}\n", dinit(CheckOptions, $.portability = true)); + ASSERT_EQUALS("[test.cpp:7:21]: (portability) ftell() result is unspecified when file is opened in mode \"t\" [ftellTextModeFile]\n", errout_str()); + } + + void fflushOnInputStream() { check("void foo()\n" "{\n" From c1644448468b6e406b3c2c6c7864a105e7aeae54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 3 Jul 2026 13:44:08 +0200 Subject: [PATCH 219/493] pass `Library` instead of `Settings` (#8660) --- lib/astutils.cpp | 26 +++++++++++++------------- lib/astutils.h | 10 +++++----- lib/checkautovariables.cpp | 22 +++++++++++----------- lib/checkbufferoverrun.cpp | 2 +- lib/checkclass.cpp | 2 +- lib/checkio.cpp | 6 +++--- lib/checkio.h | 3 ++- lib/checkleakautovar.cpp | 14 +++++++------- lib/checknullpointer.cpp | 12 ++++++------ lib/checknullpointer.h | 2 +- lib/checkother.cpp | 8 ++++---- lib/checkstl.cpp | 4 ++-- lib/checkuninitvar.cpp | 4 ++-- lib/checkunusedfunctions.cpp | 30 +++++++++++++++--------------- lib/checkunusedfunctions.h | 5 +++-- lib/cppcheck.cpp | 10 +++++----- lib/valueflow.cpp | 8 ++++---- lib/vf_analyzers.cpp | 4 ++-- lib/vf_common.cpp | 8 ++++---- lib/vf_common.h | 3 ++- test/testastutils.cpp | 2 +- test/testunusedfunctions.cpp | 12 ++++++------ 22 files changed, 100 insertions(+), 97 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 8700d2d2cd9..a6fe2573f08 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2334,14 +2334,14 @@ bool isWithinScope(const Token* tok, const Variable* var, ScopeType type) return false; } -bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings &settings, bool *inconclusive) +bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Library &library, bool *inconclusive) { if (!tok) return false; if (tok->varId() == varid) - return isVariableChangedByFunctionCall(tok, indirect, settings, inconclusive); - return isVariableChangedByFunctionCall(tok->astOperand1(), indirect, varid, settings, inconclusive) || - isVariableChangedByFunctionCall(tok->astOperand2(), indirect, varid, settings, inconclusive); + return isVariableChangedByFunctionCall(tok, indirect, library, inconclusive); + return isVariableChangedByFunctionCall(tok->astOperand1(), indirect, varid, library, inconclusive) || + isVariableChangedByFunctionCall(tok->astOperand2(), indirect, varid, library, inconclusive); } bool isScopeBracket(const Token* tok) @@ -2522,7 +2522,7 @@ bool isMutableExpression(const Token* tok) return true; } -bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings &settings, bool *inconclusive) +bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Library &library, bool *inconclusive) { if (!tok) return false; @@ -2562,13 +2562,13 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti if (!tok->function() && !tok->variable() && tok->isName()) { // Check if direction (in, out, inout) is specified in the library configuration and use that - const Library::ArgumentChecks::Direction argDirection = settings.library.getArgDirection(tok, 1 + argnr, indirect); + const Library::ArgumentChecks::Direction argDirection = library.getArgDirection(tok, 1 + argnr, indirect); if (argDirection == Library::ArgumentChecks::Direction::DIR_IN) return false; if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT || argDirection == Library::ArgumentChecks::Direction::DIR_INOUT) return true; - const bool requireNonNull = settings.library.isnullargbad(tok, 1 + argnr); + const bool requireNonNull = library.isnullargbad(tok, 1 + argnr); if (Token::simpleMatch(tok->tokAt(-2), "std :: tie")) return true; // if the library says 0 is invalid @@ -2796,7 +2796,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, if (indirect == 0 && astIsLHS(tok2) && Token::Match(ptok, ". %var%") && astIsPointer(ptok->next())) pindirect = 1; bool inconclusive = false; - bool isChanged = isVariableChangedByFunctionCall(ptok, pindirect, settings, &inconclusive); + bool isChanged = isVariableChangedByFunctionCall(ptok, pindirect, settings.library, &inconclusive); isChanged |= inconclusive; if (isChanged) return true; @@ -3421,7 +3421,7 @@ bool isConstVarExpression(const Token *tok, const std::functionastParent() && tok->astParent()->isUnaryOp("&"); @@ -3483,14 +3483,14 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings } else if (ftok->str() == "{") { return indirect == 0 ? ExprUsage::Used : ExprUsage::Inconclusive; } else { - const bool isnullbad = settings.library.isnullargbad(ftok, argnr + 1); + const bool isnullbad = library.isnullargbad(ftok, argnr + 1); if (indirect == 0 && astIsPointer(tok) && !addressOf && isnullbad) return ExprUsage::Used; bool hasIndirect = false; - const bool isuninitbad = settings.library.isuninitargbad(ftok, argnr + 1, indirect, &hasIndirect); + const bool isuninitbad = library.isuninitargbad(ftok, argnr + 1, indirect, &hasIndirect); if (isuninitbad && (!addressOf || isnullbad)) return ExprUsage::Used; - const Library::ArgumentChecks::Direction argDirection = settings.library.getArgDirection(ftok, argnr + 1, indirect); + const Library::ArgumentChecks::Direction argDirection = library.getArgDirection(ftok, argnr + 1, indirect); if (argDirection == Library::ArgumentChecks::Direction::DIR_IN) // TODO: DIR_INOUT? return ExprUsage::Used; if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT) @@ -3560,7 +3560,7 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings& settings) (astIsLHS(tok) || Token::simpleMatch(parent, "( )"))) return ExprUsage::Used; } - return getFunctionUsage(tok, indirect, settings); + return getFunctionUsage(tok, indirect, settings.library); } static void getLHSVariablesRecursive(std::vector& vars, const Token* tok) diff --git a/lib/astutils.h b/lib/astutils.h index 617e01f0415..2c6650068b5 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -327,20 +327,20 @@ bool isMutableExpression(const Token* tok); * * @param tok ast tree * @param varid Variable Id - * @param settings program settings + * @param library library configurations * @param inconclusive pointer to output variable which indicates that the answer of the question is inconclusive */ -bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings &settings, bool *inconclusive); +bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Library &library, bool *inconclusive); /** Is variable changed by function call? * In case the answer of the question is inconclusive, e.g. because the function declaration is not known * the return value is false and the output parameter inconclusive is set to true * - * @param tok token of variable in function call - * @param settings program settings + * @param tok token of variable in function call + * @param library library configurations * @param inconclusive pointer to output variable which indicates that the answer of the question is inconclusive */ -CPPCHECKLIB bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings &settings, bool *inconclusive); +CPPCHECKLIB bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Library &library, bool *inconclusive); /** Is variable changed in block of code? */ CPPCHECKLIB bool isVariableChanged(const Token *start, const Token *end, nonneg int exprid, bool globalvar, const Settings &settings, int depth = 20); diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index b848928ebf4..de70772a279 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -139,14 +139,14 @@ static bool isAutoVarArray(const Token *tok) return false; } -static bool isLocalContainerBuffer(const Token* tok, const Settings& settings) +static bool isLocalContainerBuffer(const Token* tok, const Library& library) { if (!tok) return false; // x+y if (tok->str() == "+") - return isLocalContainerBuffer(tok->astOperand1(), settings) || isLocalContainerBuffer(tok->astOperand2(), settings); + return isLocalContainerBuffer(tok->astOperand1(), library) || isLocalContainerBuffer(tok->astOperand2(), library); if (tok->str() != "(" || !Token::simpleMatch(tok->astOperand1(), ".")) return false; @@ -157,7 +157,7 @@ static bool isLocalContainerBuffer(const Token* tok, const Settings& settings) if (!var || !var->isLocal() || var->isStatic()) return false; - const Library::Container::Yield yield = astContainerYield(tok, settings.library); + const Library::Container::Yield yield = astContainerYield(tok, library); return yield == Library::Container::Yield::BUFFER || yield == Library::Container::Yield::BUFFER_NT; } @@ -233,8 +233,8 @@ void CheckAutoVariablesImpl::assignFunctionArg() } } -static bool isAutoVariableRHS(const Token* tok, const Settings& settings) { - return isAddressOfLocalVariable(tok) || isAutoVarArray(tok) || isLocalContainerBuffer(tok, settings); +static bool isAutoVariableRHS(const Token* tok, const Library& library) { + return isAddressOfLocalVariable(tok) || isAutoVarArray(tok) || isLocalContainerBuffer(tok, library); } static bool hasOverloadedAssignment(const Token* tok, bool& inconclusive) @@ -257,7 +257,7 @@ static bool hasOverloadedAssignment(const Token* tok, bool& inconclusive) return true; } -static bool isMemberAssignment(const Token* tok, const Token*& rhs, const Settings& settings) +static bool isMemberAssignment(const Token* tok, const Token*& rhs, const Library& library) { const Token *endBracket = nullptr; if (!Token::Match(tok, "[;{}] %var% . %var%")) { @@ -274,7 +274,7 @@ static bool isMemberAssignment(const Token* tok, const Token*& rhs, const Settin assign = assign->astParent(); if (!Token::simpleMatch(assign, "=")) return false; - if (!isAutoVariableRHS(assign->astOperand2(), settings)) + if (!isAutoVariableRHS(assign->astOperand2(), library)) return false; rhs = assign->astOperand2(); return true; @@ -295,15 +295,15 @@ void CheckAutoVariablesImpl::autoVariables() } // Critical assignment const Token* rhs{}; - if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2(), mSettings)) { + if (Token::Match(tok, "[;{}] %var% =") && isRefPtrArg(tok->next()) && isAutoVariableRHS(tok->tokAt(2)->astOperand2(), mSettings.library)) { checkAutoVariableAssignment(tok->next(), false); - } else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2(), mSettings)) { + } else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAutoVariableRHS(tok->tokAt(3)->astOperand2(), mSettings.library)) { const Token* lhs = tok->tokAt(2); bool inconclusive = false; if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive)) checkAutoVariableAssignment(tok->next(), inconclusive); tok = tok->tokAt(4); - } else if (isMemberAssignment(tok, rhs, mSettings)) { + } else if (isMemberAssignment(tok, rhs, mSettings.library)) { const Token* lhs = tok->tokAt(3); bool inconclusive = false; if (!hasOverloadedAssignment(lhs, inconclusive) || (printInconclusive && inconclusive)) @@ -311,7 +311,7 @@ void CheckAutoVariablesImpl::autoVariables() tok = rhs; } else if (Token::Match(tok, "[;{}] %var% [") && Token::simpleMatch(tok->linkAt(2), "] =") && (isPtrArg(tok->next()) || isArrayArg(tok->next(), mSettings)) && - isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2(), mSettings)) { + isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2(), mSettings.library)) { errorAutoVariableAssignment(tok->next(), false); } // Invalid pointer deallocation diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 496ca6905a1..81b6653d348 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -133,7 +133,7 @@ static int getMinFormatStringOutputLength(const std::vector ¶m case 's': parameterLength = 0; if (inputArgNr < parameters.size()) - parameterLength = ValueFlow::valueFlowGetStrLength(parameters[inputArgNr], settings); + parameterLength = ValueFlow::valueFlowGetStrLength(parameters[inputArgNr], settings.library); handleNextParameter = true; break; diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index b610e963d76..e04df8b5748 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1059,7 +1059,7 @@ void CheckClassImpl::initializeVarList(const Function &func, std::listnext(); if (tok2->str() == "&") tok2 = tok2->next(); - if (isVariableChangedByFunctionCall(tok2, tok2->strAt(-1) == "&", tok2->varId(), mSettings, nullptr)) + if (isVariableChangedByFunctionCall(tok2, tok2->strAt(-1) == "&", tok2->varId(), mSettings.library, nullptr)) assignVar(usage, tok2->varId()); } } diff --git a/lib/checkio.cpp b/lib/checkio.cpp index c753dd80739..3d82bdb796a 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -875,7 +875,7 @@ void CheckIOImpl::checkFormatString(const Token * const tok, // Perform type checks ArgumentInfo argInfo(argListTok, mSettings, mTokenizer->isCPP()); - if ((argInfo.typeToken && !argInfo.isLibraryType(mSettings)) || *i == ']') { + if ((argInfo.typeToken && !argInfo.isLibraryType(mSettings.library)) || *i == ']') { if (scan) { std::string specifier; bool done = false; @@ -1877,9 +1877,9 @@ bool CheckIOImpl::ArgumentInfo::isKnownType() const return typeToken->isStandardType() || Token::Match(typeToken, "std :: string|wstring"); } -bool CheckIOImpl::ArgumentInfo::isLibraryType(const Settings &settings) const +bool CheckIOImpl::ArgumentInfo::isLibraryType(const Library &library) const { - return typeToken && typeToken->isStandardType() && settings.library.podtype(typeToken->str()); + return typeToken && typeToken->isStandardType() && library.podtype(typeToken->str()); } void CheckIOImpl::wrongPrintfScanfArgumentsError(const Token* tok, diff --git a/lib/checkio.h b/lib/checkio.h index ae0ea242dab..06c6d8d973b 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -35,6 +35,7 @@ class Token; class Variable; class ErrorLogger; class Tokenizer; +class Library; enum class Severity : std::uint8_t; /// @addtogroup Checks @@ -101,7 +102,7 @@ class CPPCHECKLIB CheckIOImpl : public CheckImpl { bool isKnownType() const; bool isStdVectorOrString(); bool isStdContainer(const Token *tok); - bool isLibraryType(const Settings &settings) const; + bool isLibraryType(const Library &library) const; const Variable* variableInfo{}; const Token* typeToken{}; diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 9049d56e7ff..e8271f9eed0 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -267,7 +267,7 @@ static const Token * isFunctionCall(const Token * nameToken) return nullptr; } -static const Token* getOutparamAllocation(const Token* tok, const Settings& settings) +static const Token* getOutparamAllocation(const Token* tok, const Library& library) { if (!tok) return nullptr; @@ -275,16 +275,16 @@ static const Token* getOutparamAllocation(const Token* tok, const Settings& sett const Token* ftok = getTokenArgumentFunction(tok, argn); if (!ftok) return nullptr; - if (const Library::AllocFunc* allocFunc = settings.library.getAllocFuncInfo(ftok)) { + if (const Library::AllocFunc* allocFunc = library.getAllocFuncInfo(ftok)) { if (allocFunc->arg == argn + 1) return ftok; } return nullptr; } -static const Token* getReturnValueFromOutparamAlloc(const Token* alloc, const Settings& settings) +static const Token* getReturnValueFromOutparamAlloc(const Token* alloc, const Library& library) { - if (const Token* ftok = getOutparamAllocation(alloc, settings)) { + if (const Token* ftok = getOutparamAllocation(alloc, library)) { if (Token::simpleMatch(ftok->astParent()->astParent(), "=")) return ftok->next()->astParent()->astOperand1(); } @@ -623,7 +623,7 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, if (std::any_of(varInfo1.alloctype.begin(), varInfo1.alloctype.end(), [&](const std::pair& info) { if (info.second.status != VarInfo::ALLOC) return false; - const Token* ret = getReturnValueFromOutparamAlloc(info.second.allocTok, mSettings); + const Token* ret = getReturnValueFromOutparamAlloc(info.second.allocTok, mSettings.library); return ret && vartok && ret->varId() && ret->varId() == vartok->varId(); })) { varInfo1.clear(); @@ -896,7 +896,7 @@ const Token * CheckLeakAutoVarImpl::checkTokenInsideExpression(const Token * con if (var != varInfo.alloctype.end()) { bool unknown = false; if (var->second.status == VarInfo::DEALLOC && tok->valueType() && tok->valueType()->pointer && - CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings, /*checkNullArg*/ false) && !unknown) { + CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings.library, /*checkNullArg*/ false) && !unknown) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { varInfo.erase(tok->varId()); @@ -1232,7 +1232,7 @@ void CheckLeakAutoVarImpl::ret(const Token *tok, VarInfo &varInfo, const bool is // don't warn when returning after checking return value of outparam allocation const Token* outparamFunc{}; if ((tok->scope()->type == ScopeType::eIf || tok->scope()->type== ScopeType::eElse) && - (outparamFunc = getOutparamAllocation(it->second.allocTok, mSettings))) { + (outparamFunc = getOutparamAllocation(it->second.allocTok, mSettings.library))) { const Scope* scope = tok->scope(); if (scope->type == ScopeType::eElse) { scope = scope->bodyStart->tokAt(-2)->scope(); diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index ac56f19eb09..5c2e64e9a6c 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -130,10 +130,10 @@ namespace { bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown) const { - return isPointerDeRef(tok, unknown, mSettings); + return isPointerDeRef(tok, unknown, mSettings.library); } -bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings, bool checkNullArg) +bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const Library &library, bool checkNullArg) { unknown = false; @@ -146,7 +146,7 @@ bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const ftok = ftok->previous(); } if (ftok && ftok->previous()) { - const std::list varlist = CheckNullPointerImpl::parseFunctionCall(*ftok->previous(), settings.library, checkNullArg); + const std::list varlist = CheckNullPointerImpl::parseFunctionCall(*ftok->previous(), library, checkNullArg); if (std::find(varlist.cbegin(), varlist.cend(), tok) != varlist.cend()) { return true; } @@ -161,7 +161,7 @@ bool CheckNullPointerImpl::isPointerDeRef(const Token *tok, bool &unknown, const return false; const bool addressOf = parent->astParent() && parent->astParent()->str() == "&"; if (parent->str() == "." && astIsRHS(tok)) - return isPointerDeRef(parent, unknown, settings); + return isPointerDeRef(parent, unknown, library); const bool firstOperand = parent->astOperand1() == tok; parent = astParentSkipParens(tok); if (!parent) @@ -298,7 +298,7 @@ void CheckNullPointerImpl::nullPointerByDeRefAndCheck() // Pointer dereference. bool unknown = false; - if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings)) { + if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings.library)) { if (unknown) nullPointerError(tok, tok->expressionString(), value, true); continue; @@ -578,7 +578,7 @@ static bool isUnsafeUsage(const Settings &settings, const Token *vartok, CTU::Fi { (void)value; bool unknown = false; - return CheckNullPointerImpl::isPointerDeRef(vartok, unknown, settings); + return CheckNullPointerImpl::isPointerDeRef(vartok, unknown, settings.library); } // a Clang-built executable will crash when using the anonymous MyFileInfo later on - so put it in a unique namespace for now diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index bc494dad70f..ed6a617d81a 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -92,7 +92,7 @@ class CPPCHECKLIB CheckNullPointerImpl : public CheckImpl { */ bool isPointerDeRef(const Token *tok, bool &unknown) const; - static bool isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings, bool checkNullArg = true); + static bool isPointerDeRef(const Token *tok, bool &unknown, const Library &library, bool checkNullArg = true); /** * @brief parse a function call and extract information about variable usage diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 9dee8df7810..51124c45d1c 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1793,7 +1793,7 @@ void CheckOtherImpl::checkConstVariable() continue; } else if (const Token* ftok = getTokenArgumentFunction(tok, argn)) { bool inconclusive{}; - if (var->valueType() && !isVariableChangedByFunctionCall(ftok, var->valueType()->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) + if (var->valueType() && !isVariableChangedByFunctionCall(ftok, var->valueType()->pointer, var->declarationId(), mSettings.library, &inconclusive) && !inconclusive) continue; } usedInAssignment = true; @@ -1989,7 +1989,7 @@ void CheckOtherImpl::checkConstPointer() continue; else if (const Token* ftok = getTokenArgumentFunction(parent, argn)) { bool inconclusive{}; - if (!isVariableChangedByFunctionCall(ftok->next(), vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) + if (!isVariableChangedByFunctionCall(ftok->next(), vt->pointer, var->declarationId(), mSettings.library, &inconclusive) && !inconclusive) continue; } } else { @@ -2014,7 +2014,7 @@ void CheckOtherImpl::checkConstPointer() const Variable* argVar = ftok->function()->getArgumentVar(argn); if (argVar && argVar->valueType() && argVar->valueType()->isConst(vt->pointer)) { bool inconclusive{}; - if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) + if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), mSettings.library, &inconclusive) && !inconclusive) continue; } } @@ -3981,7 +3981,7 @@ void CheckOtherImpl::checkAccessOfMovedVariable() if (usage == ExprUsage::Used) accessOfMoved = true; if (usage == ExprUsage::PassedByReference) - accessOfMoved = !isVariableChangedByFunctionCall(tok, 0, mSettings, &inconclusive); + accessOfMoved = !isVariableChangedByFunctionCall(tok, 0, mSettings.library, &inconclusive); else if (usage == ExprUsage::Inconclusive) inconclusive = true; } diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 4c3b51ac5db..743ac8a3cb4 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2552,7 +2552,7 @@ void CheckStlImpl::checkDereferenceInvalidIterator2() emptyAdvance = tok->astParent(); } } - if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings) && !isInvalidIterator && !emptyAdvance) { + if (!CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings.library) && !isInvalidIterator && !emptyAdvance) { if (!unknown) continue; inconclusive = true; @@ -2895,7 +2895,7 @@ namespace { int n = 1 + (astIsPointer(tok) ? 1 : 0); for (int i = 0; i < n; i++) { bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, i, mSettings, &inconclusive)) + if (isVariableChangedByFunctionCall(tok, i, mSettings.library, &inconclusive)) return true; if (inconclusive) return true; diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 6bc2a86b8a5..d05ea3fbd28 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1664,7 +1664,7 @@ void CheckUninitVarImpl::valueFlowUninit() if (yield != Library::Container::Yield::AT_INDEX && yield != Library::Container::Yield::ITEM) continue; } - const bool deref = CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings); + const bool deref = CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings.library); uninitderef = deref && v->indirect == 0; const bool isleaf = isLeafDot(tok) || uninitderef; if (!isleaf && Token::Match(tok->astParent(), ". %name%") && @@ -1681,7 +1681,7 @@ void CheckUninitVarImpl::valueFlowUninit() isVariableChanged(tok, v->indirect, mSettings)) continue; bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, v->indirect, mSettings, &inconclusive) || inconclusive) + if (isVariableChangedByFunctionCall(tok, v->indirect, mSettings.library, &inconclusive) || inconclusive) continue; } uninitvarError(tok, *v); diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index 5965de1aada..4177a13a013 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -65,11 +65,11 @@ static bool isRecursiveCall(const Token* ftok) return ftok->function() && ftok->function() == Scope::nestedInFunction(ftok->scope()); } -void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Settings &settings) +void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Library &library) { const char * const FileName = tokenizer.list.getFiles().front().c_str(); - const bool doMarkup = settings.library.markupFile(FileName); + const bool doMarkup = library.markupFile(FileName); // Function declarations.. if (!doMarkup) { @@ -139,8 +139,8 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting lambdaEndToken = findLambdaEndToken(tok); // parsing of library code to find called functions - if (settings.library.isexecutableblock(FileName, tok->str())) { - const Token * markupVarToken = tok->tokAt(settings.library.blockstartoffset(FileName)); + if (library.isexecutableblock(FileName, tok->str())) { + const Token * markupVarToken = tok->tokAt(library.blockstartoffset(FileName)); // not found if (!markupVarToken) continue; @@ -148,12 +148,12 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting bool start = true; // find all function calls in library code (starts with '(', not if or while etc) while ((scope || start) && markupVarToken) { - if (markupVarToken->str() == settings.library.blockstart(FileName)) { + if (markupVarToken->str() == library.blockstart(FileName)) { scope++; start = false; - } else if (markupVarToken->str() == settings.library.blockend(FileName)) + } else if (markupVarToken->str() == library.blockend(FileName)) scope--; - else if (!settings.library.iskeyword(FileName, markupVarToken->str())) { + else if (!library.iskeyword(FileName, markupVarToken->str())) { mFunctionCalls.insert(markupVarToken->str()); if (mFunctions.find(markupVarToken->str()) != mFunctions.end()) mFunctions[markupVarToken->str()].usedOtherFile = true; @@ -171,10 +171,10 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting } if (!doMarkup // only check source files - && settings.library.isexporter(tok->str()) && tok->next() != nullptr) { + && library.isexporter(tok->str()) && tok->next() != nullptr) { const Token * propToken = tok->next(); while (propToken && propToken->str() != ")") { - if (settings.library.isexportedprefix(tok->str(), propToken->str())) { + if (library.isexportedprefix(tok->str(), propToken->str())) { const Token* nextPropToken = propToken->next(); const std::string& value = nextPropToken->str(); if (mFunctions.find(value) != mFunctions.end()) { @@ -182,7 +182,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting } mFunctionCalls.insert(value); } - if (settings.library.isexportedsuffix(tok->str(), propToken->str())) { + if (library.isexportedsuffix(tok->str(), propToken->str())) { const Token* prevPropToken = propToken->previous(); const std::string& value = prevPropToken->str(); if (value != ")" && mFunctions.find(value) != mFunctions.end()) { @@ -194,7 +194,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting } } - if (doMarkup && settings.library.isimporter(FileName, tok->str()) && tok->next()) { + if (doMarkup && library.isimporter(FileName, tok->str()) && tok->next()) { const Token * propToken = tok->next(); if (propToken->next()) { propToken = propToken->next(); @@ -210,8 +210,8 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting } } - if (settings.library.isreflection(tok->str())) { - const int argIndex = settings.library.reflectionArgument(tok->str()); + if (library.isreflection(tok->str())) { + const int argIndex = library.reflectionArgument(tok->str()); if (argIndex >= 0) { const Token * funcToken = tok->next(); int index = 0; @@ -366,7 +366,7 @@ void CheckUnusedFunctions::staticFunctionError(ErrorLogger& errorLogger, errorLogger.reportErr(errmsg); \ } while (false) -bool CheckUnusedFunctions::check(const Settings& settings, ErrorLogger& errorLogger) const +bool CheckUnusedFunctions::check(const Library& library, ErrorLogger& errorLogger) const { logChecker("CheckUnusedFunctions::check"); // unusedFunction @@ -379,7 +379,7 @@ bool CheckUnusedFunctions::check(const Settings& settings, ErrorLogger& errorLog const FunctionUsage &func = it->second; if (func.usedOtherFile || func.filename.empty()) continue; - if (settings.library.isentrypoint(it->first)) + if (library.isentrypoint(it->first)) continue; if (!func.usedSameFile) { if (isOperatorFunction(it->first)) diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 5c5b369c194..1b560cfb7cb 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -33,6 +33,7 @@ class ErrorLogger; class Function; class Settings; class Tokenizer; +class Library; /** @brief Check for functions never called */ /// @{ @@ -44,7 +45,7 @@ class CPPCHECKLIB CheckUnusedFunctions { // Parse current tokens and determine.. // * Check what functions are used // * What functions are declared - void parseTokens(const Tokenizer &tokenizer, const Settings &settings); + void parseTokens(const Tokenizer &tokenizer, const Library &library); std::string analyzerInfo(const Tokenizer &tokenizer) const; @@ -56,7 +57,7 @@ class CPPCHECKLIB CheckUnusedFunctions { } // Return true if an error is reported. - bool check(const Settings& settings, ErrorLogger& errorLogger) const; + bool check(const Library& library, ErrorLogger& errorLogger) const; void updateFunctionData(const CheckUnusedFunctions& checkUnusedFunctions); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 9a3e2e2a053..50f7fa36e80 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -977,7 +977,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str tokenlist.createTokens(std::move(tokens)); // this is not a real source file - we just want to tokenize it. treat it as C anyways as the language needs to be determined. Tokenizer tokenizer(std::move(tokenlist), mErrorLogger); - mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings); + mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings.library); if (analyzerInformation) { mLogger->setAnalyzerInfo(nullptr); @@ -1358,10 +1358,10 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation } if (mSettings.checks.isEnabled(Checks::unusedFunction) && !mSettings.buildDir.empty()) { - unusedFunctionsChecker.parseTokens(tokenizer, mSettings); + unusedFunctionsChecker.parseTokens(tokenizer, mSettings.library); } if (mUnusedFunctionsCheck && mSettings.useSingleJob() && mSettings.buildDir.empty()) { - mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings); + mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings.library); } if (mSettings.clang) { @@ -1830,7 +1830,7 @@ bool CppCheck::analyseWholeProgram() } if (mUnusedFunctionsCheck) - errors |= mUnusedFunctionsCheck->check(mSettings, mErrorLogger); + errors |= mUnusedFunctionsCheck->check(mSettings.library, mErrorLogger); return errors && (mLogger->exitcode() > 0); } @@ -1841,7 +1841,7 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st CheckUnusedFunctions::analyseWholeProgram(mSettings, mErrorLogger, buildDir); if (mUnusedFunctionsCheck) - mUnusedFunctionsCheck->check(mSettings, mErrorLogger); + mUnusedFunctionsCheck->check(mSettings.library, mErrorLogger); if (Settings::unusedFunctionOnly()) return mLogger->exitcode(); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7d25166bf99..ef81fc772ac 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6183,7 +6183,7 @@ static bool isContainerSizeChangedByFunction(const Token* tok, } bool inconclusive = false; - const bool isChanged = isVariableChangedByFunctionCall(tok, indirect, settings, &inconclusive); + const bool isChanged = isVariableChangedByFunctionCall(tok, indirect, settings.library, &inconclusive); return (isChanged || inconclusive); } @@ -6850,17 +6850,17 @@ static void valueFlowContainerSize(const TokenList& tokenlist, } else if (tok->str() == "+=" && astIsContainer(tok->astOperand1())) { const Token* containerTok = tok->astOperand1(); const Token* valueTok = tok->astOperand2(); - const MathLib::bigint size = ValueFlow::valueFlowGetStrLength(valueTok, settings); + const MathLib::bigint size = ValueFlow::valueFlowGetStrLength(valueTok, settings.library); forwardMinimumContainerSize(size, tok, containerTok); } else if (tok->str() == "=" && Token::simpleMatch(tok->astOperand2(), "+") && astIsContainerString(tok)) { const Token* tok2 = tok->astOperand2(); MathLib::bigint size = 0; while (Token::simpleMatch(tok2, "+") && tok2->astOperand2()) { - size += ValueFlow::valueFlowGetStrLength(tok2->astOperand2(), settings); + size += ValueFlow::valueFlowGetStrLength(tok2->astOperand2(), settings.library); tok2 = tok2->astOperand1(); } - size += ValueFlow::valueFlowGetStrLength(tok2, settings); + size += ValueFlow::valueFlowGetStrLength(tok2, settings.library); forwardMinimumContainerSize(size, tok, tok->astOperand1()); } } diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 10efc6d6f39..44c86cbc2b7 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -222,7 +222,7 @@ struct ValueFlowAnalyzer : Analyzer { return Action::Read; } bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, getIndirect(tok), getSettings(), &inconclusive)) + if (isVariableChangedByFunctionCall(tok, getIndirect(tok), getSettings().library, &inconclusive)) return Action::Read | Action::Invalid; if (inconclusive) return Action::Read | Action::Inconclusive; @@ -1569,7 +1569,7 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer { case Library::Container::Action::APPEND: { std::vector args = getArguments(tok->astParent()->tokAt(2)); if (args.size() == 1) // TODO: handle overloads - n = ValueFlow::valueFlowGetStrLength(tok->astParent()->tokAt(3), settings); + n = ValueFlow::valueFlowGetStrLength(tok->astParent()->tokAt(3), settings.library); if (n == 0) // TODO: handle known empty append val->setPossible(); break; diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index b4bd756d05e..ef48423f38a 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -398,7 +398,7 @@ namespace ValueFlow v.debugPath.emplace_back(tok, std::move(s)); } - MathLib::bigint valueFlowGetStrLength(const Token* tok, const Settings& settings) + MathLib::bigint valueFlowGetStrLength(const Token* tok, const Library& library) { if (tok->tokType() == Token::eString) return Token::getStrLength(tok); @@ -408,10 +408,10 @@ namespace ValueFlow return v->intvalue; if (const Value* v = tok->getKnownValue(Value::ValueType::TOK)) { if (v->tokvalue != tok) - return valueFlowGetStrLength(v->tokvalue, settings); + return valueFlowGetStrLength(v->tokvalue, library); } - if (const Token* cont = settings.library.getContainerFromYield(tok, Library::Container::Yield::BUFFER_NT)) - return valueFlowGetStrLength(cont, settings); + if (const Token* cont = library.getContainerFromYield(tok, Library::Container::Yield::BUFFER_NT)) + return valueFlowGetStrLength(cont, library); return 0; } } diff --git a/lib/vf_common.h b/lib/vf_common.h index 9859955cbfe..aca438a0dff 100644 --- a/lib/vf_common.h +++ b/lib/vf_common.h @@ -30,6 +30,7 @@ class Token; class Settings; class Platform; +class Library; namespace ValueFlow { @@ -53,7 +54,7 @@ namespace ValueFlow const Token* tok, SourceLocation local = SourceLocation::current()); - MathLib::bigint valueFlowGetStrLength(const Token* tok, const Settings& settings); + MathLib::bigint valueFlowGetStrLength(const Token* tok, const Library& library); } #endif // vfCommonH diff --git a/test/testastutils.cpp b/test/testastutils.cpp index 904ea92b466..6a6e0624587 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -259,7 +259,7 @@ class TestAstUtils : public TestFixture { const Token * const argtok = Token::findmatch(tokenizer.tokens(), pattern); ASSERT_LOC(argtok, file, line); int indirect = (argtok->variable() && argtok->variable()->isArray()); - return (isVariableChangedByFunctionCall)(argtok, indirect, settingsDefault, inconclusive); + return (isVariableChangedByFunctionCall)(argtok, indirect, settingsDefault.library, inconclusive); } void isVariableChangedByFunctionCallTest() { diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 3e78b119012..938a1394394 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -111,8 +111,8 @@ class TestUnusedFunctions : public TestFixture { // Check for unused functions.. CheckUnusedFunctions checkUnusedFunctions; - checkUnusedFunctions.parseTokens(tokenizer, settings1); - (checkUnusedFunctions.check)(settings1, *this); // TODO: check result + checkUnusedFunctions.parseTokens(tokenizer, settings1.library); + (checkUnusedFunctions.check)(settings1.library, *this); // TODO: check result } // TODO: get rid of this @@ -123,8 +123,8 @@ class TestUnusedFunctions : public TestFixture { // Check for unused functions.. CheckUnusedFunctions checkUnusedFunctions; - checkUnusedFunctions.parseTokens(tokenizer, settings); - (checkUnusedFunctions.check)(settings, *this); // TODO: check result + checkUnusedFunctions.parseTokens(tokenizer, settings.library); + (checkUnusedFunctions.check)(settings.library, *this); // TODO: check result } void incondition() { @@ -602,11 +602,11 @@ class TestUnusedFunctions : public TestFixture { SimpleTokenizer tokenizer{settings, *this, fname}; ASSERT(tokenizer.tokenize(code)); - c.parseTokens(tokenizer, settings); + c.parseTokens(tokenizer, settings.library); } // Check for unused functions.. - (c.check)(settings, *this); // TODO: check result + (c.check)(settings.library, *this); // TODO: check result ASSERT_EQUALS("[test1.cpp:1:13]: (style) The function 'f' is never used. [unusedFunction]\n", errout_str()); } From e039c081179b135089469c40ba78ef9d9b37c523 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 3 Jul 2026 18:45:31 +0200 Subject: [PATCH 220/493] Fix #14887 FP objectIndex with pointer to array member (#8689) --- lib/checkbufferoverrun.cpp | 8 ++++++-- test/testbufferoverrun.cpp | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 81b6653d348..c72db22a68c 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1088,8 +1088,12 @@ void CheckBufferOverrunImpl::objectIndex() for (const ValueFlow::Value& v:values) { if (v.lifetimeKind != ValueFlow::Value::LifetimeKind::Address && v.lifetimeKind != ValueFlow::Value::LifetimeKind::Object) continue; - const Token* varTok = nextAfterAstRightmostLeaf(v.tokvalue->astParent()); - varTok = varTok ? varTok->previous() : nullptr; + const Token* varTok = v.tokvalue; + if (Token::simpleMatch(varTok->astParent(), ".")) { + varTok = varTok->astParent(); + while (Token::simpleMatch(varTok, ".")) + varTok = varTok->astOperand2(); + } const Variable *var = varTok ? varTok->variable() : nullptr; if (!var) continue; diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index e51a1708389..387a0eeea8a 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -5860,6 +5860,26 @@ class TestBufferOverrun : public TestFixture { ASSERT_EQUALS("[test.cpp:7:20] -> [test.cpp:9:12]: (error) The address of variable 's.a' is accessed at non-zero index. [objectIndex]\n" "[test.cpp:7:20] -> [test.cpp:10:12]: (error) The address of variable 's.a' is accessed at non-zero index. [objectIndex]\n", errout_str()); + + check("const int N = 12;\n" // #14887 + "struct S {\n" + " void f() const;\n" + " int a[N];\n" + "};\n" + "struct T {\n" + " void f() const;\n" + " S s;\n" + "};\n" + "int g(const int* p) { return p[5]; }\n" + "void S::f() const {\n" + " const int* q = a;\n" + " g(q);\n" + "}\n" + "void T::f() const {\n" + " const int* q = s.a;\n" + " g(q);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void checkPipeParameterSize() { // #3521 From bcd74c735e745f7b1bd8d5362e91dd748acbe2b3 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sat, 4 Jul 2026 06:29:46 -0500 Subject: [PATCH 221/493] Partial fix for 9049: False negative: uninitialized variable with nested ifs (#8680) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the case for this: ```cpp unsigned int g(); void f(bool a) { unsigned int dimensions = 0; bool mightBeLarger; if (a) { dimensions = g(); if (dimensions >= 1) mightBeLarger = false; } else { mightBeLarger = false; } if (dimensions == 1) return; if (!mightBeLarger) {} } ``` Which doesnt use a compund condition `dimensions >= 1 && b)` and it also requires complete variables and functions. The compund condition could be handled in the future by forking within the condition, so `if(a && b) { ... }` can be treated as `if(a) { if(b) { ... }}`. Here is a summary of the changes: 1. Fork-based condition handling — lib/forwardanalyzer.cpp (the largest change) - When a condition can't be resolved, the traversal now forks: the then-branch is walked by a separate ForwardTraversal, in analyze-only mode when the value can't actually flow into it (opaque/correlated conditions like if (f(x))), so the branch's effect is tracked but nothing is reported there. - Branch breaks are deferred: if the else kills the value on the main path, the then-fork can still carry it forward. - Escapes the traversal didn't flag (e.g. unknown noreturn calls) are detected via isEscapeScope, and exit/abort are now recognized as escape functions (lib/astutils.cpp). 2. Program-state anchoring at block boundaries — lib/vf_analyzers.cpp + lib/analyzer.h - assume() now anchors the assumed state at the block's end (not the condition) when control is leaving an already-traversed branch. This keeps an assumption on a variable modified inside the block (e.g. a nested if narrowing a value computed there) from being discarded as "modified" once control leaves the block. - New Assume::Pending flag marks the pre-traversal assume (branch walked separately) so it doesn't record premature boundary state. - ProgramMemoryState::assume gained an optional origin parameter so the anchor point can be overridden. 3. vars-aware execute — lib/programmemory.cpp / .h - execute/conditionIsTrue/conditionIsFalse now take the tracked values (vars). A tracked value is the authoritative current value of its expression (returned and written back into the program memory), and any cached compound that depends on a tracked value is re-evaluated instead of served stale (getTrackedValue / dependsOnTrackedValue). - The per-assignment substitution was removed from fillProgramMemoryFromAssignments and now lives entirely in execute so it can be used for all executions. --------- Co-authored-by: Your Name --- lib/analyzer.h | 10 +- lib/astutils.cpp | 2 + lib/forwardanalyzer.cpp | 225 ++++++++++++++++++++----------------- lib/programmemory.cpp | 209 +++++++++++++++++++++++----------- lib/programmemory.h | 38 ++++++- lib/settings.cpp | 4 + lib/settings.h | 9 ++ lib/vf_analyzers.cpp | 61 ++++++---- test/testautovariables.cpp | 4 +- test/testcondition.cpp | 24 ++++ test/testnullpointer.cpp | 5 + test/testother.cpp | 5 +- test/teststl.cpp | 4 +- test/testuninitvar.cpp | 46 +++++++- test/testvalueflow.cpp | 75 ++++++++++++- 15 files changed, 514 insertions(+), 207 deletions(-) diff --git a/lib/analyzer.h b/lib/analyzer.h index a4546eb7dc4..9b87310530f 100644 --- a/lib/analyzer.h +++ b/lib/analyzer.h @@ -153,9 +153,13 @@ struct Analyzer { struct Assume { enum Flags : std::uint8_t { None = 0, - Quiet = (1 << 0), - Absolute = (1 << 1), - ContainerEmpty = (1 << 2), + Quiet = (1u << 0), + Absolute = (1u << 1), + ContainerEmpty = (1u << 2), + // The branch this condition guards is not traversed yet (a separate path walks it), so + // the assume must not record the program state at the branch boundaries - they would be + // premature. When unset, the branch has been traversed and control is leaving it. + Pending = (1u << 3), }; }; diff --git a/lib/astutils.cpp b/lib/astutils.cpp index a6fe2573f08..c433036cfcc 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2230,6 +2230,8 @@ bool isEscapeFunction(const Token* ftok, const Library& library) { if (!Token::Match(ftok, "%name% (")) return false; + if (Token::Match(ftok, "exit|abort")) + return true; const Function* function = ftok->function(); if (function) { if (function->isEscapeFunction()) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 670db0b1090..727c64b076d 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -59,6 +59,10 @@ namespace { Analyzer::Terminate terminate = Analyzer::Terminate::None; std::vector loopEnds; int branchCount = 0; + // Nested condition-fork depth on this lineage (copied by fork()); bounds the fan-out. + int forkDepth = 0; + // Total forks of the traversal (shared via the fork() copy); backstop past the depth bound. + std::shared_ptr forkBudget = std::make_shared(0); Progress Break(Analyzer::Terminate t = Analyzer::Terminate::None) { if ((!analyzeOnly || analyzeTerminate) && t != Analyzer::Terminate::None) @@ -73,7 +77,6 @@ namespace { bool check = false; bool escape = false; bool escapeUnknown = false; - bool active = false; bool isEscape() const { return escape || escapeUnknown; } @@ -89,6 +92,9 @@ namespace { bool isDead() const { return action.isModified() || action.isInconclusive() || isEscape(); } + bool hasGoto() const { + return endBlock ? ForwardTraversal::hasGoto(endBlock) : false; + } }; bool stopUpdates() { @@ -348,18 +354,6 @@ namespace { return Token::findmatch(endBlock->link(), "goto|break", endBlock); } - bool hasInnerReturnScope(const Token* start, const Token* end) const { - for (const Token* tok=start; tok != end; tok = tok->previous()) { - if (Token::simpleMatch(tok, "}")) { - const Token* ftok = nullptr; - const bool r = isReturnScope(tok, settings.library, &ftok); - if (r) - return true; - } - } - return false; - } - bool isEscapeScope(const Token* endBlock, bool& unknown) const { const Token* ftok = nullptr; const bool r = isReturnScope(endBlock, settings.library, &ftok); @@ -383,30 +377,34 @@ namespace { return a; } - bool checkBranch(Branch& branch) const { - Analyzer::Action a = analyzeScope(branch.endBlock); - branch.action = a; - std::vector ft1 = tryForkUpdateScope(branch.endBlock, a.isModified()); - const bool bail = hasGoto(branch.endBlock); - if (!a.isModified() && !bail) { - if (ft1.empty()) { - // Traverse into the branch to see if there is a conditional escape - if (!branch.escape && hasInnerReturnScope(branch.endBlock->previous(), branch.endBlock->link())) { - ForwardTraversal ft2 = fork(true); - ft2.updateScope(branch.endBlock); - if (ft2.terminate == Analyzer::Terminate::Escape) { - branch.escape = true; - branch.escapeUnknown = false; - } - } - } else { - if (ft1.front().terminate == Analyzer::Terminate::Escape) { - branch.escape = true; - branch.escapeUnknown = false; - } + Progress updateBranch(Branch& branch, int depth) + { + // Save and reset actions + Analyzer::Action prevActions = actions; + actions = Analyzer::Action::None; + Progress p = updateRange(branch.endBlock->link(), branch.endBlock, depth); + branch.action |= actions; + // Restore actions + actions |= prevActions; + + if (terminate == Analyzer::Terminate::Escape) { + branch.escape = true; + // The traversal followed an escaping path, but if the scope does not structurally + // always escape then another path (e.g. a modified fork) falls through, so the escape + // is only conditional - keep isModified() meaningful by not treating it as conclusive. + bool structuralUnknown = false; + const bool structuralEscape = isEscapeScope(branch.endBlock, structuralUnknown); + branch.escapeUnknown = !structuralEscape || structuralUnknown; + } else { + // Detect an escape the traversal did not flag (e.g. an unknown noreturn call); + // escapeUnknown reports a possible (unknown) escape. + branch.escape = isEscapeScope(branch.endBlock, branch.escapeUnknown); + if (terminate != Analyzer::Terminate::None && terminate != Analyzer::Terminate::Modified) { + branch.action |= analyzeScope(branch.endBlock); } } - return bail; + + return p; } bool reentersLoop(Token* endBlock, const Token* condTok, const Token* stepTok) const { @@ -529,14 +527,12 @@ namespace { forkContinue = false; } - if (allAnalysis.isModified() || !forkContinue) { - // TODO: Don't bail on missing condition - if (!condTok) - return Break(Analyzer::Terminate::Bail); - if (analyzer->isConditional() && stopUpdates()) - return Break(Analyzer::Terminate::Conditional); - analyzer->assume(condTok, false); - } + // TODO: Don't bail on missing condition + if (!condTok) + return Break(Analyzer::Terminate::Bail); + if (analyzer->isConditional() && stopUpdates()) + return Break(Analyzer::Terminate::Conditional); + analyzer->assume(condTok, false); if (forkContinue) { for (ForwardTraversal& ft : ftv) { if (!ft.actions.isIncremental()) @@ -646,11 +642,20 @@ namespace { const bool inElse = scope->type == ScopeType::eElse; const bool inDoWhile = scope->type == ScopeType::eDo; const bool inLoop = contains({ScopeType::eDo, ScopeType::eFor, ScopeType::eWhile}, scope->type); + const bool hasElse = Token::simpleMatch(tok, "} else {"); Token* condTok = getCondTokFromEnd(tok); if (!condTok) return Break(); + // When the 'else' branch escapes (e.g. returns), control can only continue + // here via the 'then' branch, so the value established there is still + // definite - keep it known instead of lowering to possible. + bool elseEscape = false; + if (!inLoop && !inElse && hasElse) { + bool unknownEscape = false; + elseEscape = isEscapeScope(tok->linkAt(2), unknownEscape); + } if (!condTok->hasKnownIntValue() || inLoop) { - if (!analyzer->lowerToPossible()) + if (!elseEscape && !analyzer->lowerToPossible()) return Break(Analyzer::Terminate::Bail); } else if (condTok->getKnownIntValue() == inElse) { return Break(); @@ -675,7 +680,7 @@ namespace { } analyzer->assume(condTok, !inElse, Analyzer::Assume::Quiet); assert(!inDoWhile || Token::simpleMatch(tok, "} while (")); - if (Token::simpleMatch(tok, "} else {") || inDoWhile) + if (hasElse || inDoWhile) tok = tok->linkAt(2); } else if (contains({ScopeType::eTry, ScopeType::eCatch}, scope->type)) { if (!analyzer->lowerToPossible()) @@ -731,71 +736,83 @@ namespace { if (!thenBranch.check && !elseBranch.check && stopOnCondition(condTok) && stopUpdates()) return Break(Analyzer::Terminate::Conditional); const bool hasElse = Token::simpleMatch(endBlock, "} else {"); - bool bail = false; - - // Traverse then block - thenBranch.escape = isEscapeScope(endBlock, thenBranch.escapeUnknown); + tok = hasElse ? endBlock->linkAt(2) : endBlock; if (thenBranch.check) { - thenBranch.active = true; - if (updateScope(endBlock, depth - 1) == Progress::Break) + // The condition is only "known" because of an earlier assumption, so the + // skipped else block could still modify the value -> lower to possible + if (!condTok->hasKnownIntValue() && hasElse && + analyzeScope(elseBranch.endBlock).isModified() && !analyzer->lowerToPossible()) + return Break(Analyzer::Terminate::Bail); + if (updateScope(thenBranch.endBlock, depth - 1) == Progress::Break) + return Break(); + } else if (elseBranch.check) { + // Likewise the skipped then block could still modify the value + if (!condTok->hasKnownIntValue() && analyzeScope(thenBranch.endBlock).isModified() && + !analyzer->lowerToPossible()) + return Break(Analyzer::Terminate::Bail); + if (elseBranch.endBlock && updateScope(elseBranch.endBlock, depth - 1) == Progress::Break) return Break(); - } else if (!elseBranch.check) { - thenBranch.active = true; - if (checkBranch(thenBranch)) - bail = true; - } - // Traverse else block - if (hasElse) { - elseBranch.escape = isEscapeScope(endBlock->linkAt(2), elseBranch.escapeUnknown); - if (elseBranch.check) { - elseBranch.active = true; - const Progress result = updateScope(endBlock->linkAt(2), depth - 1); - if (result == Progress::Break) - return Break(); - } else if (!thenBranch.check) { - elseBranch.active = true; - if (checkBranch(elseBranch)) - bail = true; - } - tok = endBlock->linkAt(2); } else { - tok = endBlock; - } - if (thenBranch.active) + const bool conditional = stopOnCondition(condTok); + // The value only flows into the then-branch when the condition can split + // it; for an opaque or correlated condition (e.g. 'if (f(x))') it does + // not, so fork in analyze-only mode: the branch's effect is still tracked + // but nothing is reported in it. + ForwardTraversal ft = fork(!analyzer->updateScope(thenBranch.endBlock, false)); + // The branch is traversed below, so don't record its boundary state here. + ft.analyzer->assume(condTok, true, Analyzer::Assume::Pending); + Progress pThen = ft.updateBranch(thenBranch, depth - 1); + // Merge the fork's actions so a modification in the then-branch bubbles up + // to the enclosing branch's isModified(). actions |= thenBranch.action; - if (elseBranch.active) - actions |= elseBranch.action; - if (bail) - return Break(Analyzer::Terminate::Bail); - if (thenBranch.isDead() && elseBranch.isDead()) { - if (thenBranch.isModified() && elseBranch.isModified()) - return Break(Analyzer::Terminate::Modified); - if (thenBranch.isConclusiveEscape() && elseBranch.isConclusiveEscape()) - return Break(Analyzer::Terminate::Escape); - return Break(Analyzer::Terminate::Bail); - } - // Conditional return - if (thenBranch.active && thenBranch.isEscape() && !hasElse) { - if (!thenBranch.isConclusiveEscape()) { - if (!analyzer->lowerToInconclusive()) - return Break(Analyzer::Terminate::Bail); - } else if (thenBranch.check) { - return Break(); - } else { - if (stopOnCondition(condTok) && stopUpdates()) - return Break(Analyzer::Terminate::Conditional); - analyzer->assume(condTok, false); + + // Commit the condition as false on the main path only when the then-branch + // is dead. The else block, if any, is traversed separately (Pending); with + // no else the false path continues past the closing brace, so record the + // assumed state there (None). + if (thenBranch.isDead()) + analyzer->assume(condTok, + false, + hasElse ? Analyzer::Assume::Pending : Analyzer::Assume::None); + // The else block is traversed on the main path. If it kills the value + // (modified) the main path stops, but the then-fork may still carry the + // value forward, so defer the break until after the fork continues. + Progress pElse = Progress::Continue; + if (hasElse) + pElse = updateBranch(elseBranch, depth - 1); + if (thenBranch.isDead() || elseBranch.isDead()) { + if (conditional && stopUpdates()) + pElse = Break(Analyzer::Terminate::Conditional); } - } - if (thenBranch.isInconclusive() || elseBranch.isInconclusive()) { - if (!analyzer->lowerToInconclusive()) - return Break(Analyzer::Terminate::Bail); - } else if (thenBranch.isModified() || elseBranch.isModified()) { - if (!hasElse && analyzer->isConditional() && stopUpdates()) - return Break(Analyzer::Terminate::Conditional); - if (!analyzer->lowerToPossible()) + if (thenBranch.isModified() || elseBranch.isModified()) { + if (!ft.analyzer->lowerToPossible()) + pThen = Progress::Break; + if (pElse != Progress::Break && !analyzer->lowerToPossible()) + pElse = Break(Analyzer::Terminate::Bail); + } + if (thenBranch.isInconclusive() || elseBranch.isInconclusive()) { + if (!ft.analyzer->lowerToInconclusive()) + pThen = Progress::Break; + if (pElse != Progress::Break && !analyzer->lowerToInconclusive()) + pElse = Break(Analyzer::Terminate::Bail); + } + if (thenBranch.hasGoto() || elseBranch.hasGoto()) { return Break(Analyzer::Terminate::Bail); - analyzer->assume(condTok, elseBranch.isModified()); + } + // Carry the then-fork forward, unless a limit is hit - then only the linear main + // path continues (no bail). forkDepth bounds nesting, forkBudget total. <0 = off. + assert(forkBudget != nullptr); + const int forkDepthLimit = settings.vfOptions.maxForwardConditionForkDepth; + const int forkBudgetLimit = settings.vfOptions.maxForwardConditionForks; + const bool depthOk = forkDepthLimit < 0 || forkDepth < forkDepthLimit; + const bool budgetOk = forkBudgetLimit < 0 || *forkBudget < forkBudgetLimit; + if (pThen != Progress::Break && !thenBranch.isEscape() && depthOk && budgetOk) { + ++(*forkBudget); + ++ft.forkDepth; + ft.updateRange(thenBranch.endBlock, end, depth - 1); + } + if (pElse == Progress::Break) + return Break(); } } } else if (Token::simpleMatch(tok, "try {")) { diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index b86ca2d8812..013906d00ae 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -262,26 +262,33 @@ ProgramMemory::Map::iterator ProgramMemory::find(nonneg int exprid) return mValues->find(ExprIdToken::create(exprid)); } -static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings& settings); - -static bool evaluateCondition(MathLib::bigint r, const Token* condition, ProgramMemory& pm, const Settings& settings) +static ValueFlow::Value execute(const Token* expr, + ProgramMemory& pm, + const Settings& settings, + const ProgramMemory::Map& vars = {}); + +static bool evaluateCondition(MathLib::bigint r, + const Token* condition, + ProgramMemory& pm, + const Settings& settings, + const ProgramMemory::Map& vars = {}) { if (!condition) return false; MathLib::bigint result = 0; bool error = false; - execute(condition, pm, &result, &error, settings); + execute(condition, pm, &result, &error, settings, vars); return !error && result == r; } -bool conditionIsFalse(const Token* condition, ProgramMemory pm, const Settings& settings) +bool conditionIsFalse(const Token* condition, ProgramMemory pm, const Settings& settings, const ProgramMemory::Map& vars) { - return evaluateCondition(0, condition, pm, settings); + return evaluateCondition(0, condition, pm, settings, vars); } -bool conditionIsTrue(const Token* condition, ProgramMemory pm, const Settings& settings) +bool conditionIsTrue(const Token* condition, ProgramMemory pm, const Settings& settings, const ProgramMemory::Map& vars) { - return evaluateCondition(1, condition, pm, settings); + return evaluateCondition(1, condition, pm, settings, vars); } static bool frontIs(const std::vector& v, bool i) @@ -337,7 +344,13 @@ static bool isBasicForLoop(const Token* tok) return true; } -static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings& settings, bool then) +// findChanged: optional cached findExpressionChanged (see ProgramMemoryState::FindChangedFn). +static void programMemoryParseCondition(ProgramMemory& pm, + const Token* tok, + const Token* endTok, + const Settings& settings, + bool then, + const ProgramMemoryState::FindChangedFn& findChanged = {}) { auto eval = [&](const Token* t) -> std::vector { if (!t) @@ -351,6 +364,10 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con return {result}; return std::vector{}; }; + // Use the cached closure if given, else compute directly. + auto changed = [&](const Token* e, const Token* s, const Token* en) -> const Token* { + return findChanged ? findChanged(e, s, en) : findExpressionChanged(e, s, en, settings); + }; if (Token::Match(tok, "==|>=|<=|<|>|!=")) { ValueFlow::Value truevalue; ValueFlow::Value falsevalue; @@ -361,7 +378,7 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con return; if (!truevalue.isIntValue()) return; - if (endTok && findExpressionChanged(vartok, tok->next(), endTok, settings)) + if (endTok && changed(vartok, tok->next(), endTok)) return; const bool impossible = (tok->str() == "==" && !then) || (tok->str() == "!=" && then); const ValueFlow::Value& v = then ? truevalue : falsevalue; @@ -370,26 +387,26 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con if (containerTok) pm.setContainerSizeValue(containerTok, v.intvalue, !impossible); } else if (Token::simpleMatch(tok, "!")) { - programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, !then); + programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, !then, findChanged); } else if (then && Token::simpleMatch(tok, "&&")) { - programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then); - programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then); + programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then, findChanged); + programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then, findChanged); } else if (!then && Token::simpleMatch(tok, "||")) { - programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then); - programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then); + programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then, findChanged); + programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then, findChanged); } else if (Token::Match(tok, "&&|%oror%")) { std::vector lhs = eval(tok->astOperand1()); std::vector rhs = eval(tok->astOperand2()); if (lhs.empty() || rhs.empty()) { if (frontIs(lhs, !then)) - programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then); + programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then, findChanged); else if (frontIs(rhs, !then)) - programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then); + programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then, findChanged); else pm.setIntValue(tok, 0, then); } } else if (tok && tok->exprId() > 0) { - if (endTok && findExpressionChanged(tok, tok->next(), endTok, settings)) + if (endTok && changed(tok, tok->next(), endTok)) return; pm.setIntValue(tok, 0, then); const Token* containerTok = settings.library.getContainerFromYield(tok, Library::Container::Yield::EMPTY); @@ -398,14 +415,18 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con } } -static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Scope* scope, const Token* endTok, const Settings& settings) +static void fillProgramMemoryFromConditions(ProgramMemory& pm, + const Scope* scope, + const Token* endTok, + const Settings& settings, + const ProgramMemoryState::FindChangedFn& findChanged) { if (!scope) return; if (!scope->isLocal()) return; assert(scope != scope->nestedIn); - fillProgramMemoryFromConditions(pm, scope->nestedIn, endTok, settings); + fillProgramMemoryFromConditions(pm, scope->nestedIn, endTok, settings, findChanged); if (scope->type == ScopeType::eIf || scope->type == ScopeType::eWhile || scope->type == ScopeType::eElse || scope->type == ScopeType::eFor) { const Token* condTok = getCondTokFromEnd(scope->bodyEnd); if (!condTok) @@ -414,13 +435,16 @@ static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Scope* scop bool error = false; execute(condTok, pm, &result, &error, settings); if (error) - programMemoryParseCondition(pm, condTok, endTok, settings, scope->type != ScopeType::eElse); + programMemoryParseCondition(pm, condTok, endTok, settings, scope->type != ScopeType::eElse, findChanged); } } -static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Token* tok, const Settings& settings) +static void fillProgramMemoryFromConditions(ProgramMemory& pm, + const Token* tok, + const Settings& settings, + const ProgramMemoryState::FindChangedFn& findChanged = {}) { - fillProgramMemoryFromConditions(pm, tok->scope(), tok, settings); + fillProgramMemoryFromConditions(pm, tok->scope(), tok, settings, findChanged); } static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok, const Settings& settings, const ProgramMemory& state, const ProgramMemory::Map& vars) @@ -429,22 +453,12 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok for (const Token *tok2 = tok; tok2; tok2 = tok2->previous()) { if ((Token::simpleMatch(tok2, "=") || Token::Match(tok2->previous(), "%var% (|{")) && tok2->astOperand1() && tok2->astOperand2()) { - bool setvar = false; const Token* vartok = tok2->astOperand1(); - for (const auto& p:vars) { - if (p.first.getExpressionId() != vartok->exprId()) - continue; - if (vartok == tok) - continue; - pm.setValue(vartok, p.second); - setvar = true; - } - if (!setvar) { - if (!pm.hasValue(vartok->exprId())) { - const Token* valuetok = tok2->astOperand2(); - ProgramMemory local = state; - pm.setValue(vartok, execute(valuetok, local, settings)); - } + if (!pm.hasValue(vartok->exprId())) { + const Token* valuetok = tok2->astOperand2(); + ProgramMemory local = state; + // Tracked values are substituted by execute() when the expression is evaluated. + pm.setValue(vartok, execute(valuetok, local, settings, vars)); } } else if (Token::simpleMatch(tok2, ")") && tok2->link() && Token::Match(tok2->link()->previous(), "assert|ASSERT ( !!)")) { @@ -516,7 +530,7 @@ static ProgramMemory getInitialProgramState(const Token* tok, return pm; } -ProgramMemoryState::ProgramMemoryState(const Settings& s) : settings(s) +ProgramMemoryState::ProgramMemoryState(const Settings& s) : settings(s), changedCache(std::make_shared()) {} void ProgramMemoryState::replace(ProgramMemory pm, const Token* origin) @@ -539,7 +553,7 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va { ProgramMemory local = state; addVars(local, vars); - fillProgramMemoryFromConditions(local, tok, settings); + fillProgramMemoryFromConditions(local, tok, settings, getCachedFindExpressionChanged(/*skipDeadCode*/ false)); ProgramMemory pm; fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); local.replace(std::move(pm)); @@ -547,44 +561,73 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va replace(std::move(local), tok); } -void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty) +void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty, const Token* origin) { ProgramMemory pm = state; if (isEmpty) pm.setContainerSizeValue(tok, 0, b); else programMemoryParseCondition(pm, tok, nullptr, settings, b); - const Token* origin = tok; - const Token* top = tok->astTop(); - if (Token::Match(top->previous(), "for|while|if (") && !Token::simpleMatch(tok->astParent(), "?")) { - origin = top->link()->next(); - if (!b && origin->link()) { - origin = origin->link(); + if (!origin) { + origin = tok; + const Token* top = tok->astTop(); + if (Token::Match(top->previous(), "for|while|if (") && !Token::simpleMatch(tok->astParent(), "?")) { + origin = top->link()->next(); + if (!b && origin->link()) { + origin = origin->link(); + } } } replace(std::move(pm), origin); } -void ProgramMemoryState::removeModifiedVars(const Token* tok) +ProgramMemoryState::FindChangedFn ProgramMemoryState::getCachedFindExpressionChanged(bool skipDeadCode) const { - const ProgramMemory& pm = state; - auto eval = [&](const Token* cond) -> std::vector { - ProgramMemory pm2 = pm; - auto result = execute(cond, pm2, settings); - if (isTrue(result)) - return {1}; - if (isFalse(result)) - return {0}; - return {}; + // Structural findExpressionChanged() is pure, so memoize it in changedCache (never invalidated). + // skipDeadCode adds the dead-code walk; it evaluates guards against a fixed state snapshot (so every + // variable follows the same path) and memoizes those evals in evalCache for the closure's lifetime. + using EvalCache = std::map>; + const std::shared_ptr cache = changedCache; + const Settings* const sp = &settings; + ProgramMemory snapshot = state; + const std::shared_ptr evalCache = skipDeadCode ? std::make_shared() : nullptr; + return [cache, sp, snapshot, skipDeadCode, evalCache](const Token* expr, + const Token* start, + const Token* end) -> const Token* { + const auto key = std::make_tuple(expr, start, end); + const auto it = cache->find(key); + const Token* modified = (it != cache->end()) + ? it->second + : cache->emplace(key, findExpressionChanged(expr, start, end, *sp)).first->second; + if (!skipDeadCode || !modified) + return modified; + auto eval = [&](const Token* cond) -> std::vector { + const auto cit = evalCache->find(cond); + if (cit != evalCache->end()) + return cit->second; + ProgramMemory pm2 = snapshot; + const auto result = execute(cond, pm2, *sp); + std::vector r; + if (isTrue(result)) + r = {1}; + else if (isFalse(result)) + r = {0}; + return evalCache->emplace(cond, std::move(r)).first->second; + }; + return findExpressionChangedSkipDeadCode(expr, start, end, *sp, eval); }; +} + +void ProgramMemoryState::removeModifiedVars(const Token* tok) +{ + const auto findChanged = getCachedFindExpressionChanged(/*skipDeadCode*/ true); state.erase_if([&](const ExprIdToken& e) { const Token* start = origins[e.getExpressionId()]; const Token* expr = e.tok; - if (!expr || findExpressionChangedSkipDeadCode(expr, start, tok, settings, eval)) { + const bool changed = !expr || findChanged(expr, start, tok); + if (changed) origins.erase(e.getExpressionId()); - return true; - } - return false; + return changed; }); } @@ -1316,6 +1359,9 @@ namespace { struct Executor { ProgramMemory* pm; const Settings& settings; + // Values tracked by the forward/reverse analysis. A tracked value is the authoritative + // current value of its expression and takes precedence over the program memory. + const ProgramMemory::Map* vars = nullptr; int fdepth = 4; int depth = 10; @@ -1324,6 +1370,26 @@ namespace { assert(pm != nullptr); } + // Is the tracked value for this expression available? + const ValueFlow::Value* getTrackedValue(const Token* expr) const + { + if (!vars || expr->exprId() == 0) + return nullptr; + const auto it = vars->find(ExprIdToken::create(expr->exprId())); + return it == vars->end() ? nullptr : &it->second; + } + + // Does the expression read a tracked value? If so, any value cached for it may be stale + // (the tracked value may have changed since), so it must be re-evaluated, not served cached. + bool dependsOnTrackedValue(const Token* expr) const + { + if (!vars || vars->empty()) + return false; + return findAstNode(expr, [&](const Token* tok) { + return getTrackedValue(tok) != nullptr; + }) != nullptr; + } + static ValueFlow::Value unknown() { return ValueFlow::Value::unknown(); } @@ -1622,7 +1688,15 @@ namespace { } return execute(expr->astOperand1()); } - if (expr->exprId() > 0 && pm->hasValue(expr->exprId())) { + // Return the tracked value and write it back when it differs, so later reads see the + // same value (as fillProgramMemoryFromAssignments used to do). + if (const ValueFlow::Value* tracked = getTrackedValue(expr)) { + const ValueFlow::Value* stored = pm->getValue(expr->exprId(), /*impossible*/ true); + if (!stored || *stored != *tracked) + pm->setValue(expr, *tracked); + return *tracked; + } + if (expr->exprId() > 0 && pm->hasValue(expr->exprId()) && !dependsOnTrackedValue(expr)) { ValueFlow::Value result = utils::as_const(*pm).at(expr->exprId()); if (result.isImpossible() && result.isIntValue() && result.intvalue == 0 && isUsedAsBool(expr, settings)) { result.intvalue = !result.intvalue; @@ -1815,9 +1889,13 @@ namespace { }; } // namespace -static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings& settings) +static ValueFlow::Value execute(const Token* expr, + ProgramMemory& pm, + const Settings& settings, + const ProgramMemory::Map& vars) { Executor ex{&pm, settings}; + ex.vars = &vars; return ex.execute(expr); } @@ -1907,9 +1985,10 @@ void execute(const Token* expr, ProgramMemory& programMemory, MathLib::bigint* result, bool* error, - const Settings& settings) + const Settings& settings, + const ProgramMemory::Map& vars) { - ValueFlow::Value v = execute(expr, programMemory, settings); + ValueFlow::Value v = execute(expr, programMemory, settings, vars); if (!v.isIntValue() || v.isImpossible()) { if (error) *error = true; diff --git a/lib/programmemory.h b/lib/programmemory.h index ec24c0df59f..de81d0bc901 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -161,9 +162,26 @@ struct CPPCHECKLIB ProgramMemory { }; struct ProgramMemoryState { + struct ChangedKeyHash { + std::size_t operator()(const std::tuple& t) const + { + const std::hash h; + std::size_t seed = h(std::get<0>(t)); + seed ^= h(std::get<1>(t)) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + seed ^= h(std::get<2>(t)) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } + }; + using ChangedCache = + std::unordered_map, const Token*, ChangedKeyHash>; + // The token modifying expr between start and end, or nullptr. + using FindChangedFn = std::function; + ProgramMemory state; std::map origins; const Settings& settings; + // Memoized findExpressionChanged() pre-filter; structural, so never invalidated. + std::shared_ptr changedCache; explicit ProgramMemoryState(const Settings& s); @@ -171,10 +189,13 @@ struct ProgramMemoryState { void addState(const Token* tok, const ProgramMemory::Map& vars); - void assume(const Token* tok, bool b, bool isEmpty = false); + void assume(const Token* tok, bool b, bool isEmpty = false, const Token* origin = nullptr); void removeModifiedVars(const Token* tok); + // A findExpressionChanged() closure memoized in changedCache + FindChangedFn getCachedFindExpressionChanged(bool skipDeadCode) const; + ProgramMemory get(const Token* tok, const Token* ctx, const ProgramMemory::Map& vars) const; }; @@ -184,21 +205,30 @@ void execute(const Token* expr, ProgramMemory& programMemory, MathLib::bigint* result, bool* error, - const Settings& settings); + const Settings& settings, + const ProgramMemory::Map& vars = {}); /** * Is condition always false when variable has given value? * \param condition top ast token in condition * \param pm program memory + * \param vars optional tracked values that take precedence over the program memory */ -bool conditionIsFalse(const Token* condition, ProgramMemory pm, const Settings& settings); +bool conditionIsFalse(const Token* condition, + ProgramMemory pm, + const Settings& settings, + const ProgramMemory::Map& vars = {}); /** * Is condition always true when variable has given value? * \param condition top ast token in condition * \param pm program memory + * \param vars optional tracked values that take precedence over the program memory */ -bool conditionIsTrue(const Token* condition, ProgramMemory pm, const Settings& settings); +bool conditionIsTrue(const Token* condition, + ProgramMemory pm, + const Settings& settings, + const ProgramMemory::Map& vars = {}); /** * Get program memory by looking backwards from given token. diff --git a/lib/settings.cpp b/lib/settings.cpp index c0539bbeaba..479346208e3 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -335,6 +335,7 @@ void Settings::setCheckLevel(CheckLevel level) vfOptions.maxIfCount = 100; vfOptions.doConditionExpressionAnalysis = false; vfOptions.maxForwardBranches = 4; + vfOptions.maxForwardConditionForkDepth = 0; vfOptions.maxIterations = 1; } else if (level == CheckLevel::normal) { @@ -344,6 +345,7 @@ void Settings::setCheckLevel(CheckLevel level) vfOptions.maxIfCount = 100; vfOptions.doConditionExpressionAnalysis = false; vfOptions.maxForwardBranches = 4; + vfOptions.maxForwardConditionForkDepth = 1; } else if (level == CheckLevel::exhaustive) { // Checking can take a little while. ~ 10 times slower than normal analysis is OK. @@ -352,6 +354,8 @@ void Settings::setCheckLevel(CheckLevel level) vfOptions.maxSubFunctionArgs = 256; vfOptions.doConditionExpressionAnalysis = true; vfOptions.maxForwardBranches = -1; + vfOptions.maxForwardConditionForkDepth = 4; + vfOptions.maxForwardConditionForks = 256; } } diff --git a/lib/settings.h b/lib/settings.h index 4a73f35039b..ce4a32e1690 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -512,6 +512,15 @@ class CPPCHECKLIB WARN_UNUSED Settings { /** @brief Maximum performed forward branches */ int maxForwardBranches = -1; + /** @brief Maximum depth of nested condition-fork continuations in the forward analyzer. + Bounds the exponential fan-out of carrying condition state forward at exhaustive level (where + maxForwardBranches is unlimited); past it the forward analysis continues on a single linear path + without skipping any branch. 0 disables forking (linear); a negative value means unlimited. */ + int maxForwardConditionForkDepth = 4; + + /** @brief Maximum total condition-fork continuations in one forward traversal. */ + int maxForwardConditionForks = 256; + /** @brief Maximum performed alignof recursion */ int maxAlignOfRecursion = 100; diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 44c86cbc2b7..cfba7d5f970 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -678,16 +678,20 @@ struct ValueFlowAnalyzer : Analyzer { if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) return {v->intvalue}; std::vector result; - ProgramMemory pm = getProgramMemoryFunc(); + // Pass the tracked values so a cached program-memory value that depends on one (e.g. 'h(p)' + // after 'p' was reassigned) is re-evaluated rather than served stale. The memory is built + // from the same state, so compute it once and hand it to the builder. + const ProgramState vars = getProgramState(); + ProgramMemory pm = getProgramMemoryFunc(vars); if (Token::Match(tok, "&&|%oror%")) { - if (conditionIsTrue(tok, pm, getSettings())) + if (conditionIsTrue(tok, pm, getSettings(), vars)) result.push_back(1); - if (conditionIsFalse(tok, std::move(pm), getSettings())) + if (conditionIsFalse(tok, std::move(pm), getSettings(), vars)) result.push_back(0); } else { MathLib::bigint out = 0; bool error = false; - execute(tok, pm, &out, &error, getSettings()); + execute(tok, pm, &out, &error, getSettings(), vars); if (!error) result.push_back(out); } @@ -696,16 +700,16 @@ struct ValueFlowAnalyzer : Analyzer { std::vector evaluateInt(const Token* tok) const { - return evaluateInt(tok, [&] { - return ProgramMemory{getProgramState()}; + return evaluateInt(tok, [](const ProgramState& vars) { + return ProgramMemory{vars}; }); } std::vector evaluate(Evaluate e, const Token* tok, const Token* ctx = nullptr) const override { if (e == Evaluate::Integral) { - return evaluateInt(tok, [&] { - return pms.get(tok, ctx, getProgramState()); + return evaluateInt(tok, [&](const ProgramState& vars) { + return pms.get(tok, ctx, vars); }); } if (e == Evaluate::ContainerEmpty) { @@ -723,30 +727,43 @@ struct ValueFlowAnalyzer : Analyzer { return {}; } - void assume(const Token* tok, bool state, unsigned int flags) override { - // Update program state - pms.removeModifiedVars(tok); - pms.addState(tok, getProgramState()); - pms.assume(tok, state, flags & Assume::ContainerEmpty); - + void assume(const Token* tok, bool state, unsigned int flags) override + { bool isCondBlock = false; const Token* parent = tok->astParent(); if (parent) { isCondBlock = Token::Match(parent->previous(), "if|while ("); } + const Token* endBlock = nullptr; if (isCondBlock) { const Token* startBlock = parent->link()->next(); if (Token::simpleMatch(startBlock, ";") && Token::simpleMatch(parent->tokAt(-2), "} while (")) startBlock = parent->linkAt(-2); - const Token* endBlock = startBlock->link(); - if (state) { - pms.removeModifiedVars(endBlock); - pms.addState(endBlock->previous(), getProgramState()); - } else { - if (Token::simpleMatch(endBlock, "} else {")) - pms.addState(endBlock->linkAt(2)->previous(), getProgramState()); - } + endBlock = startBlock->link(); + } + + // Without Pending the 'then' block has been traversed and control is leaving it, so anchor + // the assumed state at the block end instead of the condition. That keeps assumptions on + // variables modified inside the block (e.g. an 'if' narrowing a value computed there) from + // being discarded as "modified" once control leaves the block. + const bool scopeEnd = !(flags & Assume::Pending) && state && endBlock; + const Token* anchor = scopeEnd ? endBlock : tok; + const Token* origin = scopeEnd ? endBlock : nullptr; + + // Update program state + pms.removeModifiedVars(anchor); + pms.addState(anchor, getProgramState()); + pms.assume(tok, state, flags & Assume::ContainerEmpty, origin); + + // The false path (the true path uses scopeEnd above): record the assumed state where control + // continues - the end of the else block, or the closing brace when there is no else - so it + // reaches the enclosing scope. + if (isCondBlock && !(flags & Assume::Pending) && !state) { + if (Token::simpleMatch(endBlock, "} else {")) + pms.addState(endBlock->linkAt(2)->previous(), getProgramState()); + else + pms.addState(endBlock, getProgramState()); } if (!(flags & Assume::Quiet)) { diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 2867f147d81..df421d6879c 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -4941,7 +4941,9 @@ class TestAutoVariables : public TestFixture { " return *iPtr;\n" " return 0;\n" "}"); - ASSERT_EQUALS("[test.cpp:5:16] -> [test.cpp:4:13] -> [test.cpp:8:17]: (error) Using pointer to local variable 'x' that is out of scope. [invalidLifetime]\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:5:16] -> [test.cpp:7:10] -> [test.cpp:4:13] -> [test.cpp:8:17]: (error) Using pointer to local variable 'x' that is out of scope. [invalidLifetime]\n", + errout_str()); // #11753 check("int main(int argc, const char *argv[]) {\n" diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 3143b6eb201..837cd4e78ba 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4911,6 +4911,30 @@ class TestCondition : public TestFixture { ASSERT_EQUALS("[test.cpp:3:10]: (style) Condition 'b()' is always false [knownConditionTrueFalse]\n" "[test.cpp:4:9]: (style) Condition '!b()' is always true [knownConditionTrueFalse]\n", errout_str()); + + check("int g();\n" // a value modified inside a nested branch must be lowered to possible + "void f(int outer, int inner) {\n" + " int bits = 0;\n" + " if (outer) {\n" + " if (inner == 1)\n" + " bits = g();\n" + " }\n" + " if (bits > 0) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("int g();\n" // the modifying branch has an escaping sibling - still must be lowered + "void f(int t, int u) {\n" + " int v = 0;\n" + " if (t) {\n" + " if (u == 2)\n" + " v = g();\n" + " else\n" + " return;\n" + " }\n" + " if (v > 0) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void alwaysTrueSymbolic() diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 369c04a2101..2483a967947 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -2450,6 +2450,9 @@ class TestNullPointer : public TestFixture { void nullpointer77() { + // No warning: 'i' is passed to the unknown function 'h' in the same condition that guards the + // dereference. 'h' may validate the pointer (e.g. return false for null), so '*i' can be safe + // - this is the common "if (check(p) && p->...)" pattern, so we must not assume 'i' is null. check("bool h(int*);\n" "void f(int* i) {\n" " int* i = nullptr;\n" @@ -2465,6 +2468,8 @@ class TestNullPointer : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); + // Likewise here, even though 'i' is null when the first 'h(i)' was true: the second 'h(i)' is an + // independent call that may validate 'i', so '*i' is not necessarily a null dereference. check("bool h(int*);\n" "void f(int* x) {\n" " int* i = x;\n" diff --git a/test/testother.cpp b/test/testother.cpp index fa6899cf543..02418df5627 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -11511,8 +11511,9 @@ class TestOther : public TestFixture { " x = a + b;\n" " return x;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:4:9]: (style) Variable 'x' is assigned an expression that holds the same value. [redundantAssignment]\n", - errout_str()); + ASSERT_EQUALS( + "[test.cpp:2:11] -> [test.cpp:3:9] -> [test.cpp:4:9]: (style) Variable 'x' is assigned an expression that holds the same value. [redundantAssignment]\n", + errout_str()); } void varFuncNullUB() { // #4482 diff --git a/test/teststl.cpp b/test/teststl.cpp index 35941f6422c..93b53b43671 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -368,7 +368,9 @@ class TestStl : public TestFixture { " if(b) ++x;\n" " return s[x];\n" "}"); - ASSERT_EQUALS("[test.cpp:5:13]: error: Out of bounds access in 's[x]', if 's' size is 6 and 'x' is 6 [containerOutOfBounds]\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:5:13]: error: Out of bounds access in 's[x]', if 's' size is 6 and 'x' is 7 [containerOutOfBounds]\n", + errout_str()); checkNormal("void f() {\n" " static const int N = 4;\n" diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index e0c5512f1fd..6a43493cd0d 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -4265,7 +4265,7 @@ class TestUninitVar : public TestFixture { " else {}\n" " return y;\n" "}"); - TODO_ASSERT_EQUALS("", "[test.cpp:5:9] -> [test.cpp:7:12]: (warning) Uninitialized variable: y [uninitvar]\n", errout_str()); + ASSERT_EQUALS("", errout_str()); // #4560: escaping else keeps x known, so x is true and y is initialized valueFlowUninit("int f(int a) {\n" // #6583 " int x;\n" @@ -4284,7 +4284,8 @@ class TestUninitVar : public TestFixture { " else y = 123;\n" // <- y is always initialized " return y;\n" "}"); - TODO_ASSERT_EQUALS("", "[test.cpp:5:9] -> [test.cpp:7:12]: (warning) Uninitialized variable: y [uninitvar]\n", errout_str()); + ASSERT_EQUALS("", + errout_str()); // #4560: fork-based condition analysis tracks x==0 -> else branch -> y initialized valueFlowUninit("void f(int x) {\n" // #3948 " int value;\n" @@ -5614,6 +5615,47 @@ class TestUninitVar : public TestFixture { "}"); ASSERT_EQUALS("[test.cpp:18:9] -> [test.cpp:12:13] -> [test.cpp:8:15]: (warning) Uninitialized variable: s->flag [uninitvar]\n", errout_str()); + // A value narrowed by a nested condition (dimensions < 1 here) must survive the enclosing + // 'if' so a later correlated condition can be resolved: dimensions == 1 is then false, the + // function does not return, and the uninitialized read is reached. + valueFlowUninit("unsigned int g();\n" + "void f(bool a) {\n" + " unsigned int dimensions = 0;\n" + " bool mightBeLarger;\n" + " if (a) {\n" + " dimensions = g();\n" + " if (dimensions >= 1)\n" + " mightBeLarger = false;\n" + " } else {\n" + " mightBeLarger = false;\n" + " }\n" + " if (dimensions == 1)\n" + " return;\n" + " if (!mightBeLarger) {}\n" + "}"); + ASSERT_EQUALS( + "[test.cpp:5:9] -> [test.cpp:7:24] -> [test.cpp:14:10]: (warning) Uninitialized variable: mightBeLarger [uninitvar]\n", + errout_str()); + + // Same shape, but the later condition (dimensions == 0) is implied by the narrowing, so the + // early return fires on the uninitialized path and there must be no warning. + valueFlowUninit("unsigned int g();\n" + "void f(bool a) {\n" + " unsigned int dimensions = 0;\n" + " bool mightBeLarger;\n" + " if (a) {\n" + " dimensions = g();\n" + " if (dimensions >= 1)\n" + " mightBeLarger = false;\n" + " } else {\n" + " mightBeLarger = false;\n" + " }\n" + " if (dimensions == 0)\n" + " return;\n" + " if (!mightBeLarger) {}\n" + "}"); + ASSERT_EQUALS("", errout_str()); + // Ticket #2207 - False negative valueFlowUninit("void foo() {\n" " int a;\n" diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index c015664554a..888710ce57d 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -6123,9 +6123,9 @@ class TestValueFlow : public TestFixture { " c++;\n" "}\n"; values = tokenValues(code, "c ++ ; }"); - TODO_ASSERT_EQUALS(true, false, values.size() == 2); - // ASSERT_EQUALS(true, values.front().isUninitValue() || values.back().isUninitValue()); - // ASSERT_EQUALS(true, values.front().isPossible() || values.back().isPossible()); + ASSERT_EQUALS(true, values.size() == 2); + ASSERT_EQUALS(true, values.front().isUninitValue() || values.back().isUninitValue()); + ASSERT_EQUALS(true, values.front().isPossible() || values.back().isPossible()); // ASSERT_EQUALS(true, values.front().intvalue == 0 || values.back().intvalue == 0); code = "void b(bool d, bool e) {\n" @@ -8446,6 +8446,75 @@ class TestValueFlow : public TestFixture { " static T f[64];\n" "};\n"; (void)valueOfTok(code, "("); + + // fork explosion on many opaque conditions; bounded by maxForwardConditionForks + code = "int g(int);\n" + "bool h(int);\n" + "void f() {\n" + " int x = 0;\n" + " if (h(0)) g(x);\n" + " if (h(1)) g(x);\n" + " if (h(2)) g(x);\n" + " if (h(3)) g(x);\n" + " if (h(4)) g(x);\n" + " if (h(5)) g(x);\n" + " if (h(6)) g(x);\n" + " if (h(7)) g(x);\n" + " if (h(8)) g(x);\n" + " if (h(9)) g(x);\n" + " if (h(10)) g(x);\n" + " if (h(11)) g(x);\n" + " if (h(12)) g(x);\n" + " if (h(13)) g(x);\n" + " if (h(14)) g(x);\n" + " if (h(15)) g(x);\n" + " if (h(16)) g(x);\n" + " if (h(17)) g(x);\n" + " if (h(18)) g(x);\n" + " if (h(19)) g(x);\n" + " if (h(20)) g(x);\n" + " if (h(21)) g(x);\n" + " if (h(22)) g(x);\n" + " if (h(23)) g(x);\n" + " if (h(24)) g(x);\n" + " if (h(25)) g(x);\n" + " if (h(26)) g(x);\n" + " if (h(27)) g(x);\n" + " if (h(28)) g(x);\n" + " if (h(29)) g(x);\n" + " if (h(30)) g(x);\n" + " if (h(31)) g(x);\n" + " if (h(32)) g(x);\n" + " if (h(33)) g(x);\n" + " if (h(34)) g(x);\n" + " if (h(35)) g(x);\n" + " if (h(36)) g(x);\n" + " if (h(37)) g(x);\n" + " if (h(38)) g(x);\n" + " if (h(39)) g(x);\n" + " if (h(40)) g(x);\n" + " if (h(41)) g(x);\n" + " if (h(42)) g(x);\n" + " if (h(43)) g(x);\n" + " if (h(44)) g(x);\n" + " if (h(45)) g(x);\n" + " if (h(46)) g(x);\n" + " if (h(47)) g(x);\n" + " if (h(48)) g(x);\n" + " if (h(49)) g(x);\n" + " if (h(50)) g(x);\n" + " if (h(51)) g(x);\n" + " if (h(52)) g(x);\n" + " if (h(53)) g(x);\n" + " if (h(54)) g(x);\n" + " if (h(55)) g(x);\n" + " if (h(56)) g(x);\n" + " if (h(57)) g(x);\n" + " if (h(58)) g(x);\n" + " if (h(59)) g(x);\n" + " (void)x;\n" + "}\n"; + (void)valueOfTok(code, "x"); } void valueFlowCrashConstructorInitialization() { // #9577 From 1e1bc87e2b424512af04e071840f59512c3453f9 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 6 Jul 2026 08:34:42 +0200 Subject: [PATCH 222/493] Fix #14884 fuzzing timeout (hang) in TemplateSimplifier::expandTemplate() (#8691) --- lib/templatesimplifier.cpp | 8 ++++++-- .../timeout-5225c0e6e895cdd05a15c388547d13a78a2574e2 | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 test/cli/fuzz-timeout/timeout-5225c0e6e895cdd05a15c388547d13a78a2574e2 diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 4051b05c204..6fdd423628b 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -170,8 +170,12 @@ TemplateSimplifier::TokenAndName::TokenAndName(Token *token, std::string scope, if (isFunction()) tok1 = tok1->link()->next(); while (tok1 && !Token::Match(tok1, ";|{")) { - if (tok1->str() == "<") - tok1 = tok1->findClosingBracket(); + if (tok1->str() == "<") { + if (const Token* closing = tok1->findClosingBracket()) + tok1 = closing; + else + syntaxError(tok1); + } else if (Token::Match(tok1, "(|[") && tok1->link()) tok1 = tok1->link(); if (tok1) diff --git a/test/cli/fuzz-timeout/timeout-5225c0e6e895cdd05a15c388547d13a78a2574e2 b/test/cli/fuzz-timeout/timeout-5225c0e6e895cdd05a15c388547d13a78a2574e2 new file mode 100644 index 00000000000..71e751bb201 --- /dev/null +++ b/test/cli/fuzz-timeout/timeout-5225c0e6e895cdd05a15c388547d13a78a2574e2 @@ -0,0 +1 @@ +templatestruct e<; From 08db3048d54dcf6a3cc3b19613f286e30268cc9e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 6 Jul 2026 09:11:57 +0200 Subject: [PATCH 223/493] Fix #14883 fuzzing crash (null-pointer-use) in Tokenizer::findGarbageCode() (#8692) --- lib/tokenize.cpp | 2 ++ .../fuzz-crash/crash-17be2b85446aeb0c7722bedfad4b0e4af27fae3d | 1 + 2 files changed, 3 insertions(+) create mode 100644 test/cli/fuzz-crash/crash-17be2b85446aeb0c7722bedfad4b0e4af27fae3d diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 61719f5291d..3046bea69cc 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8962,6 +8962,8 @@ void Tokenizer::findGarbageCode() const const Token* const endTok = tok->linkAt(1); for (tok = tok->tokAt(2); tok != endTok; tok = tok->next()) { if (const Token* lam = findLambdaEndTokenWithoutAST(tok)) { + if (lam == endTok) + break; tok = lam; continue; } diff --git a/test/cli/fuzz-crash/crash-17be2b85446aeb0c7722bedfad4b0e4af27fae3d b/test/cli/fuzz-crash/crash-17be2b85446aeb0c7722bedfad4b0e4af27fae3d new file mode 100644 index 00000000000..0f06807b7ba --- /dev/null +++ b/test/cli/fuzz-crash/crash-17be2b85446aeb0c7722bedfad4b0e4af27fae3d @@ -0,0 +1 @@ +{for([]{});} From 42a08059f71f3952f7f992dfe82828e2af495c6e Mon Sep 17 00:00:00 2001 From: glankk Date: Tue, 7 Jul 2026 13:27:26 +0200 Subject: [PATCH 224/493] Fix #14898: Update simplecpp to 1.8.1 (#8702) --- .selfcheck_suppressions | 1 - externals/simplecpp/simplecpp.cpp | 216 +++++++++++++++++++----------- externals/simplecpp/simplecpp.h | 65 +++------ 3 files changed, 154 insertions(+), 128 deletions(-) diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index 402fdbeb75d..f21492e783a 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -79,4 +79,3 @@ useStlAlgorithm:externals/simplecpp/simplecpp.cpp funcArgNamesDifferentUnnamed:externals/simplecpp/simplecpp.h missingMemberCopy:externals/simplecpp/simplecpp.h shadowFunction:externals/simplecpp/simplecpp.h -knownConditionTrueFalse:externals/simplecpp/simplecpp.cpp \ No newline at end of file diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index 47e674837ba..d2c398c49e1 100644 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -3,18 +3,12 @@ * Copyright (C) 2016-2023 simplecpp team */ +// needs to be specified here otherwise _mingw.h will define it as 0x0601 +// causing FileIdInfo not to be available #if defined(_WIN32) # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0602 # endif -# ifndef NOMINMAX -# define NOMINMAX -# endif -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# undef ERROR #endif #include "simplecpp.h" @@ -51,10 +45,19 @@ #include #include -#ifdef _WIN32 +#if defined(_WIN32) +# ifndef NOMINMAX +# define NOMINMAX +# endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# undef ERROR # include #else # include +# include #endif static bool isHex(const std::string &s) @@ -658,8 +661,6 @@ static const std::string COMMENT_END("*/"); void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, OutputList *outputList) { - std::stack loc; - unsigned int multiline = 0U; const Token *oldLastToken = nullptr; @@ -698,59 +699,44 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, if (oldLastToken != cback()) { oldLastToken = cback(); - const Token * const llTok = isLastLinePreprocessor(); - if (!llTok) + + // #line 3 + // #line 3 "file.c" + // #3 + // #3 "file.c" + const Token * ppTok = isLastLinePreprocessor(); + if (!ppTok) continue; - const Token * const llNextToken = llTok->next; - if (!llTok->next) + + const auto advanceAndSkipComments = [](const Token* tok) { + do { + tok = tok->next; + } while (tok && tok->comment); + return tok; + }; + + // skip # + ppTok = advanceAndSkipComments(ppTok); + if (!ppTok) continue; - if (llNextToken->next) { - // #file "file.c" - if (llNextToken->str() == "file" && - llNextToken->next->str()[0] == '\"') - { - const Token *strtok = cback(); - while (strtok->comment) - strtok = strtok->previous; - loc.push(location); - location.fileIndex = fileIndex(strtok->str().substr(1U, strtok->str().size() - 2U)); - location.line = 1U; - } - // TODO: add support for "# 3" - // #3 "file.c" - // #line 3 "file.c" - else if ((llNextToken->number && - llNextToken->next->str()[0] == '\"') || - (llNextToken->str() == "line" && - llNextToken->next->number && - llNextToken->next->next && - llNextToken->next->next->str()[0] == '\"')) - { - const Token *strtok = cback(); - while (strtok->comment) - strtok = strtok->previous; - const Token *numtok = strtok->previous; - while (numtok->comment) - numtok = numtok->previous; - lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")), - std::atol(numtok->str().c_str()), location); - } - // #line 3 - else if (llNextToken->str() == "line" && - llNextToken->next->number) - { - const Token *numtok = cback(); - while (numtok->comment) - numtok = numtok->previous; - lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), location); - } - } - // #endfile - else if (llNextToken->str() == "endfile" && !loc.empty()) - { - location = loc.top(); - loc.pop(); - } + + if (ppTok->str() == "line") + ppTok = advanceAndSkipComments(ppTok); + + if (!ppTok || !ppTok->number) + continue; + + const unsigned int line = std::atol(ppTok->str().c_str()); + ppTok = advanceAndSkipComments(ppTok); + + unsigned int fileindex; + + if (ppTok && ppTok->str()[0] == '\"') + fileindex = fileIndex(replaceAll(ppTok->str().substr(1U, ppTok->str().size() - 2U),"\\\\","\\")); + else + fileindex = location.fileIndex; + + lineDirective(fileindex, line, location); } continue; @@ -1031,8 +1017,7 @@ static bool isAlternativeAndBitandBitor(const simplecpp::Token* tok) void simplecpp::TokenList::combineOperators() { - std::stack executableScope; - executableScope.push(false); + std::stack> executableScope{{false}}; for (Token *tok = front(); tok; tok = tok->next) { if (tok->op == '{') { if (executableScope.top()) { @@ -1040,7 +1025,7 @@ void simplecpp::TokenList::combineOperators() continue; } const Token *prev = tok->previous; - while (prev && prev->isOneOf(";{}()")) + while (prev && prev->isOneOf(";{}(")) prev = prev->previous; executableScope.push(prev && prev->op == ')'); continue; @@ -2332,9 +2317,6 @@ namespace simplecpp { const Token *nextTok = B->next; if (canBeConcatenatedStringOrChar) { - if (unexpectedA) - throw invalidHashHash::unexpectedToken(tok->location, name(), A); - // It seems clearer to handle this case separately even though the code is similar-ish, but we don't want to merge here. // TODO The question is whether the ## or varargs may still apply, and how to provoke? if (expandArg(tokensB, B, parametertokens)) { @@ -3090,6 +3072,65 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const return ""; } +namespace { + struct FileID { +#ifdef _WIN32 + struct { + std::uint64_t VolumeSerialNumber; + struct { + std::uint64_t IdentifierHi; + std::uint64_t IdentifierLo; + } FileId; + } fileIdInfo; + + bool operator==(const FileID &that) const noexcept { + return fileIdInfo.VolumeSerialNumber == that.fileIdInfo.VolumeSerialNumber && + fileIdInfo.FileId.IdentifierHi == that.fileIdInfo.FileId.IdentifierHi && + fileIdInfo.FileId.IdentifierLo == that.fileIdInfo.FileId.IdentifierLo; + } +#else + dev_t dev; + ino_t ino; + + bool operator==(const FileID& that) const noexcept { + return dev == that.dev && ino == that.ino; + } +#endif + struct Hasher { + std::size_t operator()(const FileID &id) const { +#ifdef _WIN32 + return static_cast(id.fileIdInfo.FileId.IdentifierHi ^ id.fileIdInfo.FileId.IdentifierLo ^ + id.fileIdInfo.VolumeSerialNumber); +#else + return static_cast(id.dev) ^ static_cast(id.ino); +#endif + } + }; + }; +} + +struct simplecpp::FileDataCache::Impl +{ + void clear() + { + mIdMap.clear(); + } + + using id_map_type = std::unordered_map; + + id_map_type mIdMap; +}; + +simplecpp::FileDataCache::FileDataCache() + : mImpl(new Impl) +{} + +simplecpp::FileDataCache::~FileDataCache() = default; +simplecpp::FileDataCache::FileDataCache(FileDataCache &&) noexcept = default; +simplecpp::FileDataCache &simplecpp::FileDataCache::operator=(simplecpp::FileDataCache &&) noexcept = default; + +static bool getFileId(const std::string &path, FileID &id); + std::pair simplecpp::FileDataCache::tryload(FileDataCache::name_map_type::iterator &name_it, const simplecpp::DUI &dui, std::vector &filenames, simplecpp::OutputList *outputList) { const std::string &path = name_it->first; @@ -3098,8 +3139,8 @@ std::pair simplecpp::FileDataCache::tryload(FileDat if (!getFileId(path, fileId)) return {nullptr, false}; - const auto id_it = mIdMap.find(fileId); - if (id_it != mIdMap.end()) { + const auto id_it = mImpl->mIdMap.find(fileId); + if (id_it != mImpl->mIdMap.end()) { name_it->second = id_it->second; return {id_it->second, false}; } @@ -3110,9 +3151,12 @@ std::pair simplecpp::FileDataCache::tryload(FileDat data->tokens.removeComments(); name_it->second = data; - mIdMap.emplace(fileId, data); + mImpl->mIdMap.emplace(fileId, data); mData.emplace_back(data); + if (mLoadCallback) + mLoadCallback(*data); + return {data, true}; } @@ -3162,7 +3206,14 @@ std::pair simplecpp::FileDataCache::get(const std:: return {nullptr, false}; } -bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id) +void simplecpp::FileDataCache::clear() +{ + mImpl->clear(); + mNameMap.clear(); + mData.clear(); +} + +static bool getFileId(const std::string &path, FileID &id) { #ifdef _WIN32 HANDLE hFile = CreateFileA(path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); @@ -3349,20 +3400,20 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL std::map sizeOfType(rawtokens.sizeOfType); sizeOfType.insert(std::make_pair("char", sizeof(char))); sizeOfType.insert(std::make_pair("short", sizeof(short))); - sizeOfType.insert(std::make_pair("short int", sizeOfType["short"])); + sizeOfType.insert(std::make_pair("short int", sizeof(short))); sizeOfType.insert(std::make_pair("int", sizeof(int))); sizeOfType.insert(std::make_pair("long", sizeof(long))); - sizeOfType.insert(std::make_pair("long int", sizeOfType["long"])); + sizeOfType.insert(std::make_pair("long int", sizeof(long))); sizeOfType.insert(std::make_pair("long long", sizeof(long long))); sizeOfType.insert(std::make_pair("float", sizeof(float))); sizeOfType.insert(std::make_pair("double", sizeof(double))); sizeOfType.insert(std::make_pair("long double", sizeof(long double))); sizeOfType.insert(std::make_pair("char *", sizeof(char *))); sizeOfType.insert(std::make_pair("short *", sizeof(short *))); - sizeOfType.insert(std::make_pair("short int *", sizeOfType["short *"])); + sizeOfType.insert(std::make_pair("short int *", sizeof(short *))); sizeOfType.insert(std::make_pair("int *", sizeof(int *))); sizeOfType.insert(std::make_pair("long *", sizeof(long *))); - sizeOfType.insert(std::make_pair("long int *", sizeOfType["long *"])); + sizeOfType.insert(std::make_pair("long int *", sizeof(long *))); sizeOfType.insert(std::make_pair("long long *", sizeof(long long *))); sizeOfType.insert(std::make_pair("float *", sizeof(float *))); sizeOfType.insert(std::make_pair("double *", sizeof(double *))); @@ -3466,8 +3517,19 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL includetokenstack.push(rawtokens.cfront()); for (auto it = dui.includes.cbegin(); it != dui.includes.cend(); ++it) { const FileData *const filedata = cache.get("", *it, dui, false, files, outputList).first; - if (filedata != nullptr && filedata->tokens.cfront() != nullptr) + if (filedata == nullptr) { + if (outputList) { + simplecpp::Output err{ + simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND, + {}, + "Can not open include file '" + *it + "' that is explicitly included." + }; + outputList->emplace_back(std::move(err)); + } + } + else if (filedata->tokens.cfront() != nullptr) { includetokenstack.push(filedata->tokens.cfront()); + } } std::map> maybeUsedMacros; diff --git a/externals/simplecpp/simplecpp.h b/externals/simplecpp/simplecpp.h index f29166ff061..3d6fc5262b9 100644 --- a/externals/simplecpp/simplecpp.h +++ b/externals/simplecpp/simplecpp.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -41,10 +42,6 @@ # define SIMPLECPP_LIB #endif -#ifndef _WIN32 -# include -#endif - #if defined(_MSC_VER) # pragma warning(push) // suppress warnings about "conversion from 'type1' to 'type2', possible loss of data" @@ -452,13 +449,14 @@ namespace simplecpp { class SIMPLECPP_LIB FileDataCache { public: - FileDataCache() = default; + FileDataCache(); + ~FileDataCache(); FileDataCache(const FileDataCache &) = delete; - FileDataCache(FileDataCache &&) = default; + FileDataCache(FileDataCache &&) noexcept; FileDataCache &operator=(const FileDataCache &) = delete; - FileDataCache &operator=(FileDataCache &&) = default; + FileDataCache &operator=(FileDataCache &&) noexcept; /** Get the cached data for a file, or load and then return it if it isn't cached. * returns the file data and true if the file was loaded, false if it was cached. */ @@ -472,11 +470,7 @@ namespace simplecpp { mNameMap.emplace(newdata->filename, newdata); } - void clear() { - mNameMap.clear(); - mIdMap.clear(); - mData.clear(); - } + void clear(); using container_type = std::vector>; using iterator = container_type::iterator; @@ -505,52 +499,23 @@ namespace simplecpp { return mData.cend(); } - private: - struct FileID { -#ifdef _WIN32 - struct { - std::uint64_t VolumeSerialNumber; - struct { - std::uint64_t IdentifierHi; - std::uint64_t IdentifierLo; - } FileId; - } fileIdInfo; - - bool operator==(const FileID &that) const noexcept { - return fileIdInfo.VolumeSerialNumber == that.fileIdInfo.VolumeSerialNumber && - fileIdInfo.FileId.IdentifierHi == that.fileIdInfo.FileId.IdentifierHi && - fileIdInfo.FileId.IdentifierLo == that.fileIdInfo.FileId.IdentifierLo; - } -#else - dev_t dev; - ino_t ino; + using load_callback_type = std::function; - bool operator==(const FileID& that) const noexcept { - return dev == that.dev && ino == that.ino; - } -#endif - struct Hasher { - std::size_t operator()(const FileID &id) const { -#ifdef _WIN32 - return static_cast(id.fileIdInfo.FileId.IdentifierHi ^ id.fileIdInfo.FileId.IdentifierLo ^ - id.fileIdInfo.VolumeSerialNumber); -#else - return static_cast(id.dev) ^ static_cast(id.ino); -#endif - } - }; - }; + void set_load_callback(load_callback_type cb) { + mLoadCallback = std::move(cb); + } - using name_map_type = std::unordered_map; - using id_map_type = std::unordered_map; + private: + struct Impl; + std::unique_ptr mImpl; - static bool getFileId(const std::string &path, FileID &id); + using name_map_type = std::unordered_map; std::pair tryload(name_map_type::iterator &name_it, const DUI &dui, std::vector &filenames, OutputList *outputList); container_type mData; name_map_type mNameMap; - id_map_type mIdMap; + load_callback_type mLoadCallback; }; /** Converts character literal (including prefix, but not ud-suffix) to long long value. From e7e54f7ea596fe252f39f405f4aae0c4f45d3b76 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 7 Jul 2026 15:09:18 +0200 Subject: [PATCH 225/493] Fix #14889 FP constStatement with GNU statement expression (#8698) --- lib/checkother.cpp | 2 +- test/testincompletestatement.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 51124c45d1c..ef6fb9003b1 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2408,7 +2408,7 @@ void CheckOtherImpl::checkIncompleteStatement() !(tok->str() == "," && tok->astParent() && tok->astParent()->isAssignmentOp())) continue; // Skip statement expressions - if (Token::simpleMatch(rtok, "; } )")) + if (Token::simpleMatch(rtok, "; } )") || Token::simpleMatch(tok->next(), "; } )")) continue; if (!isConstStatement(tok, mSettings.library, false)) continue; diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index b72b6524872..806f734274e 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -758,6 +758,11 @@ class TestIncompleteStatement : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (warning) Redundant code: Found unused array access. [constStatement]\n", errout_str()); + + check("int f(int i) {\n" // #14889 + " return i ? 8 : ({ int x = 2; x; });\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void vardecl() { From 7cc7c0bb500d775d4d533ace64295c2cd0fa7134 Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:33:51 -0400 Subject: [PATCH 226/493] gtk.cfg: Add pure annotations for more GLib functions (#8687) This fixes assertWithSideEffect false positives for the following functions: g_error_matches g_list_find g_str_has_prefix g_str_has_suffix --- cfg/gtk.cfg | 3 +++ test/cfg/gtk.c | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index 71d0f3dee05..e28aa2ad7a5 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -2251,6 +2251,7 @@
+ false @@ -5218,6 +5219,7 @@ + false @@ -6586,6 +6588,7 @@ + false diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c index 4accf7b63ec..6b48bca2f9e 100644 --- a/test/cfg/gtk.c +++ b/test/cfg/gtk.c @@ -59,6 +59,8 @@ void validCode(int argInt, GHashTableIter * hash_table_iter, GHashTable * hash_t g_string_free(pGStr1, TRUE); gchar * pGchar1 = g_strconcat("a", "b", NULL); + g_assert_true(g_str_has_prefix(pGchar1, "a")); + g_assert_true(g_str_has_suffix(pGchar1, "b")); printf("%s", pGchar1); g_free(pGchar1); @@ -406,6 +408,7 @@ void g_error_new_test() g_error_new(1, -2, "a %d", 1); const GError * pNew2 = g_error_new(1, -2, "a %d", 1); + g_assert_true(g_error_matches(pNew2, 1, -2)); printf("%p", pNew2); // cppcheck-suppress memleak } @@ -530,6 +533,16 @@ void g_variant_test() { // cppcheck-suppress memleak } +void g_list_test() { + GList *list1 = NULL; + gchar *c = "c"; + + list1 = g_list_append(list1, c); + g_assert_true(g_list_find(list1, c) != NULL); + + g_list_free(list1); +} + void g_queue_test() { // cppcheck-suppress leakReturnValNotUsed g_queue_new(); From ee22150faf8a585c0ad3406534f5159045601041 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:34:13 +0200 Subject: [PATCH 227/493] Fix #13846 FP invalidFunctionArgBool with Qt SLOT() macro (#8686) `` causes a warning when passing `false`, which is rejected by a modern compiler anyway. --------- Co-authored-by: chrchr-github --- cfg/qt.cfg | 1 - test/cfg/qt.cpp | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cfg/qt.cfg b/cfg/qt.cfg index 66f6e78b3b6..c7bf3d8779b 100644 --- a/cfg/qt.cfg +++ b/cfg/qt.cfg @@ -410,7 +410,6 @@ - diff --git a/test/cfg/qt.cpp b/test/cfg/qt.cpp index 78827d3583c..2b683648dcd 100644 --- a/test/cfg/qt.cpp +++ b/test/cfg/qt.cpp @@ -33,6 +33,7 @@ #include #include #include +#include // TODO: this is actually available via Core5Compat but I could not get it to work with pkg-config #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) @@ -892,3 +893,13 @@ int qdateIsValid() Q_ASSERT(qd.isValid()); // Should not warn here with assertWithSideEffect return qd.month(); } + +struct S_QTimer_connect : QObject { // #13846 + S_QTimer_connect() { + // cppcheck-suppress checkLibraryFunction - timeout() is a signal from QTimer + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(update())); + } + QTimer timer; +private slots: + bool update(); +}; From a93e550d041337164dd17f15d240151010658641 Mon Sep 17 00:00:00 2001 From: glankk Date: Wed, 8 Jul 2026 11:52:51 +0200 Subject: [PATCH 228/493] Fix #14113 (Slow analysis: microchip xc16 code) (#7838) --- .github/workflows/selfcheck.yml | 2 +- .selfcheck_suppressions | 2 + lib/cppcheck.cpp | 113 ++++++++++++++++++------- lib/cppcheck.h | 5 +- lib/errorlogger.cpp | 9 +- lib/errorlogger.h | 18 ++-- lib/preprocessor.cpp | 142 +++++++++++++------------------- lib/preprocessor.h | 35 +++++--- test/cli/performance_test.py | 25 ++++++ test/helpers.cpp | 3 +- test/testcppcheck.cpp | 7 +- test/testpreprocessor.cpp | 63 ++++++++++++-- test/testtokenize.cpp | 8 +- 13 files changed, 283 insertions(+), 149 deletions(-) diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 6d100c4ddc8..1a213039f93 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -121,7 +121,7 @@ jobs: - name: Self check (unusedFunction / no test / no gui) run: | - supprs="--suppress=unusedFunction:lib/errorlogger.h:197 --suppress=unusedFunction:lib/importproject.cpp:1671 --suppress=unusedFunction:lib/importproject.cpp:1695" + supprs="--suppress=unusedFunction:lib/errorlogger.h:198 --suppress=unusedFunction:lib/importproject.cpp:1671 --suppress=unusedFunction:lib/importproject.cpp:1695" ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs env: DISABLE_VALUEFLOW: 1 diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index f21492e783a..63d33fd2704 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -62,6 +62,8 @@ templateInstantiation:test/testutils.cpp naming-varname:externals/simplecpp/simplecpp.h naming-privateMemberVariable:externals/simplecpp/simplecpp.h +# false positive; lambda captures its owner +danglingLifetime:externals/simplecpp/simplecpp.h:505 # TODO: these warnings need to be addressed upstream uninitMemberVar:externals/tinyxml2/tinyxml2.h diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 50f7fa36e80..26d98c0c7b4 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -61,6 +61,7 @@ #include // IWYU pragma: keep #include #include +#include #include #include #include @@ -100,9 +101,9 @@ class CppCheck::CppCheckLogger : public ErrorLogger closePlist(); } - void setRemarkComments(std::vector remarkComments) + void addRemarkComments(const std::vector &remarkComments) { - mRemarkComments = std::move(remarkComments); + mRemarkComments.insert(mRemarkComments.end(), remarkComments.begin(), remarkComments.end()); } void setLocationMacros(const Token* startTok, const std::vector& files) @@ -124,17 +125,25 @@ class CppCheck::CppCheckLogger : public ErrorLogger mErrorList.clear(); } - void openPlist(const std::string& filename, const std::vector& files) + void openPlist(const std::string& filename) { mPlistFile.open(filename); - mPlistFile << ErrorLogger::plistHeader(version(), files); + mPlistFile << ErrorLogger::plistHeader(version()); + } + + void setPlistFilenames(std::vector files) + { + if (mPlistFile.is_open()) { + mPlistFilenames = std::move(files); + } } void closePlist() { if (mPlistFile.is_open()) { - mPlistFile << ErrorLogger::plistFooter(); + mPlistFile << ErrorLogger::plistFooter(mPlistFilenames); mPlistFile.close(); + mPlistFilenames.clear(); } } @@ -282,6 +291,7 @@ class CppCheck::CppCheckLogger : public ErrorLogger std::map> mLocationMacros; // What macros are used on a location? std::ofstream mPlistFile; + std::vector mPlistFilenames; unsigned int mExitCode{}; @@ -898,7 +908,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string return checkInternal(file, cfgname, f); } -void CppCheck::checkPlistOutput(const FileWithDetails& file, const std::vector& files) +void CppCheck::checkPlistOutput(const FileWithDetails& file) { if (!mSettings.plistOutput.empty()) { const bool slashFound = file.spath().find('/') != std::string::npos; @@ -909,7 +919,7 @@ void CppCheck::checkPlistOutput(const FileWithDetails& file, const std::vector {}(file.spath()); filename = mSettings.plistOutput + noSuffixFilename + "_" + std::to_string(fileNameHash) + ".plist"; - mLogger->openPlist(filename, files); + mLogger->openPlist(filename); } } @@ -1000,24 +1010,16 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str if (preprocessor.reportOutput(outputList, true)) return mLogger->exitcode(); - if (!preprocessor.loadFiles(files)) - return mLogger->exitcode(); - - checkPlistOutput(file, files); + checkPlistOutput(file); - std::string dumpProlog; + std::string dumpFooter; if (mSettings.dump || !mSettings.addons.empty()) { - dumpProlog += getDumpFileContentsRawTokens(files, tokens1); + dumpFooter += getDumpFileContentsRawTokensFooter(tokens1); } // Parse comments and then remove them - mLogger->setRemarkComments(preprocessor.getRemarkComments()); + mLogger->addRemarkComments(preprocessor.getRemarkComments()); preprocessor.inlineSuppressions(mSuppressions.nomsg); - if (mSettings.dump || !mSettings.addons.empty()) { - std::ostringstream oss; - mSuppressions.nomsg.dump(oss); - dumpProlog += oss.str(); - } preprocessor.removeComments(); if (!mSettings.buildDir.empty()) { @@ -1040,19 +1042,45 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str } // Get directives - std::list directives = preprocessor.createDirectives(); + std::list directives; + preprocessor.createDirectives(directives); preprocessor.simplifyPragmaAsm(); + std::set configurations; + std::set configDefines = { "__cplusplus" }; + + // Insert library defines + const auto getDefineName = [](const std::string &defineString) { + return defineString.substr(0, defineString.find_first_of("( ")); + }; + std::transform(mSettings.library.defines().begin(), + mSettings.library.defines().end(), + std::inserter(configDefines, configDefines.end()), + getDefineName); + + preprocessor.setLoadCallback([&](simplecpp::FileData &data) { + // Do preprocessing on included file + mLogger->addRemarkComments(preprocessor.getRemarkComments(data.tokens)); + preprocessor.inlineSuppressions(data.tokens, mSuppressions.nomsg); + Preprocessor::removeComments(data.tokens); + Preprocessor::createDirectives(data.tokens, directives); + Preprocessor::simplifyPragmaAsm(data.tokens); + // Discover new configurations from included file + if (configurations.size() < maxConfigs) + preprocessor.getConfigs(data.filename, data.tokens, configDefines, configurations); + }); + preprocessor.setPlatformInfo(); // Get configurations.. - std::set configurations; if (maxConfigs > 1) { Timer::run("Preprocessor::getConfigs", mTimerResults, [&]() { - configurations = preprocessor.getConfigs(); + configurations = { "" }; + preprocessor.getConfigs(configDefines, configurations); + preprocessor.loadFiles(files); }); } else { - configurations.insert(mSettings.userDefines); + configurations = { mSettings.userDefines }; } if (mSettings.checkConfiguration) { @@ -1089,7 +1117,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str createDumpFile(mSettings, file, fdump, dumpFile); if (fdump.is_open()) { fdump << getLibraryDumpData(); - fdump << dumpProlog; if (!mSettings.dump) filesDeleter.addFile(dumpFile); } @@ -1259,12 +1286,20 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str } // TODO: will not be closed if we encountered an exception - // dumped all configs, close root element now if (fdump.is_open()) { + // dump all filenames, raw tokens, suppressions + std::string dumpHeader = getDumpFileContentsRawTokensHeader(files); + fdump << getDumpFileContentsRawTokens(dumpHeader, dumpFooter); + mSuppressions.nomsg.dump(fdump); + // dumped all configs, close root element now fdump << "" << std::endl; fdump.close(); } + if (!mSettings.plistOutput.empty()) { + mLogger->setPlistFilenames(std::move(files)); + } + executeAddons(dumpFile, file); } catch (const TerminateException &) { // Analysis is terminated @@ -1892,9 +1927,26 @@ bool CppCheck::isPremiumCodingStandardId(const std::string& id) const { return false; } -std::string CppCheck::getDumpFileContentsRawTokens(const std::vector& files, const simplecpp::TokenList& tokens1) const { +std::string CppCheck::getDumpFileContentsRawTokens(const std::vector& files, const simplecpp::TokenList& tokens1) const +{ + std::string header = getDumpFileContentsRawTokensHeader(files); + std::string footer = getDumpFileContentsRawTokensFooter(tokens1); + return getDumpFileContentsRawTokens(header, footer); +} + +std::string CppCheck::getDumpFileContentsRawTokens(const std::string& header, const std::string& footer) +{ std::string dumpProlog; dumpProlog += " \n"; + dumpProlog += header; + dumpProlog += footer; + dumpProlog += " \n"; + return dumpProlog; +} + +std::string CppCheck::getDumpFileContentsRawTokensHeader(const std::vector& files) const +{ + std::string dumpProlog; for (unsigned int i = 0; i < files.size(); ++i) { dumpProlog += " \n"; } + return dumpProlog; +} + +std::string CppCheck::getDumpFileContentsRawTokensFooter(const simplecpp::TokenList& tokens1) +{ + std::string dumpProlog; for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) { dumpProlog += " location.line); dumpProlog += "\" "; - dumpProlog +="column=\""; + dumpProlog += "column=\""; dumpProlog += std::to_string(tok->location.col); dumpProlog += "\" "; @@ -1923,6 +1981,5 @@ std::string CppCheck::getDumpFileContentsRawTokens(const std::vector contents, this is only public for testing purposes */ std::string getDumpFileContentsRawTokens(const std::vector& files, const simplecpp::TokenList& tokens1) const; + static std::string getDumpFileContentsRawTokens(const std::string& header, const std::string& footer); + std::string getDumpFileContentsRawTokensHeader(const std::vector& files) const; + static std::string getDumpFileContentsRawTokensFooter(const simplecpp::TokenList& tokens1); std::string getLibraryDumpData() const; @@ -183,7 +186,7 @@ class CPPCHECKLIB CppCheck { */ unsigned int checkFile(const FileWithDetails& file, const std::string &cfgname); - void checkPlistOutput(const FileWithDetails& file, const std::vector& files); + void checkPlistOutput(const FileWithDetails& file); /** * @brief Check a file using buffer diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 3b05a7d5a8f..d58c5abcbba 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -821,7 +821,7 @@ std::string ErrorLogger::toxml(const std::string &str) return xml; } -std::string ErrorLogger::plistHeader(const std::string &version, const std::vector &files) +std::string ErrorLogger::plistHeader(const std::string &version) { std::ostringstream ostr; ostr << "\r\n" @@ -829,12 +829,7 @@ std::string ErrorLogger::plistHeader(const std::string &version, const std::vect << "\r\n" << "\r\n" << " clang_version\r\n" - << "cppcheck version " << version << "\r\n" - << " files\r\n" - << " \r\n"; - for (const std::string & file : files) - ostr << " " << ErrorLogger::toxml(file) << "\r\n"; - ostr << " \r\n" + << " cppcheck version " << version << "\r\n" << " diagnostics\r\n" << " \r\n"; return ostr.str(); diff --git a/lib/errorlogger.h b/lib/errorlogger.h index daf683bd0a3..97cc3e7f82e 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -271,12 +272,19 @@ class CPPCHECKLIB ErrorLogger { */ static std::string toxml(const std::string &str); - static std::string plistHeader(const std::string &version, const std::vector &files); + static std::string plistHeader(const std::string &version); static std::string plistData(const ErrorMessage &msg); - static const char *plistFooter() { - return " \r\n" - "\r\n" - ""; + static std::string plistFooter(const std::vector& files) { + std::ostringstream ostr; + ostr << " \r\n" + << " files\r\n" + << " \r\n"; + for (const std::string& file : files) + ostr << " " << ErrorLogger::toxml(file) << "\r\n"; + ostr << " \r\n" + << "\r\n" + << ""; + return ostr.str(); } static bool isCriticalErrorId(const std::string& id) { diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 4246da39c83..3e0b33c7f10 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -336,67 +336,49 @@ static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Sett } } -void Preprocessor::inlineSuppressions(SuppressionList &suppressions) +void Preprocessor::inlineSuppressions(SuppressionList &suppressions) const +{ + inlineSuppressions(mTokens, suppressions); +} + +void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens, SuppressionList &suppressions) const { if (!mSettings.inlineSuppressions) return; std::list err; - ::addInlineSuppressions(mTokens, mSettings, suppressions, err); - for (const auto &filedata : mFileCache) { - ::addInlineSuppressions(filedata->tokens, mSettings, suppressions, err); - } + ::addInlineSuppressions(tokens, mSettings, suppressions, err); for (const BadInlineSuppression &bad : err) { invalidSuppression(bad.location, bad.errmsg); } } -std::vector Preprocessor::getRemarkComments() const +void Preprocessor::createDirectives(std::list &directives) const { - std::vector ret; - addRemarkComments(mTokens, ret); - for (const auto &filedata : mFileCache) { - addRemarkComments(filedata->tokens, ret); - } - return ret; + createDirectives(mTokens, directives); } -std::list Preprocessor::createDirectives() const +void Preprocessor::createDirectives(const simplecpp::TokenList &tokens, std::list &directives) { - // directive list.. - std::list directives; - - std::vector list; - list.reserve(1U + mFileCache.size()); - list.push_back(&mTokens); - std::transform(mFileCache.cbegin(), mFileCache.cend(), std::back_inserter(list), - [](const std::unique_ptr &filedata) { - return &filedata->tokens; - }); - - for (const simplecpp::TokenList *tokenList : list) { - for (const simplecpp::Token *tok = tokenList->cfront(); tok; tok = tok->next) { - if ((tok->op != '#') || (tok->previous && tok->previous->location.line == tok->location.line)) - continue; - if (tok->next && tok->next->str() == "endfile") + for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) { + if ((tok->op != '#') || (tok->previous && tok->previous->location.line == tok->location.line)) + continue; + if (tok->next && tok->next->str() == "endfile") + continue; + Directive directive(tokens, tok->location, ""); + for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) { + if (tok2->comment) continue; - Directive directive(mTokens, tok->location, ""); - for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) { - if (tok2->comment) - continue; - if (!directive.str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str().size())) - directive.str += ' '; - if (directive.str == "#" && tok2->str() == "file") - directive.str += "include"; - else - directive.str += tok2->str(); - - directive.strTokens.emplace_back(*tok2); - } - directives.push_back(std::move(directive)); + if (!directive.str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str().size())) + directive.str += ' '; + if (directive.str == "#" && tok2->str() == "file") + directive.str += "include"; + else + directive.str += tok2->str(); + + directive.strTokens.emplace_back(*tok2); } + directives.push_back(std::move(directive)); } - - return directives; } static std::string readcondition(const simplecpp::Token *iftok, const std::set &defined, const std::set &undefined) @@ -769,36 +751,21 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set ret.insert(std::move(elseError)); } - -std::set Preprocessor::getConfigs() const +void Preprocessor::getConfigs(std::set &defined, std::set &configs) const { - std::set ret = { "" }; if (!mTokens.cfront()) - return ret; - - std::set defined = { "__cplusplus" }; - - // Insert library defines - for (const auto &define : mSettings.library.defines()) { - - const std::string::size_type paren = define.find("("); - const std::string::size_type space = define.find(" "); - std::string::size_type end = space; - - if (paren != std::string::npos && paren < space) - end = paren; - - defined.insert(define.substr(0, end)); - } + return; - ::getConfigs(mTokens, defined, mSettings.userDefines, mSettings.userUndefs, ret); + ::getConfigs(mTokens, defined, mSettings.userDefines, mSettings.userUndefs, configs); +} - for (const auto &filedata : mFileCache) { - if (!mSettings.configurationExcluded(filedata->filename)) - ::getConfigs(filedata->tokens, defined, mSettings.userDefines, mSettings.userUndefs, ret); - } +void Preprocessor::getConfigs(const std::string &filename, const simplecpp::TokenList &tokens, std::set &defined, std::set &configs) const +{ + if (!tokens.cfront()) + return; - return ret; + if (!mSettings.configurationExcluded(filename)) + ::getConfigs(tokens, defined, mSettings.userDefines, mSettings.userUndefs, configs); } static void splitcfg(const std::string &cfgStr, std::list &defines, const std::string &defaultValue) @@ -871,16 +838,18 @@ bool Preprocessor::loadFiles(std::vector &files) const simplecpp::DUI dui = createDUI(mSettings, "", mLang); simplecpp::OutputList outputList; - mFileCache = simplecpp::load(mTokens, files, dui, &outputList); + mFileCache = simplecpp::load(mTokens, files, dui, &outputList, std::move(mFileCache)); return !handleErrors(outputList); } void Preprocessor::removeComments() { - mTokens.removeComments(); - for (const auto &filedata : mFileCache) { - filedata->tokens.removeComments(); - } + removeComments(mTokens); +} + +void Preprocessor::removeComments(simplecpp::TokenList &tokens) +{ + tokens.removeComments(); } void Preprocessor::setPlatformInfo() @@ -1016,12 +985,12 @@ static std::string simplecppErrToId(simplecpp::Output::Type type) cppcheck::unreachable(); } -void Preprocessor::error(const simplecpp::Location& loc, const std::string &msg, simplecpp::Output::Type type) +void Preprocessor::error(const simplecpp::Location& loc, const std::string &msg, simplecpp::Output::Type type) const { error(loc, msg, simplecppErrToId(type)); } -void Preprocessor::error(const simplecpp::Location& loc, const std::string &msg, const std::string& id) +void Preprocessor::error(const simplecpp::Location& loc, const std::string &msg, const std::string& id) const { std::list locationList; if (!mTokens.file(loc).empty()) { @@ -1059,7 +1028,7 @@ void Preprocessor::missingInclude(const simplecpp::Location& loc, const std::str mErrorLogger.reportErr(errmsg); } -void Preprocessor::invalidSuppression(const simplecpp::Location& loc, const std::string &msg) +void Preprocessor::invalidSuppression(const simplecpp::Location& loc, const std::string &msg) const { error(loc, msg, "invalidSuppression"); } @@ -1143,13 +1112,10 @@ std::size_t Preprocessor::calculateHash(const std::string &toolinfo) const void Preprocessor::simplifyPragmaAsm() { - Preprocessor::simplifyPragmaAsmPrivate(mTokens); - for (const auto &filedata : mFileCache) { - Preprocessor::simplifyPragmaAsmPrivate(filedata->tokens); - } + simplifyPragmaAsm(mTokens); } -void Preprocessor::simplifyPragmaAsmPrivate(simplecpp::TokenList &tokenList) +void Preprocessor::simplifyPragmaAsm(simplecpp::TokenList &tokenList) { // assembler code.. for (simplecpp::Token *tok = tokenList.front(); tok; tok = tok->next) { @@ -1196,9 +1162,15 @@ void Preprocessor::simplifyPragmaAsmPrivate(simplecpp::TokenList &tokenList) } } +std::vector Preprocessor::getRemarkComments() const +{ + return getRemarkComments(mTokens); +} -void Preprocessor::addRemarkComments(const simplecpp::TokenList &tokens, std::vector &remarkComments) const +std::vector Preprocessor::getRemarkComments(const simplecpp::TokenList &tokens) const { + std::vector remarkComments; + for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) { if (!tok->comment) continue; @@ -1245,4 +1217,6 @@ void Preprocessor::addRemarkComments(const simplecpp::TokenList &tokens, std::ve // Add the suppressions. remarkComments.emplace_back(relativeFilename, remarkedToken->location.line, remarkText); } + + return remarkComments; } diff --git a/lib/preprocessor.h b/lib/preprocessor.h index ba4d55a1e60..3a5a8393a3e 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -98,24 +98,36 @@ class CPPCHECKLIB RemarkComment { * configurations that exist in a source file. */ class CPPCHECKLIB WARN_UNUSED Preprocessor { + friend class TestPreprocessor; + public: /** character that is inserted in expanded macros */ static char macroChar; Preprocessor(simplecpp::TokenList& tokens, const Settings& settings, ErrorLogger &errorLogger, Standards::Language lang); - void inlineSuppressions(SuppressionList &suppressions); + void inlineSuppressions(SuppressionList &suppressions) const; + + void inlineSuppressions(const simplecpp::TokenList &tokens, SuppressionList &suppressions) const; + + void createDirectives(std::list &directives) const; - std::list createDirectives() const; + static void createDirectives(const simplecpp::TokenList &tokens, std::list &directives); - std::set getConfigs() const; + void getConfigs(std::set &defined, std::set &configs) const; + + void getConfigs(const std::string &filename, const simplecpp::TokenList &tokens, std::set &defined, std::set &configs) const; std::vector getRemarkComments() const; + std::vector getRemarkComments(const simplecpp::TokenList &tokens) const; + bool loadFiles(std::vector &files); void removeComments(); + static void removeComments(simplecpp::TokenList &tokens); + void setPlatformInfo(); simplecpp::TokenList preprocess(const std::string &cfgStr, std::vector &files, simplecpp::OutputList& outputList); @@ -132,6 +144,8 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { void simplifyPragmaAsm(); + static void simplifyPragmaAsm(simplecpp::TokenList &tokenList); + static void getErrorMessages(ErrorLogger &errorLogger, const Settings &settings); /** @@ -141,12 +155,15 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { const simplecpp::Output* reportOutput(const simplecpp::OutputList &outputList, bool showerror); - void error(const simplecpp::Location& loc, const std::string &msg, simplecpp::Output::Type type); + void error(const simplecpp::Location& loc, const std::string &msg, simplecpp::Output::Type type) const; const simplecpp::Output* handleErrors(const simplecpp::OutputList &outputList); + void setLoadCallback(simplecpp::FileDataCache::load_callback_type cb) { + mFileCache.set_load_callback(std::move(cb)); + } + private: - static void simplifyPragmaAsmPrivate(simplecpp::TokenList &tokenList); /** * Include file types. @@ -157,18 +174,14 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { }; void missingInclude(const simplecpp::Location& loc, const std::string &header, HeaderTypes headerType); - void invalidSuppression(const simplecpp::Location& loc, const std::string &msg); - void error(const simplecpp::Location& loc, const std::string &msg, const std::string& id); - - void addRemarkComments(const simplecpp::TokenList &tokens, std::vector &remarkComments) const; + void invalidSuppression(const simplecpp::Location& loc, const std::string &msg) const; + void error(const simplecpp::Location& loc, const std::string &msg, const std::string& id) const; simplecpp::TokenList& mTokens; const Settings& mSettings; ErrorLogger &mErrorLogger; - /** list of all directives met while preprocessing file */ - simplecpp::FileDataCache mFileCache; /** filename for cpp/c file - useful when reporting errors */ diff --git a/test/cli/performance_test.py b/test/cli/performance_test.py index 55da3b3b04e..5be958619fc 100644 --- a/test/cli/performance_test.py +++ b/test/cli/performance_test.py @@ -3,6 +3,7 @@ import os import sys +import time import pytest @@ -413,3 +414,27 @@ class C { } }""") cppcheck([filename]) # should not take more than ~1 second + + +@pytest.mark.timeout(60) +def test_slow_many_headers(tmpdir): + # 14113 + c_file = os.path.join(tmpdir, 'source.c') + h_file = os.path.join(tmpdir, 'header.h') + n_hdr = 128 + with open(c_file, 'wt') as f: + f.write('#include "header.h"\n') + with open(h_file, 'wt') as f: + for i in range(n_hdr): + f.write(f'#ifdef CONFIG{i}\n#include "header{i}.h"\n#endif\n') + for i in range(n_hdr): + h_file_i = os.path.join(tmpdir, f"header{i}.h") + with open(h_file_i, 'wt') as f: + for j in range(2048): + f.write(f'#define MACRO{j}{(" "+str(j))*128}\n') + f.write(f'MACRO{i}\n') + # creating the files used for testing can be slow, so we use perf counter here instead + start = time.perf_counter_ns() + cppcheck(['-DCONFIG0', c_file]) + end = time.perf_counter_ns() + assert end - start < 2 * 10**9 # max 2 sec diff --git a/test/helpers.cpp b/test/helpers.cpp index 252658cc531..70437207a84 100644 --- a/test/helpers.cpp +++ b/test/helpers.cpp @@ -124,7 +124,8 @@ void SimpleTokenizer2::preprocess(const char* code, std::size_t size, std::vecto // Tokenizer.. tokenizer.list.createTokens(std::move(tokens2)); - std::list directives = preprocessor.createDirectives(); + std::list directives; + preprocessor.createDirectives(directives); tokenizer.setDirectives(std::move(directives)); } diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 84db6db6c28..17c5b8eff3c 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -527,7 +527,6 @@ class TestCppcheck : public TestFixture { void checkPlistOutput() const { Suppressions supprs; ErrorLogger2 errorLogger; - std::vector files = {"textfile.txt"}; { const auto s = dinit(Settings, $.templateFormat = templateFormat, $.plistOutput = "output"); @@ -535,7 +534,7 @@ class TestCppcheck : public TestFixture { CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); const FileWithDetails fileWithDetails {file.path(), Path::identify(file.path(), false), 0}; - cppcheck.checkPlistOutput(fileWithDetails, files); + cppcheck.checkPlistOutput(fileWithDetails); const std::string outputFile {"outputfile_" + std::to_string(std::hash {}(fileWithDetails.spath())) + ".plist"}; ASSERT(Path::exists(outputFile)); std::remove(outputFile.c_str()); @@ -547,7 +546,7 @@ class TestCppcheck : public TestFixture { CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); const FileWithDetails fileWithDetails {file.path(), Path::identify(file.path(), false), 0}; - cppcheck.checkPlistOutput(fileWithDetails, files); + cppcheck.checkPlistOutput(fileWithDetails); const std::string outputFile {"outputfile_" + std::to_string(std::hash {}(fileWithDetails.spath())) + ".plist"}; ASSERT(Path::exists(outputFile)); std::remove(outputFile.c_str()); @@ -557,7 +556,7 @@ class TestCppcheck : public TestFixture { Settings s; const ScopedFile file("file.c", ""); CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); - cppcheck.checkPlistOutput(FileWithDetails(file.path(), Path::identify(file.path(), false), 0), files); + cppcheck.checkPlistOutput(FileWithDetails(file.path(), Path::identify(file.path(), false), 0)); } } diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index b90a879738d..5da298a2714 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -32,7 +32,9 @@ #include "fixture.h" #include "helpers.h" +#include #include +#include #include #include #include @@ -137,8 +139,11 @@ class TestPreprocessor : public TestFixture { preprocessor.simplifyPragmaAsm(); std::map cfgcode; - if (cfgs.empty()) - cfgs = preprocessor.getConfigs(); + if (cfgs.empty()) { + cfgs.insert(""); + std::set configDefines = { "__cplusplus" }; + preprocessor.getConfigs(configDefines, cfgs); + } for (const std::string & config : cfgs) { try { const bool writeLocations = (strstr(code, "#include") != nullptr); @@ -368,6 +373,8 @@ class TestPreprocessor : public TestFixture { TEST_CASE(testMissingIncludeMixed); TEST_CASE(testMissingIncludeCheckConfig); + TEST_CASE(testLazyInclude); + TEST_CASE(hasInclude); TEST_CASE(limitsDefines); @@ -394,10 +401,23 @@ class TestPreprocessor : public TestFixture { simplecpp::OutputList outputList; simplecpp::TokenList tokens(code,files,"test.c",&outputList); Preprocessor preprocessor(tokens, settings, *this, Standards::Language::C); + std::set configs = { "" }; + std::set configDefines = { "__cplusplus" }; + const auto getDefineName = [](const std::string &defineString) { + return defineString.substr(0, defineString.find_first_of("( ")); + }; + std::transform(settings.library.defines().begin(), + settings.library.defines().end(), + std::inserter(configDefines, configDefines.end()), + getDefineName); + preprocessor.setLoadCallback([&](simplecpp::FileData &data) { + Preprocessor::removeComments(data.tokens); + preprocessor.getConfigs(data.filename, data.tokens, configDefines, configs); + }); + preprocessor.removeComments(); + preprocessor.getConfigs(configDefines, configs); ASSERT(preprocessor.loadFiles(files)); ASSERT(!preprocessor.reportOutput(outputList, true)); - preprocessor.removeComments(); - const std::set configs = preprocessor.getConfigs(); std::string ret; for (const std::string & config : configs) ret += config + '\n'; @@ -409,8 +429,11 @@ class TestPreprocessor : public TestFixture { std::vector files; simplecpp::TokenList tokens(code,files,"test.c"); Preprocessor preprocessor(tokens, settingsDefault, *this, Standards::Language::C); - ASSERT(preprocessor.loadFiles(files)); + preprocessor.setLoadCallback([](simplecpp::FileData &data) { + Preprocessor::removeComments(data.tokens); + }); preprocessor.removeComments(); + ASSERT(preprocessor.loadFiles(files)); return preprocessor.calculateHash(""); } @@ -3033,6 +3056,36 @@ class TestPreprocessor : public TestFixture { "test.c:11:2: information: Include file: <" + missing4 + "> not found. Please note: Standard library headers do not need to be provided to get proper results. [missingIncludeSystem]\n", errout_str()); } + void testLazyInclude() { + const char *code = "#ifdef CONFIG1\n" + "#include \"header1.h\"\n" + "#include \"missing1.h\"\n" + "#else\n" + "#include \"header2.h\"\n" + "#include \"missing2.h\"\n" + "#endif\n"; + + std::vector files; + simplecpp::TokenList tokens(code, files, "test.c"); + + ScopedFile header1("header1.h", "1"); + ScopedFile header2("header2.h", "2"); + + Settings settings; + Preprocessor preprocessor(tokens, settings, *this, Standards::Language::CPP); + + simplecpp::OutputList outputList; + simplecpp::TokenList tokens2 = preprocessor.preprocess("CONFIG1", files, outputList); + std::string out = tokens2.stringify(); + + const simplecpp::FileDataCache &cache = preprocessor.mFileCache; + + ASSERT_EQUALS("\n#line 1 \"header1.h\"\n1", out); + ASSERT_EQUALS(1, outputList.size()); + ASSERT_EQUALS("Header not found: \"missing1.h\"", outputList.begin()->msg); + ASSERT_EQUALS(1, cache.size()); + } + void hasInclude() { const char code[] = "#if __has_include()\n123\n#endif"; Settings settings; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 167d5411553..0617007744a 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -603,9 +603,13 @@ class TestTokenizer : public TestFixture { std::vector files; simplecpp::TokenList tokens1(code, files, filename, &outputList); Preprocessor preprocessor(tokens1, settings, *this, Path::identify(tokens1.getFiles()[0], false)); - (void)preprocessor.reportOutput(outputList, true); + std::list directives; + preprocessor.setLoadCallback([&](const simplecpp::FileData &data) { + Preprocessor::createDirectives(data.tokens, directives); + }); + preprocessor.createDirectives(directives); ASSERT(preprocessor.loadFiles(files)); - std::list directives = preprocessor.createDirectives(); + (void)preprocessor.reportOutput(outputList, true); TokenList tokenlist{settings, Path::identify(filename, false)}; Tokenizer tokenizer(std::move(tokenlist), *this); From 4517bc76720511a5e832803931fa4b1ce2ee8917 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 8 Jul 2026 14:27:36 +0200 Subject: [PATCH 229/493] Fix #14888 FP functionConst with array to pointer decay (#8696) Co-authored-by: chrchr-github --- lib/checkclass.cpp | 9 ++++++--- test/testclass.cpp | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index e04df8b5748..51d5718159f 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2608,9 +2608,12 @@ bool CheckClassImpl::checkConstFunc(const Scope *scope, const Function *func, Me return false; } else { if (lhs->isAssignmentOp()) { - const Variable* lhsVar = lhs->previous()->variable(); - if (lhsVar && !lhsVar->isConst() && lhsVar->isReference() && lhs == lhsVar->nameToken()->next()) - return false; + if (const Variable* lhsVar = lhs->previous()->variable()) { + if (!lhsVar->isConst() && lhsVar->isReference() && lhs == lhsVar->nameToken()->next()) + return false; + if (lhsVar->isPointer() && v && v->isArray() && !(lhsVar->valueType() && lhsVar->valueType()->isConst(/*indirect*/ 1))) + return false; + } } } diff --git a/test/testclass.cpp b/test/testclass.cpp index ae5068dcb9d..1d647eb33a1 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -196,6 +196,7 @@ class TestClass : public TestFixture { TEST_CASE(const99); TEST_CASE(const100); TEST_CASE(const101); + TEST_CASE(const102); TEST_CASE(const_handleDefaultParameters); TEST_CASE(const_passThisToMemberOfOtherClass); @@ -6998,6 +6999,22 @@ class TestClass : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void const102() { + checkConst("struct S {\n" // #14888 + " void f() {\n" + " int *p = a;\n" + " *p = 0;\n" + " }\n" + " void g() {\n" + " const int *p = a;\n" + " if (*p) {}\n" + " }\n" + " int a[3];\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:6:10]: (style, inconclusive) Technically the member function 'S::g' can be const. [functionConst]\n", + errout_str()); + } + void const_handleDefaultParameters() { checkConst("struct Foo {\n" " void foo1(int i, int j = 0) {\n" From b555588b969640a77c655fbdb177dd9c763ebf62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 9 Jul 2026 08:38:33 +0200 Subject: [PATCH 230/493] implement Path::getCurrentExecutablePath for Haiku (#8677) --- lib/path.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/path.cpp b/lib/path.cpp index c4758dfeae9..fc059cdea4e 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -51,6 +51,8 @@ #endif #if defined(__APPLE__) #include +#elif defined(__HAIKU__) +#include #endif @@ -158,6 +160,17 @@ std::string Path::getCurrentExecutablePath(const char* fallback) #elif defined(__APPLE__) uint32_t size = sizeof(buf); success = (_NSGetExecutablePath(buf, &size) == 0); +#elif defined(__HAIKU__) + int32 cookie = 0; + image_info info; + while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) + { + if (info.type == B_APP_IMAGE) + { + break; + } + } + return std::string(info.name); #else const char* procPath = #ifdef __SVR4 // Solaris From 592e7b7c29eee72ec0882fe9867b51d3de44fe46 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:49:30 +0200 Subject: [PATCH 231/493] Fix #14890 fuzzing timeout (hang) in Tokenizer::simplifyTypedef() (#8706) Co-authored-by: chrchr-github --- lib/tokenize.cpp | 20 +++++++++++-------- ...t-5e798df7f1bc86caef9901d6662319a4d636f269 | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 test/cli/fuzz-timeout/timeout-5e798df7f1bc86caef9901d6662319a4d636f269 diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 3046bea69cc..d2ad6f581e7 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9145,14 +9145,18 @@ void Tokenizer::findGarbageCode() const } if (!tok2->next() || tok2->isControlFlowKeyword() || Token::Match(tok2, "typedef|static|.")) syntaxError(tok); - if (Token::Match(tok2, "%name% %name%") && tok2->str() == tok2->strAt(1)) { - if (Token::simpleMatch(tok2->tokAt(2), ";")) - continue; - if (tok2->isStandardType() && tok2->str() == "long") - continue; - if (Token::Match(tok2->tokAt(-1), "enum|struct|union") || (isCPP() && Token::Match(tok2->tokAt(-1), "class|::"))) - continue; - syntaxError(tok2); + if (Token::Match(tok2, "%name% %name%")) { + if (tok2->str() == tok2->strAt(1)) { + if (Token::simpleMatch(tok2->tokAt(2), ";")) + continue; + if (tok2->isStandardType() && tok2->str() == "long") + continue; + if (Token::Match(tok2->tokAt(-1), "enum|struct|union") || (isCPP() && Token::Match(tok2->tokAt(-1), "class|::"))) + continue; + syntaxError(tok2); + } + if (Token::Match(tok2->tokAt(2), "%name%") && tok2->isNameOnly() && tok2->tokAt(1)->isNameOnly() && tok2->tokAt(2)->isNameOnly()) + syntaxError(tok2); } } } diff --git a/test/cli/fuzz-timeout/timeout-5e798df7f1bc86caef9901d6662319a4d636f269 b/test/cli/fuzz-timeout/timeout-5e798df7f1bc86caef9901d6662319a4d636f269 new file mode 100644 index 00000000000..35e56badcc8 --- /dev/null +++ b/test/cli/fuzz-timeout/timeout-5e798df7f1bc86caef9901d6662319a4d636f269 @@ -0,0 +1 @@ +typedef consted e,{} From a05554448f3724b7e4f33a5a727b23f74702b951 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Thu, 9 Jul 2026 01:50:44 -0500 Subject: [PATCH 232/493] Fix 14895: FP knownConditionTrueFalse: regression related to ' Partial fix for 9049: False negative: uninitialized variable with nested ifs (#8680)' (#8701) Co-authored-by: Your Name --- lib/forwardanalyzer.cpp | 5 +++++ test/testvalueflow.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 727c64b076d..ced1cfbda8d 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -395,6 +395,11 @@ namespace { bool structuralUnknown = false; const bool structuralEscape = isEscapeScope(branch.endBlock, structuralUnknown); branch.escapeUnknown = !structuralEscape || structuralUnknown; + // The traversal stopped at the escape, so the rest of the scope was not walked; a + // fall-through path could still modify the value there - include the whole scope's + // actions so isModified() sees it. + if (branch.escapeUnknown) + branch.action |= analyzeScope(branch.endBlock); } else { // Detect an escape the traversal did not flag (e.g. an unknown noreturn call); // escapeUnknown reports a possible (unknown) escape. diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 888710ce57d..8a0d181900d 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3214,6 +3214,38 @@ class TestValueFlow : public TestFixture { " return x;\n" "}\n"; ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 0)); + + code = "bool f();\n" // a modification after a conditional escape must still be seen + "void g() {\n" + " bool x = false;\n" + " if (f()) {\n" + " if (f()) return;\n" + " if (f()) x = true;\n" + " }\n" + " if (x) {}\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfX(code, 8U, 0)); + ASSERT_EQUALS(false, testValueOfXKnown(code, 8U, 0)); + + code = "bool f();\n" + "void g() {\n" + " bool x = false;\n" + " if (f()) {\n" + " if (f()) return;\n" + " x = true;\n" + " }\n" + " if (x) {}\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfX(code, 8U, 0)); + ASSERT_EQUALS(false, testValueOfXKnown(code, 8U, 0)); + + code = "bool f();\n" // the branch always escapes - keep the known value + "void g() {\n" + " bool x = false;\n" + " if (f()) { x = true; return; }\n" + " if (x) {}\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXKnown(code, 5U, 0)); } void valueFlowAfterSwap() From 376b31e0fac39db72295171d8b386c48daf6e2e8 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:51:19 +0200 Subject: [PATCH 233/493] Partial fix for #14859 FN bufferAccessOutOfBounds (memset on std::vector) (#8690) --- lib/checkbufferoverrun.cpp | 28 +++++++++++++++++++++------- lib/checkbufferoverrun.h | 2 +- test/testbufferoverrun.cpp | 6 ++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index c72db22a68c..d28ac7c64f7 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -65,7 +65,10 @@ static const CWE CWE_BUFFER_OVERRUN(788U); // Access of Memory Location After static const ValueFlow::Value *getBufferSizeValue(const Token *tok) { const std::list &tokenValues = tok->values(); - const auto it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isBufferSizeValue)); + auto it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isBufferSizeValue)); + if (it != tokenValues.cend()) + return &*it; + it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isContainerSizeValue)); return it == tokenValues.cend() ? nullptr : &*it; } @@ -552,7 +555,7 @@ void CheckBufferOverrunImpl::pointerArithmeticError(const Token *tok, const Toke //--------------------------------------------------------------------------- -ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) const +ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, const Settings& settings) const { if (!bufTok->valueType()) return ValueFlow::Value(-1); @@ -569,9 +572,20 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons const Variable *var = bufTok->variable(); if (!var || var->dimensions().empty()) { - const ValueFlow::Value *value = getBufferSizeValue(bufTok); - if (value) - return *value; + if (const ValueFlow::Value *value = getBufferSizeValue(bufTok)) { + if (value->isBufferSizeValue()) + return *value; + if (value->isContainerSizeValue() && bufTok->valueType() && bufTok->valueType()->container) { + const ValueType vtElement = ValueType::parseDecl(bufTok->valueType()->containerTypeToken, settings); + const size_t elementSize = vtElement.getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); + if (elementSize > 0) { + ValueFlow::Value bufSizeVal; + bufSizeVal.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE; + bufSizeVal.intvalue = value->intvalue * elementSize; + return bufSizeVal; + } + } + } } if (!var || var->isPointer() || (astIsContainer(bufTok) && var->getTypeName() != "std::array")) @@ -671,7 +685,7 @@ void CheckBufferOverrunImpl::bufferOverflow() if (argtok->valueType() && argtok->valueType()->pointer == 0) continue; // TODO: strcpy(buf+10, "hello"); - const ValueFlow::Value bufferSize = getBufferSize(argtok); + const ValueFlow::Value bufferSize = getBufferSize(argtok, mSettings); if (bufferSize.intvalue <= 0) continue; // buffer size == 1 => do not warn for dynamic memory @@ -782,7 +796,7 @@ void CheckBufferOverrunImpl::stringNotZeroTerminated() const Token *sizeToken = args[2]; if (!sizeToken->hasKnownIntValue()) continue; - const ValueFlow::Value &bufferSize = getBufferSize(args[0]); + const ValueFlow::Value &bufferSize = getBufferSize(args[0], mSettings); if (bufferSize.intvalue < 0 || sizeToken->getKnownIntValue() < bufferSize.intvalue) continue; if (Token::simpleMatch(args[1], "(") && Token::simpleMatch(args[1]->astOperand1(), ". c_str") && args[1]->astOperand1()->astOperand1()) { diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index b0e8b28eba0..b9b82c897e0 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -129,7 +129,7 @@ class CPPCHECKLIB CheckBufferOverrunImpl : public CheckImpl void objectIndex(); void objectIndexError(const Token *tok, const ValueFlow::Value *v, bool known); - ValueFlow::Value getBufferSize(const Token *bufTok) const; + ValueFlow::Value getBufferSize(const Token *bufTok, const Settings& settings) const; // CTU static bool isCtuUnsafeBufferUsage(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *offset, int type); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 387a0eeea8a..f9e55910c01 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3545,6 +3545,12 @@ class TestBufferOverrun : public TestFixture { " std::memset(&buf[0], 0, 25);\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" // #14859 + " std::vector buf(25);\n" + " std::memset(&buf[0], 0, 26);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (error) Buffer is accessed out of bounds: &buf[0] [bufferAccessOutOfBounds]\n", errout_str()); } void buffer_overrun_errorpath() { From 41e87ac9fd291442b9e39958e4c19558c1e7a07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 10 Jul 2026 16:03:06 +0200 Subject: [PATCH 234/493] compilerDefinitions.cmake: fixed typo in if condition (#8709) fixes compiler error with libc++ on recent clang versions: ``` /usr/bin/../include/c++/v1/__configuration/hardening.h:25:4: error: "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE= instead (see docs)" 25 | # error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE= instead (see docs)" | ^ ``` --- cmake/compilerDefinitions.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/compilerDefinitions.cmake b/cmake/compilerDefinitions.cmake index 5f03b83dcee..3daf0e7ba87 100644 --- a/cmake/compilerDefinitions.cmake +++ b/cmake/compilerDefinitions.cmake @@ -20,7 +20,7 @@ endif() if ((USE_LIBCXX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") if(CPPCHK_GLIBCXX_DEBUG AND CMAKE_BUILD_TYPE STREQUAL "Debug") # TODO: determine proper version for AppleClang - current value is based on the oldest version avaialble in CI - if((CMAKE_CXX_COMPILER_ID STREQUALS "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 18) OR + if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 18) OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 17)) add_definitions(-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG) else() From b839fa5a914e1ecf7db0195ae34559ecfe867acc Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Fri, 10 Jul 2026 15:55:28 -0500 Subject: [PATCH 235/493] Fix issue 14892: Inconsistent nullPointerOutOfResources after possible noreturn function (#8700) Co-authored-by: Your Name --- lib/forwardanalyzer.cpp | 48 ++++++++++++++++++++++++------------ lib/valueflow.cpp | 23 ++++++++++++++--- test/testnullpointer.cpp | 53 ++++++++++++++++++++++++++++++++++++++++ test/testvalueflow.cpp | 38 ++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 19 deletions(-) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index ced1cfbda8d..368ac761a53 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -412,6 +412,27 @@ namespace { return p; } + // Update the branch that the evaluated condition takes + Progress updateTakenBranch(Branch& branch, const Token* skippedBlock, const Token* condTok, int depth) + { + // The condition is only "known" because of an earlier assumption, so the + // skipped block could still modify the value -> lower to possible + if (!condTok->hasKnownIntValue() && skippedBlock && analyzeScope(skippedBlock).isModified() && + !analyzer->lowerToPossible()) + return Break(Analyzer::Terminate::Bail); + if (!branch.endBlock) + return Progress::Continue; + updateScopeState(branch.endBlock); + if (updateBranch(branch, depth - 1) == Progress::Break) + return Progress::Break; + // The branch was entered because of the tracked value; if it might not + // return (it ends in a call to an unknown, possibly noreturn function) + // then the value might not flow past the branch. + if (!condTok->hasKnownIntValue() && !branch.escape && branch.escapeUnknown && !analyzer->lowerToInconclusive()) + return Break(Analyzer::Terminate::Bail); + return Progress::Continue; + } + bool reentersLoop(Token* endBlock, const Token* condTok, const Token* stepTok) const { if (!condTok) return true; @@ -563,16 +584,21 @@ namespace { return updateLoop(endToken, endBlock, condTok, initTok, stepTok, true); } - Progress updateScope(Token* endBlock, int depth = 20) + void updateScopeState(const Token* endBlock) { - if (!endBlock) - return Break(); assert(endBlock->link()); - Token* ctx = endBlock->link()->previous(); + const Token* ctx = endBlock->link()->previous(); if (Token::simpleMatch(ctx, ")")) ctx = ctx->link()->previous(); if (ctx) analyzer->updateState(ctx); + } + + Progress updateScope(Token* endBlock, int depth = 20) + { + if (!endBlock) + return Break(); + updateScopeState(endBlock); return updateRange(endBlock->link(), endBlock, depth); } @@ -743,19 +769,11 @@ namespace { const bool hasElse = Token::simpleMatch(endBlock, "} else {"); tok = hasElse ? endBlock->linkAt(2) : endBlock; if (thenBranch.check) { - // The condition is only "known" because of an earlier assumption, so the - // skipped else block could still modify the value -> lower to possible - if (!condTok->hasKnownIntValue() && hasElse && - analyzeScope(elseBranch.endBlock).isModified() && !analyzer->lowerToPossible()) - return Break(Analyzer::Terminate::Bail); - if (updateScope(thenBranch.endBlock, depth - 1) == Progress::Break) + if (updateTakenBranch(thenBranch, hasElse ? elseBranch.endBlock : nullptr, condTok, depth) == + Progress::Break) return Break(); } else if (elseBranch.check) { - // Likewise the skipped then block could still modify the value - if (!condTok->hasKnownIntValue() && analyzeScope(thenBranch.endBlock).isModified() && - !analyzer->lowerToPossible()) - return Break(Analyzer::Terminate::Bail); - if (elseBranch.endBlock && updateScope(elseBranch.endBlock, depth - 1) == Progress::Break) + if (updateTakenBranch(elseBranch, thenBranch.endBlock, condTok, depth) == Progress::Break) return Break(); } else { const bool conditional = stopOnCondition(condTok); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index ef81fc772ac..8c77b17cf94 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4650,6 +4650,14 @@ struct ConditionHandler { }); } + static void lowerToInconclusive(std::list& values) + { + for (ValueFlow::Value& v : values) { + if (!v.isImpossible()) + v.setInconclusive(); + } + } + void afterCondition(TokenList& tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, @@ -4882,10 +4890,13 @@ struct ConditionHandler { else if (!dead_if) dead_if = isReturnScope(after, settings.library, &unknownFunction); + // If the taken branch might not return (it ends in a call to an unknown, + // possibly noreturn function) then its values might not flow past the + // conditional code -> lower them to inconclusive. if (!dead_if && unknownFunction) { if (settings.debugwarnings) bailout(tokenlist, errorLogger, unknownFunction, "possible noreturn scope"); - return; + lowerToInconclusive(thenValues); } if (Token::simpleMatch(after, "} else {")) { @@ -4896,7 +4907,7 @@ struct ConditionHandler { if (!dead_else && unknownFunction) { if (settings.debugwarnings) bailout(tokenlist, errorLogger, unknownFunction, "possible noreturn scope"); - return; + lowerToInconclusive(elseValues); } } @@ -4912,11 +4923,15 @@ struct ConditionHandler { std::copy_if(thenValues.cbegin(), thenValues.cend(), std::back_inserter(values), - std::mem_fn(&ValueFlow::Value::isPossible)); + [](const ValueFlow::Value& v) { + return v.isPossible() || v.isInconclusive(); + }); std::copy_if(elseValues.cbegin(), elseValues.cend(), std::back_inserter(values), - std::mem_fn(&ValueFlow::Value::isPossible)); + [](const ValueFlow::Value& v) { + return v.isPossible() || v.isInconclusive(); + }); } if (values.empty()) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 2483a967947..02810906fb2 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -4468,6 +4468,59 @@ class TestNullPointer : public TestFixture { "[test.cpp:3:13]: (warning) If resource allocation fails, then there is a possible null pointer dereference: fid [nullPointerOutOfResources]\n" "[test.cpp:4:12]: (warning) If resource allocation fails, then there is a possible null pointer dereference: fid [nullPointerOutOfResources]\n", errout_str()); + + // the guard might call an unknown, possibly noreturn function -> no warning + check("void f() {\n" + " FILE* fid = fopen(\"x.txt\", \"w\");\n" + " if (fid == NULL)\n" + " g();\n" + " fclose(fid);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // .. but an inconclusive warning is reported with --inconclusive + check("void f() {\n" + " FILE* fid = fopen(\"x.txt\", \"w\");\n" + " if (fid == NULL)\n" + " g();\n" + " fclose(fid);\n" + "}\n", + dinit(CheckOptions, $.inconclusive = true)); + ASSERT_EQUALS( + "[test.cpp:5:12]: (warning, inconclusive) If resource allocation fails, then there is a possible null pointer dereference: fid [nullPointerOutOfResources]\n", + errout_str()); + + check("int f(const int* p) {\n" + " if (p == nullptr)\n" + " g();\n" + " return *p;\n" + "}\n", + dinit(CheckOptions, $.inconclusive = true)); + ASSERT_EQUALS( + "[test.cpp:2:11] -> [test.cpp:4:13]: (warning, inconclusive) Either the condition 'p==nullptr' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", + errout_str()); + + check("void f() {\n" + " FILE* fid = fopen(\"x.txt\", \"w\");\n" + " if (fid != NULL)\n" + " ;\n" + " else\n" + " g();\n" + " fclose(fid);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // guard function is known to return -> warning + check("void g() {}\n" + "void f() {\n" + " FILE* fid = fopen(\"x.txt\", \"w\");\n" + " if (fid == NULL)\n" + " g();\n" + " fclose(fid);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:6:12]: (warning) If resource allocation fails, then there is a possible null pointer dereference: fid [nullPointerOutOfResources]\n", + errout_str()); } void functioncalllibrary() { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 8a0d181900d..1f144900c4d 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3866,6 +3866,44 @@ class TestValueFlow : public TestFixture { " return x;\n" "}\n"; ASSERT_EQUALS(true, testValueOfX(code, 4U, 0)); + + // if the guarded block calls an unknown, possibly noreturn function + // then the condition value is lowered to inconclusive after the block + code = "int f(int x) {\n" + " if (x == 0)\n" + " g();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXInconclusive(code, 4U, 0)); + + // .. also when the guard is in the else branch + code = "int f(int x) {\n" + " if (x != 0)\n" + " ;\n" + " else\n" + " g();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXInconclusive(code, 6U, 0)); + + // a declared function is assumed to return + code = "void g();\n" + "int f(int x) {\n" + " if (x == 0)\n" + " g();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfX(code, 5U, 0)); + ASSERT_EQUALS(false, testValueOfXInconclusive(code, 5U, 0)); + + // a noreturn function conclusively escapes + code = "int f(int x) {\n" + " if (x == 0)\n" + " abort();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); + ASSERT_EQUALS(true, testValueOfXImpossible(code, 4U, 0)); } void valueFlowAfterConditionTernary() From c9cb62fc1e6026533245e53f16f5011cb14f5cf4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 11 Jul 2026 14:30:26 +0200 Subject: [PATCH 236/493] Fix #14897 fuzzing crash (null-pointer-use) in SymbolDatabase::createSymbolDatabaseSetScopePointers() (#8703) --- lib/symboldatabase.cpp | 8 +++++++- .../crash-def181ea7bf444e7a9d0f85b3ad264c31a0b90e4 | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 test/cli/fuzz-crash/crash-def181ea7bf444e7a9d0f85b3ad264c31a0b90e4 diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index b687c9f77a4..6e6a98ee81e 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -138,8 +138,14 @@ const Token* SymbolDatabase::isEnumDefinition(const Token* tok) if (tok->str() == "{") return tok; tok = tok->next(); // skip ':' - while (Token::Match(tok, "%name%|::")) + bool hasType = false; + while (Token::Match(tok, "%name%|::")) { + if (tok->isName()) + hasType = true; tok = tok->next(); + } + if (!hasType) + throw InternalError(tok, "SymbolDatabase bailout; invalid enum", InternalError::SYNTAX); return Token::simpleMatch(tok, "{") ? tok : nullptr; } diff --git a/test/cli/fuzz-crash/crash-def181ea7bf444e7a9d0f85b3ad264c31a0b90e4 b/test/cli/fuzz-crash/crash-def181ea7bf444e7a9d0f85b3ad264c31a0b90e4 new file mode 100644 index 00000000000..3b609c62362 --- /dev/null +++ b/test/cli/fuzz-crash/crash-def181ea7bf444e7a9d0f85b3ad264c31a0b90e4 @@ -0,0 +1 @@ +enumf:{}; From cad91dab8e98ec3506269eaa36128446ce7d3406 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 11 Jul 2026 14:31:25 +0200 Subject: [PATCH 237/493] Fix #14742 fuzzing crash (stack-overflow) in CheckNullPointer::nullPointerByDeRefAndCheck() (#8693) --- lib/tokenlist.cpp | 5 ++++- test/cli/fuzz-crash_c/14742 | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 test/cli/fuzz-crash_c/14742 diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 5921621fed2..c28075fcec7 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1951,8 +1951,11 @@ void TokenList::validateAst(bool print) const if (tok->str() == "?") { if (!tok->astOperand1() || !tok->astOperand2()) throw InternalError(tok, "AST broken, ternary operator missing operand(s)", InternalError::AST); - if (tok->astOperand2()->str() != ":") + const Token* colon = tok->astOperand2(); + if (colon->str() != ":") throw InternalError(tok, "Syntax Error: AST broken, ternary operator lacks ':'.", InternalError::AST); + if ((colon->astOperand1() && !precedes(colon->astOperand1(), colon)) || !succeeds(colon->astOperand2(), colon)) + throw InternalError(tok, "AST broken, ternary operator has bad operand(s)", InternalError::AST); } // Check for endless recursion diff --git a/test/cli/fuzz-crash_c/14742 b/test/cli/fuzz-crash_c/14742 new file mode 100644 index 00000000000..a645277c405 --- /dev/null +++ b/test/cli/fuzz-crash_c/14742 @@ -0,0 +1 @@ +i(){b?8:{}!$} From 0a43e46cb526163f4aa9fd6f15e3e0cc6e35d577 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 11 Jul 2026 14:33:29 +0200 Subject: [PATCH 238/493] Fix #14436 fuzzing crash (null-pointer-use) in getEnumType() (#8711) --- lib/tokenlist.cpp | 2 +- .../fuzz-crash/crash-793c09dbb007b0e1a295f592813f40f8d6d449d1 | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test/cli/fuzz-crash/crash-793c09dbb007b0e1a295f592813f40f8d6d449d1 diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index c28075fcec7..594de5c0295 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -2005,7 +2005,7 @@ void TokenList::validateAst(bool print) const if (Token::simpleMatch(tok->previous(), "operator")) continue; // Skip incomplete code - if (!tok->astOperand1() && !tok->astOperand2() && !tok->astParent()) + if (!tok->astOperand1() && !tok->astOperand2() && !tok->astParent() && !(tok->str().size() == 2 && tok->str()[1] == '=')) continue; // Skip lambda assignment and/or initializer if (Token::Match(tok, "= {|^|[")) diff --git a/test/cli/fuzz-crash/crash-793c09dbb007b0e1a295f592813f40f8d6d449d1 b/test/cli/fuzz-crash/crash-793c09dbb007b0e1a295f592813f40f8d6d449d1 new file mode 100644 index 00000000000..706fe52b407 --- /dev/null +++ b/test/cli/fuzz-crash/crash-793c09dbb007b0e1a295f592813f40f8d6d449d1 @@ -0,0 +1 @@ +enum{A=s(u)0&=s}; From dd04e094b5e8e1b1c5fce7df4f26898c5260998d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 11 Jul 2026 21:11:34 +0200 Subject: [PATCH 239/493] [Refactor] Redundant checks for noreturn functions (#8712) --- lib/astutils.cpp | 34 ++++++++++------------------------ lib/checkother.cpp | 2 +- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index c433036cfcc..27a01ab0382 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2226,23 +2226,18 @@ static bool isEscapedOrJump(const Token* tok, bool functionsScope, const Library return Token::Match(tok, "return|goto|throw|continue|break"); } +static bool isNoreturnFunction(const Token* ftok, const Library& library) +{ + if (const Function* function = ftok->function()) + return function->isEscapeFunction() || function->isAttributeNoreturn(); + return library.isnoreturn(ftok); +} + bool isEscapeFunction(const Token* ftok, const Library& library) { if (!Token::Match(ftok, "%name% (")) return false; - if (Token::Match(ftok, "exit|abort")) - return true; - const Function* function = ftok->function(); - if (function) { - if (function->isEscapeFunction()) - return true; - if (function->isAttributeNoreturn()) - return true; - } else { - if (library.isnoreturn(ftok)) - return true; - } - return false; + return isNoreturnFunction(ftok, library); } static bool hasNoreturnFunction(const Token* tok, const Library& library, const Token** unknownFunc) @@ -2253,18 +2248,9 @@ static bool hasNoreturnFunction(const Token* tok, const Library& library, const while (Token::simpleMatch(ftok, "(")) ftok = ftok->astOperand1(); if (ftok) { - const Function * function = ftok->function(); - if (function) { - if (function->isEscapeFunction()) - return true; - if (function->isAttributeNoreturn()) - return true; - } else if (library.isnoreturn(ftok)) { - return true; - } else if (Token::Match(ftok, "exit|abort")) { + if (isNoreturnFunction(ftok, library)) return true; - } - if (unknownFunc && !function && library.functions().count(library.getFunctionName(ftok)) == 0) + if (unknownFunc && !ftok->function() && library.functions().count(library.getFunctionName(ftok)) == 0) *unknownFunc = ftok; return false; } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index ef6fb9003b1..5ea199f38e8 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -791,7 +791,7 @@ void CheckOtherImpl::redundantAssignmentSameValueError(const Token *tok, const V //--------------------------------------------------------------------------- static inline bool isFunctionOrBreakPattern(const Token *tok) { - return Token::Match(tok, "%name% (") || Token::Match(tok, "break|continue|return|exit|goto|throw"); + return Token::Match(tok, "%name% (") || (tok->isKeyword() && Token::Match(tok, "break|continue|return|goto|throw")); } void CheckOtherImpl::redundantBitwiseOperationInSwitchError() From 168777d93257e5bb0372df1e6663fc120371b946 Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Sun, 12 Jul 2026 04:09:48 -0400 Subject: [PATCH 240/493] gtk.cfg: Add G_DEPRECATED_FOR and G_ENCODE_VERSION (#8708) `G_DEPRECATED_FOR` is defined in [glib/gmacros.h](https://github.com/GNOME/glib/blob/2.89.1/glib/gmacros.h#L1313). `G_ENCODE_VERSION` is defined in [glib/gversionmacros.h](https://github.com/GNOME/glib/blob/2.89.1/glib/gversionmacros.h.in#L49). --- cfg/gtk.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index e28aa2ad7a5..5e94a0bbb5c 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -92,6 +92,7 @@ + @@ -126,6 +127,7 @@ + From ef5c1f02530b77a52f40f3ebda73dfb203b5b035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 13 Jul 2026 08:09:54 +0200 Subject: [PATCH 241/493] Fix #14869: Attribute [[maybe_unused]] used after variable (#8713) --- lib/tokenize.cpp | 2 +- test/testtokenize.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d2ad6f581e7..4475bfcb44f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9780,7 +9780,7 @@ void Tokenizer::simplifyCPPAttribute() if (!head) syntaxError(tok); - if (Token::simpleMatch(head, ";")) { + if (Token::Match(head, ";|,|)")) { Token *backTok = tok; while (Token::Match(backTok, "]|[|)")) { if (Token::Match(backTok, "]|)")) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 0617007744a..e33c98861c7 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -290,6 +290,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(cppMaybeUnusedBefore); TEST_CASE(cppMaybeUnusedAfter1); TEST_CASE(cppMaybeUnusedAfter2); + TEST_CASE(cppMaybeUnusedAfter3); TEST_CASE(cppMaybeUnusedStructuredBinding); TEST_CASE(attributeAlignasBefore); @@ -4381,6 +4382,19 @@ class TestTokenizer : public TestFixture { ASSERT(var && var->isAttributeMaybeUnused()); } + void cppMaybeUnusedAfter3() { + const char code[] = "void foo(int x [[maybe_unused]]) {}"; + const char expected[] = "void foo ( int x ) { }"; + + SimpleTokenizer tokenizer(settingsDefault, *this); + ASSERT(tokenizer.tokenize(code)); + + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + + const Token *x = Token::findsimplematch(tokenizer.tokens(), "x"); + ASSERT(x && x->isAttributeMaybeUnused()); + } + void cppMaybeUnusedStructuredBinding() { const char code[] = "[[maybe_unused]] auto [var1, var2] = f();"; const char expected[] = "auto [ var1 , var2 ] = f ( ) ;"; From 4e3063edf0e9d4736c7a8b98867d7806585807ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 13 Jul 2026 08:10:40 +0200 Subject: [PATCH 242/493] Fix #14791: FN shadowFunction depending on order of declaration of member functions (#8609) --- lib/checkother.cpp | 3 ++- lib/filesettings.h | 8 ++++---- lib/token.h | 42 +++++++++++++++++++-------------------- lib/tokenize.cpp | 18 ++++++++--------- test/testother.cpp | 3 +++ test/testpreprocessor.cpp | 4 ++-- 6 files changed, 41 insertions(+), 37 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 5ea199f38e8..f0d7fbd91f1 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4153,7 +4153,8 @@ static const Token *findShadowed(const Scope *scope, const Variable& var, int li return v.nameToken(); } auto it = std::find_if(scope->functionList.cbegin(), scope->functionList.cend(), [&](const Function& f) { - return f.type == FunctionType::eFunction && f.name() == var.name() && precedes(f.tokenDef, var.nameToken()); + return f.type == FunctionType::eFunction && f.name() == var.name() + && (scope->isClassOrStructOrUnion() || precedes(f.tokenDef, var.nameToken())); }); if (it != scope->functionList.end()) return it->tokenDef; diff --git a/lib/filesettings.h b/lib/filesettings.h index 0b4f15dd7e1..0ef53db85c5 100644 --- a/lib/filesettings.h +++ b/lib/filesettings.h @@ -46,9 +46,9 @@ class FileWithDetails throw std::runtime_error("empty path specified"); } - void setPath(std::string path) + void setPath(std::string p) { - mPath = std::move(path); + mPath = std::move(p); mPathSimplified = Path::simplifyPath(mPath); mPathAbsolute.clear(); } @@ -76,9 +76,9 @@ class FileWithDetails return mSize; } - void setLang(Standards::Language lang) + void setLang(Standards::Language language) { - mLang = lang; + mLang = language; } Standards::Language lang() const diff --git a/lib/token.h b/lib/token.h index 3328af31fa0..fd4804ec980 100644 --- a/lib/token.h +++ b/lib/token.h @@ -249,35 +249,35 @@ class CPPCHECKLIB Token { * For example index 1 would return next token, and 2 * would return next from that one. */ - const Token *tokAt(int index) const + const Token *tokAt(int idx) const { - return tokAtImpl(this, index); + return tokAtImpl(this, idx); } - Token *tokAt(int index) + Token *tokAt(int idx) { - return tokAtImpl(this, index); + return tokAtImpl(this, idx); } /** * @return the link to the token in given index, related to this token. * For example index 1 would return the link to next token. */ - const Token *linkAt(int index) const + const Token *linkAt(int idx) const { - return linkAtImpl(this, index); + return linkAtImpl(this, idx); } - Token *linkAt(int index) + Token *linkAt(int idx) { - return linkAtImpl(this, index); + return linkAtImpl(this, idx); } /** * @return String of the token in given index, related to this token. * If that token does not exist, an empty string is being returned. */ - const std::string &strAt(int index) const + const std::string &strAt(int idx) const { - const Token *tok = this->tokAt(index); + const Token *tok = this->tokAt(idx); return tok ? tok->mStr : mEmptyString; } @@ -604,11 +604,11 @@ class CPPCHECKLIB Token { bool hasAttributeCleanup() const { return !mImpl->mAttributeCleanup.empty(); } - void setCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint value) { - mImpl->setCppcheckAttribute(type, value); + void setCppcheckAttribute(CppcheckAttributesType attrType, MathLib::bigint value) { + mImpl->setCppcheckAttribute(attrType, value); } - bool getCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint &value) const { - return mImpl->getCppcheckAttribute(type, value); + bool getCppcheckAttribute(CppcheckAttributesType attrType, MathLib::bigint &value) const { + return mImpl->getCppcheckAttribute(attrType, value); } // cppcheck-suppress unusedFunction bool hasCppcheckAttributes() const { @@ -899,15 +899,15 @@ class CPPCHECKLIB Token { private: template )> - static T *tokAtImpl(T *tok, int index) + static T *tokAtImpl(T *tok, int idx) { - while (index > 0 && tok) { + while (idx > 0 && tok) { tok = tok->next(); - --index; + --idx; } - while (index < 0 && tok) { + while (idx < 0 && tok) { tok = tok->previous(); - ++index; + ++idx; } return tok; } @@ -916,9 +916,9 @@ class CPPCHECKLIB Token { * @throws InternalError thrown if index is out of range */ template )> - static T *linkAtImpl(T *thisTok, int index) + static T *linkAtImpl(T *thisTok, int idx) { - T *tok = thisTok->tokAt(index); + T *tok = thisTok->tokAt(idx); if (!tok) { throw InternalError(thisTok, "Internal error. Token::linkAt called with index outside the tokens range."); } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 4475bfcb44f..2a1920b42e9 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -568,23 +568,23 @@ namespace { const std::pair rangeBefore(start, Token::findsimplematch(start, "{")); // find typedef name token - Token* nameToken = rangeBefore.second->link()->next(); - while (Token::Match(nameToken, "%name%|* %name%|*")) - nameToken = nameToken->next(); - const std::pair rangeQualifiers(rangeBefore.second->link()->next(), nameToken); + Token* nameTok = rangeBefore.second->link()->next(); + while (Token::Match(nameTok, "%name%|* %name%|*")) + nameTok = nameTok->next(); + const std::pair rangeQualifiers(rangeBefore.second->link()->next(), nameTok); - if (Token::Match(nameToken, "%name% ;")) { + if (Token::Match(nameTok, "%name% ;")) { if (Token::Match(rangeBefore.second->previous(), "enum|struct|union|class {")) - rangeBefore.second->previous()->insertToken(nameToken->str()); + rangeBefore.second->previous()->insertToken(nameTok->str()); mRangeType = rangeBefore; mRangeTypeQualifiers = rangeQualifiers; Token* typeName = rangeBefore.second->previous(); if (typeName->isKeyword()) { // TODO typeName->insertToken("T:" + std::to_string(num++)); - typeName->insertToken(nameToken->str()); + typeName->insertToken(nameTok->str()); } - mNameToken = nameToken; - mEndToken = nameToken->next(); + mNameToken = nameTok; + mEndToken = nameTok->next(); return; } } diff --git a/test/testother.cpp b/test/testother.cpp index 02418df5627..ca42ef23deb 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -13207,6 +13207,9 @@ class TestOther : public TestFixture { check("struct S { static int i(); static void f(int i) {} };\n"); ASSERT_EQUALS("[test.cpp:1:23] -> [test.cpp:1:46]: (style) Argument 'i' shadows outer function [shadowFunction]\n", errout_str()); + + check("struct S { void g(float f) {} void f() {} };\n"); + ASSERT_EQUALS("[test.cpp:1:36] -> [test.cpp:1:25]: (style) Argument 'f' shadows outer function [shadowFunction]\n", errout_str()); } void knownArgument() { diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 5da298a2714..55fcafd4f4f 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -146,8 +146,8 @@ class TestPreprocessor : public TestFixture { } for (const std::string & config : cfgs) { try { - const bool writeLocations = (strstr(code, "#include") != nullptr); - cfgcode[config] = preprocessor.getcode(config, files, writeLocations); + const bool writeLocs = (strstr(code, "#include") != nullptr); + cfgcode[config] = preprocessor.getcode(config, files, writeLocs); } catch (const simplecpp::Output &) { cfgcode[config] = ""; } From 80ab5388763157ec42bd00449c95221b7d17af68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 13 Jul 2026 08:11:37 +0200 Subject: [PATCH 243/493] Fix #14803: `ValueType::BOOL` set for `&&` in rvalue reference declaration (#8606) --- lib/symboldatabase.cpp | 2 +- test/testsymboldatabase.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 6e6a98ee81e..b82a3f790b0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -7823,7 +7823,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to setValueType(tok, ValueType(sign, type, 0U)); } - } else if (tok->isComparisonOp() || tok->tokType() == Token::eLogicalOp) { + } else if ((tok->isComparisonOp() || tok->tokType() == Token::eLogicalOp) && tok->astOperand1()) { if (tok->isCpp() && tok->isComparisonOp() && (getClassScope(tok->astOperand1()) || getClassScope(tok->astOperand2()))) { const Function *function = getOperatorFunction(tok); if (function) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 84681b00c85..345bfdb7990 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -10192,6 +10192,15 @@ class TestSymbolDatabase : public TestFixture { ASSERT(tok); TODO_ASSERT(tok->valueType() && "container(std :: string|wstring|u16string|u32string)" == tok->valueType()->str()); } + { + GET_SYMBOL_DB("void f() {\n" + " int &&x = 0;\n" + "}\n"); + + const Token* tok = Token::findsimplematch(tokenizer.tokens(), "&&"); + ASSERT(tok); + ASSERT_EQUALS(static_cast(nullptr), tok->valueType()); + } } void valueTypeThis() { From ad04c7aff4217928764073e7fe7f53e6dc8e58b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 13 Jul 2026 08:12:40 +0200 Subject: [PATCH 244/493] Fix #14836: FP syntaxError for anonymous struct in for loop (#8710) --- lib/tokenize.cpp | 13 ++++++++++++- test/testtokenize.cpp | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 2a1920b42e9..4e00e0d184e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8973,7 +8973,7 @@ void Tokenizer::findGarbageCode() const if (tok->strAt(-1) == ",") syntaxError(tok); colons++; - } else if (tok->str() == "(") { // skip pairs of ( ) + } else if (tok->str() == "(" || tok->str() == "{") { // skip pairs of ( ) tok = tok->link(); } } @@ -9417,6 +9417,7 @@ void Tokenizer::simplifyStructDecl() if (Token::Match(after->next(), "const|static|volatile| *|&| const| (| %type% )| ,|;|[|=|(|{")) { after->insertToken(";"); after = after->next(); + Token *declEnd = after; while (!Token::Match(start, "struct|class|union|enum")) { after->insertToken(start->str()); after = after->next(); @@ -9459,6 +9460,16 @@ void Tokenizer::simplifyStructDecl() } } } + + // pull declaration out of for loop + if (Token::simpleMatch(start->tokAt(-2), "for ( struct")) { + Token *link = start->linkAt(-1); + start->deletePrevious(2); + declEnd->insertToken("("); + declEnd->next()->link(link); + link->link(declEnd->next()); + declEnd->insertToken("for"); + } } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index e33c98861c7..c4de2be00e7 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -2274,6 +2274,11 @@ class TestTokenizer : public TestFixture { const char code4[] = "union U { struct { int a; int b; }; int ab[2]; };"; const char expected4[] = "union U { struct { int a ; int b ; } ; int ab [ 2 ] ; } ;"; ASSERT_EQUALS(expected4, tokenizeAndStringify(code4)); + + // #14836: FP syntaxError for anonymous struct in for loop + const char code5[] = "void f(void) { for (struct { int a; } it = {0}; it.a < 10; it.a++) {} }"; + const char expected5[] = "void f ( ) { struct Anonymous0 { int a ; } ; for ( struct Anonymous0 it = { 0 } ; it . a < 10 ; it . a ++ ) { } }"; + ASSERT_EQUALS(expected5, tokenizeAndStringify(code5)); } void vardecl1() { From f49f1aa318d46f92109da3c59e4f1b011889339a Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Mon, 13 Jul 2026 01:19:10 -0500 Subject: [PATCH 245/493] Fix 14900: FP knownConditionTrueFalse on variable after if/else-if chain (#8715) Co-authored-by: Your Name --- lib/forwardanalyzer.cpp | 7 ++++++- test/testcondition.cpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 368ac761a53..c38d93155ea 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -834,8 +834,13 @@ namespace { ++ft.forkDepth; ft.updateRange(thenBranch.endBlock, end, depth - 1); } - if (pElse == Progress::Break) + if (pElse == Progress::Break) { + // Only the else branch escaped; the then branch falls through, so + // the scope as a whole does not always escape. + if (terminate == Analyzer::Terminate::Escape && !thenBranch.isEscape()) + terminate = Analyzer::Terminate::None; return Break(); + } } } } else if (Token::simpleMatch(tok, "try {")) { diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 837cd4e78ba..da4ecae43b3 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4935,6 +4935,20 @@ class TestCondition : public TestFixture { " if (v > 0) {}\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("bool f(int x) {\n" // only the innermost else escapes - x is 0 or >1 afterwards, not known + " if (!x) {}\n" + " else if (x > 1) {}\n" + " else return false;\n" + " return x ? false : true;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("bool f(int x) {\n" // the branch's fall-through path must clear the escape + " if (x) { if (x > 1) {} else return false; }\n" + " return x ? false : true;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void alwaysTrueSymbolic() From 3d88880e833ed9f60e1ba48f256498440368d86c Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Mon, 13 Jul 2026 01:59:30 -0500 Subject: [PATCH 246/493] Fix issue 13254: FN: containerOutOfBounds (std::equal) (#8695) This adds a new check `algorithmOutOfBounds` that checks when one of the algorithms will access elements out of bounds based on the sizes of other containers passed in. Right now, it directly checks for the stl algorithms, but we could add attributes to the Library to better describe these algorithms so it can be used for other algorithm libraries. --------- Co-authored-by: Your Name --- lib/checkers.cpp | 1 + lib/checkstl.cpp | 407 ++++++++++++++++++++++++++- lib/checkstl.h | 16 ++ lib/valueflow.cpp | 12 + man/checkers/algorithmOutOfBounds.md | 69 +++++ releasenotes.txt | 1 + test/cli/other_test.py | 9 +- test/teststl.cpp | 372 +++++++++++++++++++++++- test/testvalueflow.cpp | 42 +++ 9 files changed, 908 insertions(+), 21 deletions(-) create mode 100644 man/checkers/algorithmOutOfBounds.md diff --git a/lib/checkers.cpp b/lib/checkers.cpp index cc8c4054ea2..56d91cc4f05 100644 --- a/lib/checkers.cpp +++ b/lib/checkers.cpp @@ -167,6 +167,7 @@ namespace checkers { {"CheckSizeof::sizeofVoid","portability"}, {"CheckSizeof::sizeofsizeof","warning"}, {"CheckSizeof::suspiciousSizeofCalculation","warning,inconclusive"}, + {"CheckStl::algorithmOutOfBounds",""}, {"CheckStl::checkDereferenceInvalidIterator","warning"}, {"CheckStl::checkDereferenceInvalidIterator2",""}, {"CheckStl::checkFindInsert","performance"}, diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 743ac8a3cb4..500adc08b01 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -35,6 +35,7 @@ #include "checknullpointer.h" #include +#include #include #include #include @@ -127,6 +128,16 @@ static const Token* getContainerFromSize(const Library::Container* container, co return nullptr; } +// A value that out of bounds analysis can use: not impossible, and inconclusive only when enabled +static bool isUsableValue(const ValueFlow::Value& value, const Settings& settings) +{ + if (value.isImpossible()) + return false; + if (value.isInconclusive() && !settings.certainty.isEnabled(Certainty::inconclusive)) + return false; + return true; +} + void CheckStlImpl::outOfBounds() { logChecker("CheckStl::outOfBounds"); @@ -148,9 +159,7 @@ void CheckStlImpl::outOfBounds() for (const ValueFlow::Value &value : tok->values()) { if (!value.isContainerSizeValue()) continue; - if (value.isImpossible()) - continue; - if (value.isInconclusive() && !mSettings.certainty.isEnabled(Certainty::inconclusive)) + if (!isUsableValue(value, mSettings)) continue; if (!value.errorSeverity() && !mSettings.severity.isEnabled(Severity::warning)) continue; @@ -2482,8 +2491,6 @@ void CheckStlImpl::checkDereferenceInvalidIterator() void CheckStlImpl::checkDereferenceInvalidIterator2() { - const bool printInconclusive = (mSettings.certainty.isEnabled(Certainty::inconclusive)); - logChecker("CheckStl::checkDereferenceInvalidIterator2"); for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { @@ -2496,20 +2503,16 @@ void CheckStlImpl::checkDereferenceInvalidIterator2() continue; std::vector contValues; - std::copy_if(tok->values().cbegin(), tok->values().cend(), std::back_inserter(contValues), [&](const ValueFlow::Value& value) { - if (value.isImpossible()) - return false; - if (!printInconclusive && value.isInconclusive()) - return false; - return value.isContainerSizeValue(); + std::copy_if(tok->values().cbegin(), + tok->values().cend(), + std::back_inserter(contValues), + [&](const ValueFlow::Value& value) { + return isUsableValue(value, mSettings) && value.isContainerSizeValue(); }); - // Can iterator point to END or before START? for (const ValueFlow::Value& value:tok->values()) { - if (value.isImpossible()) - continue; - if (!printInconclusive && value.isInconclusive()) + if (!isUsableValue(value, mSettings)) continue; if (!value.isIteratorValue()) continue; @@ -3379,6 +3382,378 @@ void CheckStlImpl::eraseIteratorOutOfBounds() } } +namespace { +// An iterator position described by the ValueFlow values attached to the iterator expression + struct IteratorPosition { + const ValueFlow::Value* value = nullptr; // ITERATOR_START or ITERATOR_END value + const ValueFlow::Value* sizeValue = nullptr; // container size value with the same path, if available + bool fromEnd() const { + return value->isIteratorEndValue(); + } + explicit operator bool() const { + return value != nullptr; + } + }; + +// A number of elements together with the ValueFlow values it was derived from + struct ElementCount { + MathLib::bigint count = 0; + std::vector values; + explicit operator bool() const { + return !values.empty(); + } + }; + +// The best candidate proving an out of bounds access, preferring proofs without possible values + struct BestCandidate { + ElementCount best; + bool certain = false; + void consider(const ElementCount& candidate) + { + const bool candidateCertain = + std::none_of(candidate.values.cbegin(), candidate.values.cend(), std::mem_fn(&ValueFlow::Value::isPossible)); + if (best && (certain || !candidateCertain)) + return; + best = candidate; + certain = candidateCertain; + } + }; +} // namespace + +// Get the first ValueFlow value of a token matching the predicate, preferring known values +template +static const ValueFlow::Value* selectPreferredValue(const Token* tok, const Predicate& pred) +{ + const ValueFlow::Value* result = nullptr; + for (const ValueFlow::Value& value : tok->values()) { + if (!pred(value)) + continue; + if (result && !(value.isKnown() && !result->isKnown())) + continue; + result = &value; + } + return result; +} + +// Get the iterator value of an iterator expression together with the container size value that +// ValueFlow has added to the iterator +static IteratorPosition getIteratorPosition(const Token* tok, const Settings& settings) +{ + IteratorPosition position; + if (!tok) + return position; + position.value = selectPreferredValue(tok, [&](const ValueFlow::Value& value) { + return isUsableValue(value, settings) && value.isIteratorValue(); + }); + if (!position.value) + return position; + position.sizeValue = selectPreferredValue(tok, [&](const ValueFlow::Value& value) { + return isUsableValue(value, settings) && value.isContainerSizeValue() && value.path == position.value->path; + }); + return position; +} + +// Compute the distance last-first between two iterators into the same container +static ElementCount getIteratorDistance(const IteratorPosition& first, const IteratorPosition& last) +{ + ElementCount distance; + if (first.value->path != last.value->path) + return distance; + // bounded values could make the distance an overestimate + if (first.value->bound != ValueFlow::Value::Bound::Point || last.value->bound != ValueFlow::Value::Bound::Point) + return distance; + if (first.fromEnd() == last.fromEnd()) { // the container size cancels out + distance.count = last.value->intvalue - first.value->intvalue; + distance.values = {first.value, last.value}; + return distance; + } + const IteratorPosition& endPosition = first.fromEnd() ? first : last; + if (!endPosition.sizeValue || endPosition.sizeValue->bound != ValueFlow::Value::Bound::Point) + return distance; + const MathLib::bigint endIndex = endPosition.sizeValue->intvalue + endPosition.value->intvalue; + distance.count = last.fromEnd() ? endIndex - first.value->intvalue : last.value->intvalue - endIndex; + distance.values = {first.value, last.value, endPosition.sizeValue}; + return distance; +} + +// Compute the number of elements available in the container behind the iterator position +static ElementCount getAvailableSpace(const IteratorPosition& position) +{ + ElementCount available; + // the position could be smaller, which would make more elements available + if (position.value->bound == ValueFlow::Value::Bound::Upper) + return available; + if (position.fromEnd()) { // the container size cancels out + available.count = -position.value->intvalue; + available.values = {position.value}; + return available; + } + // the container size could be larger, which would make more elements available + if (!position.sizeValue || position.sizeValue->bound == ValueFlow::Value::Bound::Lower) + return available; + available.count = position.sizeValue->intvalue - position.value->intvalue; + available.values = {position.value, position.sizeValue}; + return available; +} + +// Find iterator values and paired container sizes of the iterator that prove accessing +// elements to be out of bounds, preferring a proof that does not rely on possible values +static ElementCount findInsufficientSpace(const Token* tok, + MathLib::bigint accessed, + MathLib::bigint sourcePath, + const Settings& settings) +{ + BestCandidate insufficient; + if (!tok) + return insufficient.best; + const auto consider = [&](const ElementCount& candidate) { + if (!candidate) + return; + if (candidate.count < 0 || accessed <= candidate.count) + return; // the space is sufficient + insufficient.consider(candidate); + }; + for (const ValueFlow::Value& value : tok->values()) { + if (!isUsableValue(value, settings) || !value.isIteratorValue()) + continue; + if (value.path != 0 && sourcePath != 0 && value.path != sourcePath) + continue; + IteratorPosition position; + position.value = &value; + if (position.fromEnd()) { // the available space does not depend on the container size + consider(getAvailableSpace(position)); + continue; + } + for (const ValueFlow::Value& sizeValue : tok->values()) { + if (!isUsableValue(sizeValue, settings) || !sizeValue.isContainerSizeValue() || sizeValue.path != value.path) + continue; + position.sizeValue = &sizeValue; + consider(getAvailableSpace(position)); + } + } + return insufficient.best; +} + +// Find iterator values and paired container sizes of the source range that prove more than +// elements to be accessed, preferring a proof that does not rely on possible values +static ElementCount findExcessiveDistance(const Token* firstTok, + const Token* lastTok, + MathLib::bigint available, + MathLib::bigint destPath, + const Settings& settings) +{ + BestCandidate excessive; + const auto consider = [&](const ElementCount& candidate) { + if (!candidate) + return; + if (candidate.count <= available) + return; // the access is within bounds + excessive.consider(candidate); + }; + for (const ValueFlow::Value& firstValue : firstTok->values()) { + if (!isUsableValue(firstValue, settings) || !firstValue.isIteratorValue()) + continue; + if (firstValue.path != 0 && destPath != 0 && firstValue.path != destPath) + continue; + for (const ValueFlow::Value& lastValue : lastTok->values()) { + if (!isUsableValue(lastValue, settings) || !lastValue.isIteratorValue()) + continue; + IteratorPosition first, last; + first.value = &firstValue; + last.value = &lastValue; + if (first.fromEnd() == last.fromEnd()) { // the distance does not depend on the container size + consider(getIteratorDistance(first, last)); + continue; + } + IteratorPosition& endPosition = first.fromEnd() ? first : last; + const Token* const endTok = first.fromEnd() ? firstTok : lastTok; + for (const ValueFlow::Value& sizeValue : endTok->values()) { + if (!isUsableValue(sizeValue, settings) || !sizeValue.isContainerSizeValue() || + sizeValue.path != endPosition.value->path) + continue; + endPosition.sizeValue = &sizeValue; + consider(getIteratorDistance(first, last)); + } + } + } + return excessive.best; +} + +// Find count values of a count-based algorithm that prove more than elements to be accessed +static ElementCount findExcessiveCount(const Token* tok, + MathLib::bigint available, + MathLib::bigint destPath, + const Settings& settings) +{ + BestCandidate excessive; + if (!tok) + return excessive.best; + for (const ValueFlow::Value& value : tok->values()) { + if (!isUsableValue(value, settings) || !value.isIntValue()) + continue; + // a count with an upper bound could be smaller, which would make fewer elements accessed + if (value.bound == ValueFlow::Value::Bound::Upper) + continue; + if (value.path != 0 && destPath != 0 && value.path != destPath) + continue; + if (value.intvalue <= available) + continue; // the access is within bounds + ElementCount candidate; + candidate.count = value.intvalue; + candidate.values.push_back(&value); + excessive.consider(candidate); + } + return excessive.best; +} + +// Do not warn when the proof relies on possible values on both sides +static bool bothSidesPossible(const ElementCount& accessed, const ElementCount& available) +{ + const auto isPossible = std::mem_fn(&ValueFlow::Value::isPossible); + return std::any_of(accessed.values.cbegin(), accessed.values.cend(), isPossible) && + std::any_of(available.values.cbegin(), available.values.cend(), isPossible); +} + +// Get the number of accessed elements of a count-based algorithm such as std::fill_n +static const ValueFlow::Value* getCountValue(const Token* tok, const Settings& settings) +{ + if (!tok) + return nullptr; + return selectPreferredValue(tok, [&](const ValueFlow::Value& value) { + // a count with an upper bound could be smaller, which would make fewer elements accessed + return isUsableValue(value, settings) && value.isIntValue() && value.bound != ValueFlow::Value::Bound::Upper; + }); +} + +void CheckStlImpl::algorithmOutOfBounds() +{ + logChecker("CheckStl::algorithmOutOfBounds"); + for (const Scope* function : mTokenizer->getSymbolDatabase()->functionScopes) { + for (const Token* tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) { + if (!Token::Match(tok, "std :: %name% (")) + continue; + const Token* const nameTok = tok->tokAt(2); + // algorithms accessing the range denoted by the third argument exactly last1-first1 times.. + const bool exact = Token::Match( + nameTok, + "copy|move|swap_ranges|transform|replace_copy|replace_copy_if|reverse_copy|equal|mismatch|is_permutation|partial_sum|adjacent_difference|inner_product ("); + // ..or at most last1-first1 times, depending on the values in the input range.. + const bool atMost = !exact && Token::Match(nameTok, "copy_if|remove_copy|remove_copy_if|unique_copy ("); + // ..or accessing their iterator arguments as many times as the count argument says + const bool countBased = !exact && !atMost && Token::Match(nameTok, "copy_n|fill_n|generate_n ("); + if (!exact && !atMost && !countBased) + continue; + if (atMost && !mSettings.certainty.isEnabled(Certainty::inconclusive)) + continue; + const std::vector args = getArguments(nameTok); + if (args.size() < 3) + continue; + ElementCount accessed; // source access count using the preferred values + std::vector iterArgs; + if (countBased) { + if (const ValueFlow::Value* countValue = getCountValue(args[1], mSettings)) { + accessed.count = countValue->intvalue; + accessed.values.push_back(countValue); + } + iterArgs.push_back(args[0]); + if (Token::simpleMatch(nameTok, "copy_n")) + iterArgs.push_back(args[2]); // copy_n also writes through the third argument + } else { + // two-range overloads taking a last2 iterator do not access the second range out of bounds + if (Token::Match(nameTok, "equal|mismatch|is_permutation") && args.size() >= 4 && astIsIterator(args[3])) + continue; + // both iterators must refer to the same container + const ValueFlow::Value firstLifetime = getLifetimeIteratorValue(args[0]); + const ValueFlow::Value lastLifetime = getLifetimeIteratorValue(args[1]); + if (!firstLifetime.tokvalue || !lastLifetime.tokvalue) + continue; + if (!isSameIteratorContainerExpression(firstLifetime.tokvalue, + lastLifetime.tokvalue, + mSettings, + firstLifetime.lifetimeKind)) + continue; + const IteratorPosition first = getIteratorPosition(args[0], mSettings); + const IteratorPosition last = getIteratorPosition(args[1], mSettings); + if (first && last) + accessed = getIteratorDistance(first, last); + iterArgs.push_back(args[2]); + if (Token::simpleMatch(nameTok, "transform") && args.size() == 5) + iterArgs.push_back(args[3]); // binary transform also writes through the fourth argument + } + if (accessed.count <= 0) + accessed = ElementCount(); // there is no preferred source access count + for (const Token* const iterArg : iterArgs) { + // check the preferred source access count against all destination values.. + ElementCount sourceCount = accessed; + ElementCount available; + if (sourceCount) + available = + findInsufficientSpace(iterArg, sourceCount.count, sourceCount.values.front()->path, mSettings); + if (!available || bothSidesPossible(sourceCount, available)) { + // ..or all source access counts against the preferred destination values + const IteratorPosition dest = getIteratorPosition(iterArg, mSettings); + if (!dest) + continue; + available = getAvailableSpace(dest); + if (!available || available.count < 0) + continue; + sourceCount = + countBased + ? findExcessiveCount(args[1], available.count, dest.value->path, mSettings) + : findExcessiveDistance(args[0], args[1], available.count, dest.value->path, mSettings); + if (!sourceCount || bothSidesPossible(sourceCount, available)) + continue; + } + const ValueFlow::Value* conditionValue = nullptr; + bool inconclusiveValues = false; + std::vector usedValues = sourceCount.values; + usedValues.insert(usedValues.end(), available.values.cbegin(), available.values.cend()); + for (const ValueFlow::Value* value : usedValues) { + if (!conditionValue && value->condition) + conditionValue = value; + inconclusiveValues |= value->isInconclusive(); + } + if (conditionValue && !mSettings.severity.isEnabled(Severity::warning)) + continue; + const ValueFlow::Value* pathValue = conditionValue ? conditionValue : available.values.back(); + algorithmOutOfBoundsError(iterArg, + "std::" + nameTok->str(), + sourceCount.count, + available.count, + pathValue, + atMost, + atMost || inconclusiveValues); + } + } + } +} + +void CheckStlImpl::algorithmOutOfBoundsError(const Token* tok, + const std::string& algoName, + MathLib::bigint accessed, + MathLib::bigint available, + const ValueFlow::Value* value, + bool mayAccessFewer, + bool inconclusive) +{ + const Token* const condition = value ? value->condition : nullptr; + const std::string iterExpr = tok ? tok->expressionString() : "it"; + const std::string accessedStr = MathLib::toString(accessed) + (accessed == 1 ? " element" : " elements"); + const std::string availableStr = MathLib::toString(available) + (available == 1 ? " element is" : " elements are"); + const std::string body = "algorithm '" + algoName + "' " + (mayAccessFewer ? "may access up to " : "accesses ") + + accessedStr + " through the iterator '" + iterExpr + "' but only " + availableStr + + " available."; + const std::string msg = + condition ? (ValueFlow::eitherTheConditionIsRedundant(condition) + " or the " + body) : ("The " + body); + ErrorPath errorPath = getErrorPath(tok, value, "Access out of bounds"); + reportError(std::move(errorPath), + (condition || mayAccessFewer) ? Severity::warning : Severity::error, + "algorithmOutOfBounds", + msg, + CWE788, + inconclusive ? Certainty::inconclusive : Certainty::normal); +} + static bool isMutex(const Variable* var) { const Token* tok = Token::typeDecl(var->nameToken()).first; @@ -3478,6 +3853,7 @@ void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger& errorLogger) checkStl.mismatchingContainerIterator(); checkStl.knownEmptyContainer(); checkStl.eraseIteratorOutOfBounds(); + checkStl.algorithmOutOfBounds(); checkStl.stlBoundaries(); checkStl.checkDereferenceInvalidIterator(); @@ -3529,6 +3905,7 @@ void CheckStl::getErrorMessages(ErrorLogger& errorLogger, const Settings& settin c.dereferenceInvalidIteratorError(nullptr, "i"); // TODO: derefInvalidIteratorRedundantCheck c.eraseIteratorOutOfBoundsError(nullptr, nullptr); + c.algorithmOutOfBoundsError(nullptr, "std::copy", 10, 6, nullptr, false, false); c.useStlAlgorithmError(nullptr, ""); c.knownEmptyContainerError(nullptr, ""); c.globalLockGuardError(nullptr); diff --git a/lib/checkstl.h b/lib/checkstl.h index 4218090e707..0f9a70a7a15 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -26,6 +26,7 @@ #include "checkimpl.h" #include "config.h" #include "errortypes.h" +#include "mathlib.h" #include #include @@ -73,6 +74,7 @@ class CPPCHECKLIB CheckStl : public Check { "- useless calls of string and STL functions\n" "- dereferencing an invalid iterator\n" "- erasing an iterator that is out of bounds\n" + "- out of bounds access of an iterator passed to an STL algorithm\n" "- reading from empty STL container\n" "- iterating over an empty STL container\n" "- consider using an STL algorithm instead of raw loop\n" @@ -183,6 +185,12 @@ class CPPCHECKLIB CheckStlImpl : public CheckImpl { void eraseIteratorOutOfBounds(); + /** + * Check that the iterator given to an STL algorithm is not accessed + * out of bounds: std::equal(in.begin(), in.end(), out.begin()) + */ + void algorithmOutOfBounds(); + void checkMutexes(); bool isContainerSize(const Token *containerToken, const Token *expr) const; @@ -235,6 +243,14 @@ class CPPCHECKLIB CheckStlImpl : public CheckImpl { void eraseIteratorOutOfBoundsError(const Token* ftok, const Token* itertok, const ValueFlow::Value* val = nullptr); + void algorithmOutOfBoundsError(const Token* tok, + const std::string& algoName, + MathLib::bigint accessed, + MathLib::bigint available, + const ValueFlow::Value* value, + bool mayAccessFewer, + bool inconclusive); + void globalLockGuardError(const Token *tok); void localMutexError(const Token *tok); }; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 8c77b17cf94..096e3d56f56 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3844,12 +3844,24 @@ static void valueFlowForwardConst(Token* start, { if (!precedes(start, end)) throw InternalError(var->nameToken(), "valueFlowForwardConst: start token does not precede the end token."); + const bool hasContainerSizeValue = std::any_of(values.begin(), values.end(), [](const ValueFlow::Value& value) { + return value.isContainerSizeValue(); + }); for (Token* tok = start; tok != end; tok = tok->next()) { if (tok->varId() == var->declarationId()) { for (const ValueFlow::Value& value : values) setTokenValue(tok, value, settings); } else { [&] { + // Add the container size to iterators of the container (mirrors ContainerExpressionAnalyzer::match) + if (hasContainerSizeValue && astIsIterator(tok) && isAliasOf(tok, var->declarationId())) { + for (const ValueFlow::Value& value : values) { + if (!value.isContainerSizeValue()) + continue; + setTokenValue(tok, value, settings); + } + return; + } // Follow references const auto& refs = tok->refs(); auto it = std::find_if(refs.cbegin(), refs.cend(), [&](const ReferenceToken& ref) { diff --git a/man/checkers/algorithmOutOfBounds.md b/man/checkers/algorithmOutOfBounds.md new file mode 100644 index 00000000000..8e446f82895 --- /dev/null +++ b/man/checkers/algorithmOutOfBounds.md @@ -0,0 +1,69 @@ +# algorithmOutOfBounds + +**Message**: The algorithm 'std::copy' accesses 5 elements through the iterator 'v1.begin()' but only 3 elements are available.
+**Category**: Correctness
+**Severity**: Error
+**Language**: C++ + +## Description + +Many STL algorithms take an iterator that denotes the beginning of a second range (typically an output range) and +assume that this range is large enough. If it is not, the algorithm writes or reads past the end of the container, +which is undefined behavior. + +This checker uses the ValueFlow analysis to compare the number of elements an algorithm accesses with the number of +elements that are actually available through the iterator, and warns when the access is out of bounds. Three groups +of algorithms are checked: + +- Algorithms that access exactly `last1 - first1` elements through the other iterator: `std::copy`, `std::move`, + `std::swap_ranges`, `std::transform`, `std::replace_copy`, `std::replace_copy_if`, `std::reverse_copy`, + `std::equal`, `std::mismatch`, `std::is_permutation`, `std::partial_sum`, `std::adjacent_difference` and + `std::inner_product`. +- Algorithms that access at most `last1 - first1` elements, depending on the values in the input range: + `std::copy_if`, `std::remove_copy`, `std::remove_copy_if` and `std::unique_copy`. Since the actual number of + accessed elements is not known, these are only reported as inconclusive warnings (with `--inconclusive`). +- Count-based algorithms that access as many elements as the count argument says: `std::copy_n`, `std::fill_n` and + `std::generate_n`. + +The severity is `error` when the out of bounds access always happens. When the analysis depends on an earlier +condition in the code, the severity is `warning` and the message has the form "Either the condition 'v.size()==3' +is redundant or the algorithm ... ". + +The checker does not warn when: + +- The second range is given with both a begin and an end iterator (for example the two-range overloads of + `std::equal`, `std::mismatch` and `std::is_permutation`), since such overloads do not access the second range out + of bounds. +- An iterator adaptor such as `std::back_inserter` or `std::inserter` is used, since those grow the container as + needed. +- The proof would rely on "possible" (non-known) values on both the accessed and the available side. + +## How to fix + +Make sure the destination range is large enough before calling the algorithm, or use an iterator adaptor such as +`std::back_inserter` that grows the container as needed. + +Before: +```cpp +void f(const std::vector& v0) { + std::vector v1(3); + // If v0 has more than 3 elements, this writes past the end of v1 + std::copy(v0.begin(), v0.end(), v1.begin()); +} +``` + +After: +```cpp +void f(const std::vector& v0) { + std::vector v1(v0.size()); + std::copy(v0.begin(), v0.end(), v1.begin()); +} +``` + +Or let the container grow: +```cpp +void f(const std::vector& v0) { + std::vector v1; + std::copy(v0.begin(), v0.end(), std::back_inserter(v1)); +} +``` diff --git a/releasenotes.txt b/releasenotes.txt index 0ca26f2374a..1c0739dec0d 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -7,6 +7,7 @@ Major bug fixes & crashes: New checks: - Warn when feof() is used as a while loop condition (wrongfeofUsage). - ftell() result is unspecified when file is opened in mode "t". +- Detect when an STL algorithm such as std::copy, std::equal, std::transform, etc. accesses more elements through an iterator than are available in the container (algorithmOutOfBounds). C/C++ support: - diff --git a/test/cli/other_test.py b/test/cli/other_test.py index c79fd0c8e50..c48a0b50354 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -1,4 +1,3 @@ - # python -m pytest test-other.py import os @@ -4429,25 +4428,25 @@ def __test_active_checkers(tmp_path, active_cnt, total_cnt, use_misra=False, use def test_active_unusedfunction_only(tmp_path): - __test_active_checkers(tmp_path, 1, 187, use_unusedfunction_only=True) + __test_active_checkers(tmp_path, 1, 188, use_unusedfunction_only=True) def test_active_unusedfunction_only_builddir(tmp_path): checkers_exp = [ 'CheckUnusedFunctions::check' ] - __test_active_checkers(tmp_path, 1, 187, use_unusedfunction_only=True, checkers_exp=checkers_exp) + __test_active_checkers(tmp_path, 1, 188, use_unusedfunction_only=True, checkers_exp=checkers_exp) def test_active_unusedfunction_only_misra(tmp_path): - __test_active_checkers(tmp_path, 1, 387, use_unusedfunction_only=True, use_misra=True) + __test_active_checkers(tmp_path, 1, 388, use_unusedfunction_only=True, use_misra=True) def test_active_unusedfunction_only_misra_builddir(tmp_path): checkers_exp = [ 'CheckUnusedFunctions::check' ] - __test_active_checkers(tmp_path, 1, 387, use_unusedfunction_only=True, use_misra=True, checkers_exp=checkers_exp) + __test_active_checkers(tmp_path, 1, 388, use_unusedfunction_only=True, use_misra=True, checkers_exp=checkers_exp) def test_analyzerinfo(tmp_path): diff --git a/test/teststl.cpp b/test/teststl.cpp index 93b53b43671..ed9c5503d45 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -78,6 +78,7 @@ class TestStl : public TestFixture { TEST_CASE(iteratorSameExpression); TEST_CASE(mismatchingContainerIterator); TEST_CASE(eraseIteratorOutOfBounds); + TEST_CASE(algorithmOutOfBounds); TEST_CASE(dereference); TEST_CASE(dereference_break); // #3644 - handle "break" @@ -2421,6 +2422,372 @@ class TestStl : public TestFixture { errout_str()); } + void algorithmOutOfBounds() + { + check("void f() {\n" + " const std::deque d0{1,2,3,4,5,6,7,8,9,10};\n" + " const std::deque d1{1,2,3,4,5,6};\n" + " if(std::equal(d0.cbegin(), d0.cend(), d1.cbegin())) {}\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:52]: (error) The algorithm 'std::equal' accesses 10 elements through the iterator 'd1.cbegin()' but only 6 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " const std::deque d0{1,2,3,4,5,6};\n" + " const std::deque d1{1,2,3,4,5,6};\n" + " if(std::equal(d0.cbegin(), d0.cend(), d1.cbegin())) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // two-range overload does not access the second range out of bounds + check("void f() {\n" + " const std::deque d0{1,2,3,4,5,6,7,8,9,10};\n" + " const std::deque d1{1,2,3,4,5,6};\n" + " if(std::equal(d0.cbegin(), d0.cend(), d1.cbegin(), d1.cend())) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(3);\n" + " std::copy(v0.begin(), v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:45]: (error) The algorithm 'std::copy' accesses 5 elements through the iterator 'v1.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(5);\n" + " std::copy(v0.begin(), v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // iterator arithmetic + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(6);\n" + " std::copy(v0.begin(), v0.end(), v1.begin() + 3);\n" + " std::copy(v0.begin() + 3, v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:48]: (error) The algorithm 'std::copy' accesses 5 elements through the iterator 'v1.begin()+3' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // don't warn when using iterator adaptors + check("void f() {\n" + " const std::deque d0{1,2,3,4,5,6,7,8,9,10};\n" + " std::deque d1;\n" + " std::copy(d0.cbegin(), d0.cend(), std::back_inserter(d1));\n" + " std::copy(d0.cbegin(), d0.cend(), std::inserter(d1, d1.begin()));\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // algorithms that access at most last-first elements are inconclusive + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(3);\n" + " std::copy_if(v0.begin(), v0.end(), v1.begin(), [](int i) { return i != 3; });\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(3);\n" + " std::copy_if(v0.begin(), v0.end(), v1.begin(), [](int i) { return i != 3; });\n" + "}\n", + dinit(CheckOptions, $.inconclusive = true)); + ASSERT_EQUALS( + "[test.cpp:4:48]: (warning, inconclusive) The algorithm 'std::copy_if' may access up to 5 elements through the iterator 'v1.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(3);\n" + " std::transform(v0.begin(), v0.end(), v1.begin(), [](int i) { return i * 2; });\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:50]: (error) The algorithm 'std::transform' accesses 5 elements through the iterator 'v1.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // binary transform reads the third argument and writes the fourth argument + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " const std::vector v1{1,2,3};\n" + " std::vector v2(5);\n" + " std::transform(v0.begin(), v0.end(), v1.begin(), v2.begin(), [](int a, int b) { return a + b; });\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:5:50]: (error) The algorithm 'std::transform' accesses 5 elements through the iterator 'v1.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " const std::vector v1{1,2,3,4,5};\n" + " std::vector v2(3);\n" + " std::transform(v0.begin(), v0.end(), v1.begin(), v2.begin(), [](int a, int b) { return a + b; });\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:5:62]: (error) The algorithm 'std::transform' accesses 5 elements through the iterator 'v2.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // copying a range within the same container + check("void f() {\n" + " std::vector v{1,2,3,4,5,6,7,8,9,10};\n" + " std::copy(v.begin(), v.begin() + 3, v.begin() + 7);\n" + " std::copy(v.begin(), v.begin() + 4, v.begin() + 7);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:51]: (error) The algorithm 'std::copy' accesses 4 elements through the iterator 'v.begin()+7' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // unknown container sizes + check("void f(const std::vector& v0, std::vector& v1) {\n" + " std::copy(v0.begin(), v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // don't warn for iterator variables when the container size changes before the algorithm is called + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::list l1(3);\n" + " auto it = l1.begin();\n" + " l1.resize(10);\n" + " std::copy(v0.begin(), v0.end(), it);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // iterator variables carry the container size + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(3);\n" + " auto it = v1.begin();\n" + " std::copy(v0.begin(), v0.end(), it);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:5:37]: (error) The algorithm 'std::copy' accesses 5 elements through the iterator 'it' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // ..and the size is the size at the call, not at the creation of the iterator + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::list l1(10);\n" + " auto it = l1.begin();\n" + " l1.resize(3);\n" + " std::copy(v0.begin(), v0.end(), it);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:6:37]: (error) The algorithm 'std::copy' accesses 5 elements through the iterator 'it' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // conditional container size + check("void f(std::vector& v) {\n" + " const std::vector v0{1,2,3,4,5};\n" + " if (v.size() == 3)\n" + " std::copy(v0.begin(), v0.end(), v.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3:18] -> [test.cpp:4:48]: (warning) Either the condition 'v.size()==3' is redundant or the algorithm 'std::copy' accesses 5 elements through the iterator 'v.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f(std::vector& v) {\n" + " const std::vector v0{1,2,3,4,5};\n" + " if (v.size() < 5)\n" + " std::copy(v0.begin(), v0.end(), v.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3:18] -> [test.cpp:4:48]: (warning) Either the condition 'v.size()<5' is redundant or the algorithm 'std::copy' accesses 5 elements through the iterator 'v.begin()' but only 4 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f(std::vector& v) {\n" + " const std::vector v0{1,2,3,4,5};\n" + " if (v.size() >= 5)\n" + " std::copy(v0.begin(), v0.end(), v.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // writing through the end iterator + check("void f() {\n" + " const std::vector v0{1,2,3};\n" + " std::vector v1(10);\n" + " std::copy(v0.begin(), v0.end(), v1.end());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:43]: (error) The algorithm 'std::copy' accesses 3 elements through the iterator 'v1.end()' but only 0 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // the source range is known even when the container size is not + check("void f(const std::vector& v) {\n" + " std::vector v1(3);\n" + " std::copy(v.begin(), v.begin() + 5, v1.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3:49]: (error) The algorithm 'std::copy' accesses 5 elements through the iterator 'v1.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // count-based algorithms access both iterator arguments times + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(3);\n" + " std::copy_n(v0.begin(), 5, v1.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:40]: (error) The algorithm 'std::copy_n' accesses 5 elements through the iterator 'v1.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(10);\n" + " std::copy_n(v0.begin(), 10, v1.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:25]: (error) The algorithm 'std::copy_n' accesses 10 elements through the iterator 'v0.begin()' but only 5 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1(5);\n" + " std::copy_n(v0.begin(), 5, v1.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" + " std::vector v(5);\n" + " std::fill_n(v.begin(), 10, 0);\n" + " std::fill_n(v.begin() + 3, 3, 0);\n" + " std::fill_n(v.begin(), 5, 0);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3:24]: (error) The algorithm 'std::fill_n' accesses 10 elements through the iterator 'v.begin()' but only 5 elements are available. [algorithmOutOfBounds]\n" + "[test.cpp:4:27]: (error) The algorithm 'std::fill_n' accesses 3 elements through the iterator 'v.begin()+3' but only 2 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " std::vector v;\n" + " std::fill_n(std::back_inserter(v), 10, 0);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" + " std::vector v(5);\n" + " std::generate_n(v.begin(), 6, [] { return 1; });\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3:28]: (error) The algorithm 'std::generate_n' accesses 6 elements through the iterator 'v.begin()' but only 5 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // conditional count + check("void f(std::vector& v, int n) {\n" + " if (v.size() == 5 && n > 5)\n" + " std::fill_n(v.begin(), n, 0);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:2:28] -> [test.cpp:3:28]: (warning) Either the condition 'n>5' is redundant or the algorithm 'std::fill_n' accesses 6 elements through the iterator 'v.begin()' but only 5 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // an upper bound of the count cannot tell whether the access is out of bounds + check("void f(int n) {\n" + " std::vector v(3);\n" + " if (n < 5)\n" + " std::fill_n(v.begin(), n, 0);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // a lower bound of the container size cannot tell whether the access is out of bounds + check("void f(std::vector& v) {\n" + " const std::vector v0{1,2,3,4,5};\n" + " if (v.size() >= 4)\n" + " std::copy(v0.begin(), v0.end(), v.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // unknown count + check("void f(std::vector& v, int n) {\n" + " std::fill_n(v.begin(), n, 0);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // all container size values are checked, not only the first one + check("void f(bool b) {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1;\n" + " if (b)\n" + " v1.resize(3);\n" + " else\n" + " v1.resize(10);\n" + " std::copy(v0.begin(), v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:8:45]: (error) The algorithm 'std::copy' accesses 5 elements through the iterator 'v1.begin()' but only 3 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f(bool b) {\n" + " const std::vector v0{1,2,3,4,5};\n" + " std::vector v1;\n" + " if (b)\n" + " v1.resize(5);\n" + " else\n" + " v1.resize(10);\n" + " std::copy(v0.begin(), v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // all iterator position values are checked as well + check("void f(bool b) {\n" + " const std::vector v0{1,2,3,4};\n" + " std::vector v1(5);\n" + " auto it = b ? v1.begin() : v1.begin() + 3;\n" + " std::copy(v0.begin(), v0.end(), it);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:5:37]: (error) The algorithm 'std::copy' accesses 4 elements through the iterator 'it' but only 2 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + // do not combine possible values on both sides + check("void f(bool b, std::vector& v0, std::vector& v1) {\n" + " if (b) v0.resize(5); else v0.resize(2);\n" + " if (b) v1.resize(3); else v1.resize(10);\n" + " std::copy(v0.begin(), v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // all source range values are checked against the preferred destination values + check("void f(bool b) {\n" + " std::vector v0;\n" + " if (b)\n" + " v0.resize(3);\n" + " else\n" + " v0.resize(10);\n" + " std::vector v1(5);\n" + " std::copy(v0.begin(), v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:8:45]: (error) The algorithm 'std::copy' accesses 10 elements through the iterator 'v1.begin()' but only 5 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + + check("void f(bool b) {\n" + " std::vector v0;\n" + " if (b)\n" + " v0.resize(3);\n" + " else\n" + " v0.resize(5);\n" + " std::vector v1(5);\n" + " std::copy(v0.begin(), v0.end(), v1.begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + // all count values are checked as well + check("void f(bool b) {\n" + " std::vector v(5);\n" + " const int n = b ? 3 : 10;\n" + " std::fill_n(v.begin(), n, 0);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4:24]: (error) The algorithm 'std::fill_n' accesses 10 elements through the iterator 'v.begin()' but only 5 elements are available. [algorithmOutOfBounds]\n", + errout_str()); + } + // Dereferencing invalid pointer void dereference() { check("void f()\n" @@ -7047,7 +7414,10 @@ class TestStl : public TestFixture { " std::copy(v1.begin(), v1.end(), v2.begin());\n" "}\n", dinit(CheckOptions, $.inconclusive = true)); - ASSERT_EQUALS("[test.cpp:4:45]: (style) Using copy with iterator 'v2.begin()' that is always empty. [knownEmptyContainer]\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:4:45]: (style) Using copy with iterator 'v2.begin()' that is always empty. [knownEmptyContainer]\n" + "[test.cpp:4:45]: (error) The algorithm 'std::copy' accesses 2 elements through the iterator 'v2.begin()' but only 0 elements are available. [algorithmOutOfBounds]\n", + errout_str()); check("void f() {\n" " std::vector v;\n" diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 1f144900c4d..abeb603b660 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -137,6 +137,7 @@ class TestValueFlow : public TestFixture { TEST_CASE(valueFlowConditionExpressions); TEST_CASE(valueFlowContainerSize); + TEST_CASE(valueFlowContainerSizeIterator); TEST_CASE(valueFlowContainerElement); TEST_CASE(valueFlowDynamicBufferSize); @@ -7662,6 +7663,47 @@ class TestValueFlow : public TestFixture { ASSERT(!isKnownContainerSizeValue(tokenValues(code, "m ."), 0).empty()); } + void valueFlowContainerSizeIterator() { + const char* code; + + // valueFlowForwardConst: the container size is added to iterators of a const container + code = "void f() {\n" + " const std::vector v{1, 2, 3};\n" + " auto it = v.begin();\n" + " if (it != v.end()) {}\n" + "}"; + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "it !=", ValueFlow::Value::ValueType::CONTAINER_SIZE), 3)); + + // ..also to iterators created in place + code = "void f() {\n" + " const std::deque d{1, 2, 3, 4, 5, 6};\n" + " if (std::equal(d.cbegin(), d.cend(), d.cbegin())) {}\n" + "}"; + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "( ) ,", ValueFlow::Value::ValueType::CONTAINER_SIZE), 6)); + + // ..and to iterators of containers with a static size + code = "void f() {\n" + " std::array a;\n" + " auto it = a.begin();\n" + " if (it != a.end()) {}\n" + "}"; + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "it !=", ValueFlow::Value::ValueType::CONTAINER_SIZE), 5)); + + // the size of another container is not added to the iterator + code = "void f(std::vector& w) {\n" + " const std::vector v{1, 2, 3};\n" + " auto it = w.begin();\n" + " if (it != w.end()) {}\n" + "}"; + ASSERT(tokenValues(code, "it !=", ValueFlow::Value::ValueType::CONTAINER_SIZE).empty()); + } + void valueFlowContainerElement() { const char* code; From 174a5692e78af69120710d2d127d67afabee4f61 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 13 Jul 2026 09:01:07 +0200 Subject: [PATCH 247/493] Fix #13148 FN: constStatement (static_cast(integer|nullptr|NULL)) (#8694) Co-authored-by: chrchr-github --- lib/checkother.cpp | 38 ++++++++++----------------- test/cli/proj-inline-suppress/cfg.c | 4 +-- test/testincompletestatement.cpp | 40 ++++++++++++++++++++--------- test/testother.cpp | 7 +++-- 4 files changed, 48 insertions(+), 41 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index f0d7fbd91f1..d8f2f6ff6f4 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2323,18 +2323,12 @@ static bool isConstStatement(const Token *tok, const Library& library, bool plat static bool isVoidStmt(const Token *tok) { - if (Token::simpleMatch(tok, "( void")) + if (Token::simpleMatch(tok, "( void") && !(tok->astOperand1() && (tok->astOperand1()->isLiteral() || isNullOperand(tok->astOperand1())))) return true; - if (isCPPCast(tok) && tok->astOperand1() && Token::Match(tok->astOperand1()->next(), "< void *| >")) + if (isCPPCast(tok) && tok->astOperand1() && Token::Match(tok->astOperand1()->next(), "< void *| >") && + !(tok->astOperand2() && (tok->astOperand2()->isLiteral() || isNullOperand(tok->astOperand2())))) return true; - const Token *tok2 = tok; - while (tok2->astOperand1()) - tok2 = tok2->astOperand1(); - if (Token::simpleMatch(tok2->previous(), ")") && Token::simpleMatch(tok2->linkAt(-1), "( void")) - return true; - if (Token::simpleMatch(tok2, "( void")) - return true; - return Token::Match(tok2->previous(), "delete|throw|return"); + return false; } static bool isConstTop(const Token *tok) @@ -2425,10 +2419,6 @@ void CheckOtherImpl::checkIncompleteStatement() void CheckOtherImpl::constStatementError(const Token *tok, const std::string &type, bool inconclusive) { - const Token *valueTok = tok; - while (valueTok && valueTok->isCast()) - valueTok = valueTok->astOperand2() ? valueTok->astOperand2() : valueTok->astOperand1(); - std::string msg; if (Token::simpleMatch(tok, "==")) msg = "Found suspicious equality comparison. Did you intend to assign a value instead?"; @@ -2436,26 +2426,24 @@ void CheckOtherImpl::constStatementError(const Token *tok, const std::string &ty msg = "Found suspicious operator '" + tok->str() + "', result is not used."; else if (Token::Match(tok, "%var%")) msg = "Unused variable value '" + tok->str() + "'"; - else if (isConstant(valueTok)) { + else if (isConstant(tok)) { std::string typeStr("string"); - if (valueTok->isNumber()) + if (tok->isNumber()) typeStr = "numeric"; - else if (valueTok->isBoolean()) + else if (tok->isBoolean()) typeStr = "bool"; - else if (valueTok->tokType() == Token::eChar) + else if (tok->tokType() == Token::eChar) typeStr = "character"; - else if (isNullOperand(valueTok)) - typeStr = "NULL"; - else if (valueTok->isEnumerator()) + else if (isNullOperand(tok)) + typeStr = "null"; + else if (tok->isEnumerator()) typeStr = "enumerator"; msg = "Redundant code: Found a statement that begins with " + typeStr + " constant."; } else if (!tok) msg = "Redundant code: Found a statement that begins with " + type + " constant."; - else if (tok->isCast() && tok->tokType() == Token::Type::eExtendedOp) { - msg = "Redundant code: Found unused cast "; - msg += valueTok ? "of expression '" + valueTok->expressionString() + "'." : "expression."; - } + else if (tok->isCast() && tok->tokType() == Token::Type::eExtendedOp) + msg = "Redundant code: Found unused cast in expression '" + tok->expressionString() + "'."; else if (tok->str() == "?" && tok->tokType() == Token::Type::eExtendedOp) msg = "Redundant code: Found unused result of ternary operator."; else if (tok->str() == "." && tok->tokType() == Token::Type::eOther) diff --git a/test/cli/proj-inline-suppress/cfg.c b/test/cli/proj-inline-suppress/cfg.c index b597217fa32..42709095dcf 100644 --- a/test/cli/proj-inline-suppress/cfg.c +++ b/test/cli/proj-inline-suppress/cfg.c @@ -2,9 +2,9 @@ void f() { #if DEF_1 // cppcheck-suppress id - (void)0; + ; #endif // cppcheck-suppress id - (void)0; + ; } diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 806f734274e..da238d304b2 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -180,9 +180,25 @@ class TestIncompleteStatement : public TestFixture { } void void0() { // #6327 - check("void f() { (void*)0; }"); + check("#define assert(x) ((void)0)\n" + "void f(int* p) {\n" + " assert(p);\n" + "}\n"); ASSERT_EQUALS("", errout_str()); + check("void f() { (void*)0; }"); + ASSERT_EQUALS("[test.cpp:1:12]: (warning) Redundant code: Found unused cast in expression '(void*)0'. [constStatement]\n", errout_str()); + + check("void f() {\n" // #13148 + " static_cast(1);\n" + " static_cast(nullptr);\n" + " (void)NULL;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:22]: (warning) Redundant code: Found unused cast in expression 'static_cast(1)'. [constStatement]\n" + "[test.cpp:3:22]: (warning) Redundant code: Found unused cast in expression 'static_cast(nullptr)'. [constStatement]\n" + "[test.cpp:4:5]: (warning) Redundant code: Found unused cast in expression '(void)NULL'. [constStatement]\n", + errout_str()); + check("#define X 0\n" "void f() { X; }"); ASSERT_EQUALS("", errout_str()); @@ -432,11 +448,11 @@ class TestIncompleteStatement : public TestFixture { "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" "[test.cpp:3:6]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" - "[test.cpp:4:5]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" - "[test.cpp:5:6]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" + "[test.cpp:4:5]: (warning) Redundant code: Found unused cast in expression '(char)1'. [constStatement]\n" + "[test.cpp:5:6]: (warning) Redundant code: Found unused cast in expression '(char)1'. [constStatement]\n" "[test.cpp:6:5]: (warning, inconclusive) Found suspicious operator '!', result is not used. [constStatement]\n" "[test.cpp:7:6]: (warning, inconclusive) Found suspicious operator '!', result is not used. [constStatement]\n" - "[test.cpp:8:5]: (warning) Redundant code: Found unused cast of expression '!x'. [constStatement]\n" + "[test.cpp:8:5]: (warning) Redundant code: Found unused cast in expression '(unsigned int)!x'. [constStatement]\n" "[test.cpp:9:5]: (warning, inconclusive) Found suspicious operator '~', result is not used. [constStatement]\n", errout_str()); @@ -447,7 +463,7 @@ class TestIncompleteStatement : public TestFixture { ASSERT_EQUALS("", errout_str()); check("void f(int x) { static_cast(x); }"); - ASSERT_EQUALS("[test.cpp:1:38]: (warning) Redundant code: Found unused cast of expression 'x'. [constStatement]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1:38]: (warning) Redundant code: Found unused cast in expression 'static_cast(x)'. [constStatement]\n", errout_str()); check("void f(int x, int* p) {\n" " static_cast(x);\n" @@ -465,9 +481,9 @@ class TestIncompleteStatement : public TestFixture { " static_cast((char)i);\n" " (char)static_cast(i);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n" - "[test.cpp:3:23]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n" - "[test.cpp:4:5]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n", + ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found unused cast in expression '(float)(char)i'. [constStatement]\n" + "[test.cpp:3:23]: (warning) Redundant code: Found unused cast in expression 'static_cast((char)i)'. [constStatement]\n" + "[test.cpp:4:5]: (warning) Redundant code: Found unused cast in expression '(char)static_cast(i)'. [constStatement]\n", errout_str()); check("namespace M {\n" @@ -476,7 +492,7 @@ class TestIncompleteStatement : public TestFixture { "void f(int i) {\n" " (M::N::T)i;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5:5]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:5]: (warning) Redundant code: Found unused cast in expression '(char)i'. [constStatement]\n", errout_str()); check("void f(int (g)(int a, int b)) {\n" // #10873 " int p = 0, q = 1;\n" @@ -528,7 +544,7 @@ class TestIncompleteStatement : public TestFixture { " for (L\"y\"; ;) {}\n" "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (warning) Unused variable value 'i' [constStatement]\n" - "[test.cpp:3:10]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n" + "[test.cpp:3:10]: (warning) Redundant code: Found unused cast in expression '(long)i'. [constStatement]\n" "[test.cpp:4:10]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" "[test.cpp:5:10]: (warning) Redundant code: Found a statement that begins with bool constant. [constStatement]\n" "[test.cpp:6:10]: (warning) Redundant code: Found a statement that begins with character constant. [constStatement]\n" @@ -696,8 +712,8 @@ class TestIncompleteStatement : public TestFixture { " NULL;\n" " nullptr;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found a statement that begins with NULL constant. [constStatement]\n" - "[test.cpp:3:5]: (warning) Redundant code: Found a statement that begins with NULL constant. [constStatement]\n", + ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found a statement that begins with null constant. [constStatement]\n" + "[test.cpp:3:5]: (warning) Redundant code: Found a statement that begins with null constant. [constStatement]\n", errout_str()); check("struct S { int i; };\n" // #6504 diff --git a/test/testother.cpp b/test/testother.cpp index ca42ef23deb..0b87a07f160 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3914,7 +3914,9 @@ class TestOther : public TestFixture { " (void)(true);\n" " if (r) {}\n" "}\n"); - ASSERT_EQUALS("[test.cpp:1:13]: (style) Parameter 'r' can be declared as reference to const [constParameterReference]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found unused cast in expression '(void)(true)'. [constStatement]\n" + "[test.cpp:1:13]: (style) Parameter 'r' can be declared as reference to const [constParameterReference]\n", + errout_str()); check("struct S { void f(int&); };\n" // #12216 "void g(S& s, int& r, void (S::* p2m)(int&)) {\n" @@ -7012,7 +7014,8 @@ class TestOther : public TestFixture { " std::pair(1, 2);\n" " (void)0;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2:10]: (style) Instance of 'std::string' object is destroyed immediately. [unusedScopedObject]\n" + ASSERT_EQUALS("[test.cpp:5:5]: (warning) Redundant code: Found unused cast in expression '(void)0'. [constStatement]\n" + "[test.cpp:2:10]: (style) Instance of 'std::string' object is destroyed immediately. [unusedScopedObject]\n" "[test.cpp:3:10]: (style) Instance of 'std::string' object is destroyed immediately. [unusedScopedObject]\n" "[test.cpp:4:10]: (style) Instance of 'std::pair' object is destroyed immediately. [unusedScopedObject]\n", errout_str()); From df67f2b84f2295c65ac1b6bd386a80979cac1254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 13 Jul 2026 17:13:13 +0200 Subject: [PATCH 248/493] CI: suppress with symbolname (#8714) --- .github/workflows/selfcheck.yml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 1a213039f93..3517486df31 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -121,8 +121,25 @@ jobs: - name: Self check (unusedFunction / no test / no gui) run: | - supprs="--suppress=unusedFunction:lib/errorlogger.h:198 --suppress=unusedFunction:lib/importproject.cpp:1671 --suppress=unusedFunction:lib/importproject.cpp:1695" - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs + echo ' + + + unusedFunction + lib/errorlogger.h + verboseMessage + + + unusedFunction + lib/importproject.cpp + selectVsConfigurations + + + unusedFunction + lib/importproject.cpp + getVSConfigs + + ' > supprs.xml + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr --suppress-xml=supprs.xml env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 From b6e1f451ca73418fe6433da095c07d69c8addfbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 14 Jul 2026 08:21:25 +0200 Subject: [PATCH 249/493] Fix #14910: Wrong tokenization of qualified function-pointer member definition (#8718) --- lib/tokenize.cpp | 9 +++++++-- test/testsimplifyusing.cpp | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 4e00e0d184e..f273cd623ec 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3389,12 +3389,17 @@ bool Tokenizer::simplifyUsing() } else if (fpArgList && fpQual && Token::Match(tok1->next(), "%name%")) { // function pointer const bool isFuncDecl = Token::simpleMatch(tok1->tokAt(2), "("); - TokenList::copyTokens(tok1->next(), fpArgList, usingEnd->previous()); + Token *dest = tok1->next(); + while (Token::Match(dest, "%name% :: %name%")) + dest = dest->tokAt(2); + TokenList::copyTokens(dest, fpArgList, usingEnd->previous()); Token* const copyEnd = TokenList::copyTokens(tok1, start, fpQual->link()->previous()); Token* leftPar = copyEnd->previous(); while (leftPar->str() != "(") leftPar = leftPar->previous(); - Token* const insertTok = isFuncDecl ? copyEnd->linkAt(2) : copyEnd->next(); + Token *insertTok = isFuncDecl ? copyEnd->linkAt(2) : copyEnd->next(); + while (Token::Match(insertTok, "%name% :: %name%")) + insertTok = insertTok->tokAt(2); Token* const rightPar = insertTok->insertToken(")"); Token::createMutualLinks(leftPar, rightPar); tok1->deleteThis(); diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index 160f80762a8..5210d484d40 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -78,6 +78,7 @@ class TestSimplifyUsing : public TestFixture { TEST_CASE(simplifyUsing38); TEST_CASE(simplifyUsing39); TEST_CASE(simplifyUsing40); + TEST_CASE(simplifyUsing41); TEST_CASE(simplifyUsing8970); TEST_CASE(simplifyUsing8971); @@ -948,6 +949,13 @@ class TestSimplifyUsing : public TestFixture { ASSERT_EQUALS(expected, tok(code)); } + void simplifyUsing41() { + const char code[] = "using FpHandler = void(*)(const SourceLocation&);\n" + "inline FpHandler AssertImpl::m_fpHandler = nullptr;\n"; + const char expected[] = "void ( * AssertImpl :: m_fpHandler ) ( const SourceLocation & ) ; m_fpHandler = nullptr ;"; + ASSERT_EQUALS(expected, tok(code)); + } + void simplifyUsing8970() { const char code[] = "using V = std::vector;\n" "struct A {\n" From 1444cd8b8a1d8a918647cc422c89219254947ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 14 Jul 2026 11:29:22 +0200 Subject: [PATCH 250/493] Fix #14782: Partially or fully missing valuetype info for auto declarations (#8599) --- lib/symboldatabase.cpp | 62 +++++++++++++++++++++++++++++----- test/testsymboldatabase.cpp | 67 +++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 9 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index b82a3f790b0..0f612d5f45a 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -7021,6 +7021,10 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const setAutoTokenProperties(autoTok); if (vt2->pointer > vt.pointer) vt.pointer++; + if (Token::simpleMatch(autoTok->next(), "&")) + vt.reference = Reference::LValue; + if (Token::simpleMatch(autoTok->next(), "&&")) + vt.reference = Reference::RValue; setValueType(var1Tok, vt); if (var1Tok != parent->previous()) setValueType(parent->previous(), vt); @@ -7295,15 +7299,55 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const } // c++17 auto type deduction of braced init list - if (parent->isCpp() && mSettings.standards.cpp >= Standards::CPP17 && vt2 && Token::Match(parent->tokAt(-2), "auto %var% {")) { - Token *autoTok = parent->tokAt(-2); - setValueType(autoTok, *vt2); - setAutoTokenProperties(autoTok); - if (parent->previous()->variable()) - const_cast(parent->previous()->variable())->setValueType(*vt2); - else - debugMessage(parent->previous(), "debug", "Missing variable class for variable with varid"); - return; + if (parent->isCpp() && mSettings.standards.cpp >= Standards::CPP17 + && Token::Match(parent->astOperand1(), "%var% {") && vt2) { + + auto reference = Reference::None; + nonneg int pointer = 0; + nonneg int constness = 0; + nonneg int volatileness = 0; + + Token *varTok = parent->astOperand1(); + Token *typeTok = varTok->previous(); + + while (Token::Match(typeTok, "&|&&|*|const|volatile")) { + if (typeTok->str() == "&") + reference = Reference::LValue; + else if (typeTok->str() == "&&") + reference = Reference::RValue; + else if (typeTok->str() == "*") + pointer++; + else if (typeTok->str() == "const") + constness |= 1 << pointer; + else if (typeTok->str() == "volatile") + volatileness |= 1 << pointer; + typeTok = typeTok->previous(); + } + + if (typeTok->str() == "auto") { + setValueType(typeTok, *vt2); + setAutoTokenProperties(typeTok); + + auto *varVt = new ValueType(*vt2); + + varVt->reference = reference; + varVt->constness |= constness; + varVt->volatileness |= volatileness; + + if (Token::simpleMatch(typeTok->previous(), "const auto")) + varVt->constness |= 1 << pointer; + + if (Token::simpleMatch(typeTok->previous(), "volatile auto")) + varVt->volatileness |= 1 << pointer; + + varTok->setValueType(varVt); + + if (varTok->variable()) + const_cast(varTok->variable())->setValueType(*varVt); + else + debugMessage(varTok, "debug", "Missing variable class for variable with varid"); + return; + } } if (!vt1) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 345bfdb7990..69d345a1cc5 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -220,6 +220,8 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(VariableValueType4); // smart pointer type TEST_CASE(VariableValueType5); // smart pointer type TEST_CASE(VariableValueType6); // smart pointer type + TEST_CASE(VariableValueType7); + TEST_CASE(VariableValueType8); TEST_CASE(VariableValueTypeReferences); TEST_CASE(VariableValueTypeTemplate); @@ -1316,6 +1318,71 @@ class TestSymbolDatabase : public TestFixture { ASSERT(check->valueType()->smartPointerTypeToken); } + void VariableValueType7() { + GET_SYMBOL_DB("void f() {\n" + " auto x0 = 0;\n" + " auto &x1 = x0;\n" + " auto &x2 {x0};\n" + " auto &&x3 = 0;\n" + " auto &&x4 {0};\n" + "}\n"); + + const Token* x1 = Token::findsimplematch(tokenizer.tokens(), "x1"); + const Token* x2 = Token::findsimplematch(tokenizer.tokens(), "x2"); + const Token* x3 = Token::findsimplematch(tokenizer.tokens(), "x3"); + const Token* x4 = Token::findsimplematch(tokenizer.tokens(), "x4"); + + ASSERT(x1); + ASSERT(x2); + ASSERT(x3); + ASSERT(x4); + + ASSERT_EQUALS_ENUM(ValueType::INT, x1->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::INT, x2->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::INT, x3->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::INT, x4->valueType()->type); + + ASSERT_EQUALS_ENUM(Reference::LValue, x1->valueType()->reference); + ASSERT_EQUALS_ENUM(Reference::LValue, x2->valueType()->reference); + ASSERT_EQUALS_ENUM(Reference::RValue, x3->valueType()->reference); + ASSERT_EQUALS_ENUM(Reference::RValue, x4->valueType()->reference); + } + + void VariableValueType8() { + GET_SYMBOL_DB("void f() {\n" + " char buf[128];\n" + " const auto *const x0 {buf};\n" + " auto *const x1 {buf};\n" + " const auto *x2 {buf};\n" + " auto x3 {buf};\n" + "}\n"); + + const Token* x0 = Token::findsimplematch(tokenizer.tokens(), "x0"); + const Token* x1 = Token::findsimplematch(tokenizer.tokens(), "x1"); + const Token* x2 = Token::findsimplematch(tokenizer.tokens(), "x2"); + const Token* x3 = Token::findsimplematch(tokenizer.tokens(), "x3"); + + ASSERT(x0); + ASSERT(x1); + ASSERT(x2); + ASSERT(x3); + + ASSERT_EQUALS_ENUM(ValueType::CHAR, x0->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::CHAR, x1->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::CHAR, x2->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::CHAR, x3->valueType()->type); + + ASSERT_EQUALS(3, x0->valueType()->constness); + ASSERT_EQUALS(1, x1->valueType()->constness); + ASSERT_EQUALS(2, x2->valueType()->constness); + ASSERT_EQUALS(0, x3->valueType()->constness); + + ASSERT_EQUALS(1, x0->valueType()->pointer); + ASSERT_EQUALS(1, x1->valueType()->pointer); + ASSERT_EQUALS(1, x2->valueType()->pointer); + ASSERT_EQUALS(1, x3->valueType()->pointer); + } + void VariableValueTypeReferences() { { GET_SYMBOL_DB("void foo(int x) {}\n"); From a1beb847d99392a77382b8a32171d3e140bd568b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 14 Jul 2026 13:12:01 +0200 Subject: [PATCH 251/493] Add test for #14797: internalAstError with if in do while loop (#8725) Fixed in 42a08059f71f3952f7f992dfe82828e2af495c6e. --- test/testtokenize.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index c4de2be00e7..f1a2a85e212 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -92,6 +92,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(tokenize40); // #13181 TEST_CASE(tokenize41); // #13847 TEST_CASE(tokenize42); // #13861 + TEST_CASE(tokenize43); // #13861 TEST_CASE(validate); @@ -941,6 +942,12 @@ class TestTokenizer : public TestFixture { (void)errout_str(); } + void tokenize43() { + const char code[] = "void f(int i) { do if (i &= 1) {} while (0); }"; + ASSERT_NO_THROW(tokenizeAndStringify(code)); + (void)errout_str(); + } + void validate() { // C++ code in C file ASSERT_THROW_INTERNAL(tokenizeAndStringify(";using namespace std;",dinit(TokenizeOptions, $.expand = false, $.cpp = false)), SYNTAX); From 3deb36d1f386553bbcee076082e33e7b58d68537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 14 Jul 2026 13:13:58 +0200 Subject: [PATCH 252/493] Fix #14901: fuzzing timeout (hang) in Tokenizer::simplifyTypedef() (#8717) --- lib/tokenize.cpp | 18 ++++++++++++++++++ ...ut-242e02017d15d072fd7a230de22faeef0816693d | 1 + test/testsimplifytypedef.cpp | 10 ++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/cli/fuzz-timeout/timeout-242e02017d15d072fd7a230de22faeef0816693d diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f273cd623ec..3dc83082e4e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -589,12 +589,27 @@ namespace { } } + const auto checkForRecursion = [this]() { + if (Token::Match(mTypedefToken, "typedef %name% %name% ;")) + return; + for (const Token *tok = mTypedefToken; tok != mEndToken; tok = tok->next()) { + if (tok == mNameToken) + continue; + if (tok->str() != mNameToken->str()) + continue; + if (Token::Match(tok->previous(), "struct|class|enum|union")) + continue; + throw InternalError(tok, "recursive typedef encountered"); + } + }; + for (Token* type = start; Token::Match(type, "%name%|*|&|&&"); type = type->next()) { if (type != start && Token::Match(type, "%name% ;") && !type->isStandardType()) { mRangeType.first = start; mRangeType.second = type; mNameToken = type; mEndToken = mNameToken->next(); + checkForRecursion(); return; } if (type != start && Token::Match(type, "%name% [")) { @@ -609,6 +624,7 @@ namespace { mEndToken = end->next(); mRangeAfterVar.first = mNameToken->next(); mRangeAfterVar.second = mEndToken; + checkForRecursion(); return; } if (Token::Match(type->next(), "( * const| %name% ) (") && Token::simpleMatch(type->linkAt(1)->linkAt(1), ") ;")) { @@ -618,6 +634,7 @@ namespace { mRangeType.second = mNameToken; mRangeAfterVar.first = mNameToken->next(); mRangeAfterVar.second = mEndToken; + checkForRecursion(); return; } if (type != start && Token::Match(type, "%name% ( !!(") && Token::simpleMatch(type->linkAt(1), ") ;") && !type->isStandardType()) { @@ -627,6 +644,7 @@ namespace { mRangeType.second = type; mRangeAfterVar.first = mNameToken->next(); mRangeAfterVar.second = mEndToken; + checkForRecursion(); return; } } diff --git a/test/cli/fuzz-timeout/timeout-242e02017d15d072fd7a230de22faeef0816693d b/test/cli/fuzz-timeout/timeout-242e02017d15d072fd7a230de22faeef0816693d new file mode 100644 index 00000000000..c269baf1efe --- /dev/null +++ b/test/cli/fuzz-timeout/timeout-242e02017d15d072fd7a230de22faeef0816693d @@ -0,0 +1 @@ +typedef const v*v,*; \ No newline at end of file diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 84a95a81cfc..5a14399e406 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -233,6 +233,7 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedef160); TEST_CASE(simplifyTypedef161); TEST_CASE(simplifyTypedef162); + TEST_CASE(simplifyTypedef163); TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -3836,11 +3837,11 @@ class TestSimplifyTypedef : public TestFixture { "}"; ASSERT_EQUALS(exp, tok(code)); - const char code2[] = "typedef stuct T* T;\n" // #14669 + const char code2[] = "typedef struct T* T;\n" // #14669 "struct T {\n" " T p;\n" "};\n"; - const char exp2[] = "struct T { stuct T * p ; } ;"; + const char exp2[] = "struct T { struct T * p ; } ;"; ASSERT_EQUALS(exp2, simplifyTypedefC(code2)); } @@ -3868,6 +3869,11 @@ class TestSimplifyTypedef : public TestFixture { ASSERT_EQUALS(exp, tok(code)); } + void simplifyTypedef163() { + const char code[] = "typedef v *v;"; + ASSERT_THROW_INTERNAL(tok(code), INTERNAL); + } + void simplifyTypedefFunction1() { { const char code[] = "typedef void (*my_func)();\n" From 5aa31d0da84926c8abf213942498c53cba2445c1 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 15 Jul 2026 08:33:20 +0200 Subject: [PATCH 253/493] Fix #14452 fuzzing crash (null-pointer-use) in ReverseTraversal::traverse() (#8723) --- lib/tokenlist.cpp | 3 +++ .../crash-85cab41781812453dfc8e74e1f0b915225f7a0a1 | 1 + 2 files changed, 4 insertions(+) create mode 100644 test/cli/fuzz-crash_c/crash-85cab41781812453dfc8e74e1f0b915225f7a0a1 diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 594de5c0295..53d1c4f94dd 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1947,6 +1947,9 @@ void TokenList::validateAst(bool print) const if ((tok->isAssignmentOp() || tok->isComparisonOp() || Token::Match(tok,"[|^/%]")) && tok->astOperand1() && !tok->astOperand2()) throw InternalError(tok, "Syntax Error: AST broken, binary operator has only one operand.", InternalError::AST); + if (!(tok->astOperand1() && tok->astOperand2()) && ((isC() && tok->str() == "&&") || Token::Match(tok, "%or%|%oror%"))) + throw InternalError(tok, "Syntax Error: AST broken, binary operator is missing operand(s).", InternalError::AST); + // Syntax error if we encounter "?" with operand2 that is not ":" if (tok->str() == "?") { if (!tok->astOperand1() || !tok->astOperand2()) diff --git a/test/cli/fuzz-crash_c/crash-85cab41781812453dfc8e74e1f0b915225f7a0a1 b/test/cli/fuzz-crash_c/crash-85cab41781812453dfc8e74e1f0b915225f7a0a1 new file mode 100644 index 00000000000..a2e58c69ea7 --- /dev/null +++ b/test/cli/fuzz-crash_c/crash-85cab41781812453dfc8e74e1f0b915225f7a0a1 @@ -0,0 +1 @@ +n(f=n){n&&,n} From a0a31d927acd129c125d4f85008380eee334d710 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 15 Jul 2026 08:35:20 +0200 Subject: [PATCH 254/493] Fix #14741 fuzzing crash (null-pointer-use) in SymbolicConditionHandler::parse() (#8722) --- lib/tokenlist.cpp | 4 ++-- .../crash-401f925d3c6fd78f864ffd7bf0531bd6a76bb832 | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 test/cli/fuzz-crash_c/crash-401f925d3c6fd78f864ffd7bf0531bd6a76bb832 diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 53d1c4f94dd..ca509904db3 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -2032,9 +2032,9 @@ void TokenList::validateAst(bool print) const "' doesn't have two operands.", InternalError::AST); } - if (tok->str() == "case" && !tok->astOperand1()) { + if (!tok->astOperand1() && Token::Match(tok, "case|!")) { throw InternalError(tok, - "Syntax Error: AST broken, 'case' doesn't have an operand.", + "Syntax Error: AST broken, '" + tok->str() + "' doesn't have an operand.", InternalError::AST); } diff --git a/test/cli/fuzz-crash_c/crash-401f925d3c6fd78f864ffd7bf0531bd6a76bb832 b/test/cli/fuzz-crash_c/crash-401f925d3c6fd78f864ffd7bf0531bd6a76bb832 new file mode 100644 index 00000000000..a778e6e2823 --- /dev/null +++ b/test/cli/fuzz-crash_c/crash-401f925d3c6fd78f864ffd7bf0531bd6a76bb832 @@ -0,0 +1 @@ +i(){!!:!=!&&d} From ae6a77d2e284a5d56b957f117af021a2414405f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 15 Jul 2026 09:54:56 +0200 Subject: [PATCH 255/493] Fix #14798: internalError on sscanf format string (#8724) --- lib/checkio.cpp | 2 ++ test/testio.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 3d82bdb796a..468e2867619 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -841,6 +841,8 @@ void CheckIOImpl::checkFormatString(const Token * const tok, } ++i; } + while (!width.empty() && width[0] == '0') + width = width.substr(1); auto bracketBeg = formatString.cend(); if (i != formatString.cend() && *i == '[') { bracketBeg = i; diff --git a/test/testio.cpp b/test/testio.cpp index f90773d4cf4..843c5a62ccc 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -53,6 +53,7 @@ class TestIO : public TestFixture { TEST_CASE(testScanf3); // #3494 TEST_CASE(testScanf4); // #ticket 2553 TEST_CASE(testScanf5); // #10632 + TEST_CASE(testScanf6); mNewTemplate = false; TEST_CASE(testScanfArgument); @@ -892,6 +893,14 @@ class TestIO : public TestFixture { "[test.cpp:3:5]: (error) Width 42 given in format string (no. 2) is larger than destination buffer 's2[42]', use %41[a-z] to prevent overflowing it. [invalidScanfFormatWidth]\n", errout_str()); } + void testScanf6() { + ASSERT_NO_THROW(check("int f(const char *p) {\n" + " char a[3];\n" + " return sscanf(p, \"%02s\", a);\n" + "}\n")); + ASSERT_EQUALS("", errout_str()); + } + #define TEST_SCANF_CODE(format, type) \ "void f(){" type " x; scanf(\"" format "\", &x);}" From 0873197005c7a44abce603dbb48188b03d3629e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 15 Jul 2026 09:55:15 +0200 Subject: [PATCH 256/493] Fix #14704: False positive: IOWithoutPositioning reported for user functions fread and fwrite (#8726) --- lib/checkio.cpp | 2 ++ test/testio.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 468e2867619..0a0ca70a833 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -155,6 +155,8 @@ void CheckIOImpl::checkFileUsage() tok = tok->linkAt(1); continue; } + if (tok->function() && tok->function()->nestedIn) + continue; if (tok->str() == "{") indent++; else if (tok->str() == "}") { diff --git a/test/testio.cpp b/test/testio.cpp index 843c5a62ccc..2d191555ba6 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -694,6 +694,23 @@ class TestIO : public TestFixture { " fwrite(X::data(), sizeof(char), buffer.size(), d->file);\n" "}"); ASSERT_EQUALS("[test.cpp:9:5]: (error) Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour. [IOWithoutPositioning]\n", errout_str()); + + check("struct MemStream {\n" + " char buf[1024];\n" + " int pos = 0;\n" + " void fwrite(const void *ptr, size_t n) { memcpy(buf + pos, ptr, n); pos += (int)n; }\n" + "};\n" + "struct FileStream {\n" + " FILE *fp;\n" + " size_t _fread(void *ptr, size_t n) { return ::fread(ptr, 1, n, fp); }\n" + " size_t fread(void *ptr, size_t n) { return _fread(ptr, n); }\n" + " void copy_to(MemStream *dst, size_t n) {\n" + " char tmp[256];\n" + " fread(tmp, n);\n" + " dst->fwrite(tmp, n);\n" + " }\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); } void seekOnAppendedFile() { From fdd606703d11911910d49a62692770b4c928e837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 15 Jul 2026 13:26:00 +0200 Subject: [PATCH 257/493] Add test for #14684 (#8728) Fixed by 1444cd8b8a1d8a918647cc422c89219254947ef5. --- test/testunusedvar.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 03ef0a14a83..849d34b49b0 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -156,6 +156,7 @@ class TestUnusedVar : public TestFixture { TEST_CASE(localvar70); TEST_CASE(localvar71); TEST_CASE(localvar72); + TEST_CASE(localvar73); TEST_CASE(localvarloops); // loops TEST_CASE(localvaralias1); TEST_CASE(localvaralias2); // ticket #1637 @@ -4074,6 +4075,16 @@ class TestUnusedVar : public TestFixture { ASSERT_EQUALS("[test.cpp:4:12]: (style) Unused variable: mp [unusedVariable]\n", errout_str()); } + void localvar73() { + functionVariableUsage("struct S { S(); ~S(); };\n" + "void f() {\n" + " auto a{ S() };\n" + " auto const &b{ S() };\n" + " const auto &&c{ S() };\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void localvarloops() { // loops functionVariableUsage("void fun(int c) {\n" From 8e5682d993323cc605de65896ac090fe9db93876 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:55:24 +0200 Subject: [PATCH 258/493] Fix #14437 fuzzing crash (null-pointer-use) in ValueFlowAnalyzer::assume() (#8730) --- lib/tokenize.cpp | 2 +- .../fuzz-crash/crash-b4bd9ce1af8a423d15d034f42c7b99dc0f8a0a7d | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test/cli/fuzz-crash/crash-b4bd9ce1af8a423d15d034f42c7b99dc0f8a0a7d diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 3dc83082e4e..031ab624bfb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6920,7 +6920,7 @@ Token *Tokenizer::simplifyAddBracesToCommand(Token *tok) // before the "while" if (tokEnd) { tokEnd=tokEnd->next(); - if (!tokEnd || tokEnd->str()!="while") // no while + if (!Token::simpleMatch(tokEnd, "while (") || !Token::simpleMatch(tokEnd->linkAt(1), ") ;")) // no while syntaxError(tok); } } diff --git a/test/cli/fuzz-crash/crash-b4bd9ce1af8a423d15d034f42c7b99dc0f8a0a7d b/test/cli/fuzz-crash/crash-b4bd9ce1af8a423d15d034f42c7b99dc0f8a0a7d new file mode 100644 index 00000000000..e7b11b223da --- /dev/null +++ b/test/cli/fuzz-crash/crash-b4bd9ce1af8a423d15d034f42c7b99dc0f8a0a7d @@ -0,0 +1 @@ +d o(n c){do if(c){}while(0)n} From bc9349a87163483fd1d70cbce66455c690eff38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 16 Jul 2026 10:58:58 +0200 Subject: [PATCH 259/493] Fix #14919: FP constVariableReference (initialization with parentheses) (#8731) --- lib/astutils.cpp | 2 +- test/testother.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 27a01ab0382..3c5c51498ba 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3001,7 +3001,7 @@ bool isVariableChanged(const Variable * var, const Settings &settings, int depth const Token * start = var->declEndToken(); if (!start) return false; - if (Token::Match(start, "; %varid% =", var->declarationId())) + if (Token::Match(start, "; %varid% =", var->declarationId()) && !Token::simpleMatch(start->previous(), ")")) start = start->tokAt(2); if (Token::simpleMatch(start, "=")) { const Token* next = nextAfterAstRightmostLeafGeneric(start); diff --git a/test/testother.cpp b/test/testother.cpp index 0b87a07f160..92fefb72fd3 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4146,6 +4146,14 @@ class TestOther : public TestFixture { " *o = 1;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("int f() {\n" + " int x = 0;\n" + " int& r(x);\n" + " r = x;\n" + " return r;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void constParameterCallback() { From d32c01d1b9fd2612417dedff95bf96be71915805 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Thu, 16 Jul 2026 05:01:21 -0400 Subject: [PATCH 260/493] Fix #14880 add support for Folders in slnx project file and skip non C++ projects (#8681) --- lib/importproject.cpp | 46 ++++++--- test/cli/project_test.py | 46 +++++++++ test/cli/slnx-folders/app/app.cpp | 7 ++ test/cli/slnx-folders/app/app.vcxproj | 102 ++++++++++++++++++++ test/cli/slnx-folders/lib/lib.cpp | 9 ++ test/cli/slnx-folders/lib/lib.h | 1 + test/cli/slnx-folders/lib/lib.vcxproj | 97 +++++++++++++++++++ test/cli/slnx-folders/slnx-folders.cppcheck | 17 ++++ test/cli/slnx-folders/slnx-folders.slnx | 12 +++ test/cli/slnx-folders_test.py | 73 ++++++++++++++ 10 files changed, 399 insertions(+), 11 deletions(-) create mode 100644 test/cli/slnx-folders/app/app.cpp create mode 100644 test/cli/slnx-folders/app/app.vcxproj create mode 100644 test/cli/slnx-folders/lib/lib.cpp create mode 100644 test/cli/slnx-folders/lib/lib.h create mode 100644 test/cli/slnx-folders/lib/lib.vcxproj create mode 100644 test/cli/slnx-folders/slnx-folders.cppcheck create mode 100644 test/cli/slnx-folders/slnx-folders.slnx create mode 100644 test/cli/slnx-folders_test.py diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 2d63fa8bbb7..0e6ca353480 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -529,27 +529,51 @@ bool ImportProject::importSlnx(const std::string& filename, const std::vectorName(), "Solution") != 0) { + errors.emplace_back("Invalid Visual Studio solution file format"); + return false; + } + std::map variables; variables["SolutionDir"] = Path::simplifyPath(Path::getPathFromFilename(filename)); bool found = false; std::vector sharedItemsProjects; + auto processProject = [&](const tinyxml2::XMLElement* projectNode) { + const char* pathAttribute = projectNode->Attribute("Path"); + if (pathAttribute == nullptr) + return true; + + std::string vcxproj(pathAttribute); + vcxproj = Path::toNativeSeparators(std::move(vcxproj)); + + if (Path::getFilenameExtensionInLowerCase(vcxproj) != ".vcxproj") + return true; // skip other project types + + if (!Path::isAbsolute(vcxproj)) + vcxproj = variables["SolutionDir"] + vcxproj; + + vcxproj = Path::fromNativeSeparators(std::move(vcxproj)); + if (!importVcxproj(vcxproj, variables, "", fileFilters, sharedItemsProjects)) { + errors.emplace_back("failed to load '" + vcxproj + "' from Visual Studio solution"); + return false; + } + found = true; + return true; + }; + for (const tinyxml2::XMLElement* node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) { const char* name = node->Name(); if (std::strcmp(name, "Project") == 0) { - const char* labelAttribute = node->Attribute("Path"); - if (labelAttribute) { - std::string vcxproj(labelAttribute); - vcxproj = Path::toNativeSeparators(std::move(vcxproj)); - if (!Path::isAbsolute(vcxproj)) - vcxproj = variables["SolutionDir"] + vcxproj; - vcxproj = Path::fromNativeSeparators(std::move(vcxproj)); - if (!importVcxproj(vcxproj, variables, "", fileFilters, sharedItemsProjects)) { - errors.emplace_back("failed to load '" + vcxproj + "' from Visual Studio solution"); - return false; + if (!processProject(node)) + return false; + } else if (std::strcmp(name, "Folder") == 0) { + for (const tinyxml2::XMLElement* childNode = node->FirstChildElement(); childNode; childNode = childNode->NextSiblingElement()) { + if (std::strcmp(childNode->Name(), "Project") == 0) { + if (!processProject(childNode)) + return false; } - found = true; } } } diff --git a/test/cli/project_test.py b/test/cli/project_test.py index 7421ca406a6..64bb406a709 100644 --- a/test/cli/project_test.py +++ b/test/cli/project_test.py @@ -147,6 +147,16 @@ def test_slnx_no_xml_root(tmpdir): __test_project_error(tmpdir, "slnx", content, expected) +def test_slnx_invalid_xml_root(tmpdir): + content = '\r\n' \ + "\r\n" \ + "\r\n" + + expected = "Invalid Visual Studio solution file format" + + __test_project_error(tmpdir, "slnx", content, expected) + + def test_slnx_no_projects(tmpdir): content = '\r\n' \ "\r\n" \ @@ -161,6 +171,22 @@ def test_slnx_no_projects(tmpdir): __test_project_error(tmpdir, "slnx", content, expected) +def test_slnx_no_projects_in_folder(tmpdir): + content = '\r\n' \ + "\r\n" \ + " \r\n" \ + ' \r\n' \ + ' \r\n' \ + " \r\n" \ + ' \r\n' \ + ' \r\n' \ + "\r\n" + + expected = "no projects found in Visual Studio solution file" + + __test_project_error(tmpdir, "slnx", content, expected) + + def test_slnx_project_file_not_found(tmpdir): content = '\r\n' \ "\r\n" \ @@ -179,6 +205,26 @@ def test_slnx_project_file_not_found(tmpdir): __test_project_error(tmpdir, "slnx", content, expected) +def test_slnx_project_file_in_folder_not_found(tmpdir): + content = '\r\n' \ + "\r\n" \ + " \r\n" \ + ' \r\n' \ + ' \r\n' \ + " \r\n" \ + ' \r\n' \ + ' \r\n' \ + ' \r\n' \ + "\r\n" + + expected = "Visual Studio project file is not a valid XML - XML_ERROR_FILE_NOT_FOUND\n" \ + "cppcheck: error: failed to load '{}' from Visual Studio solution".format(os.path.join(tmpdir, "common/test.vcxproj")) + if sys.platform == "win32": + expected = expected.replace('\\', '/') + + __test_project_error(tmpdir, "slnx", content, expected) + + def test_vcxproj_no_xml_root(tmpdir): content = '' diff --git a/test/cli/slnx-folders/app/app.cpp b/test/cli/slnx-folders/app/app.cpp new file mode 100644 index 00000000000..3454c2de254 --- /dev/null +++ b/test/cli/slnx-folders/app/app.cpp @@ -0,0 +1,7 @@ +#include "../lib/lib.h" + +int main(int argc, char *argv[]) +{ + int x = 3 / 0; (void)x; // ERROR + return foo(); +} diff --git a/test/cli/slnx-folders/app/app.vcxproj b/test/cli/slnx-folders/app/app.vcxproj new file mode 100644 index 00000000000..b72ae55c565 --- /dev/null +++ b/test/cli/slnx-folders/app/app.vcxproj @@ -0,0 +1,102 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 18.0 + Win32Proj + {0de77c38-881a-4f9f-bdfa-2c429968985e} + unused + 10.0 + + + + Application + true + v145 + Unicode + + + Application + false + v145 + true + Unicode + + + + + + + + + + + + + + + ..\x64\Debug\ + x64\Debug\ + + + ..\x64\Release\ + x64\Release\ + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + + + Console + true + ../lib + + + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + + + + {93BE1430-BE74-35DF-1882-AF70E49C9898} + + + + + + diff --git a/test/cli/slnx-folders/lib/lib.cpp b/test/cli/slnx-folders/lib/lib.cpp new file mode 100644 index 00000000000..b4a89cee1c7 --- /dev/null +++ b/test/cli/slnx-folders/lib/lib.cpp @@ -0,0 +1,9 @@ +#include +#include "lib.h" + +int foo() +{ + std::cout << "hello world\n"; + int x = 3 / 0; (void)x; // ERROR + return 0; +} diff --git a/test/cli/slnx-folders/lib/lib.h b/test/cli/slnx-folders/lib/lib.h new file mode 100644 index 00000000000..cf790ac3eab --- /dev/null +++ b/test/cli/slnx-folders/lib/lib.h @@ -0,0 +1 @@ +extern int foo(); diff --git a/test/cli/slnx-folders/lib/lib.vcxproj b/test/cli/slnx-folders/lib/lib.vcxproj new file mode 100644 index 00000000000..232c2478e2f --- /dev/null +++ b/test/cli/slnx-folders/lib/lib.vcxproj @@ -0,0 +1,97 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 18.0 + Win32Proj + {93BE1430-BE74-35DF-1882-AF70E49C9898} + unused + 10.0 + + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v145 + true + Unicode + + + + + + + + + + + + + + + ..\x64\Debug\ + x64\Debug\ + + + ..\x64\Release\ + x64\Release\ + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + + + Console + true + ../lib + + + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + + + + + diff --git a/test/cli/slnx-folders/slnx-folders.cppcheck b/test/cli/slnx-folders/slnx-folders.cppcheck new file mode 100644 index 00000000000..4fa0c4e7623 --- /dev/null +++ b/test/cli/slnx-folders/slnx-folders.cppcheck @@ -0,0 +1,17 @@ + + + slnx-folders-cppcheck-build-dir + slnx-folders.slnx + false + true + true + true + 2 + 100 + + Debug + Release + + + slnx-folders + diff --git a/test/cli/slnx-folders/slnx-folders.slnx b/test/cli/slnx-folders/slnx-folders.slnx new file mode 100644 index 00000000000..ce6b9014431 --- /dev/null +++ b/test/cli/slnx-folders/slnx-folders.slnx @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/test/cli/slnx-folders_test.py b/test/cli/slnx-folders_test.py new file mode 100644 index 00000000000..b9dd5f09c92 --- /dev/null +++ b/test/cli/slnx-folders_test.py @@ -0,0 +1,73 @@ + +# python -m pytest slnx-folders_test.py + +import os +import re + +from testutils import cppcheck + +__script_dir = os.path.dirname(os.path.abspath(__file__)) +__proj_dir = os.path.join(__script_dir, 'slnx-folders') + +def get_lines(s): + return sorted(s.split('\n')) + +# Get Visual Studio configurations checking a file +# Checking {file} {config}... +def __getVsConfigs(stdout, filename): + ret = [] + for line in stdout.split('\n'): + if not line.startswith('Checking %s ' % filename): + continue + if not line.endswith('...'): + continue + res = re.match(r'.* ([A-Za-z0-9|]+)...', line) + if res: + ret.append(res.group(1)) + ret.sort() + return ' '.join(ret) + +def test_relative_path(): + args = [ + '--template=cppcheck1', + 'slnx-folders' + ] + ret, stdout, stderr = cppcheck(args, cwd=__script_dir) + filename1 = os.path.join('slnx-folders', 'app', 'app.cpp') + filename2 = os.path.join('slnx-folders', 'lib', 'lib.cpp') + assert ret == 0, stdout + expected = ( + '[%s:5]: (error) Division by zero.\n' + '[%s:7]: (error) Division by zero.\n' % (filename1, filename2) + ) + assert get_lines(stderr) == get_lines(expected) + +def test_local_path(): + args = [ + '--template=cppcheck1', + '.' + ] + ret, stdout, stderr = cppcheck(args, cwd=__proj_dir) + filename1 = os.path.join('app', 'app.cpp') + filename2 = os.path.join('lib', 'lib.cpp') + assert ret == 0, stdout + expected = ( + '[%s:5]: (error) Division by zero.\n' + '[%s:7]: (error) Division by zero.\n' % (filename1, filename2) + ) + assert get_lines(stderr) == get_lines(expected) + +def test_absolute_path(): + args = [ + '--template=cppcheck1', + __proj_dir + ] + ret, stdout, stderr = cppcheck(args) + filename1 = os.path.join(__proj_dir, 'app', 'app.cpp') + filename2 = os.path.join(__proj_dir, 'lib', 'lib.cpp') + assert ret == 0, stdout + expected = ( + '[%s:5]: (error) Division by zero.\n' + '[%s:7]: (error) Division by zero.\n' % (filename1, filename2) + ) + assert get_lines(stderr) == get_lines(expected) From 6edf26edb3e136945886bee40d1fceee567d3aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 17 Jul 2026 16:15:28 +0200 Subject: [PATCH 261/493] fixed #14922 - do not use absolute paths in CMake `INSTALL()` / added TODOs (#8734) --- .github/workflows/CI-unixish.yml | 1 + .github/workflows/CI-windows.yml | 4 ++++ cli/CMakeLists.txt | 17 +++++++++++------ cmake/options.cmake | 8 ++++++-- cmake/printInfo.cmake | 2 ++ gui/CMakeLists.txt | 4 ++-- 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index 4a7d94c4057..8fb5c8d76d6 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -150,6 +150,7 @@ jobs: - name: Run CMake install run: | cmake --build cmake.output --target install + # TODO: validate the installed files - name: Run CMake on ubuntu (no CLI) if: matrix.os == 'ubuntu-22.04' diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml index f9d108eefc9..ce73819bc70 100644 --- a/.github/workflows/CI-windows.yml +++ b/.github/workflows/CI-windows.yml @@ -21,6 +21,7 @@ defaults: jobs: + # TODO: use Debug build to speed it up? build_qt: strategy: matrix: @@ -68,7 +69,10 @@ jobs: - name: Run CMake install run: | + rem TODO: this performs a Debug build + rem TODO: the Qt DLLS are not being installed (because of the missing windeployqt?) cmake --build build --target install + rem TODO: validate the installed files build_cmake_cxxstd: strategy: diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index f63f3291849..52103bdb8ec 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -40,27 +40,32 @@ if (BUILD_CLI) endif() install(TARGETS cppcheck - RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT applications) install(PROGRAMS ${CMAKE_SOURCE_DIR}/htmlreport/cppcheck-htmlreport - DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT applications) + # TODO: leverage CMAKE_INSTALL_DATAROOTDIR (share)? + install(FILES ${addons_py} - DESTINATION ${FILESDIR_DEF}/addons + DESTINATION ${FILESDIR_INSTALL}/addons COMPONENT headers) install(FILES ${addons_json} - DESTINATION ${FILESDIR_DEF}/addons + DESTINATION ${FILESDIR_INSTALL}/addons COMPONENT headers) install(FILES ${cfgs} - DESTINATION ${FILESDIR_DEF}/cfg + DESTINATION ${FILESDIR_INSTALL}/cfg COMPONENT headers) install(FILES ${platforms} - DESTINATION ${FILESDIR_DEF}/platforms + DESTINATION ${FILESDIR_INSTALL}/platforms COMPONENT headers) + # TODO: install manpage into CMAKE_INSTALL_MANDIR + # TODO: install documentation into CMAKE_INSTALL_DOCDIR? + endif() diff --git a/cmake/options.cmake b/cmake/options.cmake index 0fa27e4734b..bda080fe77b 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -134,18 +134,22 @@ set(CMAKE_DISABLE_PRECOMPILE_HEADERS Off CACHE BOOL "Disable precompiled headers # see https://gitlab.kitware.com/cmake/cmake/-/issues/21219 set(CMAKE_PCH_PROLOGUE "") +# TODO: do we need to set these? set(CMAKE_INCLUDE_DIRS_CONFIGCMAKE ${CMAKE_INSTALL_PREFIX}/include CACHE PATH "Output directory for headers") set(CMAKE_LIB_DIRS_CONFIGCMAKE ${CMAKE_INSTALL_PREFIX}/lib CACHE PATH "Output directory for libraries") +# TODO: do we need to set these? set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) string(LENGTH "${FILESDIR}" _filesdir_len) # override FILESDIR if it is set or empty +# needs to be an absolute path in Cppcheck but a relative one for CMake install if(FILESDIR OR ${_filesdir_len} EQUAL 0) -# TODO: verify that it is an absolute path? + set(FILESDIR_INSTALL "${FILESDIR}") # TODO: make relative - leverage CMAKE_INSTALL_DATAROOTDIR? set(FILESDIR_DEF "${FILESDIR}") else() - set(FILESDIR_DEF ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME} CACHE STRING "Cppcheck files directory") + set(FILESDIR_INSTALL "share/${PROJECT_NAME}") + set(FILESDIR_DEF "${CMAKE_INSTALL_PREFIX}/${FILESDIR_INSTALL}") endif() diff --git a/cmake/printInfo.cmake b/cmake/printInfo.cmake index 87c7e41f284..7869169708d 100644 --- a/cmake/printInfo.cmake +++ b/cmake/printInfo.cmake @@ -8,6 +8,7 @@ message(STATUS "Compiler Version = ${CMAKE_CXX_COMPILER_VERSION}") message(STATUS "Build type = ${CMAKE_BUILD_TYPE}") message(STATUS "CMake C++ Standard = ${CMAKE_CXX_STANDARD}") message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}") +message(STATUS "CMAKE_INSTALL_BINDIR = ${CMAKE_INSTALL_BINDIR}") message(STATUS "CMAKE_DISABLE_PRECOMPILE_HEADERS = ${CMAKE_DISABLE_PRECOMPILE_HEADERS}") message(STATUS "C++ flags (General) = ${CMAKE_CXX_FLAGS}") message(STATUS "C++ flags (Release) = ${CMAKE_CXX_FLAGS_RELEASE}") @@ -109,6 +110,7 @@ message(STATUS) message(STATUS "USE_LIBCXX = ${USE_LIBCXX}") message(STATUS) message(STATUS "FILESDIR = ${FILESDIR}") +message(STATUS "FILESDIR_INSTALL = ${FILESDIR_INSTALL}") message(STATUS "FILESDIR_DEF = ${FILESDIR_DEF}") message(STATUS) diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index d640c341458..50980bfb262 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -71,8 +71,8 @@ CheckOptions: add_dependencies(cppcheck-gui online-help.qhc) endif() - install(TARGETS cppcheck-gui RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} COMPONENT applications) - install(FILES ${qms} DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} COMPONENT applications) + install(TARGETS cppcheck-gui RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT applications) + install(FILES ${qms} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT applications) install(FILES cppcheck-gui.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) From 95a327779a199d973763a8e05e1308f638027c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sat, 18 Jul 2026 20:43:27 +0200 Subject: [PATCH 262/493] CI-windows.yml: cleaned up and sped up `build_qt` job (#8735) --- .github/workflows/CI-windows.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml index ce73819bc70..a63be4e0ad9 100644 --- a/.github/workflows/CI-windows.yml +++ b/.github/workflows/CI-windows.yml @@ -21,7 +21,6 @@ defaults: jobs: - # TODO: use Debug build to speed it up? build_qt: strategy: matrix: @@ -52,27 +51,26 @@ jobs: - name: Run CMake run: | rem TODO: enable rules? - rem specify Release build so matchcompiler is used - cmake -S . -B build -Werror=dev --warn-uninitialized -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DBUILD_TESTING=Off -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DBUILD_ONLINE_HELP=On -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake -S . -B build -Werror=dev --warn-uninitialized -DCMAKE_BUILD_TYPE=Debug -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DBUILD_TESTING=Off -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DBUILD_ONLINE_HELP=On -DISABLE_DMAKE=On -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! - - name: Build GUI release + - name: Build GUI run: | - cmake --build build --target cppcheck-gui --config Release || exit /b !errorlevel! + cmake --build build --config Debug --target cppcheck-gui || exit /b !errorlevel! + # TODO: can this be done in CMake? - name: Deploy GUI run: | - windeployqt build\bin\Release || exit /b !errorlevel! - del build\bin\Release\cppcheck-gui.ilk || exit /b !errorlevel! - del build\bin\Release\cppcheck-gui.pdb || exit /b !errorlevel! + windeployqt --no-translations build\bin\Debug || exit /b !errorlevel! + del build\bin\Debug\cppcheck-gui.pdb || exit /b !errorlevel! # TODO: run GUI tests - name: Run CMake install run: | - rem TODO: this performs a Debug build - rem TODO: the Qt DLLS are not being installed (because of the missing windeployqt?) - cmake --build build --target install + rem TODO: the Qt DLLs are not being installed + cmake --build build --config Debug --target install rem TODO: validate the installed files + rem TODO: the structure does not match an actual Windows installation build_cmake_cxxstd: strategy: From d01dca600b0ddea551011bae55e1468ce91c0af1 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 18 Jul 2026 22:24:17 +0200 Subject: [PATCH 263/493] Fix #14909 internalAstError with x.size() passed to template parameter (#8716) --- lib/templatesimplifier.cpp | 2 +- test/testtokenize.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 6fdd423628b..24cc0bcbe1d 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -496,7 +496,7 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) return 0; // num/type .. - if (!tok->isNumber() && tok->tokType() != Token::eChar && tok->tokType() != Token::eString && !tok->isName() && !tok->isOp()) + if (!tok->isNumber() && tok->tokType() != Token::eChar && tok->tokType() != Token::eString && !tok->isName() && !tok->isOp() && tok->str() != ".") return 0; tok = tok->next(); if (!tok) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index f1a2a85e212..79da0177e19 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -241,6 +241,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(vardecl_stl_3); TEST_CASE(vardecl_template_1); TEST_CASE(vardecl_template_2); + TEST_CASE(vardecl_template_3); TEST_CASE(vardecl_union); TEST_CASE(vardecl_par); // #2743 - set links if variable type contains parentheses TEST_CASE(vardecl_par2); // #3912 - set correct links @@ -2394,6 +2395,19 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS(expected, tokenizeAndStringify(code)); } + void vardecl_template_3() { + const char code[] = "template \n" // #14909 + "void f(T x) {\n" + " const auto y = h;\n" + "}"; + const char expected[] = "template < class T >\n" + "void f ( T x ) {\n" + "const auto y = h < T , x . size ( ) > ;\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code)); + ASSERT_EQUALS("[test.cpp:3:11]: (debug) auto token with no type. [autoNoType]\n", errout_str()); + } + void vardecl_union() { // ticket #1976 const char code1[] = "class Fred { public: union { int a ; int b ; } ; } ;"; From 1fb66305f057029071f6b7175bc557eefaebfb87 Mon Sep 17 00:00:00 2001 From: Felix Patschkowski <49550034+Patschkowski@users.noreply.github.com> Date: Sun, 19 Jul 2026 15:41:59 +0700 Subject: [PATCH 264/493] Added configuration file for Microsoft.GSL library (#8738) Added configuration file to support: https://github.com/microsoft/gsl --- AUTHORS | 1 + cfg/microsoft_gsl.cfg | 17 ++++++++ man/manual.md | 1 + releasenotes.txt | 2 +- test/cfg/microsoft_gsl.cpp | 72 +++++++++++++++++++++++++++++++ test/cfg/runtests.sh | 5 ++- test/tools/donate_cpu_lib_test.py | 1 + tools/donate_cpu_lib.py | 1 + win_installer/cppcheck.wxs | 1 + 9 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 cfg/microsoft_gsl.cfg create mode 100644 test/cfg/microsoft_gsl.cpp diff --git a/AUTHORS b/AUTHORS index 1a7543b0d93..b4917d7d157 100644 --- a/AUTHORS +++ b/AUTHORS @@ -133,6 +133,7 @@ Felipe Pena Felix Faber Felix Geyer Felix Passenberg +Felix Patschkowski Felix Wolff Florian Mueller Florin Iucha diff --git a/cfg/microsoft_gsl.cfg b/cfg/microsoft_gsl.cfg new file mode 100644 index 00000000000..07fbfcb74a6 --- /dev/null +++ b/cfg/microsoft_gsl.cfg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/man/manual.md b/man/manual.md index 47a3a43fd36..7db916d4777 100644 --- a/man/manual.md +++ b/man/manual.md @@ -1161,6 +1161,7 @@ To use a `.cfg` file shipped with Cppcheck, pass the `--library=` option. T | `lua.cfg` | | | | `mfc.cfg` | [MFC](https://learn.microsoft.com/en-us/cpp/mfc/mfc-desktop-applications) | | | `microsoft_atl.cfg` | [ATL](https://learn.microsoft.com/en-us/cpp/atl/active-template-library-atl-concepts) | | +| `microsoft_gsl.cfg` | [Microsoft.GSL](https://github.com/microsoft/gsl) | | | `microsoft_sal.cfg` | [SAL annotations](https://learn.microsoft.com/en-us/cpp/c-runtime-library/sal-annotations) | | | `microsoft_unittest.cfg` | [CppUnitTest](https://learn.microsoft.com/en-us/visualstudio/test/microsoft-visualstudio-testtools-cppunittestframework-api-reference) | | | `motif.cfg` | | | diff --git a/releasenotes.txt b/releasenotes.txt index 1c0739dec0d..4b3ef047c5c 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -22,4 +22,4 @@ Infrastructure & dependencies: - Other: -- +- Added configuration file for Microsoft.GSL (Guideline Support Library). diff --git a/test/cfg/microsoft_gsl.cpp b/test/cfg/microsoft_gsl.cpp new file mode 100644 index 00000000000..4241cce045d --- /dev/null +++ b/test/cfg/microsoft_gsl.cpp @@ -0,0 +1,72 @@ +// Test library configuration for microsoft_gsl.cfg +// +// Usage: +// $ cppcheck --check-library --library=microsoft_gsl --enable=style,information --inconclusive --error-exitcode=1 --inline-suppr --suppress=autoNoType test/cfg/microsoft_gsl.cpp +// => +// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0 +// + +// C++ Standard Library +#include + +// Guideline Support Library +#include + +struct owner_type +{ + owner_type() = default; + owner_type(const owner_type &) = delete; + owner_type(owner_type &&) = default; + + ~owner_type() { delete ptr_; } + + auto operator=(const owner_type &) -> owner_type & = delete; + auto operator=(owner_type &&) -> owner_type & = default; + +private: + gsl::owner ptr_{new int(42)}; +}; + +auto pre_and_post_condition_test(int i) -> int +{ + Expects(i > 0); + + const auto result{i * 2}; + + Ensures(result > 0); + return result; +} + +auto suppress_macro_test(std::span s) -> int +{ + GSL_SUPPRESS("bounds.1") + return s[0]; +} + +auto iterate_over_container_test(const std::vector &v) -> int +{ + int sum{0}; + + for (gsl::index i{0}; i < v.size(); ++i) + { + sum += v[i]; + } + return sum; +} + +void not_null_test(gsl::not_null p) +{ + Expects(p != nullptr); + *p = 42; +} + +void strict_not_null_test(gsl::strict_not_null p) +{ + Expects(p != nullptr); + *p = 42; +} + +auto byte_test(gsl::byte b) -> gsl::byte +{ + return b | 0x81; +} diff --git a/test/cfg/runtests.sh b/test/cfg/runtests.sh index c8c1515e66c..4cf17b3a9df 100755 --- a/test/cfg/runtests.sh +++ b/test/cfg/runtests.sh @@ -549,7 +549,7 @@ function check_file { kde.cpp) # TODO: "kde-4config" is no longer commonly available in recent distros #kde_fn - cppcheck_run --library="$lib" --library=qt "${DIR}""$f" + cppcheck_run --library="$lib" --library=qt "${DIR}""$f" ;; libcurl.c) libcurl_fn @@ -563,6 +563,9 @@ function check_file { lua_fn cppcheck_run --library="$lib" "${DIR}""$f" ;; + microsoft_gsl.cpp) + cppcheck_run --suppress=autoNoType --library="$lib" "${DIR}""$f" + ;; mfc.cpp) mfc_fn cppcheck_run --platform=win64 --library="$lib" "${DIR}""$f" diff --git a/test/tools/donate_cpu_lib_test.py b/test/tools/donate_cpu_lib_test.py index e00a3d296a0..141781192aa 100644 --- a/test/tools/donate_cpu_lib_test.py +++ b/test/tools/donate_cpu_lib_test.py @@ -58,6 +58,7 @@ def test_library_includes(tmpdir): _test_library_includes(tmpdir, ['posix', 'gnu', 'bsd', 'opengl'], '#include\t ') _test_library_includes(tmpdir, ['posix', 'gnu', 'bsd', 'nspr'], '#include\t"prtypes.h"') _test_library_includes(tmpdir, ['posix', 'gnu', 'bsd', 'lua'], '#include \t') + _test_library_includes(tmpdir, ['posix', 'gnu', 'bsd', 'microsoft_gsl'], '#include ') def test_match_multiple_time(tmpdir): libinc = LibraryIncludes() diff --git a/tools/donate_cpu_lib.py b/tools/donate_cpu_lib.py index c292d2b9a13..ed345cb10c9 100644 --- a/tools/donate_cpu_lib.py +++ b/tools/donate_cpu_lib.py @@ -723,6 +723,7 @@ def __init__(self): 'wxwidgets': [''], + 'microsoft_gsl': [''], } self.__library_includes_re = {} diff --git a/win_installer/cppcheck.wxs b/win_installer/cppcheck.wxs index e7b597e2046..91d08c1c946 100644 --- a/win_installer/cppcheck.wxs +++ b/win_installer/cppcheck.wxs @@ -107,6 +107,7 @@ + From 2807561de51f59afd4993dd4b1e96d786fb546bf Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 20 Jul 2026 11:34:29 +0200 Subject: [PATCH 265/493] Followup to #8731: use isSplittedVarDeclEq() (#8739) --- lib/astutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 3c5c51498ba..74d2274ae6c 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3001,7 +3001,7 @@ bool isVariableChanged(const Variable * var, const Settings &settings, int depth const Token * start = var->declEndToken(); if (!start) return false; - if (Token::Match(start, "; %varid% =", var->declarationId()) && !Token::simpleMatch(start->previous(), ")")) + if (start->isSplittedVarDeclEq() && Token::Match(start, "; %varid% =", var->declarationId())) start = start->tokAt(2); if (Token::simpleMatch(start, "=")) { const Token* next = nextAfterAstRightmostLeafGeneric(start); From 678290cf0670ba88a4e1fcecc9d9d22b37cdb003 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Jul 2026 08:23:08 +0200 Subject: [PATCH 266/493] Add test for #14422 (#8742) Co-authored-by: chrchr-github --- test/testnullpointer.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 02810906fb2..86b0f4aeeb9 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -145,6 +145,7 @@ class TestNullPointer : public TestFixture { TEST_CASE(nullpointer105); // #13861 TEST_CASE(nullpointer106); // #13682 TEST_CASE(nullpointer107); // #13682 (FP/FN cases around guards that depend on the pointer indirectly) + TEST_CASE(nullpointer108); TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 @@ -3105,6 +3106,15 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void nullpointer108() { // #14422 + check("void f() {\n" + " int *p{};\n" + " int *&r{p};\n" + " if (*r) {}\n" + "}"); + ASSERT_EQUALS("[test.cpp:4:10]: (error) Null pointer dereference: r [nullPointer]\n", errout_str()); + } + void nullpointer_addressOf() { // address of check("void f() {\n" " struct X *x = 0;\n" From 4ba79f2c5885f6916851ce0ea5642beac9b70a8a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:24:31 +0200 Subject: [PATCH 267/493] Fix #14929 Crash in CheckBufferOverrunImpl::getBufferSize() (#8743) Co-authored-by: chrchr-github --- lib/checkbufferoverrun.cpp | 2 +- test/testbufferoverrun.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index d28ac7c64f7..246d428802e 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -575,7 +575,7 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons if (const ValueFlow::Value *value = getBufferSizeValue(bufTok)) { if (value->isBufferSizeValue()) return *value; - if (value->isContainerSizeValue() && bufTok->valueType() && bufTok->valueType()->container) { + if (value->isContainerSizeValue() && bufTok->valueType() && bufTok->valueType()->containerTypeToken) { const ValueType vtElement = ValueType::parseDecl(bufTok->valueType()->containerTypeToken, settings); const size_t elementSize = vtElement.getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); if (elementSize > 0) { diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index f9e55910c01..b44fd742ab1 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3551,6 +3551,12 @@ class TestBufferOverrun : public TestFixture { " std::memset(&buf[0], 0, 26);\n" "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (error) Buffer is accessed out of bounds: &buf[0] [bufferAccessOutOfBounds]\n", errout_str()); + + check("void f(FILE *fp) {\n" // #14929 + " std::string s;\n" + " fwrite(&s, 1, 1, fp);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); // don't crash } void buffer_overrun_errorpath() { From e0e5a04717d7d30b5ac068c44a591ec4f9c6c041 Mon Sep 17 00:00:00 2001 From: glankk Date: Thu, 23 Jul 2026 10:07:27 +0200 Subject: [PATCH 268/493] Fix #14931: dump file: Add classDef to scope (#8747) --- lib/symboldatabase.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 0f612d5f45a..4dbd09e98c4 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4457,6 +4457,11 @@ void SymbolDatabase::printXml(std::ostream &out) const outs += ErrorLogger::toxml(scope->className); outs += "\""; } + if (scope->classDef) { + outs += " classDef=\""; + outs += id_string(scope->classDef); + outs += "\""; + } if (scope->bodyStart) { outs += " bodyStart=\""; outs += id_string(scope->bodyStart); From f87363d10451c97a6987d5e729369cd5084d69b7 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Thu, 23 Jul 2026 04:26:30 -0500 Subject: [PATCH 269/493] Fix 14924: FP containerOutOfBounds (copy accessed in loop) (#8740) Co-authored-by: Your Name --- lib/programmemory.cpp | 29 +++++++++++++++++++++++++++-- test/teststl.cpp | 12 ++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 013906d00ae..9571e04ea00 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1512,6 +1512,31 @@ namespace { return unknown(); } + // Get the size of the container. If the container itself is not tracked in the program + // memory then check if it is symbolically equal to a container whose size is tracked. + ValueFlow::Value executeContainerSize(const Token* containerTok) + { + ValueFlow::Value v = execute(containerTok); + if (v.isContainerSizeValue()) + return v; + for (const ValueFlow::Value& value : containerTok->values()) { + if (!value.isSymbolicValue()) + continue; + if (value.isImpossible()) + continue; + if (value.intvalue != 0) + continue; + if (!value.tokvalue) + continue; + if (value.tokvalue->exprId() == 0) + continue; + const ValueFlow::Value* sizeValue = pm->getValue(value.tokvalue->exprId()); + if (sizeValue && sizeValue->isContainerSizeValue()) + return *sizeValue; + } + return unknown(); + } + ValueFlow::Value executeImpl(const Token* expr) { const ValueFlow::Value* value = nullptr; @@ -1540,14 +1565,14 @@ namespace { const Token* containerTok = expr->tokAt(-2)->astOperand1(); const Library::Container::Yield yield = containerTok->valueType()->container->getYield(expr->strAt(-1)); if (yield == Library::Container::Yield::SIZE) { - ValueFlow::Value v = execute(containerTok); + ValueFlow::Value v = executeContainerSize(containerTok); if (!v.isContainerSizeValue()) return unknown(); v.valueType = ValueFlow::Value::ValueType::INT; return v; } if (yield == Library::Container::Yield::EMPTY) { - ValueFlow::Value v = execute(containerTok); + ValueFlow::Value v = executeContainerSize(containerTok); if (!v.isContainerSizeValue()) return unknown(); if (v.isImpossible() && v.intvalue == 0) diff --git a/test/teststl.cpp b/test/teststl.cpp index ed9c5503d45..c030fb4c6f6 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1003,6 +1003,18 @@ class TestStl : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: error: Out of bounds access in 'v[2]', if 'v' size is 1 and '2' is 2 [containerOutOfBounds]\n", errout_str()); + + checkNormal("std::string f(const std::string& str) {\n" // do not warn, the copy has the same size as 'str' + " std::string outStr = str;\n" + " if (!outStr.empty())\n" + " outStr[0] = 'a';\n" + " for (int i = 0; i < str.size(); ++i) {\n" + " if (outStr[i] == '_')\n" + " outStr[i] = ' ';\n" + " }\n" + " return outStr;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void outOfBoundsSymbolic() From 7aa7114cce28124d409ebf76e0e2a022f21e1553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 23 Jul 2026 11:44:22 +0200 Subject: [PATCH 270/493] Fix #14796: FP assertWithSideEffect for member functions without definition (#8607) --- lib/checkassert.cpp | 6 +++--- lib/checkassert.h | 2 +- test/testassert.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index 1d0ecde7959..4578f7395ba 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -83,7 +83,7 @@ void CheckAssertImpl::assertWithSideEffects() if (!scope) { // guess that const method doesn't have side effects if (f->nestedIn->isClassOrStruct() && !f->isConst() && !f->isStatic()) - sideEffectInAssertError(tmp, f->name()); // Non-const member function called, assume it has side effects + sideEffectInAssertError(tmp, f->name(), " If there are no side effects, consider declaring the method const."); // Non-const member function called, assume it has side effects continue; } @@ -117,12 +117,12 @@ void CheckAssertImpl::assertWithSideEffects() //--------------------------------------------------------------------------- -void CheckAssertImpl::sideEffectInAssertError(const Token *tok, const std::string& functionName) +void CheckAssertImpl::sideEffectInAssertError(const Token *tok, const std::string& functionName, const std::string &extra) { reportError(tok, Severity::warning, "assertWithSideEffect", "$symbol:" + functionName + "\n" - "Assert statement calls a function which may have desired side effects: '$symbol'.\n" + "Assert statement calls a function which may have desired side effects: '$symbol'." + extra + "\n" "Non-pure function: '$symbol' is called inside assert statement. " "Assert statements are removed from release builds so the code inside " "assert statement is not executed. If the code is needed also in release " diff --git a/lib/checkassert.h b/lib/checkassert.h index 2db9d804fcb..15f97fb1746 100644 --- a/lib/checkassert.h +++ b/lib/checkassert.h @@ -65,7 +65,7 @@ class CPPCHECKLIB CheckAssertImpl : public CheckImpl { void checkVariableAssignment(const Token* assignTok, const Scope *assertionScope); static bool inSameScope(const Token* returnTok, const Token* assignTok); - void sideEffectInAssertError(const Token *tok, const std::string& functionName); + void sideEffectInAssertError(const Token *tok, const std::string& functionName, const std::string &extra = ""); void assignmentInAssertError(const Token *tok, const std::string &varname); }; /// @} diff --git a/test/testassert.cpp b/test/testassert.cpp index 80bb5d3b827..ea170c43f2d 100644 --- a/test/testassert.cpp +++ b/test/testassert.cpp @@ -156,7 +156,7 @@ class TestAssert : public TestFixture { "void foo(SquarePack s) {\n" " assert( s.Foo() );\n" "}"); - ASSERT_EQUALS("[test.cpp:5:14]: (warning) Assert statement calls a function which may have desired side effects: 'Foo'. [assertWithSideEffect]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:14]: (warning) Assert statement calls a function which may have desired side effects: 'Foo'. If there are no side effects, consider declaring the method const. [assertWithSideEffect]\n", errout_str()); check("struct SquarePack {\n" " int Foo() const;\n" From d272996589c5d7c75fd6f2e4e4f52d00e5224a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 23 Jul 2026 11:46:18 +0200 Subject: [PATCH 271/493] Fix #14894: false positive: co_return not recognized as return in combination with {} (#8741) --- lib/astutils.cpp | 20 ++++++++++++++++++++ lib/astutils.h | 2 ++ lib/forwardanalyzer.cpp | 2 +- test/testnullpointer.cpp | 13 +++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 74d2274ae6c..ea54232b551 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3918,3 +3918,23 @@ const Token *skipUnreachableBranch(const Token *tok) return tok; } + +bool isEscapeKeyword(const Token *tok, const Settings &settings) +{ + if (!tok) + return false; + + if (tok->str() == "return") + return true; + + if (!tok->isCpp()) + return false; + + if (tok->str() == "throw") + return true; + + if (settings.standards.cpp < Standards::CPP20) + return false; + + return tok->str() == "co_return"; +} diff --git a/lib/astutils.h b/lib/astutils.h index 2c6650068b5..79a607108fd 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -463,4 +463,6 @@ bool isUnreachableOperand(const Token *tok); const Token *skipUnreachableBranch(const Token *tok); +bool isEscapeKeyword(const Token *tok, const Settings &settings); + #endif // astutilsH diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index c38d93155ea..3e227873b26 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -144,7 +144,7 @@ namespace { // If we are in a loop then jump to the end if (out) *out = loopEnds.back(); - } else if (Token::Match(tok, "return|throw")) { + } else if (isEscapeKeyword(tok, settings)) { traverseRecursive(tok->astOperand2(), f, traverseUnknown); traverseRecursive(tok->astOperand1(), f, traverseUnknown); return Break(Analyzer::Terminate::Escape); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 86b0f4aeeb9..698946b8efa 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -146,6 +146,7 @@ class TestNullPointer : public TestFixture { TEST_CASE(nullpointer106); // #13682 TEST_CASE(nullpointer107); // #13682 (FP/FN cases around guards that depend on the pointer indirectly) TEST_CASE(nullpointer108); + TEST_CASE(nullpointer109); TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 @@ -3115,6 +3116,18 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("[test.cpp:4:10]: (error) Null pointer dereference: r [nullPointer]\n", errout_str()); } + void nullpointer109() + { + check("boost::asio::awaitable test()\n" + "{\n" + " const auto *s = getStr();\n" + " if(!s) co_return int{1};\n" + " std::print(\"{}\",*s);\n" + " co_return int{9};\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void nullpointer_addressOf() { // address of check("void f() {\n" " struct X *x = 0;\n" From 55ae8c452452de1214e9598fcc3ac02e651fff26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 23 Jul 2026 11:47:05 +0200 Subject: [PATCH 272/493] Fix #14896: false positive: missing co_return in void function (#8719) --- lib/checkfunctions.cpp | 2 ++ lib/symboldatabase.cpp | 14 ++++++++++++++ lib/symboldatabase.h | 1 + test/testfunctions.cpp | 9 +++++++++ 4 files changed, 26 insertions(+) diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 23db248816d..1edfdfab6ac 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -329,6 +329,8 @@ void CheckFunctionsImpl::checkMissingReturn() continue; if (Function::returnsVoid(function, true)) continue; + if (Function::isCoroutine(function, mSettings.standards, *mTokenizer)) + continue; const Token *errorToken = checkMissingReturnScope(scope->bodyEnd, mSettings.library); if (errorToken) missingReturnError(errorToken); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4dbd09e98c4..d98c66770e1 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3407,6 +3407,20 @@ bool Function::returnsVoid(const Function* function, bool unknown) }); } +bool Function::isCoroutine(const Function* function, const Standards &standards, const Tokenizer &tokens) +{ + if (!tokens.isCPP() || standards.cpp < Standards::CPP20) + return false; + if (!function->functionScope) + return false; + const Scope *scope = function->functionScope; + for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { + if (Token::Match(tok, "co_return|co_await|co_yield")) + return true; + } + return false; +} + std::vector Function::findReturns(const Function* f) { std::vector result; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 166f228ad99..7d52d0bfb32 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -945,6 +945,7 @@ class CPPCHECKLIB Function { static bool returnsStandardType(const Function* function, bool unknown = false); static bool returnsVoid(const Function* function, bool unknown = false); + static bool isCoroutine(const Function* function, const Standards &standards, const Tokenizer &tokens); static std::vector findReturns(const Function* f); diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index 788ff7a0d14..f5067bc31dc 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -86,6 +86,7 @@ class TestFunctions : public TestFixture { TEST_CASE(checkMissingReturn5); TEST_CASE(checkMissingReturn6); // #13180 TEST_CASE(checkMissingReturn7); // #14370 - FN try/catch + TEST_CASE(checkMissingReturn8); TEST_CASE(checkMissingReturnStdInt); // #14482 - FN std::int32_t // std::move for locar variable @@ -1927,6 +1928,14 @@ class TestFunctions : public TestFixture { ASSERT_EQUALS("[test.cpp:3:19]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); } + void checkMissingReturn8() { + const Settings s = settingsBuilder(settings).cpp(Standards::CPP20).build(); + check("boost::asio::awaitable test() {\n" + " co_return;\n" + "}\n",s); + ASSERT_EQUALS("", errout_str()); + } + void checkMissingReturnStdInt() {// #14482 - FN check("std::int32_t f() {}\n"); ASSERT_EQUALS("[test.cpp:1:19]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); From 354edf03694e7d2d2f91e5cf496356a4c458a73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 24 Jul 2026 06:01:24 +0200 Subject: [PATCH 273/493] Fixed #14930 (Manual: Document hash value for warnings) (#8745) --- man/manual-premium.md | 28 ++++++++++++++++++++++++++++ man/manual.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/man/manual-premium.md b/man/manual-premium.md index 4c30dc6d4b3..c8e38666530 100644 --- a/man/manual-premium.md +++ b/man/manual-premium.md @@ -572,6 +572,34 @@ The usage of the suppressions file is as follows: cppcheck --suppress-xml=suppressions.xml src/ +### The `` element + +Cppcheck calculates a unique ID for each error, called the hash. The hash depends on the code that +is related to the error, not on where that code is located. This means that the hash for an error +stays the same even when unrelated code elsewhere in the file is added, removed or moved, shifting +the line numbers around. The hash only changes if the related code itself is modified. + +This makes hash-based suppressions more robust than line-based suppressions: once you have +reviewed and suppressed a specific warning, the suppression keeps working even after the file is +edited, as long as the offending code is not changed. + +The hash for an error is included as the `hash` attribute in the [XML output](#the-error-element). +You can copy that value into a `` element in a suppressions XML file: + + + + + uninitvar + src/file1.c + 12345678 + + + +A suppression can use `` on its own, without ``, to suppress a specific error regardless +of its id. It is also possible to combine `` with ``, ``, `` and +``; when several of these are specified, all of them must match for the suppression to +apply. + ## Inline suppressions Suppressions can also be added directly in the code by adding comments that contain special keywords. diff --git a/man/manual.md b/man/manual.md index 7db916d4777..93d67e8f402 100644 --- a/man/manual.md +++ b/man/manual.md @@ -573,6 +573,34 @@ The usage of the suppressions file is as follows: cppcheck --suppress-xml=suppressions.xml src/ +### The `` element + +Cppcheck calculates a unique ID for each error, called the hash. The hash depends on the code that +is related to the error, not on where that code is located. This means that the hash for an error +stays the same even when unrelated code elsewhere in the file is added, removed or moved, shifting +the line numbers around. The hash only changes if the related code itself is modified. + +This makes hash-based suppressions more robust than line-based suppressions: once you have +reviewed and suppressed a specific warning, the suppression keeps working even after the file is +edited, as long as the offending code is not changed. + +The hash for an error is included as the `hash` attribute in the [XML output](#the-error-element). +You can copy that value into a `` element in a suppressions XML file: + + + + + uninitvar + src/file1.c + 12345678 + + + +A suppression can use `` on its own, without ``, to suppress a specific error regardless +of its id. It is also possible to combine `` with ``, ``, `` and +``; when several of these are specified, all of them must match for the suppression to +apply. + ## Inline suppressions Suppressions can also be added directly in the code by adding comments that contain special keywords. From 93546a2bcf80347b1fab523c52ecf1db1a0e0d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 24 Jul 2026 11:37:17 +0200 Subject: [PATCH 274/493] Fix #14565 xml suppression: add macro attribute for specifying macro name (#8749) --- lib/suppressions.cpp | 5 ++- test/testsuppressions.cpp | 81 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index fe483e347fe..b45ba151914 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -136,7 +136,10 @@ std::string SuppressionList::parseXmlFile(const char *filename) s.lineNumber = strToInt(text); else if (std::strcmp(name, "symbolName") == 0) s.symbolName = text; - else if (*text && std::strcmp(name, "hash") == 0) + else if (std::strcmp(name, "macroName") == 0) { + s.macroName = text; + s.type = SuppressionList::Type::macro; + } else if (*text && std::strcmp(name, "hash") == 0) s.hash = strToInt(text); else return std::string("unknown element '") + name + "' in suppressions XML '" + filename + "', expected id/fileName/lineNumber/symbolName/hash."; diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 90c64eb809e..949bad20bb4 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -119,6 +119,7 @@ class TestSuppressions : public TestFixture { TEST_CASE(addSuppressionLineMultiple); TEST_CASE(suppressionsParseXmlFile); + TEST_CASE(xmlMacroSuppressions); TEST_CASE(toString); @@ -1705,6 +1706,25 @@ class TestSuppressions : public TestFixture { ASSERT_EQUALS("sym", suppr.symbolName); } + { + ScopedFile file("suppressparsexml.xml", + "\n" + "\n" + "uninitvar\n" + "MACRO_NAME\n" + "\n" + ""); + + SuppressionList supprList; + ASSERT_EQUALS("", supprList.parseXmlFile(file.path().c_str())); + const auto& supprs = supprList.getSuppressions(); + ASSERT_EQUALS(1, supprs.size()); + const auto& suppr = *supprs.cbegin(); + ASSERT_EQUALS("uninitvar", suppr.errorId); + ASSERT_EQUALS("MACRO_NAME", suppr.macroName); + ASSERT_EQUALS_ENUM(SuppressionList::Type::macro, suppr.type); + } + // no file specified { SuppressionList supprList; @@ -1758,6 +1778,67 @@ class TestSuppressions : public TestFixture { } } + #define testXmlSuppressions(...) testXmlSuppressions_(__FILE__,__LINE__,__VA_ARGS__) + void testXmlSuppressions_(const char *thisfile, + int thisline, + const std::string &xml, + const std::string &code, + const std::string &expected) + { + const char *xmlpath = "testsupressions.xml"; + const char *sourcepath = "test.c"; + + Suppressions supprs; + const ScopedFile xmlfile(xmlpath, xml); + ASSERT_EQUALS_LOC("", supprs.nomsg.parseXmlFile(xmlpath), thisfile, thisline); + + Settings settings; + settings.templateFormat = templateFormat; + settings.quiet = true; + + const FileWithDetails sourcefile(sourcepath, Standards::Language::C, 0); + CppCheck instance(settings, supprs, *this, nullptr, true, nullptr); + instance.checkBuffer(sourcefile, code.c_str(), code.size()); + + ASSERT_EQUALS_LOC(expected, errout_str(), thisfile, thisline); + } + + void xmlMacroSuppressions() + { + testXmlSuppressions( + "\n" + "\n" + "uninitvar\n" + "VAR\n" + "\n" + "", + + "#define VAR x\n" + "int f(void) {\n" + " int VAR;\n" + " return VAR;\n" + "}\n", + + "" + ); + testXmlSuppressions( + "\n" + "\n" + "uninitvar\n" + "WRONG\n" + "\n" + "", + + "#define VAR x\n" + "int f(void) {\n" + " int VAR;\n" + " return VAR;\n" + "}\n", + + "[test.c:4:12]: (error) Uninitialized variable: x [uninitvar]\n" + ); + } + void addSuppressionDuplicate() const { SuppressionList supprs; From 74747650087f9755bc0b8f66a71c76ae3ba3f356 Mon Sep 17 00:00:00 2001 From: Daniel <52839433+DanTheMan2000@users.noreply.github.com> Date: Fri, 24 Jul 2026 12:41:04 -0500 Subject: [PATCH 275/493] Fix #14371: FP redundantAssignment for nested union members (#8748) --- lib/checkother.cpp | 6 +++++- test/testother.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d8f2f6ff6f4..2e6d5eafa4e 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -700,8 +700,12 @@ void CheckOtherImpl::checkRedundantAssignment() // Get next assignment.. const Token *nextAssign = fwdAnalysis.reassign(tokenToCheck, start, scope->bodyEnd); // extra check for union - if (nextAssign && tokenToCheck != tok->astOperand1()) + if (nextAssign && tokenToCheck != tok->astOperand1()) { nextAssign = fwdAnalysis.reassign(tok->astOperand1(), start, scope->bodyEnd); + // reading another member of the same union in the rhs is a use through aliasing + if (nextAssign && fwdAnalysis.hasOperand(nextAssign->astOperand2(), tokenToCheck)) + nextAssign = nullptr; + } if (!nextAssign) continue; diff --git a/test/testother.cpp b/test/testother.cpp index 92fefb72fd3..1fddea4b536 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -11063,6 +11063,48 @@ class TestOther : public TestFixture { " Dst.s->y = Src.s->y;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + // Ticket #14371 "redundantAssignment when using a union" + check("union U {\n" + " struct {\n" + " unsigned int abcd;\n" + " } u32;\n" + " struct {\n" + " unsigned short ab;\n" + " unsigned short cd;\n" + " } u16;\n" + "};\n" + "void f1() {\n" + " U m;\n" + " m.u32.abcd = 1234;\n" + " m.u32.abcd = 5 * m.u16.ab;\n" + "}\n" + "void f2(unsigned int a, unsigned short b) {\n" + " U m;\n" + " m.u32.abcd = a;\n" + " m.u32.abcd += 0x8000;\n" + " m.u32.abcd = m.u16.ab * b;\n" + "}\n" + "void f3(unsigned int seed) {\n" + " U m, other;\n" + " other.u32.abcd = seed;\n" + " m.u32.abcd = 1234;\n" + " m.u32.abcd = other.u16.ab * 2;\n" + "}\n" + "void f4(unsigned short x) {\n" + " U m;\n" + " m.u16.ab = x;\n" + " m.u16.cd = 0;\n" + " m.u16.ab = m.u32.abcd / 53;\n" + "}\n" + "void f5(unsigned short x, unsigned int y) {\n" + " U m;\n" + " m.u16.ab = x;\n" + " m.u16.cd = 0;\n" + " m.u16.ab = y;\n" + "}\n", dinit(CheckOptions, $.inconclusive = false)); + ASSERT_EQUALS("[test.cpp:24:16] -> [test.cpp:25:16]: (style) Variable 'm.u32.abcd' is reassigned a value before the old one has been used. [redundantAssignment]\n" + "[test.cpp:35:14] -> [test.cpp:37:14]: (style) Variable 'm.u16.ab' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); } void redundantVarAssignment_7133() { From 807ce9ff3b9715940fa9a2fcddd633037b2e5421 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 24 Jul 2026 19:54:03 +0200 Subject: [PATCH 276/493] Refs #14935: Fix index values in function call in for loop (#8753) --- lib/astutils.cpp | 2 +- test/testvalueflow.cpp | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index ea54232b551..2a231dccfd5 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2778,7 +2778,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, if (ftok->str() == "(" && Token::simpleMatch(ftok->astOperand1(), "[")) // operator() on array element, bail out return true; const Token * ptok = tok2; - while (Token::Match(ptok->astParent(), ".|::|[")) + while (Token::Match(ptok->astParent(), ".|::")) ptok = ptok->astParent(); int pindirect = indirect; if (indirect == 0 && astIsLHS(tok2) && Token::Match(ptok, ". %var%") && astIsPointer(ptok->next())) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index abeb603b660..45c7f884715 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5112,6 +5112,27 @@ class TestValueFlow : public TestFixture { ++it; ASSERT_EQUALS(0, it->intvalue); ASSERT(it->isPossible()); + + code = "void g(int*);\n" + "void f(int* a) {\n" + " for (int i = 0; i < 5; ++i) {\n" + " g(&a[i]);\n" + " }\n" + "}\n"; + values = tokenValues(code, "i ]"); + ASSERT_EQUALS(4, values.size()); + it = values.begin(); + ASSERT_EQUALS(0, it->intvalue); + ASSERT(it->isPossible()); + ++it; + ASSERT_EQUALS(-1, it->intvalue); + ASSERT(it->isImpossible()); + ++it; + ASSERT_EQUALS(4, it->intvalue); + ASSERT(it->isPossible()); + ++it; + ASSERT_EQUALS(5, it->intvalue); + ASSERT(it->isImpossible()); } void valueFlowSubFunction() { From 1ef5ef36c18b7769569ce1a517ce8188a8a058c3 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 24 Jul 2026 19:54:54 +0200 Subject: [PATCH 277/493] Fix #14928 Duplicate accessMoved in range-based for (#8746) --- lib/vf_settokenvalue.cpp | 2 +- test/testother.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index 315f4a40129..aab64170890 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -384,7 +384,7 @@ namespace ValueFlow setTokenValueCast(parent, valueType, std::move(value), settings); } - else if (parent->str() == ":") { + else if (parent->str() == ":" && Token::simpleMatch(parent->astParent(), "?")) { setTokenValue(parent,std::move(value),settings); } diff --git a/test/testother.cpp b/test/testother.cpp index 1fddea4b536..39eb23110a0 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -12945,6 +12945,13 @@ class TestOther : public TestFixture { " cif::condition mWhere;\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + check("void g(std::string);\n" // #14928 + "void f(std::string s) {\n" + " g(std::move(s));\n" + " for (char c : s) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:19]: (warning) Access of moved variable 's'. [accessMoved]\n", errout_str()); } void moveTernary() From 3daba5fe546e25ec2a35f1f90a3177d0e2d87561 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 26 Jul 2026 09:49:18 +0200 Subject: [PATCH 278/493] Fix #14891 FP knownConditionTrueFalse (dereferencing pointer to array member) (#8704) Co-authored-by: chrchr-github --- lib/valueflow.cpp | 3 +++ test/testvalueflow.cpp | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 096e3d56f56..5f6fc1cf622 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3606,6 +3606,9 @@ static void valueFlowSymbolic(const TokenList& tokenlist, const SymbolDatabase& continue; if (tok->astOperand2()->exprId() == 0) continue; + if (tok->astOperand2()->variable() && tok->astOperand2()->variable()->isArray() && + tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->pointer) // array to pointer decay + continue; if (!isConstExpression(tok->astOperand2(), settings.library)) continue; if (tok->astOperand1()->valueType() && tok->astOperand2()->valueType()) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 45c7f884715..c98680b8180 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -9225,6 +9225,15 @@ class TestValueFlow : public TestFixture { " return x;\n" "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 3U, "malloc(10)", 0)); + + code = "struct S {\n" // #14891 + " void f() const {\n" + " const int* p = a;\n" + " if (*p) {}\n" + " }\n" + " int a[3];\n" + "};\n"; + ASSERT(tokenValues(code, "* p )").empty()); } void valueFlowSymbolicIdentity() From 6640862c9381f447f05950b5dd186f83ead9a91d Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 26 Jul 2026 07:32:28 -0400 Subject: [PATCH 279/493] Fix #14933: Each GUI log entry line should be output on a separate line (#8744) --- gui/resultsview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index 55f673ab80c..d11cae35bc6 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -518,6 +518,7 @@ void ResultsView::logCopyComplete() const QListWidgetItem * item = mUI->mListLog->item(i); if (nullptr != item) { logText += item->text(); + logText += "\n"; } } QClipboard *clipboard = QApplication::clipboard(); From 9c8507f5cea972b85112a71448a117bf4ac99869 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 27 Jul 2026 08:53:13 +0200 Subject: [PATCH 280/493] Fix #14913 FN duplicateExpression with parenthesized subexpression (#8727) --- lib/astutils.cpp | 2 +- lib/checkother.cpp | 10 ++++++++++ test/testother.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 2a231dccfd5..c99e9b19bd5 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1700,7 +1700,7 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se compare = true; } } - if (compare && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings)) + if (compare && varTok1 != varTok2 && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings)) return isSameExpression(macro, varTok1, varTok2, settings, pure, followVar, errors); } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 2e6d5eafa4e..7f22e531230 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3058,6 +3058,16 @@ void CheckOtherImpl::checkDuplicateExpression() checkDuplicate(ast1->astOperand1(), tok->astOperand2(), ast1); ast1 = ast1->astOperand1(); } + if (tok->str() != "=") { + const Token* par = tok->astParent(); + while (par && tok->str() == par->str() && precedes(par->astOperand1(), tok)) { // chain of identical operators with parentheses + checkDuplicate(par->astOperand1(), tok->astOperand1(), par); + checkDuplicate(par->astOperand1(), tok->astOperand2(), par); + checkDuplicate(par->astOperand2(), tok->astOperand1(), par); + checkDuplicate(par->astOperand2(), tok->astOperand2(), par); + par = par->astParent(); + } + } } } } else if (tok->astOperand1() && tok->astOperand2() && tok->str() == ":" && tok->astParent() && tok->astParent()->str() == "?") { diff --git a/test/testother.cpp b/test/testother.cpp index 39eb23110a0..f69c7cae1c2 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -201,6 +201,7 @@ class TestOther : public TestFixture { TEST_CASE(duplicateExpression19); TEST_CASE(duplicateExpression20); TEST_CASE(duplicateExpression21); + TEST_CASE(duplicateExpression22); TEST_CASE(duplicateExpressionLoop); TEST_CASE(duplicateValueTernary); TEST_CASE(duplicateValueTernarySizeof); // #13773 @@ -8366,6 +8367,35 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void duplicateExpression22() { + check("int f() {\n" // #14913 + " return 0x1 | (0x2 | 0x4) | 0x1;\n" + "}\n" + "int g() {\n" + " return 0x1 | (0x2 | 0x1);\n" + "}\n" + "int h() {\n" + " return 0x1 | (0x1 | 0x2);\n" + "}\n" + "int i() {\n" + " return 0x2 | (0x4 | 0x1) | 0x1;\n" + "}\n" + "int j() {\n" + " return 0x2 | (0x1 | 0x4) | 0x1;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:30]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" + "[test.cpp:5:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" + "[test.cpp:8:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" + "[test.cpp:11:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" + "[test.cpp:14:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n", + errout_str()); + + check("bool f(const int** a, const int** b) {\n" + " return (a[0] != nullptr) != (b[0] != nullptr);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void duplicateExpressionLoop() { check("void f() {\n" " int a = 1;\n" From 422e90c953ae5e825e24f68ff53145a06c4a406f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 27 Jul 2026 08:53:51 +0200 Subject: [PATCH 281/493] fix #14795: FP unusedStructMember when type is a template parameter (#8600) --- lib/checkunusedvar.cpp | 21 +++++++++++++++++++++ test/testunusedvar.cpp | 15 +++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index fe85260fc8d..f4ced7f158d 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1676,6 +1676,27 @@ void CheckUnusedVarImpl::checkStructMemberUsage() if (use) break; } + // Class used in template with unknown definition + if (Token::Match(tok, "%name% <") && tok->linkAt(1)) { + if (tok->function()) + continue; + if (tok->type() && tok->type()->classScope) + continue; + const Token *start = tok; + while (Token::Match(start->tokAt(-2), "%name% ::")) + start = start->tokAt(-2); + if (mSettings.library.detectContainer(start)) + continue; + const Token *end = tok->linkAt(1); + for (; tok != end; tok = tok->next()) { + if (tok->type() && tok->type()->classScope == &scope) { + use = true; + break; + } + } + if (use) + break; + } if (tok->variable() != &var) continue; if (tok != var.nameToken()) { diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 849d34b49b0..0cf50a5ceb9 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -80,6 +80,7 @@ class TestUnusedVar : public TestFixture { TEST_CASE(structmember32); // #14483 TEST_CASE(structmember33); TEST_CASE(structmember34); + TEST_CASE(structmember35); TEST_CASE(structmember_macro); TEST_CASE(structmember_template_argument); // #13887 - do not report that member used in template argument is unused TEST_CASE(classmember); @@ -2102,6 +2103,20 @@ class TestUnusedVar : public TestFixture { ASSERT_EQUALS("[test.cpp:2:24]: (style) struct member 'S::p' is never used. [unusedStructMember]\n", errout_str()); } + void structmember35() { + checkStructMemberUsage("struct S { int i; };\n" + "int f() { return g(); }\n"); + ASSERT_EQUALS("", errout_str()); + + checkStructMemberUsage("struct S { int i; };\n" + "int f() { A *a = nullptr; (void) a; }\n"); + ASSERT_EQUALS("", errout_str()); + + checkStructMemberUsage("struct S { int i; };\n" + "int f() { const std::vector a {}; (void) a; }\n"); + ASSERT_EQUALS("[test.cpp:1:16]: (style) struct member 'S::i' is never used. [unusedStructMember]\n", errout_str()); + } + void structmember_macro() { checkStructMemberUsageP("#define S(n) struct n { int a, b, c; };\n" "S(unused);\n"); From 6d7e1da9dd61ea3ba584caf8b24ddda633fff8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 28 Jul 2026 10:02:37 +0200 Subject: [PATCH 282/493] Fix #14936: Failures to add suppressions are ignored in `importCppcheckGuiProject` (#8757) --- lib/importproject.cpp | 13 ++++++++++++- test/cli/more-projects_test.py | 1 - test/cli/project-suppressions.py | 33 ++++++++++++++++++++++++++++++++ test/testimportproject.cpp | 21 ++++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 test/cli/project-suppressions.py diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 0e6ca353480..242c1719ba9 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1653,7 +1653,18 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings &setti for (const std::string &p : paths) guiProject.pathNames.push_back(Path::fromNativeSeparators(p)); - supprs.nomsg.addSuppressions(std::move(suppressions)); // TODO: check result + + bool ok = true; + for (const auto &suppression : suppressions) { + const std::string addError = supprs.nomsg.addSuppression(suppression); + if (!addError.empty()) { + errors.emplace_back(addError); + ok = false; + } + } + if (!ok) + return false; + settings.checkHeaders = temp.checkHeaders; settings.checkUnusedTemplates = temp.checkUnusedTemplates; settings.maxCtuDepth = temp.maxCtuDepth; diff --git a/test/cli/more-projects_test.py b/test/cli/more-projects_test.py index 504a2b14431..98304bbe8aa 100644 --- a/test/cli/more-projects_test.py +++ b/test/cli/more-projects_test.py @@ -173,7 +173,6 @@ def test_project_empty_fields(tmpdir): - diff --git a/test/cli/project-suppressions.py b/test/cli/project-suppressions.py new file mode 100644 index 00000000000..e2b6ba5e7d6 --- /dev/null +++ b/test/cli/project-suppressions.py @@ -0,0 +1,33 @@ + +# python -m pytest project-suppressions.py + +from testutils import create_gui_project_file, assert_cppcheck + +def test_cli_and_project_suppressions(tmp_path): + # Uninitvar suppressed in project file + suppressions = [{ 'id': 'uninitvar' }] + project_path = tmp_path / 'project.cppcheck' + create_gui_project_file(project_path, root_path=str(tmp_path), suppressions=suppressions) + + # Uninitvar suppressed on command line before import + args = ['--suppress=uninitvar', f'--project={project_path}'] + out_exp = [ + "cppcheck: error: suppression 'uninitvar' already exists", + f"cppcheck: error: failed to load project '{project_path}'. An error occurred." + ] + assert_cppcheck(args, ec_exp=1, out_exp=out_exp) + +def test_multiple_cli_and_project_suppressions(tmp_path): + # Uninitvar and unreadVariable suppressed in project file + suppressions = [{ 'id': 'uninitvar' }, { 'id': 'unreadVariable' },] + project_path = tmp_path / 'project.cppcheck' + create_gui_project_file(project_path, root_path=str(tmp_path), suppressions=suppressions) + + # Uninitvar and unreadVariable suppressed on command line before import + args = ['--suppress=uninitvar', '--suppress=unreadVariable', f'--project={project_path}'] + out_exp = [ + "cppcheck: error: suppression 'uninitvar' already exists", + "cppcheck: error: suppression 'unreadVariable' already exists", + f"cppcheck: error: failed to load project '{project_path}'. An error occurred." + ] + assert_cppcheck(args, ec_exp=1, out_exp=out_exp) diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index c9889445c3c..873272030f6 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -79,6 +79,7 @@ class TestImportProject : public TestFixture { TEST_CASE(importCompileCommandsDirectoryMissing); // 'directory' field missing TEST_CASE(importCompileCommandsDirectoryInvalid); // 'directory' field not a string TEST_CASE(importCppcheckGuiProject); + TEST_CASE(importCppcheckGuiProjectDuplicateSuppressions); TEST_CASE(importCppcheckGuiProjectPremiumMisra); TEST_CASE(ignorePaths); TEST_CASE(testVcxprojUnicode); @@ -536,6 +537,26 @@ class TestImportProject : public TestFixture { ASSERT_EQUALS(true, s.inlineSuppressions); } + void importCppcheckGuiProjectDuplicateSuppressions() const { + REDIRECT; + constexpr char xml[] = "\n" + "\n" + " \n" + " test test\n" + " \n" + " uninitvar\n" + " uninitvar\n" + " \n" + "\n"; + std::istringstream istr(xml); + Settings s; + Suppressions supprs; + TestImporter project; + ASSERT_EQUALS(false, project.importCppcheckGuiProject(istr, s, supprs)); + ASSERT_EQUALS(1, project.errors.size()); + ASSERT_EQUALS("suppression 'uninitvar' already exists", project.errors[0]); + } + void importCppcheckGuiProjectPremiumMisra() const { REDIRECT; constexpr char xml[] = "\n" From f26de0cc37b8ebd9142c43346150999c21c2a879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 28 Jul 2026 12:55:08 +0200 Subject: [PATCH 283/493] Fix #14941: FN memleak with `_create_locale` (#8758) --- cfg/windows.cfg | 37 +++++++++++++++++++++++++++++++++++++ test/cfg/windows.cpp | 22 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/cfg/windows.cfg b/cfg/windows.cfg index 6a0bd111afa..b2251900d42 100644 --- a/cfg/windows.cfg +++ b/cfg/windows.cfg @@ -1331,6 +1331,11 @@ AllocateAndInitializeSid FreeSid + + _create_locale + _wcreate_locale + _free_locale + + + + false + + + + + + + + + + + false + + + + + + + + + + false + + + + + arg1 diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp index c01e57f6f91..37c580a0134 100644 --- a/test/cfg/windows.cpp +++ b/test/cfg/windows.cpp @@ -23,6 +23,7 @@ #include #include #include +#include bool UpdateTraceACalled(TRACEHANDLE traceHandle, LPCSTR loggerName, EVENT_TRACE_PROPERTIES* pProperties) { @@ -615,6 +616,27 @@ void memleak_malloca() // cppcheck-suppress memleak } +void memleak_create_locale() +{ + // cppcheck-suppress-begin valueFlowBailoutIncompleteVar + _locale_t locale = _create_locale(LC_ALL, "C"); + _locale_t wlocale = _wcreate_locale(LC_ALL, L"C"); + (void) locale; + (void) wlocale; + // cppcheck-suppress-end valueFlowBailoutIncompleteVar + // cppcheck-suppress memleak +} + +void no_memleak_create_locale() +{ + // cppcheck-suppress-begin valueFlowBailoutIncompleteVar + _locale_t locale = _create_locale(LC_ALL, "C"); + _locale_t wlocale = _wcreate_locale(LC_ALL, L"C"); + _free_locale(locale); + _free_locale(wlocale); + // cppcheck-suppress-end valueFlowBailoutIncompleteVar +} + void memleak_AllocateAndInitializeSid() { PSID pEveryoneSID = NULL; From bc88becf0b4344dc214a0f93c294f0e602a68dd4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 28 Jul 2026 13:47:08 +0200 Subject: [PATCH 284/493] Fix #14935 FN bufferAccessOutOfBounds (memset() in loop) (#8754) --- lib/checkbufferoverrun.cpp | 16 +++++++++++----- test/testbufferoverrun.cpp | 11 +++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 246d428802e..46d8e1c7c6c 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -560,12 +560,18 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons if (!bufTok->valueType()) return ValueFlow::Value(-1); + MathLib::bigint index = 0; if (bufTok->isUnaryOp("&")) { bufTok = bufTok->astOperand1(); if (Token::simpleMatch(bufTok, "[")) { - const Token* index = bufTok->astOperand2(); - if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0)) - return ValueFlow::Value(-1); + if (const Token* indexTok = bufTok->astOperand2()) { + if (indexTok->hasKnownIntValue()) + index = indexTok->getKnownIntValue(); + else if (const ValueFlow::Value* maxValue = indexTok->getMaxValue(false)) + index = maxValue->intvalue; + else + return ValueFlow::Value(-1); + } bufTok = bufTok->astOperand1(); } } @@ -600,10 +606,10 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons v.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE; if (var->isPointerArray()) - v.intvalue = dim * mSettings.platform.sizeof_pointer; + v.intvalue = (dim - index) * mSettings.platform.sizeof_pointer; else { const size_t typeSize = bufTok->valueType()->getSizeOf(mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee); - v.intvalue = dim * typeSize; + v.intvalue = (dim - index) * typeSize; } return v; diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index b44fd742ab1..37ab7083902 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3537,7 +3537,7 @@ class TestBufferOverrun : public TestFixture { "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[5] [bufferAccessOutOfBounds]\n" "[test.cpp:7:12]: (error) Buffer is accessed out of bounds: &a[0][0] [bufferAccessOutOfBounds]\n", - "", + "[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[5] [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" // #14866 @@ -3557,6 +3557,13 @@ class TestBufferOverrun : public TestFixture { " fwrite(&s, 1, 1, fp);\n" "}\n"); ASSERT_EQUALS("", errout_str()); // don't crash + + check("void f() {\n" // #14935 + " int a[5];\n" + " for (int i = 0; i < 5; ++i)\n" + " memset(&a[i], 0, sizeof(a));\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:16]: (error) Buffer is accessed out of bounds: &a[i] [bufferAccessOutOfBounds]\n", errout_str()); } void buffer_overrun_errorpath() { @@ -3814,7 +3821,7 @@ class TestBufferOverrun : public TestFixture { " int i[10];\n" " memset(&i[1], 0, 1000);\n" "}"); - TODO_ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: &i[1] [bufferAccessOutOfBounds]\n", "", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: &i[1] [bufferAccessOutOfBounds]\n", errout_str()); check("struct S { int x; };\n" // #8616 "void f() {\n" From 8effc6c60d7b135df159a305e23ac95d29b02b1b Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Wed, 29 Jul 2026 01:33:02 -0500 Subject: [PATCH 285/493] Fix 14937: False positive: inconclusive nullPointerRedundantCheck with thunk (#8755) --- lib/symboldatabase.cpp | 30 +++++++++---- lib/symboldatabase.h | 12 +++++- test/testnullpointer.cpp | 19 ++++++++ test/testsymboldatabase.cpp | 86 +++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 11 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d98c66770e1..e6f676e7a20 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5861,7 +5861,10 @@ bool Scope::hasInlineOrLambdaFunction(const Token** tokStart, bool onlyInline) c }); } -void Scope::findFunctionInBase(const Token* tok, size_t args, std::vector & matches) const +void Scope::findFunctionInBase(const std::string& name, + const Token* tok, + size_t args, + std::vector& matches) const { if (isClassOrStruct() && definedType && !definedType->derivedFrom.empty()) { const std::vector &derivedFrom = definedType->derivedFrom; @@ -5871,7 +5874,7 @@ void Scope::findFunctionInBase(const Token* tok, size_t args, std::vectorclassScope == this) // Ticket #5120, #5125: Recursive class; tok should have been found already continue; - auto range = base->classScope->functionMap.equal_range(tok->str()); + auto range = base->classScope->functionMap.equal_range(name); for (auto it = range.first; it != range.second; ++it) { const Function *func = it->second; if (func->isDestructor() && !Token::simpleMatch(tok->tokAt(-1), "~")) @@ -5882,7 +5885,7 @@ void Scope::findFunctionInBase(const Token* tok, size_t args, std::vectorclassScope->findFunctionInBase(tok, args, matches); + base->classScope->findFunctionInBase(name, tok, args, matches); } } } @@ -6021,8 +6024,10 @@ static bool hasMatchingConstructor(const Scope* classScope, const ValueType* arg }); } -const Function* Scope::findFunction(const Token *tok, bool requireConst, Reference ref) const +const Function* Scope::findFunction(const Token* tok, bool requireConst, Reference ref, const std::string& funcName) const { + const std::string& name = funcName.empty() ? tok->str() : funcName; + const bool isCall = Token::Match(tok->next(), "(|{"); const std::vector arguments = getArguments(tok); @@ -6032,8 +6037,8 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst, Referen // find all the possible functions that could match const std::size_t args = arguments.size(); - auto addMatchingFunctions = [&](const Scope *scope) { - auto range = scope->functionMap.equal_range(tok->str()); + auto addMatchingFunctions = [&](const Scope* scope) { + auto range = scope->functionMap.equal_range(name); for (auto it = range.first; it != range.second; ++it) { const Function *func = it->second; if (ref == Reference::LValue && func->hasRvalRefQualifier()) @@ -6068,7 +6073,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst, Referen const std::size_t numberOfMatchesNonBase = matches.size(); // check in base classes - findFunctionInBase(tok, args, matches); + findFunctionInBase(name, tok, args, matches); // Non-call => Do not match parameters if (!isCall) { @@ -6298,8 +6303,8 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst, Referen matches.erase(itPure); // Only one candidate left - if (matches.size() == 1 && std::none_of(functionList.begin(), functionList.end(), [tok](const Function& f) { - return startsWith(f.name(), tok->str() + " <"); + if (matches.size() == 1 && std::none_of(functionList.begin(), functionList.end(), [&name](const Function& f) { + return startsWith(f.name(), name + " <"); })) return matches[0]; @@ -7792,6 +7797,13 @@ static const Function* getFunction(const Token* tok) { lambda = lvar->nameToken()->tokAt(2)->function(); if (lambda && lambda->retDef) return lambda; + // calling an object of a class that overloads operator() + if (tok != lvar->nameToken() && !lvar->isPointer() && !lvar->isArray() && lvar->typeScope()) { + const Function* callOp = + lvar->typeScope()->findFunction(tok, lvar->isConst(), Reference::LValue, "operator()"); + if (callOp && callOp->retDef) + return callOp; + } } return nullptr; } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 7d52d0bfb32..86ce9419999 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1144,9 +1144,14 @@ class CPPCHECKLIB Scope { * @brief find a function * @param tok token of function call * @param requireConst if const refers to a const variable only const methods should be matched + * @param ref reference qualification of the object the function is called on + * @param funcName name to look up instead of tok->str(), e.g. "operator()" when tok is a variable that is called * @return pointer to function if found or NULL if not found */ - const Function *findFunction(const Token *tok, bool requireConst=false, Reference ref=Reference::None) const; + const Function* findFunction(const Token* tok, + bool requireConst = false, + Reference ref = Reference::None, + const std::string& funcName = "") const; const Scope *findRecordInNestedList(const std::string & name, bool isC = false) const; Scope *findRecordInNestedList(const std::string & name, bool isC = false); @@ -1210,7 +1215,10 @@ class CPPCHECKLIB Scope { */ bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; - void findFunctionInBase(const Token* tok, size_t args, std::vector & matches) const; + void findFunctionInBase(const std::string& name, + const Token* tok, + size_t args, + std::vector& matches) const; /** @brief initialize varlist */ void getVariableList(const Token *start, const Token *end); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 698946b8efa..c1bf766b8bb 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -147,6 +147,7 @@ class TestNullPointer : public TestFixture { TEST_CASE(nullpointer107); // #13682 (FP/FN cases around guards that depend on the pointer indirectly) TEST_CASE(nullpointer108); TEST_CASE(nullpointer109); + TEST_CASE(nullpointer110); // #14937 TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 @@ -3128,6 +3129,24 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void nullpointer110() + { // #14937 - noreturn member function called on operator() result + check("struct A {\n" + " [[noreturn]] void g(int);\n" + "};\n" + "template\n" + "struct Thunk {\n" + " T& operator()() const;\n" + "};\n" + "void f(Thunk
thunk, int* p) {\n" + " if (!p)\n" + " thunk().g(0);\n" + " *p = 1;\n" + "}", + dinit(CheckOptions, $.inconclusive = true)); + ASSERT_EQUALS("", errout_str()); + } + void nullpointer_addressOf() { // address of check("void f() {\n" " struct X *x = 0;\n" diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 69d345a1cc5..1ce349cf969 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -542,6 +542,8 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(findFunction60); TEST_CASE(findFunction61); TEST_CASE(findFunction62); // #14272 - pointer passed to function is const + TEST_CASE(findFunction63); // #14937 - member function of type returned by operator() + TEST_CASE(findFunction64); // overloaded operator() TEST_CASE(findFunctionRef1); TEST_CASE(findFunctionRef2); // #13328 TEST_CASE(findFunctionContainer); @@ -8875,6 +8877,90 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(2, functionCall->function()->token->linenr()); } + void findFunction63() + { // #14937 + GET_SYMBOL_DB("struct A {\n" + " void g(int);\n" + "};\n" + "template\n" + "struct Thunk {\n" + " T& operator()() const;\n" + "};\n" + "void f(Thunk thunk) {\n" + " thunk().g(0);\n" + "}\n"); + const Token* g = Token::findsimplematch(tokenizer.tokens(), "g ( 0 )"); + ASSERT(g); + ASSERT(g->function()); + ASSERT(g->function()->tokenDef); + ASSERT_EQUALS(2, g->function()->tokenDef->linenr()); + const Token* call = Token::findsimplematch(tokenizer.tokens(), "( ) . g"); + ASSERT(call && call->valueType()); + ASSERT(call->valueType()->typeScope && call->valueType()->typeScope->className == "A"); + ASSERT_EQUALS(static_cast(Reference::LValue), static_cast(call->valueType()->reference)); + } + + void findFunction64() + { // overloaded operator() + { + GET_SYMBOL_DB("struct A { void g(int); };\n" // overloads distinguished by argument count + "struct B { void h(int); };\n" + "template\n" + "struct C {\n" + " A& operator()();\n" + " B& operator()(int);\n" + "};\n" + "void f(C c) {\n" + " c().g(1);\n" + " c(1).h(1);\n" + "}\n"); + const Token* g = Token::findsimplematch(tokenizer.tokens(), "g ( 1 )"); + ASSERT(g && g->function()); + ASSERT_EQUALS(1, g->function()->tokenDef->linenr()); + const Token* h = Token::findsimplematch(tokenizer.tokens(), "h ( 1 )"); + ASSERT(h && h->function()); + ASSERT_EQUALS(2, h->function()->tokenDef->linenr()); + } + { + GET_SYMBOL_DB("struct A { void g(int); };\n" // overloads distinguished by constness of the object + "struct B { void h(int); };\n" + "template\n" + "struct C {\n" + " A& operator()();\n" + " B& operator()() const;\n" + "};\n" + "void f(C c, const C& k) {\n" + " c().g(1);\n" + " k().h(1);\n" + "}\n"); + const Token* g = Token::findsimplematch(tokenizer.tokens(), "g ( 1 )"); + ASSERT(g && g->function()); + ASSERT_EQUALS(1, g->function()->tokenDef->linenr()); + const Token* h = Token::findsimplematch(tokenizer.tokens(), "h ( 1 )"); + ASSERT(h && h->function()); + ASSERT_EQUALS(2, h->function()->tokenDef->linenr()); + } + { + GET_SYMBOL_DB("struct A { void g(int); };\n" // overloads distinguished by argument type + "struct B { void h(int); };\n" + "template\n" + "struct C {\n" + " A& operator()(int);\n" + " B& operator()(double);\n" + "};\n" + "void f(C c, int i, double d) {\n" + " c(i).g(1);\n" + " c(d).h(1);\n" + "}\n"); + const Token* g = Token::findsimplematch(tokenizer.tokens(), "g ( 1 )"); + ASSERT(g && g->function()); + ASSERT_EQUALS(1, g->function()->tokenDef->linenr()); + const Token* h = Token::findsimplematch(tokenizer.tokens(), "h ( 1 )"); + ASSERT(h && h->function()); + ASSERT_EQUALS(2, h->function()->tokenDef->linenr()); + } + } + void findFunctionRef1() { GET_SYMBOL_DB("struct X {\n" " const std::vector getInts() const & { return mInts; }\n" From 0911ee6994d6ea0a25580a45672ad51bd5b4c873 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:10:01 +0200 Subject: [PATCH 286/493] Fix #14818 FP returnDanglingLifetime when passing c_str() to function (#8750) Co-authored-by: chrchr-github --- lib/valueflow.cpp | 2 ++ test/testautovariables.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 5f6fc1cf622..63543e1a8f5 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2542,6 +2542,8 @@ static void valueFlowLifetimeFunction(Token *tok, const TokenList &tokenlist, Er for (const Token* returnTok : returns) { if (returnTok == tok) continue; + if (!ValueFlow::isLifetimeBorrowed(returnTok, settings)) + return; const Variable *returnVar = ValueFlow::getLifetimeVariable(returnTok, settings); if (returnVar && returnVar->isArgument() && (returnVar->isConst() || !isVariableChanged(returnVar, settings))) { LifetimeStore ls = LifetimeStore::fromFunctionArg(f, tok, returnVar, tokenlist, settings, errorLogger); diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index df421d6879c..7774d7fa733 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2962,6 +2962,15 @@ class TestAutoVariables : public TestFixture { " int m;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("std::string to_string(const char* p) {\n" // #14818 + " return p;\n" + "}\n" + "std::string get() {\n" + " std::string s;\n" + " return to_string(s.c_str());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void danglingLifetimeContainerView() From 71de6753d64f176e30335b5e4b93bc90464908e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 30 Jul 2026 09:39:24 +0200 Subject: [PATCH 287/493] Fix #14914: fuzzing timeout (hang) in Tokenizer::simplifyTypedef() (#8762) --- lib/tokenize.cpp | 29 ++++++++++--------- ...m-6fd8356f0baeb3bb43463298803b94ac8ea93cac | 1 + test/testsimplifytypedef.cpp | 6 ++++ 3 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 test/cli/fuzz-timeout/oom-6fd8356f0baeb3bb43463298803b94ac8ea93cac diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 031ab624bfb..5ebf6c51951 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -563,6 +563,20 @@ namespace { if (Token::simpleMatch(start, "typename")) start = start->next(); + const auto checkForRecursion = [this]() { + if (Token::Match(mTypedefToken, "typedef %name% %name% ;")) + return; + for (const Token *tok = mTypedefToken; tok != mEndToken; tok = tok->next()) { + if (tok == mNameToken) + continue; + if (tok->str() != mNameToken->str()) + continue; + if (Token::Match(tok->previous(), "struct|class|enum|union")) + continue; + throw InternalError(tok, "recursive typedef encountered"); + } + }; + // TODO handle unnamed structs etc if (Token::Match(start, "const| enum|struct|union|class %name%| {")) { const std::pair rangeBefore(start, Token::findsimplematch(start, "{")); @@ -585,24 +599,11 @@ namespace { } mNameToken = nameTok; mEndToken = nameTok->next(); + checkForRecursion(); return; } } - const auto checkForRecursion = [this]() { - if (Token::Match(mTypedefToken, "typedef %name% %name% ;")) - return; - for (const Token *tok = mTypedefToken; tok != mEndToken; tok = tok->next()) { - if (tok == mNameToken) - continue; - if (tok->str() != mNameToken->str()) - continue; - if (Token::Match(tok->previous(), "struct|class|enum|union")) - continue; - throw InternalError(tok, "recursive typedef encountered"); - } - }; - for (Token* type = start; Token::Match(type, "%name%|*|&|&&"); type = type->next()) { if (type != start && Token::Match(type, "%name% ;") && !type->isStandardType()) { mRangeType.first = start; diff --git a/test/cli/fuzz-timeout/oom-6fd8356f0baeb3bb43463298803b94ac8ea93cac b/test/cli/fuzz-timeout/oom-6fd8356f0baeb3bb43463298803b94ac8ea93cac new file mode 100644 index 00000000000..29e36cf8c55 --- /dev/null +++ b/test/cli/fuzz-timeout/oom-6fd8356f0baeb3bb43463298803b94ac8ea93cac @@ -0,0 +1 @@ +typedef struct D{itoftor;}tor tor; \ No newline at end of file diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 5a14399e406..42718a2f99c 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -234,6 +234,7 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedef161); TEST_CASE(simplifyTypedef162); TEST_CASE(simplifyTypedef163); + TEST_CASE(simplifyTypedef164); TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -3874,6 +3875,11 @@ class TestSimplifyTypedef : public TestFixture { ASSERT_THROW_INTERNAL(tok(code), INTERNAL); } + void simplifyTypedef164() { + const char code[] = "typedef struct D{x;}y y;"; + ASSERT_THROW_INTERNAL(tok(code), INTERNAL); + } + void simplifyTypedefFunction1() { { const char code[] = "typedef void (*my_func)();\n" From a156364fa3f5edbcba3ad7a5bd37310e6ea7d8ae Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 30 Jul 2026 18:29:55 +0200 Subject: [PATCH 288/493] Partial fix for #14911 FN knownConditionTrueFalse for number literals (regression) (#8737) Co-authored-by: chrchr-github --- lib/checkcondition.cpp | 19 ++++++++++++++----- test/testcondition.cpp | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index e77641f89e7..4776cbea38f 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1575,10 +1575,19 @@ void CheckConditionImpl::alwaysTrueFalse() continue; if (Token::simpleMatch(tok->astParent(), "return") && Token::Match(tok, ".|%var%")) continue; - if (Token::Match(tok, "%num%|%bool%|%char%")) - continue; - if (Token::Match(tok, "! %num%|%bool%|%char%")) - continue; + bool warnForNumber = false; + if (Token::Match(tok, "%num%|%bool%|%char%")) { + const bool isZeroOrOne = (tok->getKnownIntValue() >> 1) == 0; + warnForNumber = !isZeroOrOne && tok->tokType() == Token::eNumber && tok->astParent() == condition->astParent(); + if (!warnForNumber) + continue; + } + if (Token::Match(tok, "! %num%|%bool%|%char%")) { + const bool isZeroOrOne = tok->next()->hasKnownIntValue() && (tok->next()->getKnownIntValue() >> 1) == 0; + warnForNumber = !isZeroOrOne && tok->next()->tokType() == Token::eNumber && tok->astParent() == condition->astParent(); + if (!warnForNumber) + continue; + } if (Token::Match(tok, "%oror%|&&")) { bool bail = false; for (const Token* op : { tok->astOperand1(), tok->astOperand2() }) { @@ -1603,7 +1612,7 @@ void CheckConditionImpl::alwaysTrueFalse() true)) continue; - if (!pedantic && isConstVarExpression(tok, [](const Token* tok) { + if (!pedantic && !warnForNumber && isConstVarExpression(tok, [](const Token* tok) { return Token::Match(tok, "[|(|&|+|-|*|/|%|^|>>|<<") && !Token::simpleMatch(tok, "( )"); })) continue; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index da4ecae43b3..85efa6eab63 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4949,6 +4949,28 @@ class TestCondition : public TestFixture { " return x ? false : true;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" + " if (42) {}\n" + " if (42U) {}\n" + " if (42L) {}\n" + " if (42UL) {}\n" + " if (42LL) {}\n" + " if (042) {}\n" + " if (0x42) {}\n" + " if (0b101010) {}\n" + " if (!42) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:9]: (style) Condition '42' is always true [knownConditionTrueFalse]\n" + "[test.cpp:3:9]: (style) Condition '42U' is always true [knownConditionTrueFalse]\n" + "[test.cpp:4:9]: (style) Condition '42L' is always true [knownConditionTrueFalse]\n" + "[test.cpp:5:9]: (style) Condition '42UL' is always true [knownConditionTrueFalse]\n" + "[test.cpp:6:9]: (style) Condition '42LL' is always true [knownConditionTrueFalse]\n" + "[test.cpp:7:9]: (style) Condition '042' is always true [knownConditionTrueFalse]\n" + "[test.cpp:8:9]: (style) Condition '0x42' is always true [knownConditionTrueFalse]\n" + "[test.cpp:9:9]: (style) Condition '0b101010' is always true [knownConditionTrueFalse]\n" + "[test.cpp:10:9]: (style) Condition '!42' is always false [knownConditionTrueFalse]\n", + errout_str()); } void alwaysTrueSymbolic() From 8745a78a43281593e755c91c835cc6211ce99ed9 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 30 Jul 2026 22:28:32 +0200 Subject: [PATCH 289/493] Fix #14945 FN memleak with nested scopes. (#8761) --- lib/checkleakautovar.cpp | 2 ++ test/testleakautovar.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index e8271f9eed0..e5220e701a3 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -342,6 +342,8 @@ bool CheckLeakAutoVarImpl::checkScope(const Token * const startToken, } } + if (tok == tok->scope()->bodyEnd && tok->scope()->type == ScopeType::eUnconditional) + ret(tok, varInfo, /*isEndOfScope*/ true); // look for end of statement const bool isInit = Token::Match(tok->tokAt(-1), "%var% {|(") && tok->tokAt(-1)->variable() && tok->tokAt(-1) == tok->tokAt(-1)->variable()->nameToken(); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index b7f8b024a8c..6b6397851fb 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -211,6 +211,7 @@ class TestLeakAutoVar : public TestFixture { TEST_CASE(inlineFunction); // #3989 TEST_CASE(smartPtrInContainer); // #8262 + TEST_CASE(unconditionalScope); TEST_CASE(functionCallCastConfig); // #9652 TEST_CASE(functionCallLeakIgnoreConfig); // #7923 @@ -3178,6 +3179,34 @@ class TestLeakAutoVar : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void unconditionalScope() { + check("void f() {\n" // #14945 + " {\n" + " int* p = new int;\n" + " *p = 1;\n" + " }\n" + " {\n" + " int* q = new int;\n" + " *q = 2;\n" + " delete q;\n" + " }\n" + " int* r = new int;\n" + " *r = 3;\n" + " delete r;\n" + "}\n", dinit(CheckOptions, $.cpp = true)); + ASSERT_EQUALS("[test.cpp:5:5]: (error) Memory leak: p [memleak]\n", errout_str()); + + check("void f() {\n" + " int* p = new int;\n" + " {\n" + " (void)p;\n" + " }\n" + " *p = 1;\n" + " delete p;\n" + "}\n", dinit(CheckOptions, $.cpp = true)); + ASSERT_EQUALS("", errout_str()); + } + void functionCallCastConfig() { // #9652 constexpr char xmldata[] = "\n" "\n" From da92ba351e39bb86c03879920e8a2de35d435aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 31 Jul 2026 11:50:48 +0200 Subject: [PATCH 290/493] Fix #14951: FP unreadVariable with function pointer member (#8768) --- lib/tokenize.cpp | 4 +++- test/testsymboldatabase.cpp | 17 +++++++++++++++++ test/testunusedvar.cpp | 12 ++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 5ebf6c51951..07ffa4c666c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4549,7 +4549,7 @@ static void setVarIdStructMembers(Token *&tok1, return; } - while (Token::Match(tok->next(), ")| . %name% !!(")) { + while (Token::Match(tok->next(), ")| . %name%")) { // Don't set varid for trailing return type if (tok->strAt(1) == ")" && Token::Match(tok->linkAt(1)->tokAt(-1), "%name%|]") && !tok->linkAt(1)->tokAt(-1)->isKeyword() && TokenList::isFunctionHead(tok->linkAt(1), "{;")) { @@ -4571,6 +4571,8 @@ static void setVarIdStructMembers(Token *&tok1, std::map& members = structMembers[struct_varid]; const auto it = utils::as_const(members).find(tok->str()); if (it == members.cend()) { + if (Token::Match(tok, "%name% (")) + break; members[tok->str()] = ++varId; tok->varId(varId); } else { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 1ce349cf969..eeaed0cbf3f 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -233,6 +233,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(rangeBasedFor); TEST_CASE(memberVar1); + TEST_CASE(memberVar2); TEST_CASE(arrayMemberVar1); TEST_CASE(arrayMemberVar2); TEST_CASE(arrayMemberVar3); @@ -1864,6 +1865,22 @@ class TestSymbolDatabase : public TestFixture { ASSERT(Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;")); } + void memberVar2() { + GET_SYMBOL_DB( "struct S { void (*fp)(); };\n" + "void g();\n" + "void f() {\n" + " S s;\n" + " s.fp = g;\n" + " s.fp();\n" + "}\n"); + + ASSERT(db != nullptr); + const Token *fp1 = Token::findsimplematch(tokenizer.tokens(), "fp ="); + const Token *fp2 = Token::findsimplematch(tokenizer.tokens(), "fp ("); + ASSERT(fp1->varId()); + ASSERT_EQUALS(fp2->varId(), fp1->varId()); + } + void arrayMemberVar1() { GET_SYMBOL_DB("struct Foo {\n" " int x;\n" diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 0cf50a5ceb9..a56af38c0f5 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -158,6 +158,7 @@ class TestUnusedVar : public TestFixture { TEST_CASE(localvar71); TEST_CASE(localvar72); TEST_CASE(localvar73); + TEST_CASE(localvar74); TEST_CASE(localvarloops); // loops TEST_CASE(localvaralias1); TEST_CASE(localvaralias2); // ticket #1637 @@ -4100,6 +4101,17 @@ class TestUnusedVar : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void localvar74() { + functionVariableUsage("struct S { void (*fp)(); };\n" + "void g();\n" + "void f() {\n" + " S s;\n" + " s.fp = g;\n" + " s.fp();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void localvarloops() { // loops functionVariableUsage("void fun(int c) {\n" From cb9f2a2c365f5d9468e99d4c1e5aa5765f0edbc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 31 Jul 2026 11:53:12 +0200 Subject: [PATCH 291/493] Fix #14712: FP constVariableReference , taking non const reference to member (#8767) --- lib/symboldatabase.cpp | 2 +- test/testother.cpp | 11 +++++++++++ test/testsymboldatabase.cpp | 12 ++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index e6f676e7a20..a666c15b536 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5088,7 +5088,7 @@ void Scope::getVariableList() void Scope::getVariableList(const Token* start, const Token* end) { // Variable declared in condition: if (auto x = bar()) - if (Token::Match(classDef, "if|while ( %type%") && Token::simpleMatch(classDef->next()->astOperand2(), "=")) { + if (Token::Match(classDef, "if|while|switch ( %type%") && Token::simpleMatch(classDef->next()->astOperand2(), "=")) { checkVariable(classDef->tokAt(2), defaultAccess()); } diff --git a/test/testother.cpp b/test/testother.cpp index f69c7cae1c2..b12e26e1ffa 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4155,6 +4155,17 @@ class TestOther : public TestFixture { " return r;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct Item { int state; };\n" + "void foo(std::vector &items) {\n" + " for (auto &item : items) {\n" + " switch (auto &s = item.state) {\n" + " case 0: s = 1; break;\n" + " default: break;\n" + " }\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void constParameterCallback() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index eeaed0cbf3f..8fe107080b6 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -204,6 +204,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(isVariableDeclarationRValueRef); TEST_CASE(isVariableDeclarationDoesNotIdentifyCase); TEST_CASE(isVariableDeclarationIf); + TEST_CASE(isVariableDeclarationSwitch); TEST_CASE(isVariableStlType); TEST_CASE(isVariablePointerToConstPointer); TEST_CASE(isVariablePointerToVolatilePointer); @@ -1235,6 +1236,17 @@ class TestSymbolDatabase : public TestFixture { ASSERT(y->variable()); } + void isVariableDeclarationSwitch() { + GET_SYMBOL_DB("void foo(void) {\n" + " int x = 0;\n" + " switch (auto &s = x) {}\n" + "}\n"); + const Token *s = Token::findsimplematch(tokenizer.tokens(), "s"); + ASSERT(s); + ASSERT(s->varId()); + ASSERT(s->variable()); + } + void VariableValueType1() { GET_SYMBOL_DB("typedef uint8_t u8;\n" "static u8 x;"); From cb694dd86322e83fad8caea77ceb8fa687fd0f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 3 Aug 2026 14:57:08 +0200 Subject: [PATCH 292/493] Fix #14954: False negatives: `noCopyConstructor`, `noOperatorEq` and `unsafeClassCanLeak` for file descriptor member (#8769) Co-authored-by: Aaron Danen --- lib/checkclass.cpp | 9 ++++++--- lib/checkmemoryleak.cpp | 2 +- test/testclass.cpp | 32 +++++++++++++++++++++++++++++++- test/testmemleak.cpp | 12 +++++++++++- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 51d5718159f..d691834097d 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -473,7 +473,7 @@ void CheckClassImpl::copyconstructors() if (Token::Match(tok, "%var% ( new") || (Token::Match(tok, "%var% ( %name% (") && mSettings.library.getAllocFuncInfo(tok->tokAt(2)))) { const Variable* var = tok->variable(); - if (var && var->isPointer() && var->scope() == scope) + if (var && var->scope() == scope && var->valueType() && var->valueType()->type != ValueType::SMART_POINTER) allocatedVars[tok->varId()] = tok; } } @@ -481,7 +481,7 @@ void CheckClassImpl::copyconstructors() if (Token::Match(tok, "%var% = new") || (Token::Match(tok, "%var% = %name% (") && mSettings.library.getAllocFuncInfo(tok->tokAt(2)))) { const Variable* var = tok->variable(); - if (var && var->isPointer() && var->scope() == scope && !var->isStatic()) + if (var && var->scope() == scope && !var->isStatic() && var->valueType() && var->valueType()->type != ValueType::SMART_POINTER) allocatedVars[tok->varId()] = tok; } } @@ -493,7 +493,10 @@ void CheckClassImpl::copyconstructors() (Token::Match(tok, "%name% ( %var%") && mSettings.library.getDeallocFuncInfo(tok))) { const Token *vartok = tok->str() == "delete" ? tok->next() : tok->tokAt(2); const Variable* var = vartok->variable(); - if (var && var->isPointer() && var->scope() == scope && !var->isStatic()) + if (var && var->scope() == scope && !var->isStatic() && + var->valueType() && ((var->valueType()->type != ValueType::CONTAINER && + var->valueType()->type != ValueType::RECORD && + var->valueType()->type != ValueType::UNKNOWN_TYPE) || var->valueType()->pointer)) deallocatedVars[vartok->varId()] = vartok; } } diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index cc8b6853f11..398240b06ab 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -517,7 +517,7 @@ void CheckMemoryLeakInClassImpl::check() // only check classes and structures for (const Scope * scope : symbolDatabase->classAndStructScopes) { for (const Variable &var : scope->varlist) { - if (!var.isStatic() && (var.isPointer() || var.isPointerArray())) { + if (!var.isStatic()) { // allocation but no deallocation of private variables in public function.. const Token *tok = var.typeStartToken(); // Either it is of standard type or a non-derived type diff --git a/test/testclass.cpp b/test/testclass.cpp index 1d647eb33a1..457ab5932fe 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -38,7 +38,7 @@ class TestClass : public TestFixture { const Settings settings0_i = settingsBuilder(settings0).certainty(Certainty::inconclusive).build(); const Settings settings1 = settingsBuilder().severity(Severity::warning).library("std.cfg").build(); const Settings settings2 = settingsBuilder().severity(Severity::style).library("std.cfg").certainty(Certainty::inconclusive).build(); - const Settings settings3 = settingsBuilder().severity(Severity::style).library("std.cfg").severity(Severity::warning).build(); + const Settings settings3 = settingsBuilder().severity(Severity::style).library("std.cfg").severity(Severity::warning).library("posix.cfg").build(); const Settings settings3_i = settingsBuilder(settings3).certainty(Certainty::inconclusive).build(); const Settings settings4 = settingsBuilder().severity(Severity::warning).severity(Severity::portability).library("std.cfg").library("posix.cfg").build(); @@ -62,6 +62,8 @@ class TestClass : public TestFixture { TEST_CASE(copyConstructor4); // base class with private constructor TEST_CASE(copyConstructor5); // multiple inheritance TEST_CASE(copyConstructor6); // array of pointers + TEST_CASE(copyConstructor7); // ticket #14954 + TEST_CASE(copyConstructor8); TEST_CASE(deletedMemberPointer); // deleted member pointer in destructor TEST_CASE(noOperatorEq); // class with memory management should have operator eq TEST_CASE(noDestructor); // class with memory management should have destructor @@ -1094,6 +1096,25 @@ class TestClass : public TestFixture { errout_str()); } + void copyConstructor7() { // ticket #14954 + checkCopyConstructor("struct S {\n" + " explicit S(char *name) { m_fd = mkstemp(name); }\n" + " ~S() { /* close(m_fd); */ }\n" + " S &operator =(const S&);\n" + " int m_fd;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:2:30]: (warning) Struct 'S' does not have a copy constructor which is recommended since it has dynamic memory/resource management. [noCopyConstructor]\n", errout_str()); + } + + void copyConstructor8() { + checkCopyConstructor("struct S {\n" + " S() : m_ptr(new int) {}\n" + " ~S();\n" + " std::unique_ptr m_ptr;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + void deletedMemberPointer() { // delete ... @@ -1158,6 +1179,15 @@ class TestClass : public TestFixture { " ~F();\n" "};"); ASSERT_EQUALS("", errout_str()); + + checkCopyConstructor("struct S {\n" + " explicit S(char *name) { m_fd = mkstemp(name); }\n" + " S(const S&);\n" + " ~S() { /* close(m_fd); */ }\n" + " int m_fd;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:2:30]: (warning) Struct 'S' does not have a operator= which is recommended since it has dynamic memory/resource management. [noOperatorEq]\n", errout_str()); + } void noDestructor() { diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 783a10ad089..2999fd3f441 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -488,7 +488,7 @@ class TestMemleakInClass : public TestFixture { TestMemleakInClass() : TestFixture("TestMemleakInClass") {} private: - const Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::style).library("std.cfg").build(); + const Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::style).library("std.cfg").library("posix.cfg").build(); /** * Tokenize and execute leak check for given code @@ -533,6 +533,7 @@ class TestMemleakInClass : public TestFixture { TEST_CASE(class25); // ticket #4367 - false positive implementation for destructor is not seen TEST_CASE(class26); // ticket #10789 TEST_CASE(class27); // ticket #8126 + TEST_CASE(class28); // ticket #14954 TEST_CASE(staticvar); @@ -1484,6 +1485,15 @@ class TestMemleakInClass : public TestFixture { ASSERT_EQUALS("[test.cpp:6:11]: (style) Class 'S' is unsafe, 'S::a' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); } + void class28() { // ticket #14954 + check("struct S {\n" + " explicit S(char *name) { m_fd = mkstemp(name); }\n" + " ~S() { /* close(m_fd); */ }\n" + " int m_fd;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:4:9]: (style) Class 'S' is unsafe, 'S::m_fd' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); + } + void staticvar() { check("class A\n" "{\n" From 1f1a07f41409747e4a051b9f1f0a02ce6dc97cf5 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 4 Aug 2026 08:25:50 +0200 Subject: [PATCH 293/493] Fix #11437 FP knownConditionTrueFalse when comparing clamped value (#8751) --- lib/valueflow.cpp | 1 + test/testcondition.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 63543e1a8f5..766f65e9f32 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4276,6 +4276,7 @@ static void valueFlowAfterAssign(const TokenList &tokenlist, continue; const Token* expr = value.tokvalue; value.intvalue = -value.intvalue; + value.invertBound(); value.tokvalue = tok->astOperand1(); // Skip if it intersects with an already assigned symbol diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 85efa6eab63..8567d9b11a7 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -5244,6 +5244,12 @@ class TestCondition : public TestFixture { " if (c) {}\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f(int a, int b) {\n" // #11437 + " a = a < b ? b : a;\n" + " if (a != b) {}\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void alwaysTrueInfer() { From cd55e0888f74053250ad3f2da092f76ce87cf3c8 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Tue, 4 Aug 2026 01:28:16 -0500 Subject: [PATCH 294/493] Fix 14947: FP algorithmOutOfBounds with array of arrays (#8766) --- lib/astutils.cpp | 11 ++++ lib/astutils.h | 3 + lib/checkbufferoverrun.cpp | 17 +++-- lib/checkstl.cpp | 19 +++++- lib/valueflow.cpp | 52 +++++++++------ lib/vf_analyzers.cpp | 19 +++++- lib/vf_common.cpp | 8 ++- lib/vf_settokenvalue.cpp | 22 +++++++ lib/vfvalue.h | 4 ++ test/testbufferoverrun.cpp | 64 +++++++++++++++++++ test/teststl.cpp | 15 +++++ test/testvalueflow.cpp | 126 +++++++++++++++++++++++++++++++++++++ 12 files changed, 332 insertions(+), 28 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index c99e9b19bd5..25249e7be6f 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1069,6 +1069,17 @@ bool isAliasOf(const Token *tok, nonneg int varid, bool* inconclusive) return false; } +bool isIteratorOf(const Token* tok, nonneg int exprId) +{ + if (!astIsIterator(tok)) + return false; + // An iterator into a subcontainer (e.g. c[0].begin()) aliases the container but iterates + // an unrelated range, so require an iterator value recording the container itself + return std::any_of(tok->values().cbegin(), tok->values().cend(), [&](const ValueFlow::Value& v) { + return v.isIteratorValue() && v.container && v.container->exprId() == exprId; + }); +} + bool isAliasOf(const Token* tok, const Token* expr, nonneg int* indirect) { if (indirect) diff --git a/lib/astutils.h b/lib/astutils.h index 79a607108fd..578763124ac 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -386,6 +386,9 @@ bool isAliasOf(const Token *tok, nonneg int varid, bool* inconclusive = nullptr) bool isAliasOf(const Token* tok, const Token* expr, nonneg int* indirect = nullptr); +/// If token is an iterator into the container expression with the given expression id +bool isIteratorOf(const Token* tok, nonneg int exprId); + const Token* getArgumentStart(const Token* ftok); /** Determines the number of arguments - if token is a function call or macro diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 46d8e1c7c6c..8c8912ed06d 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -230,7 +230,8 @@ static bool getDimensionsEtc(const Token * const arrayToken, const Settings &set const size_t typeSize = array->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, sizeOf); if (typeSize == 0) return false; - dim.num = value->intvalue / typeSize; + // a container size counts elements, a buffer size counts bytes + dim.num = value->isContainerSizeValue() ? value->intvalue : value->intvalue / typeSize; dimensions.emplace_back(dim); } return !dimensions.empty(); @@ -581,9 +582,17 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons if (const ValueFlow::Value *value = getBufferSizeValue(bufTok)) { if (value->isBufferSizeValue()) return *value; - if (value->isContainerSizeValue() && bufTok->valueType() && bufTok->valueType()->containerTypeToken) { - const ValueType vtElement = ValueType::parseDecl(bufTok->valueType()->containerTypeToken, settings); - const size_t elementSize = vtElement.getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); + if (value->isContainerSizeValue() && bufTok->valueType()) { + size_t elementSize = 0; + if (bufTok->valueType()->containerTypeToken) { + const ValueType vtElement = ValueType::parseDecl(bufTok->valueType()->containerTypeToken, settings); + elementSize = + vtElement.getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); + } else if (bufTok->valueType()->pointer == 1) { + elementSize = bufTok->valueType()->getSizeOf(settings, + ValueType::Accuracy::ExactOrZero, + ValueType::SizeOf::Pointee); + } if (elementSize > 0) { ValueFlow::Value bufSizeVal; bufSizeVal.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE; diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 500adc08b01..de1d82792ac 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -765,6 +765,16 @@ static ValueFlow::Value getLifetimeIteratorValue(const Token* tok, MathLib::bigi return ValueFlow::Value{}; } +// Whether a container size value found on an iterator token belongs to the range of the given +// iterator value. Both values record the container they belong to when it is known. +static bool sizeValueAppliesToIterator(const ValueFlow::Value& sizeValue, const ValueFlow::Value& iterValue) +{ + if (!sizeValue.container || !iterValue.container) + return true; // the container of the size or of the iterator is not known + return iterValue.container == sizeValue.container || + (iterValue.container->exprId() != 0 && iterValue.container->exprId() == sizeValue.container->exprId()); +} + bool CheckStlImpl::checkIteratorPair(const Token* tok1, const Token* tok2) { if (!tok1) @@ -2526,6 +2536,8 @@ void CheckStlImpl::checkDereferenceInvalidIterator2() auto it = std::find_if(contValues.cbegin(), contValues.cend(), [&](const ValueFlow::Value& c) { if (value.path != c.path) return false; + if (!sizeValueAppliesToIterator(c, value)) + return false; if (value.isIteratorStartValue() && value.intvalue >= c.intvalue) return true; if (value.isIteratorEndValue() && -value.intvalue > c.intvalue) @@ -3448,7 +3460,8 @@ static IteratorPosition getIteratorPosition(const Token* tok, const Settings& se if (!position.value) return position; position.sizeValue = selectPreferredValue(tok, [&](const ValueFlow::Value& value) { - return isUsableValue(value, settings) && value.isContainerSizeValue() && value.path == position.value->path; + return isUsableValue(value, settings) && value.isContainerSizeValue() && value.path == position.value->path && + sizeValueAppliesToIterator(value, *position.value); }); return position; } @@ -3527,6 +3540,8 @@ static ElementCount findInsufficientSpace(const Token* tok, for (const ValueFlow::Value& sizeValue : tok->values()) { if (!isUsableValue(sizeValue, settings) || !sizeValue.isContainerSizeValue() || sizeValue.path != value.path) continue; + if (!sizeValueAppliesToIterator(sizeValue, value)) + continue; position.sizeValue = &sizeValue; consider(getAvailableSpace(position)); } @@ -3571,6 +3586,8 @@ static ElementCount findExcessiveDistance(const Token* firstTok, if (!isUsableValue(sizeValue, settings) || !sizeValue.isContainerSizeValue() || sizeValue.path != endPosition.value->path) continue; + if (!sizeValueAppliesToIterator(sizeValue, *endPosition.value)) + continue; endPosition.sizeValue = &sizeValue; consider(getIteratorDistance(first, last)); } diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 766f65e9f32..29eb07bcc90 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -401,10 +401,14 @@ void ValueFlow::combineValueProperties(const ValueFlow::Value &value1, const Val result.valueType = value2.valueType; result.tokvalue = value2.tokvalue; } - if (value1.isIteratorValue()) + if (value1.isIteratorValue()) { result.valueType = value1.valueType; - if (value2.isIteratorValue()) + result.container = value1.container; + } + if (value2.isIteratorValue()) { result.valueType = value2.valueType; + result.container = value2.container; + } result.condition = value1.condition ? value1.condition : value2.condition; result.varId = (value1.varId != 0) ? value1.varId : value2.varId; result.varvalue = (result.varId == value1.varId) ? value1.varvalue : value2.varvalue; @@ -3859,11 +3863,14 @@ static void valueFlowForwardConst(Token* start, } else { [&] { // Add the container size to iterators of the container (mirrors ContainerExpressionAnalyzer::match) - if (hasContainerSizeValue && astIsIterator(tok) && isAliasOf(tok, var->declarationId())) { + if (hasContainerSizeValue && isIteratorOf(tok, var->declarationId())) { for (const ValueFlow::Value& value : values) { if (!value.isContainerSizeValue()) continue; - setTokenValue(tok, value, settings); + ValueFlow::Value sizeValue = value; + if (!sizeValue.container) + sizeValue.container = var->nameToken(); + setTokenValue(tok, std::move(sizeValue), settings); } return; } @@ -4212,11 +4219,15 @@ static void valueFlowAfterAssign(const TokenList &tokenlist, values.remove_if([&](const ValueFlow::Value& value) { return types.count(value.valueType) > 0; }); - // Remove container size if its not a container - if (!astIsContainer(tok->astOperand2())) + // Remove container size if its not a container - unless the size records its container + // and flows into a pointer to the container data (e.g. p = v.data()) + if (!astIsContainer(tok->astOperand2())) { + const bool lhsIsPointer = astIsPointer(tok->astOperand1()); values.remove_if([&](const ValueFlow::Value& value) { - return value.valueType == ValueFlow::Value::ValueType::CONTAINER_SIZE; + return value.valueType == ValueFlow::Value::ValueType::CONTAINER_SIZE && + (!value.container || !lhsIsPointer); }); + } // Remove symbolic values that are the same as the LHS values.remove_if([&](const ValueFlow::Value& value) { if (value.isSymbolicValue() && value.tokvalue) @@ -6447,17 +6458,22 @@ static void valueFlowIterators(TokenList& tokenlist, const Settings& settings) const Library::Container::Yield yield = findIteratorYield(tok, ftok, settings.library); if (!ftok) continue; - if (yield == Library::Container::Yield::START_ITERATOR) { - ValueFlow::Value v(0); - v.setKnown(); - v.valueType = ValueFlow::Value::ValueType::ITERATOR_START; - setTokenValue(const_cast(ftok)->next(), std::move(v), settings); - } else if (yield == Library::Container::Yield::END_ITERATOR) { - ValueFlow::Value v(0); - v.setKnown(); - v.valueType = ValueFlow::Value::ValueType::ITERATOR_END; - setTokenValue(const_cast(ftok)->next(), std::move(v), settings); - } + if (yield != Library::Container::Yield::START_ITERATOR && yield != Library::Container::Yield::END_ITERATOR) + continue; + // The iterator value records the container it iterates. A pointer or a reference only + // transports the iterator, so record the container it refers to instead. + const Token* containerTok = tok; + if (astIsPointer(containerTok) || (containerTok->variable() && containerTok->variable()->isReference())) { + const ValueFlow::Value lifetime = ValueFlow::getLifetimeObjValue(containerTok); + if (lifetime.tokvalue && astIsContainer(lifetime.tokvalue) && !astIsPointer(lifetime.tokvalue)) + containerTok = lifetime.tokvalue; + } + ValueFlow::Value v(0); + v.setKnown(); + v.valueType = yield == Library::Container::Yield::START_ITERATOR ? ValueFlow::Value::ValueType::ITERATOR_START + : ValueFlow::Value::ValueType::ITERATOR_END; + v.container = containerTok; + setTokenValue(const_cast(ftok)->next(), std::move(v), settings); } } diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index cfba7d5f970..cc4a6a820cf 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -1299,6 +1299,12 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer { dependOnThis |= exprDependsOnThis(value.tokvalue); setupExprVarIds(value.tokvalue); } + if (value.isContainerSizeValue() && value.container) { + // a container size tracked through another expression (e.g. a pointer obtained from + // data()) is invalidated by writes to the container it belongs to + dependOnThis |= exprDependsOnThis(value.container); + setupExprVarIds(value.container); + } uniqueExprId = expr->isUniqueExprId() && (Token::Match(expr, "%cop%") || !isVariableChanged(expr, 0, s)); } @@ -1503,15 +1509,22 @@ ValuePtr makeMemberExpressionAnalyzer(std::string varname, const Token struct ContainerExpressionAnalyzer : ExpressionAnalyzer { ContainerExpressionAnalyzer(const Token* expr, ValueFlow::Value val, const Settings& s) : ExpressionAnalyzer(expr, std::move(val), s) - {} + { + // The size of a container expression belongs to that expression. Through a pointer the + // size keeps belonging to the container the pointer was obtained from. + if (astIsContainer(expr) && !astIsPointer(expr)) + value.container = expr; + } bool match(const Token* tok) const override { - return tok->exprId() == expr->exprId() || (astIsIterator(tok) && isAliasOf(tok, expr->exprId())); + return tok->exprId() == expr->exprId() || isIteratorOf(tok, expr->exprId()); } Action isWritable(const Token* tok, Direction /*d*/) const override { - if (astIsIterator(tok)) + // only writes to the container itself change its size - not writes through an iterator + // or to a default-inserted element + if (tok->exprId() != expr->exprId()) return Action::None; if (!getValue(tok)) return Action::None; diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index ef48423f38a..f9eecc20fb9 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -404,8 +404,12 @@ namespace ValueFlow return Token::getStrLength(tok); if (astIsGenericChar(tok) || tok->tokType() == Token::eChar) return 1; - if (const Value* v = tok->getKnownValue(Value::ValueType::CONTAINER_SIZE)) - return v->intvalue; + if (const Value* v = tok->getKnownValue(Value::ValueType::CONTAINER_SIZE)) { + // on a pointer the size is the number of elements in the buffer (possibly including + // a null terminator), not the length of the string + if (!astIsPointer(tok)) + return v->intvalue; + } if (const Value* v = tok->getKnownValue(Value::ValueType::TOK)) { if (v->tokvalue != tok) return valueFlowGetStrLength(v->tokvalue, library); diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index aab64170890..9f56b57db0a 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -231,6 +231,11 @@ namespace ValueFlow if (!value.isImpossible() && value.isIntValue()) value = truncateImplicitConversion(tok->astParent(), value, settings); + // a container size value on a container expression belongs to that expression, while a + // pointer or an iterator only transports the size of the container it was obtained from + if (value.isContainerSizeValue() && !astIsPointer(tok) && astIsContainer(tok)) + value.container = tok; + if (settings.debugnormal) setSourceLocation(value, loc, tok); @@ -300,15 +305,32 @@ namespace ValueFlow } } } + // an empty associative container implies that its default-inserted elements are empty as well + if (Token::simpleMatch(parent, "[") && astIsLHS(tok) && astIsContainer(parent) && + tok->valueType()->container && tok->valueType()->container->stdAssociativeLike && + !value.isImpossible() && value.intvalue == 0) + setTokenValue(parent, value, settings); Token* next = nullptr; const Library::Container::Yield yields = getContainerYield(parent, settings.library, next); if (yields == Library::Container::Yield::SIZE) { value.valueType = Value::ValueType::INT; + value.container = nullptr; + setTokenValue(next, std::move(value), settings); + } else if (contains({Library::Container::Yield::BUFFER, + Library::Container::Yield::BUFFER_NT, + Library::Container::Yield::START_ITERATOR, + Library::Container::Yield::END_ITERATOR, + Library::Container::Yield::ITERATOR}, + yields)) { + // The returned pointer or iterator has as many elements available as the container + if (yields == Library::Container::Yield::BUFFER_NT) + value.intvalue += 1; // ..plus the null terminator setTokenValue(next, std::move(value), settings); } else if (yields == Library::Container::Yield::EMPTY) { const Value::Bound bound = value.bound; const long long intvalue = value.intvalue; value.valueType = Value::ValueType::INT; + value.container = nullptr; value.bound = Value::Bound::Point; if (value.isImpossible()) { if (intvalue == 0) diff --git a/lib/vfvalue.h b/lib/vfvalue.h index 8a473143b68..ce33f022e58 100644 --- a/lib/vfvalue.h +++ b/lib/vfvalue.h @@ -322,6 +322,10 @@ namespace ValueFlow /** token value - the token that has the value. this is used for pointer aliases, strings, etc. */ const Token* tokvalue{}; + /** For CONTAINER_SIZE values: the container the size belongs to, when the value is + * attached to a token that is not the container itself (an iterator or a pointer) */ + const Token* container = nullptr; + /** float value */ double floatValue{}; diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 37ab7083902..8bac50a468c 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -197,6 +197,7 @@ class TestBufferOverrun : public TestFixture { TEST_CASE(array_index_function_parameter); TEST_CASE(array_index_enum_array); // #8439 TEST_CASE(array_index_container); // #9386 + TEST_CASE(array_index_container_data); // pointer from data()/c_str() carries the container size TEST_CASE(array_index_two_for_loops); TEST_CASE(array_index_new); // #7690 @@ -2902,6 +2903,69 @@ class TestBufferOverrun : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void array_index_container_data() + { + check("void f() {\n" + " std::vector v(3);\n" + " int* p = v.data();\n" + " p[2] = 1;\n" + "}"); + ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" + " std::vector v(3);\n" + " int* p = v.data();\n" + " p[5] = 1;\n" + "}"); + ASSERT_EQUALS( + "[test.cpp:4:6]: (error) Array 'p[3]' accessed at index 5, which is out of bounds. [arrayIndexOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " std::vector v(3);\n" + " memset(v.data(), 0, 12);\n" + " memset(v.data(), 0, 100);\n" + "}"); + ASSERT_EQUALS("[test.cpp:4:18]: (error) Buffer is accessed out of bounds: v.data() [bufferAccessOutOfBounds]\n", + errout_str()); + + check("void f() {\n" + " std::vector v(3);\n" + " int* p = v.data();\n" + " memset(p, 0, 100);\n" + "}"); + ASSERT_EQUALS("[test.cpp:4:12]: (error) Buffer is accessed out of bounds: p [bufferAccessOutOfBounds]\n", + errout_str()); + + // the size is not tracked past changes of the container size + check("void f() {\n" + " std::vector v(3);\n" + " v.reserve(100);\n" + " int* p = v.data();\n" + " v.resize(10);\n" + " memset(p, 0, 40);\n" + "}"); + ASSERT_EQUALS("", errout_str()); + + // ..or when the pointer is reassigned + check("void f(int* q) {\n" + " std::vector v(3);\n" + " int* p = v.data();\n" + " p = q;\n" + " memset(p, 0, 100);\n" + "}"); + ASSERT_EQUALS("", errout_str()); + + // the buffer of c_str() includes the null terminator + check("void f(char* dst) {\n" + " std::string s = \"abc\";\n" + " memcpy(dst, s.c_str(), 4);\n" + " memcpy(dst, s.c_str(), 5);\n" + "}"); + ASSERT_EQUALS("[test.cpp:4:24]: (error) Buffer is accessed out of bounds: s.c_str() [bufferAccessOutOfBounds]\n", + errout_str()); + } + void array_index_two_for_loops() { check("bool b();\n" "void f()\n" diff --git a/test/teststl.cpp b/test/teststl.cpp index c030fb4c6f6..2570059c19e 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -2798,6 +2798,21 @@ class TestStl : public TestFixture { ASSERT_EQUALS( "[test.cpp:4:24]: (error) The algorithm 'std::fill_n' accesses 10 elements through the iterator 'v.begin()' but only 5 elements are available. [algorithmOutOfBounds]\n", errout_str()); + + // an iterator into a nested container does not carry the outer container's size + check("std::array, 1> f(const std::array& a) {\n" + " std::array, 1> res;\n" + " std::copy(a.begin(), a.end(), res[0].begin());\n" + " return res;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" + " const std::vector v0{1,2,3};\n" + " std::vector> v1(1, std::vector(5));\n" + " std::copy(v0.begin(), v0.end(), v1[0].begin());\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } // Dereferencing invalid pointer diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index c98680b8180..f92ddee3685 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -517,6 +517,22 @@ class TestValueFlow : public TestFixture { return values; } + // The expression of the container recorded by the container size value of the token. The + // container token has to be resolved while the tokenizer is alive. +#define containerOfSizeValue(...) containerOfSizeValue_(__FILE__, __LINE__, __VA_ARGS__) + std::string containerOfSizeValue_(const char* file, int line, const char code[], const char tokstr[]) { + SimpleTokenizer tokenizer(settings, *this); + ASSERT_LOC(tokenizer.tokenize(code), file, line); + const Token* tok = Token::findmatch(tokenizer.tokens(), tokstr); + if (!tok) + return ""; + const std::list& values = tok->values(); + const auto it = std::find_if(values.cbegin(), values.cend(), [](const ValueFlow::Value& v) { + return v.isContainerSizeValue() && v.container; + }); + return it == values.cend() ? "" : it->container->expressionString(); + } + #define lifetimeValues(...) lifetimeValues_(__FILE__, __LINE__, __VA_ARGS__) template std::vector lifetimeValues_(const char* file, int line, const char (&code)[size], const char tokstr[]) { @@ -7682,6 +7698,93 @@ class TestValueFlow : public TestFixture { " if (m.empty()) {}\n" "}\n"; ASSERT(!isKnownContainerSizeValue(tokenValues(code, "m ."), 0).empty()); + + // the pointer returned by data() carries the container size + code = "int f() {\n" + " std::vector v(3);\n" + " int* p = v.data();\n" + " return p[1];\n" + "}"; + ASSERT_EQUALS("", + isKnownContainerSizeValue(tokenValues(code, "p [", ValueFlow::Value::ValueType::CONTAINER_SIZE), 3)); + + // ..which is invalidated when the container size changes + code = "int f() {\n" + " std::vector v(3);\n" + " int* p = v.data();\n" + " v.push_back(1);\n" + " return p[1];\n" + "}"; + ASSERT_EQUALS(0U, tokenValues(code, "p [", ValueFlow::Value::ValueType::CONTAINER_SIZE).size()); + + // the buffer of c_str() includes the null terminator + code = "const char* f() {\n" + " std::string s = \"abc\";\n" + " const char* p = s.c_str();\n" + " return p + 3;\n" + "}"; + ASSERT_EQUALS("", + isKnownContainerSizeValue(tokenValues(code, "p +", ValueFlow::Value::ValueType::CONTAINER_SIZE), 4)); + + code = "const char* f() {\n" + " std::string s = \"abc\";\n" + " return s.c_str();\n" + "}"; + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "( ) ;", ValueFlow::Value::ValueType::CONTAINER_SIZE), 4)); + + // the size value of a data() pointer records the container the size belongs to + code = "int* f() {\n" + " std::vector v(3);\n" + " return v.data();\n" + "}"; + ASSERT_EQUALS("", + isKnownContainerSizeValue(tokenValues(code, "( ) ;", ValueFlow::Value::ValueType::CONTAINER_SIZE), + 3)); + ASSERT_EQUALS("v", containerOfSizeValue(code, "( ) ;")); + + // an empty associative container implies that its default-inserted elements are empty as well + code = "void f(const std::string& k) {\n" + " std::map> m;\n" + " m[k].front();\n" + "}"; + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "[ k ] . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), + 0)); + ASSERT_EQUALS("m[k]", containerOfSizeValue(code, "[ k ] . front")); + + // ..also for nested associative containers.. + code = "void f(int a, int b) {\n" + " std::map>> m;\n" + " m[a][b].front();\n" + "}"; + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "[ b ] . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 0)); + + // ..but not for non-associative containers.. + code = "void f(int i) {\n" + " std::vector> v;\n" + " v[i].front();\n" + "}"; + ASSERT_EQUALS(0U, tokenValues(code, "[ i ] . front", ValueFlow::Value::ValueType::CONTAINER_SIZE).size()); + + // ..nor when the container is not empty.. + code = "void f(std::map>& m, const std::string& k) {\n" + " if (m.size() == 1)\n" + " m[k].front();\n" + "}"; + ASSERT_EQUALS(0U, tokenValues(code, "[ k ] . front", ValueFlow::Value::ValueType::CONTAINER_SIZE).size()); + + // ..nor when the container was modified + code = "void f(const std::string& k) {\n" + " std::map> m;\n" + " m[\"a\"].push_back(1);\n" + " m[k].front();\n" + "}"; + ASSERT_EQUALS(0U, tokenValues(code, "[ k ] . front", ValueFlow::Value::ValueType::CONTAINER_SIZE).size()); } void valueFlowContainerSizeIterator() { @@ -7723,6 +7826,29 @@ class TestValueFlow : public TestFixture { " if (it != w.end()) {}\n" "}"; ASSERT(tokenValues(code, "it !=", ValueFlow::Value::ValueType::CONTAINER_SIZE).empty()); + + // iterators created from the container carry the container size + code = "bool f() {\n" + " std::vector v(3);\n" + " return v.begin() != v.end();\n" + "}"; + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "( ) !=", ValueFlow::Value::ValueType::CONTAINER_SIZE), 3)); + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "( ) ;", ValueFlow::Value::ValueType::CONTAINER_SIZE), 3)); + + // the size value records the container it belongs to + code = "void f() {\n" + " std::vector v(3);\n" + " auto it = v.begin();\n" + " if (it != v.end()) {}\n" + "}"; + ASSERT_EQUALS( + "", + isKnownContainerSizeValue(tokenValues(code, "it !=", ValueFlow::Value::ValueType::CONTAINER_SIZE), 3)); + ASSERT_EQUALS("v", containerOfSizeValue(code, "it !=")); } void valueFlowContainerElement() From dbde18971103bb5bcf87191c391f75486cd8ca12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 4 Aug 2026 16:45:22 +0200 Subject: [PATCH 295/493] Fix #14946: `originalName` in dumpfile missing for local typedefs (#8760) --- lib/tokenize.cpp | 1 + test/testincompletestatement.cpp | 2 +- test/testsimplifytypedef.cpp | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 07ffa4c666c..610877eec53 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2044,6 +2044,7 @@ void Tokenizer::simplifyTypedefCpp() tok2->previous()->str("typedef"); tok2->insertToken(tok2->str()); } + tok2->originalName(tok2->str()); tok2->str(typeStart->str()); // restore qualification if it was removed diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index da238d304b2..72a13ee6c42 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -492,7 +492,7 @@ class TestIncompleteStatement : public TestFixture { "void f(int i) {\n" " (M::N::T)i;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5:5]: (warning) Redundant code: Found unused cast in expression '(char)i'. [constStatement]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:5]: (warning) Redundant code: Found unused cast in expression '(T)i'. [constStatement]\n", errout_str()); check("void f(int (g)(int a, int b)) {\n" // #10873 " int p = 0, q = 1;\n" diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 42718a2f99c..e83be343e01 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -256,6 +256,7 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedefOriginalName1); TEST_CASE(simplifyTypedefOriginalName2); + TEST_CASE(simplifyTypedefOriginalName3); TEST_CASE(simplifyTypedefTokenColumn1); TEST_CASE(simplifyTypedefTokenColumn2); @@ -4600,6 +4601,21 @@ class TestSimplifyTypedef : public TestFixture { ASSERT_EQUALS("A", token->originalName()); } + void simplifyTypedefOriginalName3() { + const char code[] = "void f(void) {\n" + " typedef int A;\n" + " A a;\n" + "}\n"; + TokenList tokenlist{ settings1, Standards::Language::C }; + ASSERT(TokenListHelper::createTokensFromString(tokenlist, code, "file.c")); + TokenizerTest tokenizer(std::move(tokenlist), *this); + tokenizer.createLinks(); + tokenizer.simplifyTypedef(); + ASSERT_NO_THROW(tokenizer.validate()); + const Token* token = Token::findsimplematch(tokenizer.list.front(), "int"); + ASSERT_EQUALS("A", token->originalName()); + } + void simplifyTypedefTokenColumn1() { // #13155 const char code[] = "void foo(void) {\n" " typedef signed int MY_INT;\n" From 1a96ce880c07919f85dce30fa02ffc3848f74721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 4 Aug 2026 16:48:56 +0200 Subject: [PATCH 296/493] Fix #14918: fuzzing crash (stack-overflow) in findTokensSkipDeadCodeImpl() (#8732) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Marjamäki --- lib/tokenize.cpp | 3 +++ .../crash-9feb09f580c0cf101456c6c650ab4193b1009d07 | 1 + 2 files changed, 4 insertions(+) create mode 100644 test/cli/fuzz-crash_c/crash-9feb09f580c0cf101456c6c650ab4193b1009d07 diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 610877eec53..8382c09e785 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8814,6 +8814,9 @@ void Tokenizer::findGarbageCode() const if (!cpp || mSettings.standards.cpp < Standards::CPP20 || !Token::Match(tok->previous(), "%name% : %num% =")) syntaxError(tok, tok->strAt(1) + " " + tok->strAt(2)); } + else if (!cpp && Token::Match(tok, "++|-- ++|--")) { + syntaxError(tok, tok->str() + tok->strAt(1)); + } else if (Token::simpleMatch(tok, ") return") && !Token::Match(tok->link()->previous(), "if|while|for (")) { if (tok->link()->previous() && tok->link()->previous()->isUpperCaseName()) unknownMacroError(tok->link()->previous()); diff --git a/test/cli/fuzz-crash_c/crash-9feb09f580c0cf101456c6c650ab4193b1009d07 b/test/cli/fuzz-crash_c/crash-9feb09f580c0cf101456c6c650ab4193b1009d07 new file mode 100644 index 00000000000..8577d6ccb7f --- /dev/null +++ b/test/cli/fuzz-crash_c/crash-9feb09f580c0cf101456c6c650ab4193b1009d07 @@ -0,0 +1 @@ +d(){e?&d=d++++F:a} \ No newline at end of file From 933246d2ad5b7972a2886608142be3e69df3f530 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Tue, 4 Aug 2026 10:08:26 -0500 Subject: [PATCH 297/493] Add unit tests for cppcheckdata.py (#8707) This adds unit tests for cppcheckdata.py which runs with pytest. It will also run these tests with cmake automatically if python is available, so this should run on the CI. The unit tests did surface a couple of problems, but I didnt fix it this PR to keep the scope smaller. Instead I just marked the test with `pytest.mark.xfail` for now. I can do a follow up PR to fix these issues: 1. `Token.isBoolean` is dead code. `Tokenizer::dump` (lib/tokenize.cpp:6179) checks `tok->isName()` before `isBoolean()`, and `eBoolean` tokens count as names (lib/token.h:397), so true/false are always dumped as `type="name"` and the `type="boolean"` branch at tokenize.cpp:6199 is unreachable for them(I see there is `TODO: "true"/"false" aren't really a name...`) 2. Line suppressions match every line. The final "other suppression" fallback in `Suppression.isMatch()` (cppcheckdata.py:1007) doesn't check that `lineNumber` is unset, so a suppression for line 5 also matches line 6. The fix would be a one-line `self.lineNumber is None` guard. 3. In C++ `Token::Match`, `!!x` also matches when there is no token at all (null), but Python `match()` fails when the token list ends: `match(last_brace, '} !!x')` returns false. --------- Co-authored-by: Your Name --- test/CMakeLists.txt | 2 + test/addon/CMakeLists.txt | 41 ++ test/addon/conftest.py | 201 +++++++ test/addon/requirements.txt | 1 + test/addon/test_cppcheckdata.py | 915 ++++++++++++++++++++++++++++++++ test/cli/performance_test.py | 2 +- 6 files changed, 1161 insertions(+), 1 deletion(-) create mode 100644 test/addon/CMakeLists.txt create mode 100644 test/addon/conftest.py create mode 100644 test/addon/requirements.txt create mode 100644 test/addon/test_cppcheckdata.py diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 14f3a8eac17..f1e59e17daf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -47,6 +47,8 @@ if (BUILD_TESTING) if (REGISTER_TESTS) # CMAKE_MATCH_ usage for if (MATCHES) requires CMake 3.9 + add_subdirectory(addon) + find_package(Threads REQUIRED) include(ProcessorCount) ProcessorCount(N) diff --git a/test/addon/CMakeLists.txt b/test/addon/CMakeLists.txt new file mode 100644 index 00000000000..bb04afb6c51 --- /dev/null +++ b/test/addon/CMakeLists.txt @@ -0,0 +1,41 @@ +if (NOT Python_Interpreter_FOUND) + message(WARNING "Python interpreter not found - skipping addon tests.") + return() +endif() + +# creating a virtual environment needs the venv and ensurepip modules - some +# distributions ship them separately from the interpreter (e.g. the Debian/Ubuntu +# python3-venv package) +execute_process(COMMAND ${Python_EXECUTABLE} -c "import venv, ensurepip" + RESULT_VARIABLE PYTHON_VENV_RESULT + OUTPUT_QUIET + ERROR_QUIET) +if (NOT PYTHON_VENV_RESULT EQUAL 0) + message(WARNING "Python venv module not available (e.g. install the python3-venv package) - skipping addon tests.") + return() +endif() + +set(VENV_DIR ${CMAKE_CURRENT_BINARY_DIR}/venv) +if (WIN32) + set(VENV_PYTHON ${VENV_DIR}/Scripts/python.exe) +else() + set(VENV_PYTHON ${VENV_DIR}/bin/python) +endif() + +# fixture: create a virtual environment and install the python dependencies into it +add_test(NAME addon-venv-create + COMMAND ${Python_EXECUTABLE} -m venv ${VENV_DIR}) +set_tests_properties(addon-venv-create PROPERTIES + FIXTURES_SETUP addon-venv-dir) + +add_test(NAME addon-venv-install + COMMAND ${VENV_PYTHON} -m pip install -r ${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt) +set_tests_properties(addon-venv-install PROPERTIES + FIXTURES_REQUIRED addon-venv-dir + FIXTURES_SETUP addon-venv + TIMEOUT 300) + +add_test(NAME addon-cppcheckdata + COMMAND ${VENV_PYTHON} -m pytest --cppcheck-binary=$ ${CMAKE_CURRENT_SOURCE_DIR}) +set_tests_properties(addon-cppcheckdata PROPERTIES + FIXTURES_REQUIRED addon-venv) diff --git a/test/addon/conftest.py b/test/addon/conftest.py new file mode 100644 index 00000000000..87012983951 --- /dev/null +++ b/test/addon/conftest.py @@ -0,0 +1,201 @@ +"""pytest configuration for the addon tests. + +The tests exercise addons/cppcheckdata.py against dump files that are +generated on the fly with the cppcheck binary given by --cppcheck-binary. +""" +import os +import shutil +import subprocess +import sys + +import pytest + +# Make 'import cppcheckdata' resolve to /addons/cppcheckdata.py +_ADDONS_DIR = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'addons')) +if _ADDONS_DIR not in sys.path: + sys.path.insert(0, _ADDONS_DIR) + + +def pytest_addoption(parser): + parser.addoption('--cppcheck-binary', + default='cppcheck', + help='path to the cppcheck binary used to generate dump files ' + '(default: cppcheck found in PATH)') + + +@pytest.fixture(scope='session') +def cppcheck_binary(request): + binary = request.config.getoption('--cppcheck-binary') + resolved = shutil.which(binary) + if resolved is None: + pytest.fail("cppcheck binary '%s' not found - point --cppcheck-binary at a cppcheck executable" % binary) + return os.path.abspath(resolved) + + +class DumpFactory: + """Runs 'cppcheck --dump' on a source snippet and parses the result.""" + + def __init__(self, binary, tmp_path_factory): + self.binary = binary + self.tmp_path_factory = tmp_path_factory + + def create(self, code, filename='test.c', extra_args=()): + """Write the code to a file, dump it and return the dump file path.""" + directory = self.tmp_path_factory.mktemp('cppcheckdata') + path = directory / filename + path.write_text(code) + cmd = [self.binary, '--dump', '--quiet', str(path)] + list(extra_args) + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=True, + universal_newlines=True) + assert proc.returncode == 0, \ + 'cppcheck failed with exit code %d:\n%s\n%s' % (proc.returncode, proc.stdout, proc.stderr) + return str(path) + '.dump' + + def parse(self, code, filename='test.c', extra_args=()): + """Write the code to a file, dump it and return the parsed CppcheckData.""" + import cppcheckdata + return cppcheckdata.parsedump(self.create(code, filename, extra_args)) + + +@pytest.fixture(scope='session') +def dump_factory(cppcheck_binary, tmp_path_factory): + return DumpFactory(cppcheck_binary, tmp_path_factory) + + +SAMPLE_C = """#define ANSWER 42 +static int add(int a, int b) +{ + return a + b; +} + +double half(double d) +{ + return d / 2.0; +} + +int main(void) +{ + int x = ANSWER; + int arr[10]; + arr[0] = add(x, 1); + int neg = -x; + return arr[0] + neg; +} +""" + +SAMPLE_CPP = """namespace ns { + int twice(int v) { return 2 * v; } +} + +class Shape { +public: + virtual ~Shape() {} + virtual double area() const = 0; +protected: + double mScale; +}; + +enum Color { RED, GREEN }; + +const int limit = 5; +bool flag = true; +const char *msg = "hello"; +char ch = 'x'; + +int run() +{ + Color color = RED; + if (flag && limit > 1) { + return ns::twice(21); + } + return static_cast(color); +} +""" + +MULTI_CFG_C = """typedef int myint; +typedef float myfloat; +#if defined(FOO) && FOO > 1 +int foo(void) { return 1; } +#endif +myint bar(void) { myint y = 3; return y; } +""" + +MATCH_C = """struct Point { + int x; + int y; +}; + +int calc(int a, int b) +{ + int bit_or = a | b; + int log_or = a || b; + int mod = a % b; + int mul = a * b; + int not_a = !a; + int neq = a != b; + int arr[3]; + arr[0] = a; + a += 1; + if (a > b) { + return a; + } + return calc(a, b); +} +""" + +MATCH_CPP = """class Widget {}; + +bool use(int i, int j) +{ + std::vector v; + bool less = i < j; + return less && v.empty(); +} +""" + + +@pytest.fixture(scope='session') +def sample_data(dump_factory): + """Parsed dump of the canonical C sample.""" + return dump_factory.parse(SAMPLE_C, filename='sample.c') + + +@pytest.fixture(scope='session') +def sample_cfg(sample_data): + cfgs = sample_data.configurations + assert len(cfgs) == 1 + return cfgs[0] + + +@pytest.fixture(scope='session') +def sample_cpp_data(dump_factory): + """Parsed dump of the canonical C++ sample.""" + return dump_factory.parse(SAMPLE_CPP, filename='sample.cpp') + + +@pytest.fixture(scope='session') +def sample_cpp_cfg(sample_cpp_data): + cfgs = sample_cpp_data.configurations + assert len(cfgs) == 1 + return cfgs[0] + + +@pytest.fixture(scope='session') +def multi_cfg_data(dump_factory): + """Parsed dump of a file with two preprocessor configurations.""" + return dump_factory.parse(MULTI_CFG_C, filename='multi.c') + + +@pytest.fixture(scope='session') +def match_cfg(dump_factory): + """Configuration of a C sample covering the match() pattern syntax.""" + return dump_factory.parse(MATCH_C, filename='match.c').configurations[0] + + +@pytest.fixture(scope='session') +def match_cpp_cfg(dump_factory): + """Configuration of a C++ sample with linked '<' tokens for match().""" + return dump_factory.parse(MATCH_CPP, filename='match.cpp').configurations[0] diff --git a/test/addon/requirements.txt b/test/addon/requirements.txt new file mode 100644 index 00000000000..e079f8a6038 --- /dev/null +++ b/test/addon/requirements.txt @@ -0,0 +1 @@ +pytest diff --git a/test/addon/test_cppcheckdata.py b/test/addon/test_cppcheckdata.py new file mode 100644 index 00000000000..0ff3f31a89d --- /dev/null +++ b/test/addon/test_cppcheckdata.py @@ -0,0 +1,915 @@ +"""Unit tests for addons/cppcheckdata.py + +Most tests parse dump files generated with the cppcheck binary +(see conftest.py); tests of pure helper classes construct the +objects directly from dicts (which provide the same .get() API +as the XML elements). +""" +import json +import sys + +import pytest + +import cppcheckdata + + +def find_tokens(cfg, token_str): + return [tok for tok in cfg.tokenlist if tok.str == token_str] + + +def find_token(cfg, token_str, skip=0): + tokens = find_tokens(cfg, token_str) + assert len(tokens) > skip, "token '%s' (skip=%d) not found" % (token_str, skip) + return tokens[skip] + + +def find_function(cfg, name): + for function in cfg.functions: + if function.name == name: + return function + assert False, "function '%s' not found" % name + + +def find_scope(cfg, scope_type, className=None): + for scope in cfg.scopes: + if scope.type == scope_type and (className is None or scope.className == className): + return scope + assert False, "scope '%s' not found" % scope_type + + +def find_variable(cfg, name): + for variable in cfg.variables: + if variable.nameToken and variable.nameToken.str == name: + return variable + assert False, "variable '%s' not found" % name + + +class TestCppcheckData: + def test_language(self, sample_data, sample_cpp_data): + assert sample_data.language == 'c' + assert sample_cpp_data.language == 'cpp' + + def test_platform(self, sample_data): + platform = sample_data.platform + assert platform.name + assert platform.char_bit == 8 + assert platform.short_bit >= 16 + assert platform.int_bit >= 16 + assert platform.long_bit >= 32 + assert platform.long_long_bit >= 64 + assert platform.pointer_bit > 0 + assert 'char_bit=8' in repr(platform) + + def test_files(self, sample_data): + assert len(sample_data.files) == 1 + assert sample_data.files[0].endswith('sample.c') + + def test_rawtokens(self, sample_data): + raw = sample_data.rawTokens + # the not yet preprocessed code contains the directive tokens + assert [tok.str for tok in raw[:4]] == ['#', 'define', 'ANSWER', '42'] + assert raw[-1].str == '}' + assert raw[0].file.endswith('sample.c') + assert raw[0].linenr == 1 + # next/previous chain + assert raw[0].previous is None + assert raw[-1].next is None + for i in range(len(raw) - 1): + assert raw[i].next is raw[i + 1] + assert raw[i + 1].previous is raw[i] + + def test_configurations(self, sample_data): + cfgs = sample_data.configurations + assert len(cfgs) == 1 + assert cfgs[0].name == '' + + def test_iterconfigurations(self, multi_cfg_data): + it = multi_cfg_data.iterconfigurations() + cfgs = list(it) + assert len(cfgs) == 2 + assert cfgs[0].name == '' + assert 'FOO' in cfgs[1].name + # 'foo()' is only tokenized in the FOO configuration + assert not find_tokens(cfgs[0], 'foo') + assert find_tokens(cfgs[1], 'foo') + + def test_standards(self, sample_cfg, sample_cpp_cfg): + assert sample_cfg.standards.c.startswith('c') + assert sample_cpp_cfg.standards.cpp.startswith('c++') + assert sample_cfg.standards.posix is False + assert 'c=' in repr(sample_cfg.standards) + + +class TestToken: + def test_tokenlist(self, sample_cfg): + code = ' '.join(tok.str for tok in sample_cfg.tokenlist) + assert 'static int add ( int a , int b )' in code + # the macro has been expanded + assert 'x = 42' in code + + def test_next_previous(self, sample_cfg): + tokens = sample_cfg.tokenlist + assert tokens[0].previous is None + assert tokens[-1].next is None + for i in range(len(tokens) - 1): + assert tokens[i].next is tokens[i + 1] + assert tokens[i + 1].previous is tokens[i] + + def test_location(self, sample_cfg): + tok = sample_cfg.tokenlist[0] + assert tok.str == 'static' + assert tok.file.endswith('sample.c') + assert tok.linenr == 2 + assert tok.column == 1 + + def test_link(self, sample_cfg): + parenthesis = find_token(sample_cfg, '(') + assert parenthesis.link.str == ')' + assert parenthesis.link.link is parenthesis + bracket = find_token(sample_cfg, '[') + assert bracket.link.str == ']' + brace = find_token(sample_cfg, '{') + assert brace.link.str == '}' + + def test_scope(self, sample_cfg): + assert sample_cfg.tokenlist[0].scope.type == 'Global' + return_tok = find_token(sample_cfg, 'return') + assert return_tok.scope.type == 'Function' + assert return_tok.scope.className == 'add' + + def test_name_number_flags(self, sample_cfg): + name_tok = find_token(sample_cfg, 'main') + assert name_tok.isName + assert not name_tok.isNumber + num_tok = find_token(sample_cfg, '42') + assert num_tok.isNumber + assert num_tok.isInt + assert not num_tok.isFloat + float_tok = find_token(sample_cfg, '2.0') + assert float_tok.isNumber + assert float_tok.isFloat + + def test_operator_flags(self, sample_cfg, sample_cpp_cfg): + plus = find_token(sample_cfg, '+') + assert plus.isOp + assert plus.isArithmeticalOp + assign = find_token(sample_cfg, '=') + assert assign.isOp + assert assign.isAssignmentOp + logical = find_token(sample_cpp_cfg, '&&') + assert logical.isOp + assert logical.isLogicalOp + comparison = find_token(sample_cpp_cfg, '>') + assert comparison.isOp + assert comparison.isComparisonOp + + def test_string_char(self, sample_cpp_cfg): + string_tok = find_token(sample_cpp_cfg, '"hello"') + assert string_tok.isString + assert string_tok.strlen == 5 + char_tok = find_token(sample_cpp_cfg, "'x'") + assert char_tok.isChar + + @pytest.mark.xfail(strict=False, + reason='Tokenizer::dump checks Token::isName() before Token::isBoolean() and ' + 'eBoolean tokens are names, so type="boolean" is never dumped') + def test_boolean(self, sample_cpp_cfg): + bool_tok = find_token(sample_cpp_cfg, 'true') + assert bool_tok.isBoolean + + def test_cast(self, sample_cpp_cfg): + # static_cast(...) is simplified to a C-style cast + assert any(tok.isCast for tok in sample_cpp_cfg.tokenlist) + + def test_macro_expansion(self, sample_cfg): + tok = find_token(sample_cfg, '42') + assert tok.isExpandedMacro + assert tok.macroName == 'ANSWER' + + def test_removed_void_parameter(self, sample_cfg): + main_tok = find_token(sample_cfg, 'main') + assert main_tok.next.isRemovedVoidParameter + + def test_splitted_var_decl(self, sample_cfg): + # 'int x = ANSWER;' is simplified to 'int x ; x = 42 ;' + assert any(tok.isSplittedVarDeclEq for tok in sample_cfg.tokenlist) + + def test_variable_and_var_id(self, sample_cfg): + x_decl = find_token(sample_cfg, 'x') + assert x_decl.varId + assert x_decl.variable.nameToken is x_decl + # all 'x' tokens refer to the same variable and varId + for tok in find_tokens(sample_cfg, 'x'): + assert tok.varId == x_decl.varId + assert tok.variable is x_decl.variable + + def test_function(self, sample_cfg): + add_call = find_token(sample_cfg, 'add', skip=1) + assert add_call.function + assert add_call.function.name == 'add' + + def test_value_type(self, sample_cfg): + x_tok = find_token(sample_cfg, 'x') + assert x_tok.valueType.type == 'int' + assert x_tok.valueType.sign == 'signed' + assert x_tok.valueType.pointer == 0 + assert x_tok.valueType.isIntegral() + assert not x_tok.valueType.isFloat() + assert not x_tok.valueType.isEnum() + d_tok = find_token(sample_cfg, 'd') + assert d_tok.valueType.type == 'double' + assert d_tok.valueType.isFloat() + # in 'arr[0] = ...' the array decays to a pointer + arr_use = find_token(sample_cfg, 'arr', skip=1) + assert arr_use.valueType.pointer == 1 + + def test_value_type_enum(self, sample_cpp_cfg): + color_tok = find_token(sample_cpp_cfg, 'color') + assert color_tok.valueType.isEnum() + assert color_tok.valueType.typeScope.className == 'Color' + + def test_ast(self, sample_cfg): + plus = find_token(sample_cfg, '+') + assert plus.astOperand1.str == 'a' + assert plus.astOperand2.str == 'b' + assert plus.astParent.str == 'return' + assert plus.isBinaryOp() + assert not plus.isUnaryOp('+') + + def test_ast_unary_op(self, sample_cfg): + # the '-' in 'int neg = -x;' + minus = find_token(sample_cfg, '-') + assert minus.isUnaryOp('-') + assert not minus.isBinaryOp() + assert minus.astOperand1.str == 'x' + assert minus.astOperand2 is None + + def test_ast_parents_top(self, sample_cfg): + a_tok = find_token(sample_cfg, 'a', skip=1) # the 'a' in 'return a + b;' + assert [tok.str for tok in a_tok.astParents()] == ['+', 'return'] + assert a_tok.astTop().str == 'return' + + def test_values(self, sample_cfg): + # 'x' has the known value 42 when it is used + x_use = find_token(sample_cfg, 'x', skip=2) + assert x_use.getKnownIntValue() == 42 + value = x_use.getValue(42) + assert value.intvalue == 42 + assert value.isKnown() + assert not value.isPossible() + assert x_use.getValue(43) is None + assert 'intvalue=42' in repr(value) + + def test_values_possible(self, sample_cfg): + # inside add() the argument 'a' has the possible value 42 + a_use = find_token(sample_cfg, 'a', skip=1) + assert a_use.getKnownIntValue() is None + value = a_use.getValue(42) + assert value is not None + assert value.isPossible() + + def test_impossible_values(self, sample_cfg): + # impossible values are separated from the possible/known ones + arr_tokens = find_tokens(sample_cfg, 'arr') + impossible = [v for tok in arr_tokens for v in tok.impossible_values] + assert impossible + assert all(v.isImpossible() for v in impossible) + possible_or_known = [v for tok in arr_tokens for v in tok.values] + assert all(not v.isImpossible() for v in possible_or_known) + + def test_forward_backward(self, sample_cfg): + add_def = find_token(sample_cfg, 'add') + strs = [tok.str for tok in add_def.forward()] + assert strs[:4] == ['add', '(', 'int', 'a'] + end = add_def.tokAt(2) + assert [tok.str for tok in add_def.forward(end=end)] == ['add', '('] + strs = [tok.str for tok in add_def.backward()] + assert strs[:3] == ['add', 'int', 'static'] + start = sample_cfg.tokenlist[0] + assert [tok.str for tok in add_def.backward(start=start)] == ['add', 'int'] + + def test_tokAt_linkAt(self, sample_cfg): + add_def = find_token(sample_cfg, 'add') + assert add_def.tokAt(0) is add_def + assert add_def.tokAt(1).str == '(' + assert add_def.tokAt(-1).str == 'int' + assert add_def.linkAt(1).str == ')' + + def test_repr(self, sample_cfg): + tok = sample_cfg.tokenlist[0] + assert "str='static'" in repr(tok) + + +class TestScope: + def test_scopes(self, sample_cfg): + types = [scope.type for scope in sample_cfg.scopes] + assert types.count('Global') == 1 + assert types.count('Function') == 3 + + def test_global_scope(self, sample_cfg): + global_scope = find_scope(sample_cfg, 'Global') + assert global_scope.nestedIn is None + assert not global_scope.isExecutable + assert len(global_scope.nestedList) == 3 + + def test_function_scope(self, sample_cfg): + scope = find_scope(sample_cfg, 'Function', className='add') + assert scope.bodyStart.str == '{' + assert scope.bodyEnd.str == '}' + assert scope.bodyStart.link is scope.bodyEnd + assert scope.nestedIn.type == 'Global' + assert scope.function.name == 'add' + assert scope.isExecutable + + def test_varlist(self, sample_cfg): + scope = find_scope(sample_cfg, 'Function', className='main') + names = [var.nameToken.str for var in scope.varlist] + assert names == ['x', 'arr', 'neg'] + + def test_cpp_scopes(self, sample_cpp_cfg): + types = {scope.type for scope in sample_cpp_cfg.scopes} + assert {'Global', 'Namespace', 'Class', 'Enum', 'Function', 'If'} <= types + assert find_scope(sample_cpp_cfg, 'Namespace', className='ns') + assert find_scope(sample_cpp_cfg, 'Class', className='Shape') + if_scope = find_scope(sample_cpp_cfg, 'If') + assert if_scope.isExecutable + class_scope = find_scope(sample_cpp_cfg, 'Class') + assert not class_scope.isExecutable + + +class TestFunction: + def test_functions(self, sample_cfg): + names = {function.name for function in sample_cfg.functions} + assert names == {'add', 'half', 'main'} + + def test_arguments(self, sample_cfg): + add = find_function(sample_cfg, 'add') + assert sorted(add.argument.keys()) == [1, 2] + assert add.argument[1].nameToken.str == 'a' + assert add.argument[2].nameToken.str == 'b' + main = find_function(sample_cfg, 'main') + assert main.argument == {} + + def test_attributes(self, sample_cfg): + add = find_function(sample_cfg, 'add') + assert add.isStatic + assert add.type == 'Function' + assert add.tokenDef.str == 'add' + assert add.token.str == 'add' + assert add.nestedIn.type == 'Global' + main = find_function(sample_cfg, 'main') + assert not main.isStatic + + def test_virtual(self, sample_cpp_cfg): + area = find_function(sample_cpp_cfg, 'area') + assert area.hasVirtualSpecifier + twice = find_function(sample_cpp_cfg, 'twice') + assert not twice.hasVirtualSpecifier + assert twice.nestedIn.className == 'ns' + + +class TestVariable: + def test_local(self, sample_cfg): + x = find_variable(sample_cfg, 'x') + assert x.access == 'Local' + assert x.isLocal + assert not x.isArgument + assert not x.isGlobal + assert not x.isArray + assert x.typeStartToken.str == 'int' + assert x.typeEndToken.str == 'int' + assert x.scope.className == 'main' + + def test_argument(self, sample_cfg): + a = find_variable(sample_cfg, 'a') + assert a.access == 'Argument' + assert a.isArgument + assert not a.isLocal + + def test_array(self, sample_cfg): + arr = find_variable(sample_cfg, 'arr') + assert arr.isArray + assert not arr.isPointer + + def test_global_const(self, sample_cpp_cfg): + limit = find_variable(sample_cpp_cfg, 'limit') + assert limit.access == 'Global' + assert limit.isGlobal + assert limit.isConst + assert not limit.isStatic + + def test_pointer(self, sample_cpp_cfg): + msg = find_variable(sample_cpp_cfg, 'msg') + assert msg.isPointer + assert not msg.isArray + + def test_class_member(self, sample_cpp_cfg): + member = find_variable(sample_cpp_cfg, 'mScale') + assert member.access == 'Protected' + assert member.isClass is False + + +class TestPreprocessor: + def test_directives(self, sample_cfg): + directives = sample_cfg.directives + assert len(directives) == 1 + assert directives[0].str == '#define ANSWER 42' + assert directives[0].file.endswith('sample.c') + assert directives[0].linenr == 1 + assert "#define ANSWER 42" in repr(directives[0]) + + def test_macro_usage(self, sample_cfg): + macros = sample_cfg.macro_usage + assert len(macros) == 1 + macro = macros[0] + assert macro.name == 'ANSWER' + assert macro.usefile.endswith('sample.c') + assert int(macro.useline) == 14 + assert macro.isKnownValue + assert "name='ANSWER'" in repr(macro) + + def test_if_conditions(self, multi_cfg_data): + cfgs = multi_cfg_data.configurations + for cfg in cfgs: + assert len(cfg.preprocessor_if_conditions) == 1 + assert cfg.preprocessor_if_conditions[0].linenr == 3 + assert cfgs[0].preprocessor_if_conditions[0].result == 0 + assert cfgs[1].preprocessor_if_conditions[0].result == 1 + assert 'result=' in repr(cfgs[0].preprocessor_if_conditions[0]) + + def test_typedef_info(self, multi_cfg_data): + cfg = multi_cfg_data.configurations[0] + typedefs = {info.name: info for info in cfg.typedefInfo} + assert set(typedefs.keys()) == {'myint', 'myfloat'} + assert typedefs['myint'].used + assert not typedefs['myfloat'].used + assert typedefs['myint'].linenr == 1 + + +class TestHelperFunctions: + def test_getArguments(self, sample_cfg): + add_call = find_token(sample_cfg, 'add', skip=1) + args = cppcheckdata.getArguments(add_call) + assert [tok.str for tok in args] == ['x', '1'] + + def test_getArguments_no_call(self, sample_cfg): + int_tok = find_token(sample_cfg, 'int') + assert cppcheckdata.getArguments(int_tok) is None + + def test_get_function_call_name_args(self, sample_cfg): + add_call = find_token(sample_cfg, 'add', skip=1) + name, args = cppcheckdata.get_function_call_name_args(add_call) + assert name == 'add' + assert [tok.str for tok in args] == ['x', '1'] + + def test_get_function_call_name_args_namespace(self, sample_cpp_cfg): + twice_call = find_token(sample_cpp_cfg, 'twice', skip=1) + name, args = cppcheckdata.get_function_call_name_args(twice_call) + assert name == 'ns::twice' + assert [tok.str for tok in args] == ['21'] + + def test_get_function_call_name_args_not_a_call(self, sample_cfg): + # the function definition is not a call + add_def = find_token(sample_cfg, 'add') + name, args = cppcheckdata.get_function_call_name_args(add_def) + assert name is None + assert args is None + + def test_astIsFloat(self, sample_cfg): + division = find_token(sample_cfg, '/') + assert cppcheckdata.astIsFloat(division) + plus = find_token(sample_cfg, '+') # a + b with int operands + assert not cppcheckdata.astIsFloat(plus) + assert not cppcheckdata.astIsFloat(None) + + +class TestMatch: + """Tests for the cppcheckdata.match()/simpleMatch() pattern matching.""" + + def test_simpleMatch(self, match_cfg): + calc_def = find_token(match_cfg, 'calc') + assert cppcheckdata.simpleMatch(calc_def, 'calc') + assert cppcheckdata.simpleMatch(calc_def, 'calc ( int a , int b )') + assert not cppcheckdata.simpleMatch(calc_def, 'calc ( int b') + assert not cppcheckdata.simpleMatch(None, 'calc') + + def test_literal_sequence(self, match_cfg): + calc_def = find_token(match_cfg, 'calc') + assert cppcheckdata.match(calc_def, 'calc ( int') + assert cppcheckdata.match(calc_def, 'calc ( int a , int b )') + assert not cppcheckdata.match(calc_def, 'calc ( char') + # the match is anchored at the given token + assert not cppcheckdata.match(calc_def, 'int calc') + + def test_empty_pattern_and_no_token(self, match_cfg): + calc_def = find_token(match_cfg, 'calc') + assert not cppcheckdata.match(calc_def, '') + assert not cppcheckdata.match(None, 'calc') + + def test_end(self, match_cfg): + calc_def = find_token(match_cfg, 'calc') + res = cppcheckdata.match(calc_def, 'calc') + assert res.end is calc_def + res = cppcheckdata.match(calc_def, 'calc ( int') + assert res.end.str == 'int' + + # ---- literal operator tokens ---- + + def test_literal_bitwise_or(self, match_cfg): + # a literal '|' in the pattern matches a '|' token ... + bit_or = find_token(match_cfg, '|') + assert cppcheckdata.match(bit_or, '|') + assert cppcheckdata.match(bit_or.previous, '%var% | %var% ;') + # ... but not a '||' token, and it is not an either-or alternation + log_or = find_token(match_cfg, '||') + assert not cppcheckdata.match(log_or, '|') + + def test_literal_logical_or(self, match_cfg): + log_or = find_token(match_cfg, '||') + assert cppcheckdata.match(log_or, '||') + assert cppcheckdata.match(log_or.previous, '%var% || %var% ;') + bit_or = find_token(match_cfg, '|') + assert not cppcheckdata.match(bit_or, '||') + + def test_literal_not(self, match_cfg): + not_tok = find_token(match_cfg, '!') + assert cppcheckdata.match(not_tok, '! %var% ;') + assert not cppcheckdata.match(find_token(match_cfg, '!='), '!') + + def test_literal_not_equal(self, match_cfg): + neq = find_token(match_cfg, '!=') + assert cppcheckdata.match(neq, '!=') + assert cppcheckdata.match(neq.previous, '%var% != %var% ;') + assert not cppcheckdata.match(find_token(match_cfg, '='), '!=') + assert not cppcheckdata.match(neq, '=') + + def test_literal_star(self, match_cfg): + mul = find_token(match_cfg, '*') + assert cppcheckdata.match(mul, '*') + assert cppcheckdata.match(mul.previous, '%var% * %var% ;') + + def test_literal_percent(self, match_cfg): + mod = find_token(match_cfg, '%') + assert cppcheckdata.match(mod, '%') + assert cppcheckdata.match(mod.previous, '%var% % %var% ;') + + def test_literal_parentheses(self, match_cfg): + calc_call = find_token(match_cfg, 'calc', skip=1) + assert cppcheckdata.match(calc_call, 'calc ( %var% , %var% ) ;') + + # ---- %keyword% patterns ---- + + def test_any(self, match_cfg): + for token_str in ('calc', '(', '3', ';', '|', '{'): + assert cppcheckdata.match(find_token(match_cfg, token_str), '%any%') + plus_assign = find_token(match_cfg, '+=') + assert cppcheckdata.match(plus_assign, '%assign% %any% ;') + + def test_assign(self, match_cfg): + assert cppcheckdata.match(find_token(match_cfg, '='), '%assign%') + assert cppcheckdata.match(find_token(match_cfg, '+='), '%assign%') + assert not cppcheckdata.match(find_token(match_cfg, '!='), '%assign%') + assert not cppcheckdata.match(find_token(match_cfg, '|'), '%assign%') + + def test_comp(self, match_cfg): + assert cppcheckdata.match(find_token(match_cfg, '>'), '%comp%') + assert cppcheckdata.match(find_token(match_cfg, '!='), '%comp%') + assert not cppcheckdata.match(find_token(match_cfg, '='), '%comp%') + assert not cppcheckdata.match(find_token(match_cfg, '|'), '%comp%') + + def test_name(self, match_cfg): + assert cppcheckdata.match(find_token(match_cfg, 'calc'), '%name%') + assert cppcheckdata.match(find_token(match_cfg, 'int'), '%name%') + assert not cppcheckdata.match(find_token(match_cfg, '3'), '%name%') + assert not cppcheckdata.match(find_token(match_cfg, '('), '%name%') + + def test_op(self, match_cfg): + for op in ('|', '||', '*', '%', '!=', '>', '=', '+='): + assert cppcheckdata.match(find_token(match_cfg, op), '%op%'), op + assert not cppcheckdata.match(find_token(match_cfg, ';'), '%op%') + assert not cppcheckdata.match(find_token(match_cfg, 'calc'), '%op%') + + def test_or(self, match_cfg): + assert cppcheckdata.match(find_token(match_cfg, '|'), '%or%') + assert not cppcheckdata.match(find_token(match_cfg, '||'), '%or%') + + def test_oror(self, match_cfg): + assert cppcheckdata.match(find_token(match_cfg, '||'), '%oror%') + assert not cppcheckdata.match(find_token(match_cfg, '|'), '%oror%') + + def test_var(self, match_cfg): + a_use = find_token(match_cfg, 'a', skip=1) + assert cppcheckdata.match(a_use, '%var%') + # a function name is a %name% but not a %var% + assert not cppcheckdata.match(find_token(match_cfg, 'calc'), '%var%') + assert not cppcheckdata.match(find_token(match_cfg, '3'), '%var%') + + # ---- link patterns ---- + + def test_link_parentheses(self, match_cfg): + calc_call = find_token(match_cfg, 'calc', skip=1) + res = cppcheckdata.match(calc_call.next, '(*)') + assert res + assert res.end.str == ')' + assert res.end is calc_call.next.link + # the pattern continues after the linked token + assert cppcheckdata.match(calc_call, '%name% (*) ;') + # '(*)' only matches at a '(' token + assert not cppcheckdata.match(calc_call, '(*)') + + def test_link_brackets(self, match_cfg): + arr_decl = find_token(match_cfg, 'arr') + assert cppcheckdata.match(arr_decl, 'arr [*] ;') + arr_use = find_token(match_cfg, 'arr', skip=1) + res = cppcheckdata.match(arr_use, '%name% [*] %assign% %var% ;') + assert res + + def test_link_braces(self, match_cfg): + if_scope = find_scope(match_cfg, 'If') + res = cppcheckdata.match(if_scope.bodyStart, '{*}') + assert res + assert res.end is if_scope.bodyEnd + + def test_link_combined(self, match_cfg): + if_tok = find_token(match_cfg, 'if') + res = cppcheckdata.match(if_tok, 'if (*) {*}') + assert res + assert res.end.str == '}' + + def test_link_angle_brackets(self, match_cpp_cfg): + # the '<' of 'std::vector' is linked to the '>' + template_lt = find_token(match_cpp_cfg, '<') + assert template_lt.link + res = cppcheckdata.match(template_lt, '<*>') + assert res + assert res.end.str == '>' + assert cppcheckdata.match(template_lt.previous, 'vector <*> %var%') + # the '<' in 'i < j' is a comparison without a link + comparison_lt = find_token(match_cpp_cfg, '<', skip=1) + assert comparison_lt.link is None + assert not cppcheckdata.match(comparison_lt, '<*>') + + # ---- either-or alternation ---- + + def test_alternatives(self, match_cfg): + struct_tok = find_token(match_cfg, 'struct') + assert cppcheckdata.match(struct_tok, 'struct|class %name% {') + assert not cppcheckdata.match(struct_tok, 'union|enum %name% {') + + def test_alternatives_cpp(self, match_cpp_cfg): + class_tok = find_token(match_cpp_cfg, 'class') + assert cppcheckdata.match(class_tok, 'struct|class %name% {') + + def test_alternatives_with_keyword(self, match_cfg): + struct_tok = find_token(match_cfg, 'struct') + assert cppcheckdata.match(struct_tok, '%op%|struct') + assert not cppcheckdata.match(struct_tok, '%op%|%comp%') + + # ---- negation ---- + + def test_negation(self, match_cfg): + struct_tok = find_token(match_cfg, 'struct') + assert cppcheckdata.match(struct_tok, 'struct !!;') + assert not cppcheckdata.match(struct_tok, 'struct !!Point') + + def test_negation_keyword(self, match_cfg): + calc_call = find_token(match_cfg, 'calc', skip=1) + assert cppcheckdata.match(calc_call, '%name% !!%op%') + assert not cppcheckdata.match(calc_call, '%name% !!(') + + @pytest.mark.xfail(strict=False, + reason='in the C++ Token::Match a negation also matches when there is no token, ' + 'in match() it does not') + def test_negation_no_token(self, match_cfg): + last = match_cfg.tokenlist[-1] + assert last.str == '}' + assert cppcheckdata.match(last, '} !!x') + + # ---- bindings ---- + + def test_bindings(self, match_cfg): + calc_call = find_token(match_cfg, 'calc', skip=1) + res = cppcheckdata.match(calc_call, '%name%@ftok (*)') + assert res + assert res.ftok is calc_call + assert res.ftok.str == 'calc' + assert res.end.str == ')' + + def test_multiple_bindings(self, match_cfg): + bit_or_lhs = find_token(match_cfg, 'bit_or', skip=1) + res = cppcheckdata.match(bit_or_lhs, '%var%@lhs = %var%@op1 | %var%@op2 ;') + assert res + assert res.lhs.str == 'bit_or' + assert res.op1.str == 'a' + assert res.op2.str == 'b' + + def test_binding_on_link_pattern(self, match_cfg): + calc_call = find_token(match_cfg, 'calc', skip=1) + # the binding is the '(' token, end is behind the linked ')' + res = cppcheckdata.match(calc_call, '%name% (*)@paren') + assert res + assert res.paren.str == '(' + assert res.paren.link is res.end + + def test_bindings_on_failure(self, match_cfg): + calc_call = find_token(match_cfg, 'calc', skip=1) + res = cppcheckdata.match(calc_call, '%name%@ftok [*]@brackets') + assert not res + # all bindings (including 'end') read as None on a failed match + assert res.ftok is None + assert res.brackets is None + assert res.end is None + + def test_unknown_binding_raises(self, match_cfg): + calc_call = find_token(match_cfg, 'calc', skip=1) + res = cppcheckdata.match(calc_call, '%name%@ftok (*)') + assert res + with pytest.raises(AttributeError): + res.nosuchbinding # pylint: disable=W0104 + res = cppcheckdata.match(calc_call, '%name%@ftok [*]') + assert not res + with pytest.raises(AttributeError): + res.nosuchbinding # pylint: disable=W0104 + + # ---- '**' forward search ---- + + def test_find_forward(self, match_cfg): + calc_def = find_token(match_cfg, 'calc') + # '**' searches forward, skipping linked groups: the '{' found here + # is the function body, not a '{' inside the parameter list + res = cppcheckdata.match(calc_def, 'calc **{') + assert res + assert res.end.str == '{' + assert not cppcheckdata.match(calc_def, 'calc **nosuchtoken') + + +class TestSuppressions: + def make_suppression(self, **kwargs): + return cppcheckdata.Suppression(kwargs) + + def test_line_suppression(self): + supp = self.make_suppression(errorId='zerodiv', lineNumber='5') + assert supp.isMatch('a.c', '5', 'msg', 'zerodiv') + assert not supp.isMatch('a.c', '5', 'msg', 'nullPointer') + + @pytest.mark.xfail(strict=False, + reason='the "other suppression" fallback in Suppression.isMatch() does not check ' + 'that lineNumber is unset, so a line suppression matches every line') + def test_line_suppression_other_line(self): + supp = self.make_suppression(errorId='zerodiv', lineNumber='5') + assert not supp.isMatch('a.c', '6', 'msg', 'zerodiv') + + def test_wildcard_errorId(self): + supp = self.make_suppression(errorId='*', lineNumber='5') + assert supp.isMatch('a.c', '5', 'msg', 'anything') + + def test_file_suppression(self): + supp = self.make_suppression(errorId='zerodiv', fileName='a.c', type='file') + assert supp.isMatch('a.c', '1', 'msg', 'zerodiv') + assert supp.isMatch('a.c', '99', 'msg', 'zerodiv') + assert not supp.isMatch('b.c', '1', 'msg', 'zerodiv') + + def test_block_suppression(self): + supp = self.make_suppression(errorId='zerodiv', type='block', lineBegin='3', lineEnd='7') + assert supp.isMatch('a.c', '5', 'msg', 'zerodiv') + assert not supp.isMatch('a.c', '3', 'msg', 'zerodiv') + assert not supp.isMatch('a.c', '7', 'msg', 'zerodiv') + + def test_global_suppression(self): + supp = self.make_suppression(errorId='zerodiv') + assert supp.isMatch('a.c', '1', 'msg', 'zerodiv') + assert supp.isMatch('b.c', '99', 'other', 'zerodiv') + + def test_symbolName(self): + supp = self.make_suppression(errorId='zerodiv', symbolName='xyz') + assert supp.isMatch('a.c', '1', 'error on xyz here', 'zerodiv') + assert not supp.isMatch('a.c', '1', 'other message', 'zerodiv') + + def test_dumpfile_suppressions(self, dump_factory): + code = ('void f(void)\n' + '{\n' + ' int a;\n' + ' // cppcheck-suppress uninitvar\n' + ' a++;\n' + '}\n') + data = dump_factory.parse(code, extra_args=['--inline-suppr']) + assert len(data.suppressions) == 1 + supp = data.suppressions[0] + assert supp.errorId == 'uninitvar' + assert supp.fileName.endswith('test.c') + assert int(supp.lineNumber) == 5 + # parsedump() also sets the suppressions used by is_suppressed() + location = cppcheckdata.Location({'file': supp.fileName, 'line': '5', 'column': '5'}) + assert cppcheckdata.is_suppressed(location, 'msg', 'uninitvar') + assert not cppcheckdata.is_suppressed(location, 'msg', 'nullPointer') + # NOTE: a non-matching line is not checked here - see test_line_suppression_other_line + + +class TestPureHelpers: + """Tests that construct objects from dicts and do not need a dump file.""" + + def test_location(self): + loc = cppcheckdata.Location({'file': 'a.c', 'line': '3', 'column': '7'}) + assert loc.file == 'a.c' + assert loc.linenr == 3 + assert loc.column == 7 + + def test_location_defaults(self): + loc = cppcheckdata.Location({'file': 'a.c'}) + assert loc.linenr == 0 + assert loc.column == 0 + + def test_location_linenr_alias(self): + loc = cppcheckdata.Location({'file': 'a.c', 'linenr': '4'}) + assert loc.linenr == 4 + + def test_value_kinds(self): + known = cppcheckdata.Value({'intvalue': '42', 'known': 'true'}) + assert known.intvalue == 42 + assert known.isKnown() + assert not known.isPossible() + possible = cppcheckdata.Value({'intvalue': '1', 'possible': 'true'}) + assert possible.isPossible() + impossible = cppcheckdata.Value({'intvalue': '0', 'impossible': 'true'}) + assert impossible.isImpossible() + inconclusive = cppcheckdata.Value({'intvalue': '2', 'inconclusive': 'true'}) + assert inconclusive.isInconclusive() + + def test_value_condition(self): + value = cppcheckdata.Value({'intvalue': '1', 'possible': 'true', 'condition-line': '12'}) + assert value.condition == 12 + + def test_argument_parser(self): + parser = cppcheckdata.ArgumentParser() + args = parser.parse_args(['a.dump', 'b.ctu-info', '--cli', '-q']) + assert args.dumpfile == ['a.dump', 'b.ctu-info'] + assert args.cli + assert args.quiet + assert args.file_list is None + assert '{severity}' in args.template + + def test_get_files(self, tmp_path): + file_list = tmp_path / 'files.txt' + file_list.write_text('c.dump\nd.ctu-info\n') + parser = cppcheckdata.ArgumentParser() + args = parser.parse_args(['a.dump', 'b.ctu-info', '--file-list', str(file_list)]) + dump_files, ctu_info_files = cppcheckdata.get_files(args) + assert dump_files == ['a.dump', 'c.dump'] + assert ctu_info_files == ['b.ctu-info', 'd.ctu-info'] + + +class TestReporting: + def test_reportError_cli(self, monkeypatch, capsys): + monkeypatch.setattr(sys, 'argv', ['myaddon.py', '--cli']) + location = cppcheckdata.Location({'file': 'a.c', 'line': '3', 'column': '7'}) + cppcheckdata.reportError(location, 'error', 'the message', 'myaddon', 'myid', extra='extra info') + msg = json.loads(capsys.readouterr().out) + assert msg == {'file': 'a.c', + 'linenr': 3, + 'column': 7, + 'severity': 'error', + 'message': 'the message', + 'addon': 'myaddon', + 'errorId': 'myid', + 'extra': 'extra info'} + + def test_reportError_cli_column_override(self, monkeypatch, capsys): + monkeypatch.setattr(sys, 'argv', ['myaddon.py', '--cli']) + location = cppcheckdata.Location({'file': 'a.c', 'line': '3', 'column': '7'}) + cppcheckdata.reportError(location, 'error', 'the message', 'myaddon', 'myid', columnOverride=42) + msg = json.loads(capsys.readouterr().out) + assert msg['column'] == 42 + + def test_reportError_stderr(self, monkeypatch, capsys): + monkeypatch.setattr(sys, 'argv', ['myaddon.py']) + monkeypatch.setattr(cppcheckdata, 'current_dumpfile_suppressions', []) + monkeypatch.setattr(cppcheckdata, 'EXIT_CODE', 0) + location = cppcheckdata.Location({'file': 'a.c', 'line': '3', 'column': '7'}) + cppcheckdata.reportError(location, 'style', 'the message', 'myaddon', 'myid') + stderr = capsys.readouterr().err + assert stderr == '[a.c:3] (style) the message [myaddon-myid]\n' + assert cppcheckdata.EXIT_CODE == 1 + + def test_reportError_stderr_suppressed(self, monkeypatch, capsys): + monkeypatch.setattr(sys, 'argv', ['myaddon.py']) + suppression = cppcheckdata.Suppression({'errorId': 'myaddon-myid'}) + monkeypatch.setattr(cppcheckdata, 'current_dumpfile_suppressions', [suppression]) + monkeypatch.setattr(cppcheckdata, 'EXIT_CODE', 0) + location = cppcheckdata.Location({'file': 'a.c', 'line': '3', 'column': '7'}) + cppcheckdata.reportError(location, 'style', 'the message', 'myaddon', 'myid') + assert capsys.readouterr().err == '' + assert cppcheckdata.EXIT_CODE == 0 + + def test_log_checker_cli(self, monkeypatch, capsys): + monkeypatch.setattr(sys, 'argv', ['myaddon.py', '--cli']) + cppcheckdata.log_checker('SomeChecker', 'myaddon') + msg = json.loads(capsys.readouterr().out) + assert msg == {'addon': 'myaddon', + 'severity': 'none', + 'message': 'SomeChecker', + 'errorId': 'logChecker'} + + def test_log_checker_no_cli(self, monkeypatch, capsys): + monkeypatch.setattr(sys, 'argv', ['myaddon.py']) + cppcheckdata.log_checker('SomeChecker', 'myaddon') + assert capsys.readouterr().out == '' diff --git a/test/cli/performance_test.py b/test/cli/performance_test.py index 5be958619fc..67ec3be09f6 100644 --- a/test/cli/performance_test.py +++ b/test/cli/performance_test.py @@ -268,7 +268,7 @@ def test_crash_array_in_namespace(tmpdir): @pytest.mark.skipif(sys.platform == 'darwin', reason='GitHub macOS runners are too slow') -@pytest.mark.timeout(20) +@pytest.mark.timeout(30) def test_crash_array_in_array(tmpdir): # 12861 filename = os.path.join(tmpdir, 'hang.cpp') From 569f3d6a38aa3afadc2e4791c0fce939a3ee379d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 4 Aug 2026 18:14:48 +0200 Subject: [PATCH 298/493] Fix #14952 Stack overflow in ValueFlow::isLifetimeBorrowed() (#8770) --- lib/token.cpp | 1 + lib/valueflow.cpp | 2 +- test/testvalueflow.cpp | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/token.cpp b/lib/token.cpp index d8b438c5073..eac69decee7 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2433,6 +2433,7 @@ std::pair Token::typeDecl(const Token* tok, bool poi varTok = varTok->next(); while (Token::Match(varTok, "%name% ::")) varTok = varTok->tokAt(2); + assert(varTok != tok); std::pair r = typeDecl(varTok); if (r.first) return r; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 29eb07bcc90..5efe698bf61 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3146,7 +3146,7 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co valueFlowLifetimeConstructor(tok->next(), tokenlist, errorLogger, settings); } // Check function calls - else if (Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) { + else if (tok->scope()->isExecutable() && Token::Match(tok, "%name% (")) { valueFlowLifetimeFunction(tok, tokenlist, errorLogger, settings); } // Unique pointer lifetimes diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index f92ddee3685..945555b1b3c 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -8481,6 +8481,17 @@ class TestValueFlow : public TestFixture { " auto b = a;\n" "}\n"; (void)valueOfTok(code, "b"); + + code = "namespace O {}\n" // #14952 + "namespace N {\n" + " using namespace O;\n" + " enum class E { E0 };\n" + " auto E0 = E::E0;\n" + " struct S {\n" + " E f() const { return E0; }\n" + " };\n" + "}\n"; + (void)valueOfTok(code, "E0"); } void valueFlowHang() { From 9408a1d22dc8c2281d7ce1b370c273b9118cef60 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Tue, 4 Aug 2026 15:21:45 -0400 Subject: [PATCH 299/493] add support for vcxproj ExcludedFromBuild (#8771) CMake generates a vcxproj file for the cppcheck GUI that has generated files for all configurations but adds ExcludedFromBuild so the files only gets compiled for a specific configuration. ``` true true true ``` This patch adds support for ExcludedFromBuild so a file only gets checked for a specific configuration. --- lib/importproject.cpp | 69 +++++++++++++++++------ test/cli/exclude/DebugX64.cpp | 8 +++ test/cli/exclude/ReleaseX64.cpp | 8 +++ test/cli/exclude/exclude.cppcheck | 16 ++++++ test/cli/exclude/exclude.slnx | 6 ++ test/cli/exclude/exclude.vcxproj | 94 +++++++++++++++++++++++++++++++ test/cli/exclude/foo.h | 1 + test/cli/exclude_test.py | 20 +++++++ 8 files changed, 206 insertions(+), 16 deletions(-) create mode 100644 test/cli/exclude/DebugX64.cpp create mode 100644 test/cli/exclude/ReleaseX64.cpp create mode 100644 test/cli/exclude/exclude.cppcheck create mode 100644 test/cli/exclude/exclude.slnx create mode 100644 test/cli/exclude/exclude.vcxproj create mode 100644 test/cli/exclude/foo.h create mode 100644 test/cli/exclude_test.py diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 242c1719ba9..5c9bcaadd3f 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -617,12 +617,13 @@ namespace { std::string platformStr; }; - struct ConditionalGroup { - explicit ConditionalGroup(const tinyxml2::XMLElement *idg){ + struct Conditional { + explicit Conditional(const tinyxml2::XMLElement *idg){ const char *condAttr = idg->Attribute("Condition"); if (condAttr) mCondition = condAttr; } + explicit Conditional(std::string condition) : mCondition(std::move(condition)) {} static void replaceAll(std::string &c, const std::string &from, const std::string &to) { std::string::size_type pos; @@ -751,8 +752,8 @@ namespace { std::string mCondition; }; - struct ItemDefinitionGroup : ConditionalGroup { - explicit ItemDefinitionGroup(const tinyxml2::XMLElement *idg, std::string includePaths) : ConditionalGroup(idg), additionalIncludePaths(std::move(includePaths)) { + struct ItemDefinitionGroup : Conditional { + explicit ItemDefinitionGroup(const tinyxml2::XMLElement *idg, std::string includePaths) : Conditional(idg), additionalIncludePaths(std::move(includePaths)) { for (const tinyxml2::XMLElement *e1 = idg->FirstChildElement(); e1; e1 = e1->NextSiblingElement()) { const char* name = e1->Name(); if (std::strcmp(name, "ClCompile") == 0) { @@ -802,8 +803,8 @@ namespace { Standards::cppstd_t cppstd = Standards::CPPLatest; }; - struct ConfigurationPropertyGroup : ConditionalGroup { - explicit ConfigurationPropertyGroup(const tinyxml2::XMLElement *idg) : ConditionalGroup(idg) { + struct ConfigurationPropertyGroup : Conditional { + explicit ConfigurationPropertyGroup(const tinyxml2::XMLElement *idg) : Conditional(idg) { for (const tinyxml2::XMLElement *e = idg->FirstChildElement(); e; e = e->NextSiblingElement()) { if (std::strcmp(e->Name(), "UseOfMfc") == 0) { useOfMfc = true; @@ -816,6 +817,37 @@ namespace { bool useOfMfc = false; bool useUnicode = false; }; + + struct ItemGroupClCompile { + explicit ItemGroupClCompile(std::string filename) : mFilename(std::move(filename)) {} + ItemGroupClCompile(const tinyxml2::XMLElement *element, std::string file) : mFilename(std::move(file)) { + for (const tinyxml2::XMLElement* childElement = element->FirstChildElement(); childElement; childElement = childElement->NextSiblingElement()) { + const char *name = childElement->Name(); + if (!name) + continue; + if (std::strcmp(name, "ExcludedFromBuild") == 0) { + const char *condition = childElement->Attribute("Condition"); + const char *text = childElement->GetText(); + if (!condition || !text || std::strcmp(text, "true") != 0) + continue; + mConditions.emplace_back(condition); + } + // TODO: ForcedIncludeFiles and PrecompiledHeaderFile + } + } + bool exclude(const ProjectConfiguration& p, std::vector& errors) const { + if (mConditions.empty()) + return false; + for (const std::string& condition : mConditions) { + Conditional conditional(condition); + if (conditional.conditionIsTrue(p, mFilename, errors)) + return true; + } + return false; + } + std::string mFilename; + std::list mConditions; + }; } static std::list toStringList(const std::string &s) @@ -923,7 +955,7 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X variables["ProjectDir"] = Path::simplifyPath(Path::getPathFromFilename(filename)); std::list projectConfigurationList; - std::list compileList; + std::list compileList; std::list itemDefinitionGroupList; std::vector configurationPropertyGroups; std::string includePath; @@ -954,7 +986,8 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X const char *include = e->Attribute("Include"); if (include && Path::acceptFile(include)) { std::string toInclude = Path::simplifyPath(Path::isAbsolute(include) ? include : Path::getPathFromFilename(filename) + include); - compileList.emplace_back(toInclude); + findAndReplace(toInclude, "$(MSBuildThisFileDirectory)", "./"); + compileList.emplace_back(e, toInclude); } } } @@ -1016,7 +1049,7 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X for (const auto& sharedProject : sharedItemsProjects) { for (const auto &file : sharedProject.sourceFiles) { std::string pathToFile = Path::simplifyPath(Path::getPathFromFilename(sharedProject.pathToProjectFile) + file); - compileList.emplace_back(std::move(pathToFile)); + compileList.emplace_back(pathToFile); } for (const auto &p : sharedProject.includePaths) { std::string path = Path::simplifyPath(Path::getPathFromFilename(sharedProject.pathToProjectFile) + p); @@ -1026,8 +1059,8 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X // Project files PathMatch filtermatcher(fileFilters, Path::getCurrentPath()); - for (const std::string &cfilename : compileList) { - if (!fileFilters.empty() && !filtermatcher.match(cfilename)) + for (const ItemGroupClCompile& compile : compileList) { + if (!fileFilters.empty() && !filtermatcher.match(compile.mFilename)) continue; for (const ProjectConfiguration &p : projectConfigurationList) { @@ -1040,7 +1073,11 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X continue; } - FileSettings fs{cfilename, Standards::Language::None, 0}; // file will be identified later on + // check if the file should be excluded for this configuration + if (compile.exclude(p, errors)) + continue; + + FileSettings fs{ compile.mFilename, Standards::Language::None, 0}; // file will be identified later on fs.cfg = p.name; // TODO: detect actual MSC version fs.msc = true; @@ -1053,7 +1090,7 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X } std::string additionalIncludePaths; for (const ItemDefinitionGroup &i : itemDefinitionGroupList) { - if (!i.conditionIsTrue(p, cfilename, errors)) + if (!i.conditionIsTrue(p, compile.mFilename, errors)) continue; fs.standard = Standards::getCPP(i.cppstd); fs.defines += ';' + i.preprocessorDefinitions; @@ -1071,7 +1108,7 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X } bool useUnicode = false; for (const ConfigurationPropertyGroup &c : configurationPropertyGroups) { - if (!c.conditionIsTrue(p, cfilename, errors)) + if (!c.conditionIsTrue(p, compile.mFilename, errors)) continue; // in msbuild the last definition wins useUnicode = c.useUnicode; @@ -1081,7 +1118,7 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X fs.defines += ";UNICODE=1;_UNICODE=1"; } fsSetDefines(fs, fs.defines); - fsSetIncludePaths(fs, Path::getPathFromFilename(filename), toStringList(includePath + ';' + additionalIncludePaths), variables); + fsSetIncludePaths(fs, Path::getPathFromFilename(compile.mFilename), toStringList(includePath + ';' + additionalIncludePaths), variables); for (const auto &path : sharedItemsIncludePaths) { fs.includePaths.emplace_back(path); } @@ -1754,5 +1791,5 @@ bool cppcheck::testing::evaluateVcxprojCondition(const std::string& condition, c ProjectConfiguration p; p.configuration = configuration; p.platformStr = platform; - return ConditionalGroup::evalCondition(condition, p); + return Conditional::evalCondition(condition, p); } diff --git a/test/cli/exclude/DebugX64.cpp b/test/cli/exclude/DebugX64.cpp new file mode 100644 index 00000000000..cfb1fce687a --- /dev/null +++ b/test/cli/exclude/DebugX64.cpp @@ -0,0 +1,8 @@ +#include + +int foo() +{ + std::cout << "DebugX64\n"; + int x = 3 / 0; (void)x; // ERROR + return 0; +} diff --git a/test/cli/exclude/ReleaseX64.cpp b/test/cli/exclude/ReleaseX64.cpp new file mode 100644 index 00000000000..8fa6e6d0f82 --- /dev/null +++ b/test/cli/exclude/ReleaseX64.cpp @@ -0,0 +1,8 @@ +#include + +int foo() +{ + std::cout << "ReleaseX64\n"; + int x = 3 / 0; (void)x; // ERROR + return 0; +} diff --git a/test/cli/exclude/exclude.cppcheck b/test/cli/exclude/exclude.cppcheck new file mode 100644 index 00000000000..50d7da84486 --- /dev/null +++ b/test/cli/exclude/exclude.cppcheck @@ -0,0 +1,16 @@ + + + exclude-cppcheck-build-dir + exclude.slnx + false + true + true + true + 2 + 100 + + Debug + + + exclude + diff --git a/test/cli/exclude/exclude.slnx b/test/cli/exclude/exclude.slnx new file mode 100644 index 00000000000..837662784ac --- /dev/null +++ b/test/cli/exclude/exclude.slnx @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/cli/exclude/exclude.vcxproj b/test/cli/exclude/exclude.vcxproj new file mode 100644 index 00000000000..cc326aaec2f --- /dev/null +++ b/test/cli/exclude/exclude.vcxproj @@ -0,0 +1,94 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 18.0 + Win32Proj + {c9d1dca1-d8ff-4c05-9159-f00816645319} + exclude + 10.0 + + + + StaticLibrary + true + v145 + Unicode + + + Application + false + v145 + true + Unicode + + + + + + + + + + + + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + true + + + true + + + + + + + + + \ No newline at end of file diff --git a/test/cli/exclude/foo.h b/test/cli/exclude/foo.h new file mode 100644 index 00000000000..5d5f8f0c9e7 --- /dev/null +++ b/test/cli/exclude/foo.h @@ -0,0 +1 @@ +int foo(); diff --git a/test/cli/exclude_test.py b/test/cli/exclude_test.py new file mode 100644 index 00000000000..4f674aac34e --- /dev/null +++ b/test/cli/exclude_test.py @@ -0,0 +1,20 @@ + +# python -m pytest exclude_test.py + +import os + +from testutils import cppcheck + +__script_dir = os.path.dirname(os.path.abspath(__file__)) +__proj_dir = os.path.join(__script_dir, 'exclude') + +def test_exclude(): + args = [ + '--template=cppcheck1', + '--project=exclude/exclude.cppcheck', + '--no-cppcheck-build-dir' + ] + ret, stdout, stderr = cppcheck(args, cwd=__script_dir) + filename = os.path.join('exclude', 'DebugX64.cpp') + assert ret == 0, stdout + assert stderr == '[%s:6]: (error) Division by zero.\n' % filename From 8276218b3da696bf96ff8986b7807aaf48e91ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Gr=C3=BCninger?= Date: Wed, 5 Aug 2026 09:11:41 +0200 Subject: [PATCH 300/493] [ci] Update Github actions to latest major release (#8756) --- .github/workflows/CI-cygwin.yml | 2 +- .github/workflows/CI-mingw.yml | 2 +- .github/workflows/CI-unixish-docker.yml | 4 ++-- .github/workflows/CI-unixish.yml | 22 ++++++++++----------- .github/workflows/CI-windows.yml | 12 +++++------ .github/workflows/buildman.yml | 8 ++++---- .github/workflows/cifuzz.yml | 2 +- .github/workflows/clang-tidy.yml | 4 ++-- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/corpus.yml | 4 ++-- .github/workflows/coverage.yml | 6 +++--- .github/workflows/coverity.yml | 2 +- .github/workflows/cppcheck-premium.yml | 6 +++--- .github/workflows/format.yml | 4 ++-- .github/workflows/iwyu.yml | 14 ++++++------- .github/workflows/release-windows-mingw.yml | 4 ++-- .github/workflows/release-windows.yml | 12 +++++------ .github/workflows/sanitizers.yml | 4 ++-- .github/workflows/scriptcheck.yml | 12 +++++------ .github/workflows/selfcheck.yml | 6 +++--- .github/workflows/valgrind.yml | 4 ++-- 21 files changed, 70 insertions(+), 70 deletions(-) diff --git a/.github/workflows/CI-cygwin.yml b/.github/workflows/CI-cygwin.yml index bf67967c5f8..6b0ad2cc5bd 100644 --- a/.github/workflows/CI-cygwin.yml +++ b/.github/workflows/CI-cygwin.yml @@ -37,7 +37,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false diff --git a/.github/workflows/CI-mingw.yml b/.github/workflows/CI-mingw.yml index 1b0cf3e5672..f308cfa5110 100644 --- a/.github/workflows/CI-mingw.yml +++ b/.github/workflows/CI-mingw.yml @@ -33,7 +33,7 @@ jobs: timeout-minutes: 19 # max + 3*std of the last 7K runs steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false diff --git a/.github/workflows/CI-unixish-docker.yml b/.github/workflows/CI-unixish-docker.yml index 16c1615ed04..adf4a74c81b 100644 --- a/.github/workflows/CI-unixish-docker.yml +++ b/.github/workflows/CI-unixish-docker.yml @@ -43,7 +43,7 @@ jobs: image: ${{ matrix.image }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -96,7 +96,7 @@ jobs: image: ${{ matrix.image }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index 8fb5c8d76d6..9bac980c853 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -30,7 +30,7 @@ jobs: CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -85,7 +85,7 @@ jobs: CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -97,7 +97,7 @@ jobs: # TODO: move latest compiler to separate step # TODO: bail out on warnings with latest GCC - name: Set up GCC - uses: egor-tensin/setup-gcc@v1 + uses: egor-tensin/setup-gcc@v2 if: false # matrix.os == 'ubuntu-22.04' with: version: 13 @@ -216,7 +216,7 @@ jobs: CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -265,7 +265,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -299,7 +299,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -333,7 +333,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -361,7 +361,7 @@ jobs: CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -417,7 +417,7 @@ jobs: CMAKE_VERSION_FULL: 3.22.6 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -461,7 +461,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -712,7 +712,7 @@ jobs: runs-on: ubuntu-22.04 # run on the latest image only steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml index a63be4e0ad9..66858c7afbe 100644 --- a/.github/workflows/CI-windows.yml +++ b/.github/workflows/CI-windows.yml @@ -31,7 +31,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -82,7 +82,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -108,7 +108,7 @@ jobs: CMAKE_VERSION_FULL: 3.22.6 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -154,13 +154,13 @@ jobs: PCRE_VERSION: 8.45 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false - name: Set up Python if: matrix.config == 'release' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.14' check-latest: true @@ -172,7 +172,7 @@ jobs: - name: Cache PCRE id: cache-pcre - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: | externals\pcre.h diff --git a/.github/workflows/buildman.yml b/.github/workflows/buildman.yml index b0b399dd851..e84cf4bffd9 100644 --- a/.github/workflows/buildman.yml +++ b/.github/workflows/buildman.yml @@ -19,7 +19,7 @@ jobs: convert_via_pandoc: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -38,7 +38,7 @@ jobs: with: args: --output=output/manual-premium.pdf man/manual-premium.md - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: output path: output @@ -46,7 +46,7 @@ jobs: manpage: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -59,7 +59,7 @@ jobs: run: | make man - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: cppcheck.1 path: cppcheck.1 diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index c54d47da4f1..400fb929786 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -27,7 +27,7 @@ jobs: dry-run: false language: c++ - name: Upload Crash - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 7a5b317693a..4f2db4ab113 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -27,7 +27,7 @@ jobs: QT_VERSION: 6.10.0 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -86,7 +86,7 @@ jobs: run: | cmake --build cmake.output --target run-clang-tidy-csa 2> /dev/null - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: success() || failure() with: name: Compilation Database diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 12e758d2c9e..84d37423d2e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -33,13 +33,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: persist-credentials: false # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} @@ -49,4 +49,4 @@ jobs: make -j$(nproc) CXXOPTS="-Werror" HAVE_RULES=yes CPPCHK_GLIBCXX_DEBUG= cppcheck - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/corpus.yml b/.github/workflows/corpus.yml index 0c1aeda94de..2d9f1424fad 100644 --- a/.github/workflows/corpus.yml +++ b/.github/workflows/corpus.yml @@ -16,7 +16,7 @@ jobs: if: ${{ github.repository_owner == 'cppcheck-opensource' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -51,7 +51,7 @@ jobs: # print largest size ls -l ./store | cut -d' ' -f5 | sort -u -n -r | head -n1 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: success() with: name: corpus diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 13f56172a80..b5e496adcf6 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -57,12 +57,12 @@ jobs: lcov --extract lcov_tmp.info "$(pwd)/*" --output-file lcov.info genhtml lcov.info -o coverage_report --frame --legend --demangle-cpp - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Coverage results path: coverage_report - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} # file: ./coverage.xml # optional diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 006160c7779..4c62971e4c4 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.repository_owner == 'cppcheck-opensource' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false - name: Install missing software on ubuntu diff --git a/.github/workflows/cppcheck-premium.yml b/.github/workflows/cppcheck-premium.yml index ed0f2a1bcd5..b99cccd69da 100644 --- a/.github/workflows/cppcheck-premium.yml +++ b/.github/workflows/cppcheck-premium.yml @@ -25,7 +25,7 @@ jobs: build: runs-on: ubuntu-24.04 # run on the latest image only steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -60,13 +60,13 @@ jobs: #sed -i 's|"security-severity":.*||' results.sarif cat results.sarif - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: results path: results.sarif - name: Upload report - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@v4 with: sarif_file: results.sarif category: cppcheckpremium diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index fd491c0ec0e..4ec72f935fd 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -24,12 +24,12 @@ jobs: UNCRUSTIFY_VERSION: 0.80.1 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false - name: Cache uncrustify - uses: actions/cache@v4 + uses: actions/cache@v5 id: cache-uncrustify with: path: | diff --git a/.github/workflows/iwyu.yml b/.github/workflows/iwyu.yml index de047b8d10a..2e54b92541e 100644 --- a/.github/workflows/iwyu.yml +++ b/.github/workflows/iwyu.yml @@ -39,7 +39,7 @@ jobs: QT_VERSION: 6.10.0 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -160,13 +160,13 @@ jobs: IWYU: include-what-you-use IWYU_CLANG_INC: ${{ matrix.clang_inc }} - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: success() || failure() with: name: Compilation Database (include-what-you-use - ${{ matrix.os }} ${{ matrix.stdlib }}) path: ./cmake.output/compile_commands.json - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: ${{ contains(matrix.os, 'macos') && (success() || failure()) }} with: name: macOS Mappings @@ -174,7 +174,7 @@ jobs: ./iwyu-mapgen-apple-libc.py ./macos.imp - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: success() || failure() with: name: Logs (include-what-you-use - ${{ matrix.os }} ${{ matrix.stdlib }}) @@ -199,7 +199,7 @@ jobs: QT_VERSION: 6.10.0 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -256,13 +256,13 @@ jobs: # TODO: run multi-threaded find $PWD/cli $PWD/lib $PWD/test $PWD/gui -maxdepth 1 -name "*.cpp" | xargs -t -n 1 clang-include-cleaner-22 --print=changes --extra-arg=-w --extra-arg=-stdlib=${{ matrix.stdlib }} -p cmake.output > clang-include-cleaner.log 2>&1 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: success() || failure() with: name: Compilation Database (clang-include-cleaner - ${{ matrix.stdlib }}) path: ./cmake.output/compile_commands.json - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: success() || failure() with: name: Logs (clang-include-cleaner - ${{ matrix.stdlib }}) diff --git a/.github/workflows/release-windows-mingw.yml b/.github/workflows/release-windows-mingw.yml index 3b9b836347f..8085990e39d 100644 --- a/.github/workflows/release-windows-mingw.yml +++ b/.github/workflows/release-windows-mingw.yml @@ -33,7 +33,7 @@ jobs: timeout-minutes: 19 # max + 3*std of the last 7K runs steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -63,7 +63,7 @@ jobs: cp /mingw64/bin/libstdc*.dll cppcheck-mingw/ cp /mingw64/bin/libwinpthread-1.dll cppcheck-mingw/ - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: cppcheck-mingw path: cppcheck-mingw diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index 8d09a55302e..aa467d7b875 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -32,7 +32,7 @@ jobs: BOOST_MINOR_VERSION: 89 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -95,7 +95,7 @@ jobs: del build\bin\Release\cppcheck-gui.ilk || exit /b !errorlevel! del build\bin\Release\cppcheck-gui.pdb || exit /b !errorlevel! - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: deploy path: build\bin\Release @@ -109,7 +109,7 @@ jobs: env: _CL_: /WX - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: bin path: bin @@ -158,7 +158,7 @@ jobs: :: copy libcrypto-3-x64.dll and libssl-3-x64.dll copy %RUNNER_WORKSPACE%\Qt\Tools\OpenSSLv3\Win_x64\bin\lib*.dll win_installer\files || exit /b !errorlevel! - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: collect path: win_installer\files @@ -173,7 +173,7 @@ jobs: @echo ProductVersion="%PRODUCTVER%" || exit /b !errorlevel! msbuild -m cppcheck.wixproj -p:Platform=x64,ProductVersion=%PRODUCTVER%.${{ github.run_number }} || exit /b !errorlevel! - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: installer path: win_installer/Build/ @@ -209,7 +209,7 @@ jobs: del win_installer\files\Qt6Svg.dll || exit /b !errorlevel! del win_installer\files\vc_redist.x64.exe || exit /b !errorlevel! - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: portable path: win_installer\files diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml index ea0a0276c99..6021d1237d2 100644 --- a/.github/workflows/sanitizers.yml +++ b/.github/workflows/sanitizers.yml @@ -50,7 +50,7 @@ jobs: CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -60,7 +60,7 @@ jobs: key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}-${{ matrix.sanitizer }} - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.14' check-latest: true diff --git a/.github/workflows/scriptcheck.yml b/.github/workflows/scriptcheck.yml index 844b1d5c2f3..8cee3c5a5b4 100644 --- a/.github/workflows/scriptcheck.yml +++ b/.github/workflows/scriptcheck.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -31,7 +31,7 @@ jobs: key: ${{ github.workflow }}-${{ runner.os }} - name: Cache Cppcheck - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: cppcheck key: ${{ runner.os }}-scriptcheck-cppcheck-${{ github.sha }} @@ -56,19 +56,19 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false # TODO: bailout on error - name: Restore Cppcheck - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: cppcheck key: ${{ runner.os }}-scriptcheck-cppcheck-${{ github.sha }} - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} check-latest: true @@ -209,7 +209,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 3517486df31..f16ce8d8332 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -24,7 +24,7 @@ jobs: QT_VERSION: 6.10.0 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -215,7 +215,7 @@ jobs: env: DISABLE_VALUEFLOW: 1 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Callgrind Output path: ./callgrind.* @@ -228,7 +228,7 @@ jobs: env: DISABLE_VALUEFLOW: 1 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Memcheck Output path: ./memcheck.* diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml index 3e4a02dbb48..25ef4dd63a2 100644 --- a/.github/workflows/valgrind.yml +++ b/.github/workflows/valgrind.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false @@ -64,7 +64,7 @@ jobs: #env: # DEBUGINFOD_URLS: https://debuginfod.ubuntu.com - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: success() || failure() with: name: Logs From 6a29b12ce24eb507c1cb1d2e6d5d50607655870f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 5 Aug 2026 11:22:04 +0200 Subject: [PATCH 301/493] Fix #14899: FP invalidPrintfArgType_float with _sprintf_s_l() (#8729) --- lib/checkio.cpp | 36 ++++++++++++++++++++++++++---------- test/testio.cpp | 12 ++++++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 0a0ca70a833..f726cef0cc7 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -666,16 +666,20 @@ void CheckIOImpl::wrongfeofUsage(const Token * tok) // printf("", 1); // Too much arguments //--------------------------------------------------------------------------- -static bool findFormat(nonneg int arg, const Token *firstArg, +static bool findFormat(nonneg int arg, nonneg int argc, const Token *firstArg, const Token *&formatStringTok, const Token *&formatArgTok) { + formatArgTok = firstArg; + + for (int i = 0; i < argc && formatArgTok; ++i) + formatArgTok = formatArgTok->nextArgument(); + const Token* argTok = firstArg; for (int i = 0; i < arg && argTok; ++i) argTok = argTok->nextArgument(); if (Token::Match(argTok, "%str% [,)]")) { - formatArgTok = argTok->nextArgument(); formatStringTok = argTok; return true; } @@ -686,7 +690,6 @@ static bool findFormat(nonneg int arg, const Token *firstArg, (argTok->variable()->dimensions().size() == 1 && argTok->variable()->dimensionKnown(0) && argTok->variable()->dimension(0) != 0))) { - formatArgTok = argTok->nextArgument(); if (!argTok->values().empty()) { const auto value = std::find_if( argTok->values().cbegin(), argTok->values().cend(), std::mem_fn(&ValueFlow::Value::isTokValue)); @@ -706,6 +709,17 @@ static inline bool typesMatch(const std::string& iToTest, const std::string& iTy return (iToTest == iTypename) || (iToTest == iOptionalPrefix + iTypename); } +static int getMaxArgNo(const Library::Function *func) +{ + const auto &checks = func->argumentChecks; + return std::max_element(checks.cbegin(), checks.cend(), + [](const std::pair &lhs, + const std::pair &rhs) { + return lhs.first < rhs.first; + } + )->first; +} + void CheckIOImpl::checkWrongPrintfScanfArguments() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -723,8 +737,10 @@ void CheckIOImpl::checkWrongPrintfScanfArguments() bool scan = false; bool scanf_s = false; int formatStringArgNo = -1; + int argc = -1; if (tok->strAt(1) == "(" && mSettings.library.formatstr_function(tok)) { + argc = getMaxArgNo(mSettings.library.getFunction(tok)); formatStringArgNo = mSettings.library.formatstr_argno(tok); scan = mSettings.library.formatstr_scan(tok); scanf_s = mSettings.library.formatstr_secure(tok); @@ -732,37 +748,37 @@ void CheckIOImpl::checkWrongPrintfScanfArguments() if (formatStringArgNo >= 0) { // formatstring found in library. Find format string and first argument belonging to format string. - if (!findFormat(formatStringArgNo, tok->tokAt(2), formatStringTok, argListTok)) + if (!findFormat(formatStringArgNo, argc, tok->tokAt(2), formatStringTok, argListTok)) continue; } else if (Token::simpleMatch(tok, "swprintf (")) { if (Token::Match(tok->tokAt(2)->nextArgument(), "%str%")) { // Find third parameter and format string - if (!findFormat(1, tok->tokAt(2), formatStringTok, argListTok)) + if (!findFormat(1, 2, tok->tokAt(2), formatStringTok, argListTok)) continue; } else { // Find fourth parameter and format string - if (!findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) + if (!findFormat(2, 3, tok->tokAt(2), formatStringTok, argListTok)) continue; } } else if (isWindows && Token::Match(tok, "sprintf_s|swprintf_s (")) { // template int sprintf_s(char (&buffer)[size], const char *format, ...); - if (findFormat(1, tok->tokAt(2), formatStringTok, argListTok)) { + if (findFormat(1, 2, tok->tokAt(2), formatStringTok, argListTok)) { if (!formatStringTok) continue; } // int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...); - else if (findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) { + else if (findFormat(2, 3, tok->tokAt(2), formatStringTok, argListTok)) { if (!formatStringTok) continue; } } else if (isWindows && Token::Match(tok, "_snprintf_s|_snwprintf_s (")) { // template int _snprintf_s(char (&buffer)[size], size_t count, const char *format, ...); - if (findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) { + if (findFormat(2, 3, tok->tokAt(2), formatStringTok, argListTok)) { if (!formatStringTok) continue; } // int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...); - else if (findFormat(3, tok->tokAt(2), formatStringTok, argListTok)) { + else if (findFormat(3, 4, tok->tokAt(2), formatStringTok, argListTok)) { if (!formatStringTok) continue; } diff --git a/test/testio.cpp b/test/testio.cpp index 2d191555ba6..16d770bb0bd 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -4791,6 +4791,18 @@ class TestIO : public TestFixture { "[test.cpp:17:5]: (warning) %s in format string (no. 5) requires 'char *' but the argument type is 'signed int'. [invalidPrintfArgType_s]\n" "[test.cpp:17:5]: (warning) sprintf_s format string requires 5 parameters but 6 are given. [wrongPrintfScanfArgNum]\n", errout_str()); + check("int main()\n" + "{\n" + " double value = 3.14;\n" + " const size_t buffer_size = 64;\n" + " char buffer[buffer_size];\n" + " int precision = 2;\n" + " _locale_t locale = _create_locale(LC_ALL, \"C\");\n" + " _sprintf_s_l(buffer, buffer_size, \"%.*f\", locale, precision, value);\n" + " _free_locale(locale);\n" + " return 0;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void testMicrosoftSecureScanfArgument() { From cb6d92e86287d511476b579a9e50a7b08067ebc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 5 Aug 2026 11:23:00 +0200 Subject: [PATCH 302/493] AUTHORS: Add aadanen [skip ci] (#8774) --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index b4917d7d157..cda29aa6ef8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,7 @@ The cppcheck team, in alphabetical order: 0x41head +Aaron Danen Abhijit Sawant Abhishek Bharadwaj Abigail Buccaneer From 44b9221a78e6d67f31a70533cea089d74fecf260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 5 Aug 2026 12:43:15 +0200 Subject: [PATCH 303/493] Fix #14955: Bad varid for enumerator with using namespace (#8773) --- lib/tokenize.cpp | 12 +++++++++++- test/testtokenize.cpp | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8382c09e785..033462ca2e2 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5270,7 +5270,16 @@ void Tokenizer::setVarIdPass2() std::map endOfScope; std::list scope; std::list usingnamespaces; + const Token *enumEnd = nullptr; for (Token *tok = list.front(); tok; tok = tok->next()) { + if (isEnumStart(tok)) { + enumEnd = tok->link(); + continue; + } + if (tok == enumEnd) { + enumEnd = nullptr; + continue; + } if (!tok->previous() || Token::Match(tok->previous(), "[;{}]")) { if (Token::Match(tok, "using namespace %name% ::|;")) { Token *endtok = tok->tokAt(2); @@ -5300,7 +5309,8 @@ void Tokenizer::setVarIdPass2() tok = tok->next()->findClosingBracket()->next(); else if (usingnamespaces.empty() || tok->varId() || !tok->isName() || tok->isStandardType() || tok->tokType() == Token::eKeyword || tok->tokType() == Token::eBoolean || Token::Match(tok->previous(), ".|namespace|class|struct|&|&&|*|> %name%") || Token::Match(tok->previous(), "%type%| %name% ( %type%|)") || Token::Match(tok, "public:|private:|protected:") || - (!tok->next() && Token::Match(tok->previous(), "}|; %name%"))) + (!tok->next() && Token::Match(tok->previous(), "}|; %name%")) || + (enumEnd && Token::Match(tok->previous(), "{|, %name% =|,|}"))) continue; if (tok->strAt(-1) == "::" && tok->tokAt(-2) && tok->tokAt(-2)->isName()) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 79da0177e19..600d457e944 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -93,6 +93,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(tokenize41); // #13847 TEST_CASE(tokenize42); // #13861 TEST_CASE(tokenize43); // #13861 + TEST_CASE(tokenize44); // #14955 TEST_CASE(validate); @@ -949,6 +950,21 @@ class TestTokenizer : public TestFixture { (void)errout_str(); } + void tokenize44() { // #14955 + const char code[] = "namespace O {}\n" + "namespace N {\n" + " using namespace O;\n" + " enum class E { E0 };\n" + " E E0 = E::E0;\n" + "}\n"; + const char expected[] = "2: namespace N {\n" + "3: using namespace O ;\n" + "4: enum class E { E0 } ;\n" + "5: E E0@1 ; E0@1 = E :: E0 ;\n" + "6: }\n"; + ASSERT_EQUALS(expected, tokenizeDebugListing(code)); + } + void validate() { // C++ code in C file ASSERT_THROW_INTERNAL(tokenizeAndStringify(";using namespace std;",dinit(TokenizeOptions, $.expand = false, $.cpp = false)), SYNTAX); From b702eade4a164d6739818fc1c560113215cf4929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 5 Aug 2026 13:26:37 +0200 Subject: [PATCH 304/493] partial fix #14851 (CI: run 'make test' with some old gcc versions) (#8663) --- .github/workflows/gcc-versions.yml | 39 ++++++++++++++++++++++++++++++ test/testpath.cpp | 3 ++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/gcc-versions.yml diff --git a/.github/workflows/gcc-versions.yml b/.github/workflows/gcc-versions.yml new file mode 100644 index 00000000000..3402bade743 --- /dev/null +++ b/.github/workflows/gcc-versions.yml @@ -0,0 +1,39 @@ +# the purpose of this github action is to test that cppcheck source code can be compiled using old gcc versions. +# the gcc images we use here are copied from the official gcc images on docker hub + +name: gcc-versions + +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: + +permissions: + contents: read + +jobs: + build: + + strategy: + matrix: + #image: ["ghcr.io/cppcheck-opensource/gcc:5.4", "ghcr.io/cppcheck-opensource/gcc:6.5", "ghcr.io/cppcheck-opensource/gcc:7.5", "ghcr.io/cppcheck-opensource/gcc:8.5", "ghcr.io/cppcheck-opensource/gcc:9.5"] + image: ["ghcr.io/cppcheck-opensource/gcc:5.4"] + fail-fast: false + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Build cppcheck + run: | + # FIXME: simplecpp-1.8.0 can't be compiled with gcc 5.4, so we can't run 'make test' now + #docker run --rm -v ${{ github.workspace }}:/cppcheck -w /cppcheck ${{ matrix.image }} make -j$(nproc) CXXOPTS="-Werror" test + docker run --rm -v ${{ github.workspace }}:/cppcheck -w /cppcheck ${{ matrix.image }} g++ -fsyntax-only -Iexternals -Iexternals/picojson -Iexternals/simplecpp -Iexternals/tinyxml2 -std=c++11 -Wno-multichar lib/*.cpp diff --git a/test/testpath.cpp b/test/testpath.cpp index 69ee91fa391..0ebe343685f 100644 --- a/test/testpath.cpp +++ b/test/testpath.cpp @@ -516,7 +516,8 @@ class TestPath : public TestFixture { ASSERT_EQUALS(expected, Path::getAbsoluteFilePath(Path::join(cwd, "testabspath.txt"))); std::string cwd_up = Path::getPathFromFilename(cwd); - cwd_up.pop_back(); // remove trailing slash + if (cwd_up != "/") + cwd_up.pop_back(); // remove trailing slash ASSERT_EQUALS(cwd_up, Path::getAbsoluteFilePath(Path::join(cwd, ".."))); ASSERT_EQUALS(cwd_up, Path::getAbsoluteFilePath(Path::join(cwd, "../"))); ASSERT_EQUALS(cwd_up, Path::getAbsoluteFilePath(Path::join(cwd, "..\\"))); From baf5eaa0780c38dbf2a22740a5c08974d0165546 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 6 Aug 2026 14:17:46 +0200 Subject: [PATCH 305/493] TestValueFlow: Remove redundant test configuration, make settings const (#8776) Co-authored-by: chrchr-github --- test/testvalueflow.cpp | 45 ++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 945555b1b3c..4fc47f63d86 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -43,16 +43,9 @@ class TestValueFlow : public TestFixture { TestValueFlow() : TestFixture("TestValueFlow") {} private: - /*const*/ Settings settings = settingsBuilder().library("std.cfg").build(); + const Settings settings = settingsBuilder().library("std.cfg").build(); void run() override { - // strcpy, abort cfg - constexpr char cfg[] = "\n" - "\n" - " \n" - " true \n" // abort is a noreturn function - ""; - settings = settingsBuilder(settings).libraryxml(cfg).build(); mNewTemplate = true; TEST_CASE(valueFlowNumber); @@ -437,9 +430,10 @@ class TestValueFlow : public TestFixture { return false; } - bool testValueOfX_(const char* file, int line, const char code[], unsigned int linenr, int value, ValueFlow::Value::ValueType type) { + bool testValueOfX_(const char* file, int line, const char code[], unsigned int linenr, int value, ValueFlow::Value::ValueType type, const Settings* s = nullptr) { + const Settings& curSettings = s ? *s : settings; // Tokenize.. - SimpleTokenizer tokenizer(settings, *this); + SimpleTokenizer tokenizer(curSettings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { @@ -5887,21 +5881,19 @@ class TestValueFlow : public TestFixture { ASSERT_EQUALS(false, value.isKnown()); // #13959 - const Settings settingsOld = settings; - settings.standards.c = Standards::C23; + const Settings settingsC23 = settingsBuilder(settings).c(Standards::C23).build(); code = "void f(int* p) {\n" " if (p == nullptr)\n" " return;\n" " if (p) {}\n" "}\n"; - value = valueOfTok(code, "p ) { }", &settings, /*cpp*/ false); + value = valueOfTok(code, "p ) { }", &settingsC23, /*cpp*/ false); ASSERT_EQUALS(1, value.intvalue); ASSERT_EQUALS(true, value.isKnown()); - settings.standards.c = Standards::C17; - value = valueOfTok(code, "p ) { }", &settings, /*cpp*/ false); + const Settings settingsC17 = settingsBuilder(settings).c(Standards::C17).build(); + value = valueOfTok(code, "p ) { }", &settingsC17, /*cpp*/ false); ASSERT(value == ValueFlow::Value()); - settings = settingsOld; } void valueFlowSizeofForwardDeclaredEnum() { @@ -7880,48 +7872,47 @@ class TestValueFlow : public TestFixture { void valueFlowDynamicBufferSize() { const char *code; - const Settings settingsOld = settings; // TODO: get rid of this - settings = settingsBuilder(settings).library("posix.cfg").library("bsd.cfg").build(); + const Settings settingsCfg = settingsBuilder(settings).library("posix.cfg").library("bsd.cfg").build(); code = "void* f() {\n" " void* x = malloc(10);\n" " return x;\n" "}"; - ASSERT_EQUALS(true, testValueOfX(code, 3U, 10, ValueFlow::Value::ValueType::BUFFER_SIZE)); + ASSERT_EQUALS(true, testValueOfX(code, 3U, 10, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg)); code = "void* f() {\n" " void* x = calloc(4, 5);\n" " return x;\n" "}"; - ASSERT_EQUALS(true, testValueOfX(code, 3U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE)); + ASSERT_EQUALS(true, testValueOfX(code, 3U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg)); code = "void* f() {\n" " const char* y = \"abcd\";\n" " const char* x = strdup(y);\n" " return x;\n" "}"; - ASSERT_EQUALS(true, testValueOfX(code, 4U, 5, ValueFlow::Value::ValueType::BUFFER_SIZE)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 5, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg)); code = "void* f() {\n" " void* y = malloc(10);\n" " void* x = realloc(y, 20);\n" " return x;\n" "}"; - ASSERT_EQUALS(true, testValueOfX(code, 4U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 20, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg)); code = "void* f() {\n" " void* y = calloc(10, 4);\n" " void* x = reallocarray(y, 20, 5);\n" " return x;\n" "}"; - ASSERT_EQUALS(true, testValueOfX(code, 4U, 100, ValueFlow::Value::ValueType::BUFFER_SIZE)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 100, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg)); code = "struct A {};\n" // #14305 "void* f() {\n" " A* x = new A();\n" " return x;\n" "}"; - ASSERT_EQUALS(true, testValueOfX(code, 4U, 1, ValueFlow::Value::ValueType::BUFFER_SIZE)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 1, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg)); code = "struct A {};\n" "void* f() {\n" @@ -7929,7 +7920,7 @@ class TestValueFlow : public TestFixture { " return x;\n" "}"; { - auto values = tokenValues(code, "x ; }"); + auto values = tokenValues(code, "x ; }", &settingsCfg); ASSERT_EQUALS(1, values.size()); ASSERT(values.front().isSymbolicValue()); // TODO: add BUFFER_SIZE value = 1 @@ -7940,9 +7931,7 @@ class TestValueFlow : public TestFixture { " B* x = new B();\n" " return x;\n" "}"; - ASSERT_EQUALS(true, testValueOfX(code, 4U, 4, ValueFlow::Value::ValueType::BUFFER_SIZE)); - - settings = settingsOld; + ASSERT_EQUALS(true, testValueOfX(code, 4U, 4, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg)); } void valueFlowSafeFunctionParameterValues() { From fecb3496f915944388356346dbab6dd4c08c740c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 7 Aug 2026 07:59:49 +0200 Subject: [PATCH 306/493] Fix #14959 (Warning hash for token-based warnings) (#8778) --- Makefile | 2 +- lib/errorlogger.cpp | 65 ++++++++++++++++++++++++++++++++++++++++-- lib/errorlogger.h | 2 ++ oss-fuzz/Makefile | 2 +- test/cli/other_test.py | 2 +- 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 42b754733ec..a7f3feefba6 100644 --- a/Makefile +++ b/Makefile @@ -600,7 +600,7 @@ $(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h external $(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index d58c5abcbba..d57ad999734 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -23,6 +23,7 @@ #include "path.h" #include "settings.h" #include "suppressions.h" +#include "symboldatabase.h" #include "token.h" #include "tokenlist.h" #include "utils.h" @@ -35,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +108,8 @@ ErrorMessage::ErrorMessage(const std::list& callstack, const Token file0 = list->getFiles()[0]; setmsg(msg); + + calculateWarningHash(callstack); } @@ -126,7 +130,7 @@ ErrorMessage::ErrorMessage(const std::list& callstack, const Token setmsg(msg); - // hash = calculateWarningHash(list, hashWarning.str()); + calculateWarningHash(callstack); } ErrorMessage::ErrorMessage(ErrorPath errorPath, const TokenList *tokenList, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty) @@ -159,7 +163,12 @@ ErrorMessage::ErrorMessage(ErrorPath errorPath, const TokenList *tokenList, Seve setmsg(msg); - // hash = calculateWarningHash(tokenList, hashWarning.str()); + std::list tokens; + std::transform(errorPath.cbegin(), errorPath.cend(), std::back_inserter(tokens), + [](const ErrorPathItem& e) { + return e.first; + }); + calculateWarningHash(tokens); } // TODO: improve errorhandling? @@ -244,6 +253,58 @@ void ErrorMessage::setmsg(const std::string &msg) } } +void ErrorMessage::calculateWarningHash(const std::list& callstack) +{ + if (callstack.empty()) + return; + // Calculate a hash for this warning message + std::string hashString; + for (const Token* tok: callstack) { + if (!tok) + continue; + if (!tok->scope()) + return; // might be a syntax error before scope info has been set + if (tok->scope()->isExecutable()) { + // Executable scope => include all tokens in the function => if the + // function is changed the hash is changed + for (const Token* t = tok; t; t = t->previous()) { + if (!t->scope()->isExecutable()) + break; + hashString += " " + t->str(); + } + for (const Token* t = tok->next(); t; t = t->next()) { + if (!t->scope()->isExecutable()) + break; + hashString += " " + t->str(); + } + } else { + // Non executable scope => include tokens in current statement => if the current statement is changed the hash is changed + for (const Token* t = tok; t; t = t->previous()) { + if (t->str() == ";") + break; + if (t->scope() != tok->scope()) // stop on {} unless its an initializer + break; + hashString += " " + t->str(); + } + for (const Token* t = tok->next(); t; t = t->next()) { + hashString += " " + t->str(); + if (t->str() == ";") + break; + if (t->scope() != tok->scope()) // stop on {} unless its an initializer + break; + } + } + } + + hashString = id + '\n' + mShortMessage + '\n' + hashString; + + // hash algorithm: sdbm + // any hash algorithm can be used but it has to be the same hash on different platforms and compilers + hash = std::accumulate(hashString.cbegin(), hashString.cend(), std::size_t{0}, [](std::size_t h, unsigned char c) { + return static_cast(c) + (h << 6) + (h << 16) - h; + }); +} + static void serializeString(std::string &oss, const std::string & str) { oss += std::to_string(str.length()); diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 97cc3e7f82e..b28fdba244e 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -209,6 +209,8 @@ class CPPCHECKLIB ErrorMessage { private: static std::string fixInvalidChars(const std::string& raw); + void calculateWarningHash(const std::list& callstack); + /** Short message */ std::string mShortMessage; diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index eeb795bd35c..e6966747958 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -270,7 +270,7 @@ $(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h .. $(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h diff --git a/test/cli/other_test.py b/test/cli/other_test.py index c48a0b50354..f5928c07de5 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -2666,7 +2666,7 @@ def test_xml_output(tmp_path): # #13391 / #13485 - + p From 5799d47ee5b641fbb962f4dedeff9f3d2a2a368f Mon Sep 17 00:00:00 2001 From: Swasti Shrivastava <37058682+swasti16@users.noreply.github.com> Date: Fri, 7 Aug 2026 11:41:04 +0530 Subject: [PATCH 307/493] Remove GUI compliance report instructions (feature removed) (#8781) The "Compliance report..." File menu option no longer exists in the Cppcheck Premium GUI. Compliance reports are still available via the command-line `compliance-report` tool, documented in the section immediately below. --- man/manual-premium.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/man/manual-premium.md b/man/manual-premium.md index c8e38666530..9175ef47c8a 100644 --- a/man/manual-premium.md +++ b/man/manual-premium.md @@ -1384,11 +1384,6 @@ If you want to check all files, you can append `:all` to the coding standard. Ex ## Compliance report -### Graphical user interface - -Run a analysis with some coding standards enabled. After that you can click on -the `Compliance report...` in the `File` menu. - ### Command line There is a tool `compliance-report` that is distributed with Cppcheck Premium. To see From dc9bd7fae838e0f374d89fa786cc5949752dd676 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:10:45 +0200 Subject: [PATCH 308/493] Fix #14966 internalError for valid typedef (#8783) --- lib/tokenize.cpp | 7 +++++++ test/testsimplifytypedef.cpp | 3 +++ 2 files changed, 10 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 033462ca2e2..0076ce30875 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -566,11 +566,18 @@ namespace { const auto checkForRecursion = [this]() { if (Token::Match(mTypedefToken, "typedef %name% %name% ;")) return; + int nBraces = 0; for (const Token *tok = mTypedefToken; tok != mEndToken; tok = tok->next()) { + if (tok->str() == "{") + ++nBraces; + else if (tok->str() == "}") + --nBraces; if (tok == mNameToken) continue; if (tok->str() != mNameToken->str()) continue; + if (nBraces > 0 && Token::simpleMatch(tok->next(), ";")) + continue; if (Token::Match(tok->previous(), "struct|class|enum|union")) continue; throw InternalError(tok, "recursive typedef encountered"); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index e83be343e01..f8e3eb1cdf6 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -3879,6 +3879,9 @@ class TestSimplifyTypedef : public TestFixture { void simplifyTypedef164() { const char code[] = "typedef struct D{x;}y y;"; ASSERT_THROW_INTERNAL(tok(code), INTERNAL); + + const char code2[] = "typedef struct { int t; } t;"; // #14966 + ASSERT_EQUALS("struct t { int t ; } ;", tok(code2)); } void simplifyTypedefFunction1() { From 14442692603640cf63098be3387e0f5226bc3faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 7 Aug 2026 15:46:02 +0200 Subject: [PATCH 309/493] Fix #14962: False Positive: missingReturn: return expression misdiagnosed as missing return path (#8780) --- lib/checkfunctions.cpp | 7 ++++++- test/testfunctions.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 1edfdfab6ac..1f17d0bbcdc 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -386,7 +386,12 @@ static const Token *checkMissingReturnScope(const Token *tok, const Library &lib if (!isExhaustiveSwitch(tok->link())) return tok->link(); } else if (tok->scope()->type == ScopeType::eIf) { - const Token *condition = tok->scope()->classDef->next()->astOperand2(); + const Token *paren = tok->link()->linkAt(-1); + if (!paren || !Token::simpleMatch(paren->astOperand1(), "if")) { + tok = tok->link(); + continue; + } + const Token *condition = paren->astOperand2(); if (condition && condition->hasKnownIntValue() && condition->getKnownIntValue() == 1) return checkMissingReturnScope(tok, library); return tok; diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index f5067bc31dc..d5a18f7d916 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -87,6 +87,7 @@ class TestFunctions : public TestFixture { TEST_CASE(checkMissingReturn6); // #13180 TEST_CASE(checkMissingReturn7); // #14370 - FN try/catch TEST_CASE(checkMissingReturn8); + TEST_CASE(checkMissingReturn9); TEST_CASE(checkMissingReturnStdInt); // #14482 - FN std::int32_t // std::move for locar variable @@ -1936,6 +1937,16 @@ class TestFunctions : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void checkMissingReturn9() { + check("struct S { int v; };\n" + " S operator/(S x, S y) { return { x.v / y.v }; }\n" + " S f(int a, int b) {\n" + " if (b) { return S{ a } / S{ b }; }\n" + " else { return {}; }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void checkMissingReturnStdInt() {// #14482 - FN check("std::int32_t f() {}\n"); ASSERT_EQUALS("[test.cpp:1:19]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); From 4b0c239a321ff12bd34627c0913d8712dd105456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Sat, 8 Aug 2026 09:45:12 +0200 Subject: [PATCH 310/493] Fix #14017: Missing varid on namespace member (#8784) --- lib/tokenize.cpp | 6 ++++-- test/testvarid.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 0076ce30875..1a6d4a4e53f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5172,8 +5172,10 @@ static Token * matchMemberName(const std::list &scope, const Token // Current scope.. for (auto it = scope.cbegin(); it != scope.cend(); ++it) { - if (scopeIt == scopeInfo.cend() || scopeIt->name != *it) - return nullptr; + if (scopeIt == scopeInfo.cend() || scopeIt->name != *it) { + scopeIt = scopeInfo.cbegin(); + break; + } ++scopeIt; } diff --git a/test/testvarid.cpp b/test/testvarid.cpp index c8d16bc89a5..e30c613c0bc 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -102,6 +102,7 @@ class TestVarID : public TestFixture { TEST_CASE(varid70); // #12660 - function TEST_CASE(varid71); // #12676 - wrong varid in uninstantiated templated constructor TEST_CASE(varid72); + TEST_CASE(varid73); TEST_CASE(varid_for_1); TEST_CASE(varid_for_2); TEST_CASE(varid_for_3); @@ -1409,6 +1410,14 @@ class TestVarID : public TestFixture { ASSERT_EQUALS(expected1, tokenize(code1)); } + void varid73() { + const char code[] = "namespace a { int x; };\n" + "namespace b { int x = a::x; };\n"; + const char expected[] = "1: namespace a { int x@1 ; } ;\n" + "2: namespace b { int x@2 ; x@2 = a :: x@1 ; } ;\n"; + ASSERT_EQUALS(expected, tokenize(code)); + } + void varid_for_1() { const char code[] = "void foo(int a, int b) {\n" " for (int a=1,b=2;;) {}\n" From b1b7e3ccb5e14da331e45e086df3a73101a00513 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 10 Aug 2026 09:03:31 +0200 Subject: [PATCH 311/493] Fix #14948 FP bufferAccessOutOfBounds after container size check (#8763) Co-authored-by: chrchr-github --- lib/checkbufferoverrun.cpp | 11 +++++++++-- test/testbufferoverrun.cpp | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 8c8912ed06d..f0a12efccec 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -68,7 +68,9 @@ static const ValueFlow::Value *getBufferSizeValue(const Token *tok) auto it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isBufferSizeValue)); if (it != tokenValues.cend()) return &*it; - it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isContainerSizeValue)); + it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), [](const ValueFlow::Value& v) { + return v.isContainerSizeValue() && !v.isImpossible(); + }); return it == tokenValues.cend() ? nullptr : &*it; } @@ -597,6 +599,8 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons ValueFlow::Value bufSizeVal; bufSizeVal.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE; bufSizeVal.intvalue = value->intvalue * elementSize; + bufSizeVal.valueKind = value->valueKind; + bufSizeVal.errorPath = value->errorPath; return bufSizeVal; } } @@ -730,7 +734,10 @@ void CheckBufferOverrunImpl::bufferOverflow() void CheckBufferOverrunImpl::bufferOverflowError(const Token *tok, const ValueFlow::Value *value, Certainty certainty) { - reportError(getErrorPath(tok, value, "Buffer overrun"), Severity::error, "bufferAccessOutOfBounds", "Buffer is accessed out of bounds: " + (tok ? getRealBufferTok(tok)->expressionString() : "buf"), CWE_BUFFER_OVERRUN, certainty); + const auto errorPath = getErrorPath(tok, value, "Buffer overrun"); + const auto severity = !value || value->isKnown() ? Severity::error : Severity::warning; + const std::string msg = "Buffer is accessed out of bounds: " + (tok ? getRealBufferTok(tok)->expressionString() : "buf"); + reportError(errorPath, severity, "bufferAccessOutOfBounds", msg, CWE_BUFFER_OVERRUN, certainty); } //--------------------------------------------------------------------------- diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 8bac50a468c..3914f0ee828 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3628,6 +3628,14 @@ class TestBufferOverrun : public TestFixture { " memset(&a[i], 0, sizeof(a));\n" "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (error) Buffer is accessed out of bounds: &a[i] [bufferAccessOutOfBounds]\n", errout_str()); + + check("void f(const std::vector& s) {\n" // #14948 + " if (s.size() < 4)\n" + " return;\n" + " uint32_t u = 0;\n" + " std::memcpy(&u, &s[0], sizeof(u));\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void buffer_overrun_errorpath() { @@ -3642,6 +3650,15 @@ class TestBufferOverrun : public TestFixture { ASSERT_EQUALS("[test.cpp:3:12]: error: Buffer is accessed out of bounds: p [bufferAccessOutOfBounds]\n" "[test.cpp:2:13]: note: Assign p, buffer with size 10\n" "[test.cpp:3:12]: note: Buffer overrun\n", errout_str()); + + check("void f(const std::vector& s) {\n" + " if (s.size() == 2) {}\n" + " uint32_t u = 0;\n" + " std::memcpy(&u, &s[0], sizeof(u));\n" + "}\n", s); + ASSERT_EQUALS("[test.cpp:4:21]: warning: Buffer is accessed out of bounds: &s[0] [bufferAccessOutOfBounds]\n" + "[test.cpp:2:18]: note: Assuming that condition 's.size()==2' is not redundant\n" + "[test.cpp:4:21]: note: Buffer overrun\n", errout_str()); } void buffer_overrun_bailoutIfSwitch() { From dfcec18902c43786c4e1ab5c01c302fbf718c52d Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Mon, 10 Aug 2026 04:47:39 -0400 Subject: [PATCH 312/493] gtk.cfg: Remove pure annotation from g_str_has_prefix/suffix (#8788) `g_str_has_prefix` and `g_str_has_suffix` are not technically pure because they can log to the console if a precondition fails. This partially reverts commit 7cc7c0bb5. --- Some notes: The original `gtk.cfg` change hasn't been released yet, so the revert shouldn't cause any churn for users. GLib has code like this: ```c gboolean (g_str_has_prefix) (const gchar *str, const gchar *prefix) { g_return_val_if_fail (str != NULL, FALSE); g_return_val_if_fail (prefix != NULL, FALSE); return strncmp (str, prefix, strlen (prefix)) == 0; } ``` Most real-world code is treating this function as safe to call inside of an assert, even though it could technically have side effects if one of the preconditions fails. I removed the pure annotation to err on the side of correctness and pedantry, even though most projects would view the warnings as "false positives" from a practical perspective. Here is example usage from QEMU: ```c char *qemu_chr_get_filename(Chardev *chr) { ChardevClass *cc = CHARDEV_GET_CLASS(chr); const char *typename; if (cc->chr_get_filename) { return cc->chr_get_filename(chr); } typename = object_get_typename(OBJECT(chr)); assert(g_str_has_prefix(typename, "chardev-")); return g_strdup(typename + 8); } ``` --- cfg/gtk.cfg | 1 - test/cfg/gtk.c | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index 5e94a0bbb5c..a1d7763670e 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -5221,7 +5221,6 @@ - false diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c index 6b48bca2f9e..b923135e2d9 100644 --- a/test/cfg/gtk.c +++ b/test/cfg/gtk.c @@ -59,8 +59,14 @@ void validCode(int argInt, GHashTableIter * hash_table_iter, GHashTable * hash_t g_string_free(pGStr1, TRUE); gchar * pGchar1 = g_strconcat("a", "b", NULL); + + // g_str_has_prefix and g_str_has_suffix can have side effects because they use + // g_return_val_if_fail, which logs to the console upon failure + // cppcheck-suppress assertWithSideEffect g_assert_true(g_str_has_prefix(pGchar1, "a")); + // cppcheck-suppress assertWithSideEffect g_assert_true(g_str_has_suffix(pGchar1, "b")); + printf("%s", pGchar1); g_free(pGchar1); From 4184c39b50ab7443ce62ea617ed033cf6812a5df Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:43:27 +0200 Subject: [PATCH 313/493] Fix #14971 [regression] internalError for valid typedef (#8790) Co-authored-by: chrchr-github --- lib/tokenize.cpp | 2 +- test/testsimplifytypedef.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1a6d4a4e53f..27be2e544a2 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -576,7 +576,7 @@ namespace { continue; if (tok->str() != mNameToken->str()) continue; - if (nBraces > 0 && Token::simpleMatch(tok->next(), ";")) + if (nBraces > 0 && Token::Match(tok->next(), "[;(]")) continue; if (Token::Match(tok->previous(), "struct|class|enum|union")) continue; diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index f8e3eb1cdf6..78d7bd25f3d 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -3882,6 +3882,9 @@ class TestSimplifyTypedef : public TestFixture { const char code2[] = "typedef struct { int t; } t;"; // #14966 ASSERT_EQUALS("struct t { int t ; } ;", tok(code2)); + + const char code3[] = "typedef struct S { S() {} } S;"; // #14971 + ASSERT_EQUALS("struct S { S ( ) { } } ;", tok(code3)); } void simplifyTypedefFunction1() { From b3917652c0205dfa2cea97b868186364a0104ebb Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 14 Aug 2026 09:27:11 +0200 Subject: [PATCH 314/493] Fix #14725 FP redundantIfRemove when conditional code has extra code (#8789) --- lib/checkstl.cpp | 3 +++ test/teststl.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index de1d82792ac..cf2b671606f 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1867,6 +1867,9 @@ void CheckStlImpl::redundantCondition() const Token *var3 = var2->tokAt(7); const Token *any2 = var3->tokAt(4); + if (any2->tokAt(3) != scope.bodyEnd) + continue; + // Check if all the "%name%" fields are the same and if all the "%any%" are the same.. if (var1->str() == var2->str() && var2->str() == var3->str() && diff --git a/test/teststl.cpp b/test/teststl.cpp index 2570059c19e..1cc11029804 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4556,6 +4556,16 @@ class TestStl : public TestFixture { " haystack.remove(needle);" "}"); ASSERT_EQUALS("[test.cpp:3:9]: (style) Redundant checking of STL container element existence before removing it. [redundantIfRemove]\n", errout_str()); + + check("void g(const std::string&);\n" // #14725 + "std::set g_s;\n" + "void f(const std::string& k) {\n" + " if (g_s.find(k) != g_s.end()) {\n" + " g_s.erase(k);\n" + " g(k);\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout_str()); } void missingInnerComparison1() { From 2d75160cada40e58bd54afd77f730259e069f8c9 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 14 Aug 2026 09:28:22 +0200 Subject: [PATCH 315/493] Fix #14973 FP assertWithSideEffect with function pointer comparison (#8792) --- lib/checkassert.cpp | 5 +++++ test/testassert.cpp | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index 4578f7395ba..00bb95e319a 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -78,6 +78,11 @@ void CheckAssertImpl::assertWithSideEffects() continue; } + const Token* parent = tmp->astParent(); + while (Token::Match(parent, ".|::")) + parent = parent->astParent(); + if (!Token::simpleMatch(parent, "(")) + continue; const Function* f = tmp->function(); const Scope* scope = f->functionScope; if (!scope) { diff --git a/test/testassert.cpp b/test/testassert.cpp index ea170c43f2d..a76b8207445 100644 --- a/test/testassert.cpp +++ b/test/testassert.cpp @@ -147,6 +147,17 @@ class TestAssert : public TestFixture { " assert(g());\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("int i;\n" // #14973 + "bool f() {\n" + " i = 0;\n" + " return true;\n" + "}\n" + "void g() {\n" + " bool (*fp)() = f;\n" + " assert(fp == f);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void memberFunctionCallInAssert() { From 7d48e00b6da72ff56dbab8fc5c50a89affab237f Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 17 Aug 2026 09:53:39 +0200 Subject: [PATCH 316/493] Fix #14976 FP uninitvar (std::size() used on array) (#8795) Co-authored-by: chrchr-github --- cfg/std.cfg | 4 +--- test/cfg/std.cpp | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index 4662d0a4632..6c434b8715c 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -8343,9 +8343,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - - - + false diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 850dd74b997..e4753a09f7c 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -5071,6 +5071,11 @@ int f_constVariable_std_begin() { return arr[0]; } +std::size_t uninitvar_std_size() { // #14976 + int a[3]; + return std::size(a); +} + void smartPtr_get() { std::unique_ptr p; From ab9989ca09bc7d5bc573e2e6214c422d998c4f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 17 Aug 2026 14:47:44 +0200 Subject: [PATCH 317/493] Fix #14978: Valueflow: Missing buffer size for `::operator new` (#8799) --- lib/valueflow.cpp | 8 +++++++- test/testvalueflow.cpp | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 5efe698bf61..7acf7179723 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7025,6 +7025,12 @@ static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolD auto getBufferSizeFromNew = [&](const Token* newTok) -> MathLib::bigint { MathLib::bigint sizeValue = -1, numElem = -1; + // ::operator new(size_t size) + if (Token::Match(newTok->astOperand1(), "::| operatornew")) { + const Token *sizeTok = newTok->astOperand2(); + return sizeTok->hasKnownIntValue() ? sizeTok->getKnownIntValue() : -1; + } + if (newTok && newTok->astOperand1()) { // number of elements const Token* bracTok = nullptr, *typeTok = nullptr; if (newTok->astOperand1()->str() == "[") @@ -7071,7 +7077,7 @@ static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolD if (!rhs) continue; - const bool isNew = rhs->isCpp() && rhs->str() == "new"; + const bool isNew = rhs->isCpp() && (rhs->str() == "new" || Token::Match(rhs->astOperand1(), "::| operatornew")); if (!isNew && !Token::Match(rhs->previous(), "%name% (")) continue; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 4fc47f63d86..39916ddeb43 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -7932,6 +7932,13 @@ class TestValueFlow : public TestFixture { " return x;\n" "}"; ASSERT_EQUALS(true, testValueOfX(code, 4U, 4, ValueFlow::Value::ValueType::BUFFER_SIZE, &settingsCfg)); + + code = "void f()\n" + "{\n" + " void *x = ::operator new(0);\n" + " (void) x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfX(code, 4U, 0, ValueFlow::Value::ValueType::BUFFER_SIZE)); } void valueFlowSafeFunctionParameterValues() { From 777a112d9a8ddd3f77b206807cbbfb2ee1a1d202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 17 Aug 2026 15:12:57 +0200 Subject: [PATCH 318/493] Fix #14946: `originalName` in dumpfile missing for local typedefs (#8793) --- lib/tokenize.cpp | 103 ++++++++++++++++++----------------- test/testsimplifytypedef.cpp | 32 +++++++++++ 2 files changed, 85 insertions(+), 50 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 27be2e544a2..bc50979a04f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1187,21 +1187,23 @@ void Tokenizer::simplifyTypedef() simplifyTypedefCpp(); } -static Token* simplifyTypedefCopyTokens(Token* to, const Token* fromStart, const Token* toEnd, const Token* location) { +static Token* simplifyTypedefCopyTokens(Token* to, const Token* fromStart, const Token* toEnd, const Token* location, const std::string &originalName) { Token* ret = TokenList::copyTokens(to, fromStart, toEnd); for (Token* tok = to->next(); tok != ret->next(); tok = tok->next()) { tok->linenr(location->linenr()); tok->column(location->column()); tok->isSimplifiedTypedef(true); + tok->originalName(originalName); } return ret; } -static Token* simplifyTypedefInsertToken(Token* tok, const std::string& str, const Token* location) { +static Token* simplifyTypedefInsertToken(Token* tok, const std::string& str, const Token* location, const std::string &originalName) { tok = tok->insertToken(str); tok->linenr(location->linenr()); tok->column(location->column()); tok->isSimplifiedTypedef(true); + tok->originalName(originalName); return tok; } @@ -2037,12 +2039,13 @@ void Tokenizer::simplifyTypedefCpp() // start substituting at the typedef name by replacing it with the type const Token* location = tok2; + const std::string originalName = tok2->str(); for (Token* tok3 = typeStart; tok3 && (tok3->str() != ";"); tok3 = tok3->next()) tok3->isSimplifiedTypedef(true); if (isPointerTypeCall) { tok2->deleteThis(); - tok2 = simplifyTypedefInsertToken(tok2, "0", location); - simplifyTypedefInsertToken(tok2->next(), "0", location); + tok2 = simplifyTypedefInsertToken(tok2, "0", location, originalName); + simplifyTypedefInsertToken(tok2->next(), "0", location, originalName); } if (Token::Match(tok2->tokAt(-1), "class|struct|union") && tok2->strAt(-1) == typeStart->str()) tok2->deletePrevious(); @@ -2051,7 +2054,7 @@ void Tokenizer::simplifyTypedefCpp() tok2->previous()->str("typedef"); tok2->insertToken(tok2->str()); } - tok2->originalName(tok2->str()); + tok2->originalName(originalName); tok2->str(typeStart->str()); // restore qualification if it was removed @@ -2060,12 +2063,12 @@ void Tokenizer::simplifyTypedefCpp() tok2 = tok2->previous(); if (globalScope) { - tok2 = simplifyTypedefInsertToken(tok2, "::", location); + tok2 = simplifyTypedefInsertToken(tok2, "::", location, originalName); } for (std::size_t i = classLevel; i < spaceInfo.size(); ++i) { - tok2 = simplifyTypedefInsertToken(tok2, spaceInfo[i].className, location); - tok2 = simplifyTypedefInsertToken(tok2, "::", location); + tok2 = simplifyTypedefInsertToken(tok2, spaceInfo[i].className, location, originalName); + tok2 = simplifyTypedefInsertToken(tok2, "::", location, originalName); } } @@ -2082,11 +2085,11 @@ void Tokenizer::simplifyTypedefCpp() std::string::size_type spaceIdx = 0; std::string::size_type startIdx = 0; while ((spaceIdx = removed1.find(' ', startIdx)) != std::string::npos) { - simplifyTypedefInsertToken(tok2->previous(), removed1.substr(startIdx, spaceIdx - startIdx), location); + simplifyTypedefInsertToken(tok2->previous(), removed1.substr(startIdx, spaceIdx - startIdx), location, originalName); startIdx = spaceIdx + 1; } - simplifyTypedefInsertToken(tok2->previous(), removed1.substr(startIdx), location); - simplifyTypedefInsertToken(tok2->previous(), "::", location); + simplifyTypedefInsertToken(tok2->previous(), removed1.substr(startIdx), location, originalName); + simplifyTypedefInsertToken(tok2->previous(), "::", location, originalName); break; } idx = removed1.rfind(" ::"); @@ -2098,23 +2101,23 @@ void Tokenizer::simplifyTypedefCpp() } Token* constTok = Token::simpleMatch(tok2->previous(), "const") ? tok2->previous() : nullptr; // add remainder of type - tok2 = simplifyTypedefCopyTokens(tok2, typeStart->next(), typeEnd, location); + tok2 = simplifyTypedefCopyTokens(tok2, typeStart->next(), typeEnd, location, originalName); if (!pointers.empty()) { for (const std::string &p : pointers) // cppcheck-suppress useStlAlgorithm - tok2 = simplifyTypedefInsertToken(tok2, p, location); + tok2 = simplifyTypedefInsertToken(tok2, p, location, originalName); if (constTok && !functionPtr) { - tok2 = simplifyTypedefInsertToken(tok2, "const", location); + tok2 = simplifyTypedefInsertToken(tok2, "const", location, originalName); constTok->deleteThis(); location = constTok; } } if (funcStart && funcEnd) { - tok2 = simplifyTypedefInsertToken(tok2, "(", location); + tok2 = simplifyTypedefInsertToken(tok2, "(", location, originalName); Token *paren = tok2; - tok2 = simplifyTypedefCopyTokens(tok2, funcStart, funcEnd, location); + tok2 = simplifyTypedefCopyTokens(tok2, funcStart, funcEnd, location, originalName); if (!inCast) tok2 = processFunc(tok2, inOperator); @@ -2125,17 +2128,17 @@ void Tokenizer::simplifyTypedefCpp() while (Token::Match(tok2, "%name%|] [")) tok2 = tok2->linkAt(1); - tok2 = simplifyTypedefInsertToken(tok2, ")", location); + tok2 = simplifyTypedefInsertToken(tok2, ")", location, originalName); Token::createMutualLinks(tok2, paren); - tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location); + tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location, originalName); if (specStart) { Token *spec = specStart; - tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location); + tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location, originalName); while (spec != specEnd) { spec = spec->next(); - tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location); + tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location, originalName); } } } @@ -2147,20 +2150,20 @@ void Tokenizer::simplifyTypedefCpp() if (!inTemplate && function && tok2->next() && tok2->strAt(1) != "*") needParen = false; if (needParen) { - tok2 = simplifyTypedefInsertToken(tok2, "(", location); + tok2 = simplifyTypedefInsertToken(tok2, "(", location, originalName); } Token *tok3 = tok2; if (namespaceStart) { const Token *tok4 = namespaceStart; while (tok4 != namespaceEnd) { - tok2 = simplifyTypedefInsertToken(tok2, tok4->str(), location); + tok2 = simplifyTypedefInsertToken(tok2, tok4->str(), location, originalName); tok4 = tok4->next(); } - tok2 = simplifyTypedefInsertToken(tok2, namespaceEnd->str(), location); + tok2 = simplifyTypedefInsertToken(tok2, namespaceEnd->str(), location, originalName); } if (functionPtr) { - tok2 = simplifyTypedefInsertToken(tok2, "*", location); + tok2 = simplifyTypedefInsertToken(tok2, "*", location, originalName); } if (!inCast) @@ -2170,35 +2173,35 @@ void Tokenizer::simplifyTypedefCpp() if (!tok2) syntaxError(nullptr); - tok2 = simplifyTypedefInsertToken(tok2, ")", location); + tok2 = simplifyTypedefInsertToken(tok2, ")", location, originalName); Token::createMutualLinks(tok2, tok3); } if (!tok2) syntaxError(nullptr); - tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location); + tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location, originalName); if (inTemplate) { tok2 = tok2->next(); } if (specStart) { Token *spec = specStart; - tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location); + tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location, originalName); while (spec != specEnd) { spec = spec->next(); - tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location); + tok2 = simplifyTypedefInsertToken(tok2, spec->str(), location, originalName); } } } else if (functionRetFuncPtr || functionPtrRetFuncPtr) { - tok2 = simplifyTypedefInsertToken(tok2, "(", location); + tok2 = simplifyTypedefInsertToken(tok2, "(", location, originalName); Token *tok3 = tok2; - tok2 = simplifyTypedefInsertToken(tok2, "*", location); + tok2 = simplifyTypedefInsertToken(tok2, "*", location, originalName); Token * tok4 = nullptr; if (functionPtrRetFuncPtr) { - tok2 = simplifyTypedefInsertToken(tok2, "(", location); + tok2 = simplifyTypedefInsertToken(tok2, "(", location, originalName); tok4 = tok2; - tok2 = simplifyTypedefInsertToken(tok2, "*", location); + tok2 = simplifyTypedefInsertToken(tok2, "*", location, originalName); } // skip over variable name if there @@ -2211,24 +2214,24 @@ void Tokenizer::simplifyTypedefCpp() } if (tok4 && functionPtrRetFuncPtr) { - tok2 = simplifyTypedefInsertToken(tok2,")", location); + tok2 = simplifyTypedefInsertToken(tok2,")", location, originalName); Token::createMutualLinks(tok2, tok4); } - tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location); + tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location, originalName); - tok2 = simplifyTypedefInsertToken(tok2, ")", location); + tok2 = simplifyTypedefInsertToken(tok2, ")", location, originalName); Token::createMutualLinks(tok2, tok3); - tok2 = simplifyTypedefCopyTokens(tok2, argFuncRetStart, argFuncRetEnd, location); + tok2 = simplifyTypedefCopyTokens(tok2, argFuncRetStart, argFuncRetEnd, location, originalName); } else if (ptrToArray || refToArray) { - tok2 = simplifyTypedefInsertToken(tok2, "(", location); + tok2 = simplifyTypedefInsertToken(tok2, "(", location, originalName); Token *tok3 = tok2; if (ptrToArray) - tok2 = simplifyTypedefInsertToken(tok2, "*", location); + tok2 = simplifyTypedefInsertToken(tok2, "*", location, originalName); else - tok2 = simplifyTypedefInsertToken(tok2, "&", location); + tok2 = simplifyTypedefInsertToken(tok2, "&", location, originalName); bool hasName = false; // skip over name @@ -2247,14 +2250,14 @@ void Tokenizer::simplifyTypedefCpp() tok2 = tok2->linkAt(1); } - simplifyTypedefInsertToken(tok2, ")", location); + simplifyTypedefInsertToken(tok2, ")", location, originalName); Token::createMutualLinks(tok2->next(), tok3); if (!hasName) tok2 = tok2->next(); } else if (ptrMember) { if (Token::simpleMatch(tok2, "* (")) { - tok2 = simplifyTypedefInsertToken(tok2, "*", location); + tok2 = simplifyTypedefInsertToken(tok2, "*", location, originalName); } else { // This is the case of casting operator. // Name is not available, and () should not be @@ -2263,7 +2266,7 @@ void Tokenizer::simplifyTypedefCpp() Token *openParenthesis = nullptr; if (!castOperator) { - tok2 = simplifyTypedefInsertToken(tok2, "(", location); + tok2 = simplifyTypedefInsertToken(tok2, "(", location, originalName); openParenthesis = tok2; } @@ -2271,25 +2274,25 @@ void Tokenizer::simplifyTypedefCpp() const Token *tok4 = namespaceStart; while (tok4 != namespaceEnd) { - tok2 = simplifyTypedefInsertToken(tok2, tok4->str(), location); + tok2 = simplifyTypedefInsertToken(tok2, tok4->str(), location, originalName); tok4 = tok4->next(); } - tok2 = simplifyTypedefInsertToken(tok2, namespaceEnd->str(), location); + tok2 = simplifyTypedefInsertToken(tok2, namespaceEnd->str(), location, originalName); - tok2 = simplifyTypedefInsertToken(tok2, "*", location); + tok2 = simplifyTypedefInsertToken(tok2, "*", location, originalName); if (openParenthesis) { // Skip over name, if any if (Token::Match(tok2->next(), "%name%")) tok2 = tok2->next(); - tok2 = simplifyTypedefInsertToken(tok2, ")", location); + tok2 = simplifyTypedefInsertToken(tok2, ")", location, originalName); Token::createMutualLinks(tok2, openParenthesis); } } } else if (typeOf) { - tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location); + tok2 = simplifyTypedefCopyTokens(tok2, argStart, argEnd, location, originalName); } else if (Token::Match(tok2, "%name% [")) { while (Token::Match(tok2, "%name%|] [")) { tok2 = tok2->linkAt(1); @@ -2311,7 +2314,7 @@ void Tokenizer::simplifyTypedefCpp() // reference or pointer to array? if (Token::Match(tok2, "&|*|&&")) { tok2 = tok2->previous(); - Token *tok3 = simplifyTypedefInsertToken(tok2, "(", location); + Token *tok3 = simplifyTypedefInsertToken(tok2, "(", location, originalName); // handle missing variable name if (Token::Match(tok3, "( *|&|&& *|&|&& %name%")) @@ -2349,7 +2352,7 @@ void Tokenizer::simplifyTypedefCpp() tok2 = tok2->tokAt(3); } - tok2 = simplifyTypedefInsertToken(tok2, ")", location); + tok2 = simplifyTypedefInsertToken(tok2, ")", location, originalName); Token::createMutualLinks(tok2, tok3); } @@ -2360,7 +2363,7 @@ void Tokenizer::simplifyTypedefCpp() while (tok2->strAt(1) == "[") tok2 = tok2->linkAt(1); - tok2 = simplifyTypedefCopyTokens(tok2, arrayStart, arrayEnd, location); + tok2 = simplifyTypedefCopyTokens(tok2, arrayStart, arrayEnd, location, originalName); if (!tok2->next()) syntaxError(tok2); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 78d7bd25f3d..330808b7220 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -257,6 +257,8 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedefOriginalName1); TEST_CASE(simplifyTypedefOriginalName2); TEST_CASE(simplifyTypedefOriginalName3); + TEST_CASE(simplifyTypedefOriginalName4); + TEST_CASE(simplifyTypedefOriginalName5); TEST_CASE(simplifyTypedefTokenColumn1); TEST_CASE(simplifyTypedefTokenColumn2); @@ -4622,6 +4624,36 @@ class TestSimplifyTypedef : public TestFixture { ASSERT_EQUALS("A", token->originalName()); } + void simplifyTypedefOriginalName4() { + const char code[] = "void f(void) {\n" + " typedef unsigned int A;\n" + " A a;\n" + "}\n"; + TokenList tokenlist{ settings1, Standards::Language::C }; + ASSERT(TokenListHelper::createTokensFromString(tokenlist, code, "file.c")); + TokenizerTest tokenizer(std::move(tokenlist), *this); + tokenizer.createLinks(); + tokenizer.simplifyTypedef(); + ASSERT_NO_THROW(tokenizer.validate()); + const Token* token = Token::findsimplematch(tokenizer.list.front(), "int"); + ASSERT_EQUALS("A", token->originalName()); + } + + void simplifyTypedefOriginalName5() { + const char code[] = "void f(void) {\n" + " typedef void (*A)(int);\n" + " A a;\n" + "}\n"; + TokenList tokenlist{ settings1, Standards::Language::C }; + ASSERT(TokenListHelper::createTokensFromString(tokenlist, code, "file.c")); + TokenizerTest tokenizer(std::move(tokenlist), *this); + tokenizer.createLinks(); + tokenizer.simplifyTypedef(); + ASSERT_NO_THROW(tokenizer.validate()); + const Token* token = Token::findsimplematch(tokenizer.list.front(), "int"); + ASSERT_EQUALS("A", token->originalName()); + } + void simplifyTypedefTokenColumn1() { // #13155 const char code[] = "void foo(void) {\n" " typedef signed int MY_INT;\n" From 2e19539840f28d059b7e9fa2402e81994d9d0d23 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 18 Aug 2026 17:04:48 +0200 Subject: [PATCH 319/493] Fix #14977 internalError for valid typedef (operator=) (#8798) Co-authored-by: chrchr-github --- lib/tokenize.cpp | 4 ++-- test/testsimplifytypedef.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index bc50979a04f..b22658db28c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -572,12 +572,12 @@ namespace { ++nBraces; else if (tok->str() == "}") --nBraces; + if (nBraces > 0) + continue; if (tok == mNameToken) continue; if (tok->str() != mNameToken->str()) continue; - if (nBraces > 0 && Token::Match(tok->next(), "[;(]")) - continue; if (Token::Match(tok->previous(), "struct|class|enum|union")) continue; throw InternalError(tok, "recursive typedef encountered"); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 330808b7220..6e8b8820177 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -3887,6 +3887,9 @@ class TestSimplifyTypedef : public TestFixture { const char code3[] = "typedef struct S { S() {} } S;"; // #14971 ASSERT_EQUALS("struct S { S ( ) { } } ;", tok(code3)); + + const char code4[] = "typedef struct S { S& operator=(const S&) = delete; } S;"; // #14977 + ASSERT_EQUALS("struct S { S & operator= ( const S & ) = delete ; } ;", tok(code4)); } void simplifyTypedefFunction1() { From 9699b99f66bfce37e8d946c18944e2c515549d26 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 21 Aug 2026 19:07:30 +0200 Subject: [PATCH 320/493] Fix #14980 Nullptr dereference in valueFlowDynamicBufferSize() (#8802) Co-authored-by: chrchr-github --- lib/valueflow.cpp | 2 +- test/testvalueflow.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7acf7179723..4a41bd90537 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7077,7 +7077,7 @@ static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolD if (!rhs) continue; - const bool isNew = rhs->isCpp() && (rhs->str() == "new" || Token::Match(rhs->astOperand1(), "::| operatornew")); + const bool isNew = rhs->isCpp() && (rhs->str() == "new" || (rhs->str() == "(" && Token::Match(rhs->astOperand1(), "::| operatornew"))); if (!isNew && !Token::Match(rhs->previous(), "%name% (")) continue; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 39916ddeb43..0762dacfcdb 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -8488,6 +8488,11 @@ class TestValueFlow : public TestFixture { " };\n" "}\n"; (void)valueOfTok(code, "E0"); + + code = "void f() {\n" // #14980 + " OpNew *newp = &operator new;\n" + "}\n"; + (void)valueOfTok(code, "&"); } void valueFlowHang() { From 8f7666dd3e07027c7d0325ec835b83818e9fb6d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 21 Aug 2026 19:35:31 +0200 Subject: [PATCH 321/493] Fix #14983 (GUI: exclude file with relative path) (#8804) --- gui/manualtest/projectfiledialog.md | 14 +++++++++ gui/projectfile.cpp | 9 ++++++ gui/projectfile.h | 8 +++++ gui/projectfiledialog.cpp | 13 ++++---- gui/test/projectfile/testprojectfile.cpp | 40 ++++++++++++++++++++++++ gui/test/projectfile/testprojectfile.h | 6 ++++ 6 files changed, 83 insertions(+), 7 deletions(-) diff --git a/gui/manualtest/projectfiledialog.md b/gui/manualtest/projectfiledialog.md index f11b030f246..ce7d39b1df0 100644 --- a/gui/manualtest/projectfiledialog.md +++ b/gui/manualtest/projectfiledialog.md @@ -4,6 +4,20 @@ Some manual testing in the project file dialog interface +## Test: Relative paths + +Ticket: #14983 + +1. Configure files/paths in project folder: + * import a projectfile + * add include paths in project folder + * exclude file/folder + +2. Save project + +EXPECTED: Relative paths should be used in the XML + + ## Test: Platform file pic8.xml Ticket: #14489 diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index 9144f5a6117..716288d9695 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -1193,6 +1193,15 @@ QStringList ProjectFile::getSearchPaths(const QString& projectPath, const QStrin return ret; } +QString ProjectFile::getRelativePath(const QString &absolutePath) const +{ + const QDir dir(QFileInfo(mFilename).absolutePath()); + const QString relativePath(dir.relativeFilePath(absolutePath)); + if (relativePath.startsWith("../../..") || absolutePath.length() < relativePath.length()) + return absolutePath; + return relativePath; +} + QStringList ProjectFile::getSearchPaths(const QString& dir) const { const QFileInfo inf(mFilename); const QString applicationFilePath = QCoreApplication::applicationFilePath(); diff --git a/gui/projectfile.h b/gui/projectfile.h index 5a5e0ccb89b..e0b85582c99 100644 --- a/gui/projectfile.h +++ b/gui/projectfile.h @@ -447,6 +447,14 @@ class ProjectFile : public QObject { static QStringList getSearchPaths(const QString& projectPath, const QString& appPath, const QString& datadir, const QString& dir); + /** + * @brief Convert an absolute path to a path relative to this project's directory. + * If the relative path would need to walk up more than 2 parent folders + * (i.e. "../../...") the absolute path is returned unchanged instead. + * @param absolutePath Absolute path to convert. + */ + QString getRelativePath(const QString &absolutePath) const; + /** Set user includes in settings if non-empty */ void setSettingsUserIncludes(Settings &settings) const; diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index 72e3d651471..abb7b343ec1 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -571,10 +571,7 @@ QString ProjectFileDialog::getExistingDirectory(const QString &caption, bool tra // Check if the path is relative to project file's path and if so // make it a relative path instead of absolute path. - const QDir dir(projectPath); - const QString relpath(dir.relativeFilePath(selectedDir)); - if (!relpath.startsWith("../..")) - selectedDir = relpath; + selectedDir = mProjectFile->getRelativePath(selectedDir); // Trailing slash.. if (trailingSlash && !selectedDir.endsWith('/')) @@ -631,7 +628,7 @@ void ProjectFileDialog::browseImportProject() dir.canonicalPath(), toFilterString(filters)); if (!fileName.isEmpty()) { - mUI->mEditImportProject->setText(dir.relativeFilePath(fileName)); + mUI->mEditImportProject->setText(mProjectFile->getRelativePath(fileName)); updatePathsAndDefines(); setProjectConfigurations(getProjectConfigs(fileName)); for (int row = 0; row < mUI->mListVsConfigs->count(); ++row) { @@ -652,7 +649,7 @@ void ProjectFileDialog::browseUserInclude() dir.canonicalPath(), toFilterString(filters)); if (!fileName.isEmpty()) { - mUI->mEditUserInclude->setText(dir.relativeFilePath(fileName)); + mUI->mEditUserInclude->setText(mProjectFile->getRelativePath(fileName)); } } @@ -891,7 +888,9 @@ void ProjectFileDialog::addExcludeFile() QMap filters; filters[tr("Source files")] = "*.c *.cpp"; filters[tr("All files")] = "*.*"; - addExcludePath(QFileDialog::getOpenFileName(this, tr("Exclude file"), dir.canonicalPath(), toFilterString(filters))); + QString fileName = QFileDialog::getOpenFileName(this, tr("Exclude file"), dir.canonicalPath(), toFilterString(filters)); + if (!fileName.isEmpty()) + addExcludePath(mProjectFile->getRelativePath(fileName)); } void ProjectFileDialog::editExcludePath() diff --git a/gui/test/projectfile/testprojectfile.cpp b/gui/test/projectfile/testprojectfile.cpp index efc1dce6c4f..1a66bd8de23 100644 --- a/gui/test/projectfile/testprojectfile.cpp +++ b/gui/test/projectfile/testprojectfile.cpp @@ -214,5 +214,45 @@ void TestProjectFile::emptyUserInclude() const QCOMPARE(settings.userIncludes.size(), 0); } +// Absolute path is made relative when it does not require walking up more than 3 parent folders +void TestProjectFile::getRelativePathRelative() const +{ + ProjectFile projectFile; + projectFile.setFilename("/some/path/sub/123.cppcheck"); + QCOMPARE(projectFile.getRelativePath("/some/path/externals/foo.cpp"), QString("../externals/foo.cpp")); +} + +// Absolute path is made relative even when it requires walking up 2 parent folders +void TestProjectFile::getRelativePathTwoUp() const +{ + ProjectFile projectFile; + projectFile.setFilename("/some/path/sub/123.cppcheck"); + QCOMPARE(projectFile.getRelativePath("/some/externals/foo.cpp"), QString("../../externals/foo.cpp")); +} + +// Absolute path is kept as-is when making it relative would require walking up more than 3 parent folders +void TestProjectFile::getRelativePathTooFarUp() const +{ + ProjectFile projectFile; + projectFile.setFilename("/some/path/sub/123.cppcheck"); + QCOMPARE(projectFile.getRelativePath("/other/deep/foo.cpp"), QString("/other/deep/foo.cpp")); +} + +// Absolute path in a subfolder of the project path is made relative without walking up at all +void TestProjectFile::getRelativePathSubfolder() const +{ + ProjectFile projectFile; + projectFile.setFilename("/some/path/sub/123.cppcheck"); + QCOMPARE(projectFile.getRelativePath("/some/path/sub/src/file1.c"), QString("src/file1.c")); +} + +// Absolute path is kept as-is when it is shorter than the relative path, even if it does not require walking up 3 or more parent folders +void TestProjectFile::getRelativePathAbsoluteShorter() const +{ + ProjectFile projectFile; + projectFile.setFilename("/ab/path/sub/123.cppcheck"); + QCOMPARE(projectFile.getRelativePath("/ab/foo.cpp"), QString("/ab/foo.cpp")); +} + QTEST_MAIN(TestProjectFile) diff --git a/gui/test/projectfile/testprojectfile.h b/gui/test/projectfile/testprojectfile.h index ceda2ff6b96..7203980eb7c 100644 --- a/gui/test/projectfile/testprojectfile.h +++ b/gui/test/projectfile/testprojectfile.h @@ -38,4 +38,10 @@ private slots: void getCheckingSuppressionsStar() const; void emptyUserInclude() const; + + void getRelativePathRelative() const; + void getRelativePathTwoUp() const; + void getRelativePathTooFarUp() const; + void getRelativePathSubfolder() const; + void getRelativePathAbsoluteShorter() const; }; From 5e7baff38ff8fbb87c4a25de33345436386febb5 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 23 Aug 2026 19:33:03 +0200 Subject: [PATCH 322/493] Fix #14960 Inconsistent bufferAccessOutOfBounds (possible values) (#8779) After #8763 --------- Co-authored-by: chrchr-github --- lib/checkbufferoverrun.cpp | 33 ++++++++++++++++++++++----------- test/testbufferoverrun.cpp | 17 +++++++++++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index f0a12efccec..b3aa09d137c 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -629,7 +629,7 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons } //--------------------------------------------------------------------------- -static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::MinSize &minsize, const std::vector &args, const MathLib::bigint bufferSize, const Settings &settings, const Tokenizer* tokenizer) +static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::MinSize &minsize, const std::vector &args, ValueFlow::Value& bufferSize, const Settings &settings, const Tokenizer* tokenizer) { const Token * const arg = (minsize.arg > 0 && minsize.arg - 1 < args.size()) ? args[minsize.arg - 1] : nullptr; const Token * const arg2 = (minsize.arg2 > 0 && minsize.arg2 - 1 < args.size()) ? args[minsize.arg2 - 1] : nullptr; @@ -637,20 +637,31 @@ static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::Mi switch (minsize.type) { case Library::ArgumentChecks::MinSize::Type::STRLEN: if (settings.library.isargformatstr(ftok, minsize.arg)) { - return getMinFormatStringOutputLength(args, minsize.arg, settings) < bufferSize; + return getMinFormatStringOutputLength(args, minsize.arg, settings) < bufferSize.intvalue; } else if (arg) { const Token *strtoken = arg->getValueTokenMaxStrLength(); if (strtoken) - return Token::getStrLength(strtoken) < bufferSize; + return Token::getStrLength(strtoken) < bufferSize.intvalue; } break; case Library::ArgumentChecks::MinSize::Type::ARGVALUE: { - if (arg && arg->hasKnownIntValue()) { - MathLib::bigint myMinsize = arg->getKnownIntValue(); + if (arg) { + const ValueFlow::Value* argVal = arg->hasKnownIntValue() ? + arg->getKnownValue(ValueFlow::Value::ValueType::INT) : + arg->getMaxValue(/*condition*/ true); + if (!argVal) + break; + MathLib::bigint myMinsize = argVal->intvalue; const int baseSize = tokenizer->sizeOfType(minsize.baseType); if (baseSize != 0) myMinsize *= baseSize; - return myMinsize <= bufferSize; + const bool ok = myMinsize <= bufferSize.intvalue; + if (!ok) { + bufferSize.errorPath.insert(bufferSize.errorPath.end(), argVal->errorPath.begin(), argVal->errorPath.end()); + if (!bufferSize.condition) + bufferSize.condition = argVal->condition; + } + return ok; } break; } @@ -659,14 +670,14 @@ static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::Mi break; case Library::ArgumentChecks::MinSize::Type::MUL: if (arg && arg2 && arg->hasKnownIntValue() && arg2->hasKnownIntValue()) - return (arg->getKnownIntValue() * arg2->getKnownIntValue()) <= bufferSize; + return (arg->getKnownIntValue() * arg2->getKnownIntValue()) <= bufferSize.intvalue; break; case Library::ArgumentChecks::MinSize::Type::VALUE: { MathLib::bigint myMinsize = minsize.value; const int baseSize = tokenizer->sizeOfType(minsize.baseType); if (baseSize != 0) myMinsize *= baseSize; - return myMinsize <= bufferSize; + return myMinsize <= bufferSize.intvalue; } case Library::ArgumentChecks::MinSize::Type::NONE: break; @@ -704,7 +715,7 @@ void CheckBufferOverrunImpl::bufferOverflow() if (argtok->valueType() && argtok->valueType()->pointer == 0) continue; // TODO: strcpy(buf+10, "hello"); - const ValueFlow::Value bufferSize = getBufferSize(argtok, mSettings); + ValueFlow::Value bufferSize = getBufferSize(argtok, mSettings); if (bufferSize.intvalue <= 0) continue; // buffer size == 1 => do not warn for dynamic memory @@ -723,7 +734,7 @@ void CheckBufferOverrunImpl::bufferOverflow() } } const bool error = std::none_of(minsizes->begin(), minsizes->end(), [&](const Library::ArgumentChecks::MinSize &minsize) { - return checkBufferSize(tok, minsize, args, bufferSize.intvalue, mSettings, mTokenizer); + return checkBufferSize(tok, minsize, args, bufferSize, mSettings, mTokenizer); }); if (error) bufferOverflowError(args[argnr], &bufferSize, Certainty::normal); @@ -735,7 +746,7 @@ void CheckBufferOverrunImpl::bufferOverflow() void CheckBufferOverrunImpl::bufferOverflowError(const Token *tok, const ValueFlow::Value *value, Certainty certainty) { const auto errorPath = getErrorPath(tok, value, "Buffer overrun"); - const auto severity = !value || value->isKnown() ? Severity::error : Severity::warning; + const auto severity = !value || (value->isKnown() && !value->condition) ? Severity::error : Severity::warning; const std::string msg = "Buffer is accessed out of bounds: " + (tok ? getRealBufferTok(tok)->expressionString() : "buf"); reportError(errorPath, severity, "bufferAccessOutOfBounds", msg, CWE_BUFFER_OVERRUN, certainty); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 3914f0ee828..229b2883b9e 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3659,6 +3659,23 @@ class TestBufferOverrun : public TestFixture { ASSERT_EQUALS("[test.cpp:4:21]: warning: Buffer is accessed out of bounds: &s[0] [bufferAccessOutOfBounds]\n" "[test.cpp:2:18]: note: Assuming that condition 's.size()==2' is not redundant\n" "[test.cpp:4:21]: note: Buffer overrun\n", errout_str()); + + check("void f(int i) {\n" // #14960 + " int a[1];\n" + " if (i != 2) return;\n" + " memset(a, 0, i * sizeof(int));\n" + "}" + "void g(int i) {\n" + " int a[1];\n" + " if (i != 2) {}\n" + " memset(a, 0, i * sizeof(int));\n" + "}", s); + ASSERT_EQUALS("[test.cpp:4:12]: warning: Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n" + "[test.cpp:3:11]: note: Assuming that condition 'i!=2' is not redundant\n" + "[test.cpp:4:12]: note: Buffer overrun\n" + "[test.cpp:8:12]: warning: Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n" + "[test.cpp:7:11]: note: Assuming that condition 'i!=2' is not redundant\n" + "[test.cpp:8:12]: note: Buffer overrun\n", errout_str()); } void buffer_overrun_bailoutIfSwitch() { From 518010a753d865caf1d3aab8801737c6be2cfd6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 24 Aug 2026 14:37:42 +0200 Subject: [PATCH 323/493] Fix #14984: Valueflow: Buffer size not tracked across function calls (#8806) --- lib/valueflow.cpp | 2 +- test/cli/other_test.py | 2 ++ test/testvalueflow.cpp | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 4a41bd90537..e956c92c5e0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7541,6 +7541,7 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(valueFlowInferCondition(tokenlist, settings)), VFA(valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings)), + VFA(valueFlowDynamicBufferSize(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowFunctionReturn(tokenlist, errorLogger, settings)), VFA(valueFlowLifetime(tokenlist, errorLogger, settings)), @@ -7557,7 +7558,6 @@ void ValueFlow::setValues(TokenList& tokenlist, }); runner.run_once({ - VFA(valueFlowDynamicBufferSize(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowDebug(tokenlist, errorLogger, settings)), // TODO: add option to print it after each step/iteration }); } diff --git a/test/cli/other_test.py b/test/cli/other_test.py index f5928c07de5..4d4dbec7b0a 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -210,6 +210,8 @@ def test_progress(tmpdir): "progress: ValueFlow::valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" "progress: ValueFlow::valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" "progress: ValueFlow::valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" + "progress: ValueFlow::valueFlowDynamicBufferSize(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" + "progress: ValueFlow::valueFlowDynamicBufferSize(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" "progress: ValueFlow::valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings) 1 0%\n" "progress: ValueFlow::valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings) 1 100%\n" "progress: ValueFlow::valueFlowFunctionReturn(tokenlist, errorLogger, settings) 1 0%\n" diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 0762dacfcdb..98c4271f509 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -7939,6 +7939,17 @@ class TestValueFlow : public TestFixture { " (void) x;\n" "}\n"; ASSERT_EQUALS(true, testValueOfX(code, 4U, 0, ValueFlow::Value::ValueType::BUFFER_SIZE)); + + code = "void f(int *x)\n" + "{\n" + " *x = 1;\n" + "}\n" + "void g(void)\n" + "{\n" + " int *ptr = malloc(1234);\n" + " f(ptr);\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, 1234, ValueFlow::Value::ValueType::BUFFER_SIZE)); } void valueFlowSafeFunctionParameterValues() { From ac8c1aadcc153f3ef9bd199d304390b82cd76770 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 25 Aug 2026 19:11:11 +0200 Subject: [PATCH 324/493] Partial fix for #14982 internalAstError for noexcept function with requires clause (#8808) Co-authored-by: chrchr-github --- lib/templatesimplifier.cpp | 2 +- test/testsimplifytemplate.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 24cc0bcbe1d..a194c0c8793 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -3831,7 +3831,7 @@ void TemplateSimplifier::simplifyTemplates(const std::time_t maxtime) // Remove concepts/requires // TODO concepts are not removed yet for (Token *tok = mTokenList.front(); tok; tok = tok->next()) { - if (!Token::Match(tok, ")|>|>> requires %name%|(")) + if (!Token::Match(tok, ")|>|>>|const|noexcept requires %name%|(")) continue; const Token* end = skipRequires(tok->next()); if (end) diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 6960b791426..b37ed03db34 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -314,6 +314,7 @@ class TestSimplifyTemplate : public TestFixture { TEST_CASE(requires3); TEST_CASE(requires4); TEST_CASE(requires5); + TEST_CASE(requires6); TEST_CASE(explicitBool1); TEST_CASE(explicitBool2); @@ -6696,6 +6697,22 @@ class TestSimplifyTemplate : public TestFixture { ASSERT_EQUALS(expected, tok(code)); } + void requires6() { + const char code[] = "template \n" // #14982 + "struct S {\n" + " static void f() noexcept\n" + " requires(N >= 5) {}\n" + " void g() const\n" + " requires(N >= 5) {}\n" + "};"; + const char expected[] = "template < int N > " + "struct S { " + "static void f ( ) noexcept { } " + "void g ( ) const { } " + "} ;"; + ASSERT_EQUALS(expected, tok(code)); + } + void explicitBool1() { const char code[] = "class Fred { explicit(true) Fred(int); };"; ASSERT_EQUALS("class Fred { explicit Fred ( int ) ; } ;", tok(code)); From ff4d7ce36a665f57a573f08602fa8faf2b142e15 Mon Sep 17 00:00:00 2001 From: glankk Date: Wed, 26 Aug 2026 13:42:09 +0200 Subject: [PATCH 325/493] Fix #14987: Update simplecpp to 1.9.1 (#8809) --- externals/simplecpp/simplecpp.cpp | 262 +- externals/simplecpp/simplecpp.h | 91 +- lib/cppcheck.cpp | 34 +- lib/importproject.cpp | 2 +- lib/library.cpp | 2 +- lib/preprocessor.cpp | 6 + lib/programmemory.cpp | 2 +- lib/standards.cpp | 12 + lib/standards.h | 1 + lib/symboldatabase.cpp | 4 +- lib/tokenlist.cpp | 4 +- lib/valueflow.cpp | 5 +- test/helpers.cpp | 6 +- test/test64bit.cpp | 62 +- test/testassert.cpp | 46 +- test/testastutils.cpp | 274 +-- test/testautovariables.cpp | 622 ++--- test/testbool.cpp | 330 +-- test/testbufferoverrun.cpp | 958 ++++---- test/testcharvar.cpp | 40 +- test/testclass.cpp | 1346 +++++----- test/testcondition.cpp | 1134 ++++----- test/testconstructors.cpp | 586 ++--- test/testcppcheck.cpp | 16 +- test/testerrorlogger.cpp | 8 +- test/testexceptionsafety.cpp | 72 +- test/testfunctions.cpp | 378 +-- test/testgarbage.cpp | 654 ++--- test/testincompletestatement.cpp | 100 +- test/testio.cpp | 498 ++-- test/testleakautovar.cpp | 484 ++-- test/testlibrary.cpp | 70 +- test/testmemleak.cpp | 386 +-- test/testnullpointer.cpp | 684 +++--- test/testother.cpp | 2248 ++++++++--------- test/testpostfixoperator.cpp | 60 +- test/testpreprocessor.cpp | 156 +- test/testprogrammemory.cpp | 2 +- test/testsimplifytemplate.cpp | 976 ++++---- test/testsimplifytokens.cpp | 605 ++--- test/testsimplifytypedef.cpp | 566 ++--- test/testsimplifyusing.cpp | 118 +- test/testsingleexecutor.cpp | 32 +- test/testsizeof.cpp | 248 +- test/teststl.cpp | 684 +++--- test/teststring.cpp | 254 +- test/testsummaries.cpp | 6 +- test/testsuppressions.cpp | 22 +- test/testsymboldatabase.cpp | 1324 +++++----- test/testthreadexecutor.cpp | 28 +- test/testtoken.cpp | 150 +- test/testtokenize.cpp | 3807 +++++++++++++++-------------- test/testtokenlist.cpp | 22 +- test/testtokenrange.cpp | 12 +- test/testtype.cpp | 124 +- test/testuninitvar.cpp | 1390 +++++------ test/testunusedfunctions.cpp | 118 +- test/testunusedprivfunc.cpp | 226 +- test/testunusedvar.cpp | 1148 ++++----- test/testvaarg.cpp | 62 +- test/testvalueflow.cpp | 1216 ++++----- test/testvarid.cpp | 501 ++-- 62 files changed, 12805 insertions(+), 12479 deletions(-) diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index d2c398c49e1..8237ac75fab 100644 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -96,6 +96,8 @@ static const simplecpp::TokenString IFNDEF("ifndef"); static const simplecpp::TokenString DEFINED("defined"); static const simplecpp::TokenString ELSE("else"); static const simplecpp::TokenString ELIF("elif"); +static const simplecpp::TokenString ELIFDEF("elifdef"); +static const simplecpp::TokenString ELIFNDEF("elifndef"); static const simplecpp::TokenString ENDIF("endif"); static const simplecpp::TokenString PRAGMA("pragma"); @@ -475,26 +477,26 @@ namespace { simplecpp::TokenList::TokenList(std::vector &filenames) : frontToken(nullptr), backToken(nullptr), files(filenames) {} -simplecpp::TokenList::TokenList(std::istream &istr, std::vector &filenames, const std::string &filename, OutputList *outputList) +simplecpp::TokenList::TokenList(std::istream &istr, std::vector &filenames, const std::string &filename, const DUI &dui, OutputList *outputList) : frontToken(nullptr), backToken(nullptr), files(filenames) { StdIStream stream(istr); - readfile(stream,filename,outputList); + readfile(stream,filename,dui,outputList); } -simplecpp::TokenList::TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename, OutputList *outputList, int /*unused*/) +simplecpp::TokenList::TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename, const DUI &dui, OutputList *outputList, int /*unused*/) : frontToken(nullptr), backToken(nullptr), files(filenames) { StdCharBufStream stream(data, size); - readfile(stream,filename,outputList); + readfile(stream,filename,dui,outputList); } -simplecpp::TokenList::TokenList(const std::string &filename, std::vector &filenames, OutputList *outputList) +simplecpp::TokenList::TokenList(const std::string &filename, std::vector &filenames, const DUI &dui, OutputList *outputList) : frontToken(nullptr), backToken(nullptr), files(filenames) { try { FileStream stream(filename, filenames); - readfile(stream,filename,outputList); + readfile(stream,filename,dui,outputList); } catch (const simplecpp::Output & e) { outputList->emplace_back(e); } @@ -659,18 +661,24 @@ void simplecpp::TokenList::lineDirective(unsigned int fileIndex_, unsigned int l static const std::string COMMENT_END("*/"); -void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, OutputList *outputList) +void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, const DUI &dui, OutputList *outputList) { unsigned int multiline = 0U; + bool trailing_nl = true; const Token *oldLastToken = nullptr; + const cstd_t cstd = getCStd(dui.std); + const cppstd_t cppstd = getCppStd(dui.std); + Location location(fileIndex(filename), 1, 1); while (stream.good()) { unsigned char ch = stream.readChar(); if (!stream.good()) break; + trailing_nl = false; + if (ch >= 0x80) { if (outputList) { simplecpp::Output err{ @@ -693,6 +701,7 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, } else { location.line += multiline + 1; multiline = 0U; + trailing_nl = true; } if (!multiline) location.col = 1; @@ -723,10 +732,64 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, if (ppTok->str() == "line") ppTok = advanceAndSkipComments(ppTok); + if (ppTok && (ppTok->str()[0] == '-' || ppTok->str()[0] == '+')) { + if (outputList) { + simplecpp::Output err{ + simplecpp::Output::SYNTAX_ERROR, + location, + "Invalid character in line directive: '" + ppTok->str() + "'." + }; + outputList->emplace_back(std::move(err)); + } + clear(); + return; + } + if (!ppTok || !ppTok->number) continue; - const unsigned int line = std::atol(ppTok->str().c_str()); + constexpr unsigned long line_limit = std::numeric_limits::max(); + unsigned long line; + try { + line = std::min(line_limit, std::stoul(ppTok->str())); + } catch (...) { + line = line_limit; + } + + unsigned long maxline; + if ((cstd != CUnknown && cstd < C99) || (cppstd != CPPUnknown && cppstd < CPP11)) + maxline = 32767; + else + maxline = 2147483647; + + if (line == 0 || line > maxline) { + if (outputList) { + const bool unknown_std = cstd == CUnknown && cppstd == CPPUnknown; + std::string msg = "Line number out of range: " + ppTok->str() + ". "; + if (line == 0) { + msg += "Line number zero is undefined behavior."; + } else { + msg += "Line numbers above " + std::to_string(maxline) + " are "; + if (unknown_std) + msg += "undefined behavior or conditionally supported"; + else if (cppstd >= CPP26) + msg += "conditionally supported"; + else + msg += "undefined behavior"; + if (cstd != CUnknown) + msg += std::string(" in ") + getCStdName(cstd); + else if (cppstd != CPPUnknown) + msg += std::string(" in ") + getCppStdName(cppstd); + msg += "."; + } + simplecpp::Output err{ + simplecpp::Output::PORTABILITY_LINE_DIRECTIVE, + location, msg + }; + outputList->emplace_back(std::move(err)); + } + } + ppTok = advanceAndSkipComments(ppTok); unsigned int fileindex; @@ -961,6 +1024,15 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename, location.adjust(currentToken); } + if ((cstd != CUnknown || cppstd == CPPUnknown) && !trailing_nl && outputList) { + Output err{ + Output::PORTABILITY_NO_EOF_NEWLINE, + location, + "No newline at end of file is undefined behavior in C." + }; + outputList->emplace_back(std::move(err)); + } + combineOperators(); } @@ -1523,7 +1595,7 @@ namespace simplecpp { * @throws std::runtime_error thrown on bad macro syntax */ Macro(const std::string &name, const std::string &value, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(f), valueDefinedInCode_(false) { - const std::string def(name + ' ' + value); + const std::string def(name + ' ' + value + '\n'); StdCharBufStream stream(reinterpret_cast(def.data()), def.size()); tokenListDefine.readfile(stream); if (!parseDefine(tokenListDefine.cfront())) @@ -1602,7 +1674,7 @@ namespace simplecpp { else if (rawtok->op == ')') --par; else if (rawtok->op == '#' && !sameline(rawtok->previous, rawtok)) - throw Error(rawtok->location, "it is invalid to use a preprocessor directive as macro parameter"); + throw invalidDirectiveAsMacroParameter(rawtok->location); rawtokens2.push_back(new Token(rawtok->str(), rawtok1->location, rawtok->whitespaceahead)); rawtok = rawtok->next; } @@ -1635,7 +1707,7 @@ namespace simplecpp { if (output2.cfront() != output2.cback() && macro2tok->str() == this->name()) break; const MacroMap::const_iterator macro = macros.find(macro2tok->str()); - if (macro == macros.end() || !macro->second.functionLike()) + if (macro == macros.end() || !macro->second.functionLike() || macro2tok->isExpandedFrom(¯o->second)) break; TokenList rawtokens2(inputFiles); const Location loc(macro2tok->location); @@ -1698,6 +1770,11 @@ namespace simplecpp { const std::string what; }; + struct invalidDirectiveAsMacroParameter : public Error { + explicit invalidDirectiveAsMacroParameter(const Location &loc) + : Error(loc, "it is invalid to use a preprocessor directive as macro parameter") {} + }; + /** Struct that is thrown when macro is expanded with wrong number of parameters */ struct wrongNumberOfParameters : public Error { wrongNumberOfParameters(const Location &loc, const std::string ¯oName) : Error(loc, "Wrong number of parameters for macro \'" + macroName + "\'.") {} @@ -1917,14 +1994,17 @@ namespace simplecpp { if (nameTokInst->str() == "__FILE__") { output.push_back(new Token('\"'+output.file(loc)+'\"', loc)); + output.back()->macro = "__FILE__"; return nameTokInst->next; } if (nameTokInst->str() == "__LINE__") { output.push_back(new Token(toString(loc.line), loc)); + output.back()->macro = "__LINE__"; return nameTokInst->next; } if (nameTokInst->str() == "__COUNTER__") { output.push_back(new Token(toString(usageList.size()-1U), loc)); + output.back()->macro = "__COUNTER__"; return nameTokInst->next; } @@ -2084,39 +2164,37 @@ namespace simplecpp { return functionLike() ? parametertokens2.back()->next : nameTokInst->next; } - const Token *recursiveExpandToken(TokenList &output, TokenList &temp, const Location &loc, const Token *tok, const MacroMap ¯os, const std::set &expandedmacros, const std::vector ¶metertokens) const { - if (!temp.cback() || !temp.cback()->name || !tok->next || tok->next->op != '(') { - output.takeTokens(temp); - return tok->next; - } - - if (!sameline(tok, tok->next)) { - output.takeTokens(temp); - return tok->next; - } - + /** Returns the macro to expand when the last token of @p temp is the name of a + * function-like macro and the tokens after @p tok supply its arguments; nullptr otherwise */ + static const Macro *rescanMacro(const TokenList &temp, const Token *tok, const MacroMap ¯os, const std::set &expandedmacros) { + if (!temp.cback() || !temp.cback()->name || !sameline(tok, tok->next) || tok->next->op != '(') + return nullptr; const MacroMap::const_iterator it = macros.find(temp.cback()->str()); - if (it == macros.end() || expandedmacros.find(temp.cback()->str()) != expandedmacros.end()) { - output.takeTokens(temp); - return tok->next; - } + if (it == macros.end() || expandedmacros.find(temp.cback()->str()) != expandedmacros.end()) + return nullptr; + if (!it->second.functionLike() || temp.cback()->isExpandedFrom(&it->second)) + return nullptr; + return &it->second; + } - const Macro &calledMacro = it->second; - if (!calledMacro.functionLike()) { + const Token *recursiveExpandToken(TokenList &output, TokenList &temp, const Location &loc, const Token *tok, const MacroMap ¯os, const std::set &expandedmacros, const std::vector ¶metertokens) const { + // Expand while the expansion result ends with the name of a function-like + // macro whose arguments are supplied by the tokens that follow it. Each round + // consumes that macro call from the token stream, so tok always advances. + while (const Macro * const calledMacro = rescanMacro(temp, tok, macros, expandedmacros)) { + TokenList temp2(files); + temp2.push_back(new Token(temp.cback()->str(), tok->location)); + + const Token * const tok2 = appendTokens(temp2, loc, tok->next, macros, expandedmacros, parametertokens); + if (!tok2) + break; output.takeTokens(temp); - return tok->next; + output.deleteToken(output.back()); + calledMacro->expand(temp, loc, temp2.cfront(), macros, expandedmacros); + tok = tok2; } - - TokenList temp2(files); - temp2.push_back(new Token(temp.cback()->str(), tok->location)); - - const Token * const tok2 = appendTokens(temp2, loc, tok->next, macros, expandedmacros, parametertokens); - if (!tok2) - return tok->next; output.takeTokens(temp); - output.deleteToken(output.back()); - calledMacro.expand(output, loc, temp2.cfront(), macros, expandedmacros); - return tok2->next; + return tok->next; } const Token *expandToken(TokenList &output, const Location &loc, const Token *tok, const MacroMap ¯os, const std::set &expandedmacros, const std::vector ¶metertokens) const { @@ -3126,8 +3204,8 @@ simplecpp::FileDataCache::FileDataCache() {} simplecpp::FileDataCache::~FileDataCache() = default; -simplecpp::FileDataCache::FileDataCache(FileDataCache &&) noexcept = default; -simplecpp::FileDataCache &simplecpp::FileDataCache::operator=(simplecpp::FileDataCache &&) noexcept = default; +simplecpp::FileDataCache::FileDataCache(FileDataCache &&) SIMPLECPP_NOEXCEPT = default; +simplecpp::FileDataCache &simplecpp::FileDataCache::operator=(simplecpp::FileDataCache &&) SIMPLECPP_NOEXCEPT = default; static bool getFileId(const std::string &path, FileID &id); @@ -3145,7 +3223,7 @@ std::pair simplecpp::FileDataCache::tryload(FileDat return {id_it->second, false}; } - auto *const data = new FileData {path, TokenList(path, filenames, outputList)}; + auto *const data = new FileData {path, TokenList(path, filenames, {}, outputList)}; if (dui.removeComments) data->tokens.removeComments(); @@ -3154,13 +3232,10 @@ std::pair simplecpp::FileDataCache::tryload(FileDat mImpl->mIdMap.emplace(fileId, data); mData.emplace_back(data); - if (mLoadCallback) - mLoadCallback(*data); - return {data, true}; } -std::pair simplecpp::FileDataCache::get(const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader, std::vector &filenames, simplecpp::OutputList *outputList) +std::pair simplecpp::FileDataCache::get_private(const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader, std::vector &filenames, simplecpp::OutputList *outputList) { if (isAbsolutePath(header)) { auto ins = mNameMap.emplace(simplecpp::simplifyPath(header), nullptr); @@ -3206,6 +3281,16 @@ std::pair simplecpp::FileDataCache::get(const std:: return {nullptr, false}; } +std::pair simplecpp::FileDataCache::get(const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader, std::vector &filenames, simplecpp::OutputList *outputList) +{ + auto ret = get_private(sourcefile, header, dui, systemheader, filenames, outputList); + + if (mLoadCallback && ret.first) + mLoadCallback(*ret.first, ret.second); + + return ret; +} + void simplecpp::FileDataCache::clear() { mImpl->clear(); @@ -3336,7 +3421,7 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, return cache; } -static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token *&tok1, simplecpp::MacroMap ¯os, std::vector &files, simplecpp::OutputList *outputList) +static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token *&tok1, simplecpp::MacroMap ¯os, std::vector &files, simplecpp::OutputList *outputList, const simplecpp::DUI &dui) { const simplecpp::Token * const tok = tok1; const simplecpp::MacroMap::const_iterator it = tok->name ? macros.find(tok->str()) : macros.end(); @@ -3344,6 +3429,16 @@ static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token simplecpp::TokenList value(files); try { tok1 = it->second.expand(value, tok, macros, files); + } catch (const simplecpp::Macro::invalidDirectiveAsMacroParameter &err) { + if (outputList) { + simplecpp::Output out{ + simplecpp::Output::DIRECTIVE_AS_MACRO_PARAMETER, + err.location, + "failed to expand \'" + tok->str() + "\', " + err.what + }; + outputList->emplace_back(std::move(out)); + } + return false; } catch (const simplecpp::Macro::Error &err) { if (outputList) { simplecpp::Output out{ @@ -3357,7 +3452,7 @@ static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token } output.takeTokens(value); } else { - if (!tok->comment) + if (!tok->comment || !dui.removeComments) output.push_back(new simplecpp::Token(*tok)); tok1 = tok->next; } @@ -3552,7 +3647,9 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL continue; } - if (ifstates.size() <= 1U && (rawtok->str() == ELIF || rawtok->str() == ELSE || rawtok->str() == ENDIF)) { + if (ifstates.size() <= 1U && (rawtok->str() == ELIF || rawtok->str() == ELIFDEF || + rawtok->str() == ELIFNDEF || rawtok->str() == ELSE || + rawtok->str() == ENDIF)) { if (outputList) { simplecpp::Output err{ Output::SYNTAX_ERROR, @@ -3632,7 +3729,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL TokenList inc2(files); if (!inc1.empty() && inc1.cfront()->name) { const Token *inctok = inc1.cfront(); - if (!preprocessToken(inc2, inctok, macros, files, outputList)) { + if (!preprocessToken(inc2, inctok, macros, files, outputList, dui)) { output.clear(); return; } @@ -3693,7 +3790,8 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL rawtok = filedata->tokens.cfront(); continue; } - } else if (rawtok->str() == IF || rawtok->str() == IFDEF || rawtok->str() == IFNDEF || rawtok->str() == ELIF) { + } else if (rawtok->str() == IF || rawtok->str() == IFDEF || rawtok->str() == IFNDEF || rawtok->str() == ELIF || + rawtok->str() == ELIFDEF || rawtok->str() == ELIFNDEF) { if (!sameline(rawtok,rawtok->next)) { if (outputList) { simplecpp::Output out{ @@ -3708,15 +3806,28 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL } bool conditionIsTrue; - if (ifstates.top() == AlwaysFalse || (ifstates.top() == ElseIsTrue && rawtok->str() != ELIF)) { + if (ifstates.top() == AlwaysFalse || (ifstates.top() == ElseIsTrue && rawtok->str() != ELIF && + rawtok->str() != ELIFDEF && rawtok->str() != ELIFNDEF)) { conditionIsTrue = false; } - else if (rawtok->str() == IFDEF) { - conditionIsTrue = (macros.find(rawtok->next->str()) != macros.end() || (hasInclude && rawtok->next->str() == HAS_INCLUDE)); - maybeUsedMacros[rawtok->next->str()].emplace_back(rawtok->next->location); - } else if (rawtok->str() == IFNDEF) { - conditionIsTrue = (macros.find(rawtok->next->str()) == macros.end() && !(hasInclude && rawtok->next->str() == HAS_INCLUDE)); - maybeUsedMacros[rawtok->next->str()].emplace_back(rawtok->next->location); + else if (rawtok->str() == IFDEF || rawtok->str() == ELIFDEF) { + const std::string &name = rawtok->next->str(); + conditionIsTrue = (macros.find(name) != macros.end() || (hasInclude && name == HAS_INCLUDE)); + maybeUsedMacros[name].emplace_back(rawtok->next->location); + if (ifCond) { + const std::string E = conditionIsTrue ? "1" : "0"; + const long long result = conditionIsTrue ? 1 : 0; + ifCond->emplace_back(rawtok->location, E, result); + } + } else if (rawtok->str() == IFNDEF || rawtok->str() == ELIFNDEF) { + const std::string &name = rawtok->next->str(); + conditionIsTrue = (macros.find(name) == macros.end() && !(hasInclude && name == HAS_INCLUDE)); + maybeUsedMacros[name].emplace_back(rawtok->next->location); + if (ifCond) { + const std::string E = conditionIsTrue ? "1" : "0"; + const long long result = conditionIsTrue ? 1 : 0; + ifCond->emplace_back(rawtok->location, E, result); + } } else { /*if (rawtok->str() == IF || rawtok->str() == ELIF)*/ TokenList expr(files); for (const Token *tok = rawtok->next; tok && tok->location.sameline(rawtok->location); tok = tok->next) { @@ -3802,7 +3913,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL maybeUsedMacros[rawtok->next->str()].emplace_back(rawtok->next->location); const Token *tmp = tok; - if (!preprocessToken(expr, tmp, macros, files, outputList)) { + if (!preprocessToken(expr, tmp, macros, files, outputList, dui)) { output.clear(); return; } @@ -3839,7 +3950,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL } } - if (rawtok->str() != ELIF) { + if (rawtok->str() != ELIF && rawtok->str() != ELIFDEF && rawtok->str() != ELIFNDEF) { // push a new ifstate.. if (ifstates.top() != True) ifstates.push(AlwaysFalse); @@ -3900,7 +4011,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL const Location loc(rawtok->location); TokenList tokens(files); - if (!preprocessToken(tokens, rawtok, macros, files, outputList)) { + if (!preprocessToken(tokens, rawtok, macros, files, outputList, dui)) { output.clear(); return; } @@ -3959,6 +4070,20 @@ simplecpp::cstd_t simplecpp::getCStd(const std::string &std) return CUnknown; } +const char *simplecpp::getCStdName(cstd_t std) +{ + switch (std) { + case CUnknown: return "C"; + case C89: return "C89"; + case C99: return "C99"; + case C11: return "C11"; + case C17: return "C17"; + case C23: return "C23"; + case C2Y: return "C2Y"; + } + return ""; +} + std::string simplecpp::getCStdString(cstd_t std) { switch (std) { @@ -4011,6 +4136,21 @@ simplecpp::cppstd_t simplecpp::getCppStd(const std::string &std) return CPPUnknown; } +const char *simplecpp::getCppStdName(cppstd_t std) +{ + switch (std) { + case CPPUnknown: return "C++"; + case CPP03: return "C++03"; + case CPP11: return "C++11"; + case CPP14: return "C++14"; + case CPP17: return "C++17"; + case CPP20: return "C++20"; + case CPP23: return "C++23"; + case CPP26: return "C++26"; + } + return ""; +} + std::string simplecpp::getCppStdString(cppstd_t std) { switch (std) { diff --git a/externals/simplecpp/simplecpp.h b/externals/simplecpp/simplecpp.h index 3d6fc5262b9..f4dca18374a 100644 --- a/externals/simplecpp/simplecpp.h +++ b/externals/simplecpp/simplecpp.h @@ -60,6 +60,15 @@ # endif #endif +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 9 +// Hack to workaround GCC bug. +// Details: https://trac.cppcheck.net/ticket/14850 +// seen on g++ before 10.x +#define SIMPLECPP_NOEXCEPT +#else +#define SIMPLECPP_NOEXCEPT noexcept +#endif + namespace simplecpp { /** C code standard */ enum cstd_t : std::int8_t { CUnknown=-1, C89, C99, C11, C17, C23, C2Y }; @@ -238,7 +247,10 @@ namespace simplecpp { MISSING_HEADER, INCLUDE_NESTED_TOO_DEEPLY, SYNTAX_ERROR, + DIRECTIVE_AS_MACRO_PARAMETER, PORTABILITY_BACKSLASH, + PORTABILITY_LINE_DIRECTIVE, + PORTABILITY_NO_EOF_NEWLINE, UNHANDLED_CHAR_ERROR, EXPLICIT_INCLUDE_NOT_FOUND, FILE_NOT_FOUND, @@ -251,6 +263,21 @@ namespace simplecpp { using OutputList = std::list; + /** + * Command line preprocessor settings. + * On the command line these are configured by -D, -U, -I, --include, -std + */ + struct SIMPLECPP_LIB DUI { + DUI() = default; + std::list defines; + std::set undefined; + std::list includePaths; + std::list includes; + std::string std; + bool clearIncludeCache{}; + bool removeComments{}; /** remove comment tokens from included files */ + }; + /** List of tokens. */ class SIMPLECPP_LIB TokenList { public: @@ -258,45 +285,45 @@ namespace simplecpp { explicit TokenList(std::vector &filenames); /** generates a token list from the given std::istream parameter */ - TokenList(std::istream &istr, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr); + TokenList(std::istream &istr, std::vector &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr); /** generates a token list from the given buffer */ template - TokenList(const char (&data)[size], std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr) - : TokenList(reinterpret_cast(data), size-1, filenames, filename, outputList, 0) + TokenList(const char (&data)[size], std::vector &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr) + : TokenList(reinterpret_cast(data), size-1, filenames, filename, dui, outputList, 0) {} /** generates a token list from the given buffer */ template - TokenList(const unsigned char (&data)[size], std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr) - : TokenList(data, size-1, filenames, filename, outputList, 0) + TokenList(const unsigned char (&data)[size], std::vector &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr) + : TokenList(data, size-1, filenames, filename, dui, outputList, 0) {} #if SIMPLECPP_TOKENLIST_ALLOW_PTR /** generates a token list from the given buffer */ - TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr) - : TokenList(data, size, filenames, filename, outputList, 0) + TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr) + : TokenList(data, size, filenames, filename, dui, outputList, 0) {} /** generates a token list from the given buffer */ - TokenList(const char* data, std::size_t size, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr) - : TokenList(reinterpret_cast(data), size, filenames, filename, outputList, 0) + TokenList(const char* data, std::size_t size, std::vector &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr) + : TokenList(reinterpret_cast(data), size, filenames, filename, dui, outputList, 0) {} #endif // SIMPLECPP_TOKENLIST_ALLOW_PTR /** generates a token list from the given buffer */ - TokenList(View data, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr) - : TokenList(reinterpret_cast(data.data()), data.size(), filenames, filename, outputList, 0) + TokenList(View data, std::vector &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr) + : TokenList(reinterpret_cast(data.data()), data.size(), filenames, filename, dui, outputList, 0) {} #ifdef __cpp_lib_span /** generates a token list from the given buffer */ - TokenList(std::span data, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr) - : TokenList(reinterpret_cast(data.data()), data.size(), filenames, filename, outputList, 0) + TokenList(std::span data, std::vector &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr) + : TokenList(reinterpret_cast(data.data()), data.size(), filenames, filename, dui, outputList, 0) {} /** generates a token list from the given buffer */ - TokenList(std::span data, std::vector &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr) - : TokenList(data.data(), data.size(), filenames, filename, outputList, 0) + TokenList(std::span data, std::vector &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr) + : TokenList(data.data(), data.size(), filenames, filename, dui, outputList, 0) {} #endif // __cpp_lib_span /** generates a token list from the given filename parameter */ - TokenList(const std::string &filename, std::vector &filenames, OutputList *outputList = nullptr); + TokenList(const std::string &filename, std::vector &filenames, const DUI &dui = {}, OutputList *outputList = nullptr); TokenList(const TokenList &other); TokenList(TokenList &&other); ~TokenList(); @@ -312,7 +339,7 @@ namespace simplecpp { void dump(bool linenrs = false) const; std::string stringify(bool linenrs = false) const; - void readfile(Stream &stream, const std::string &filename=std::string(), OutputList *outputList = nullptr); + void readfile(Stream &stream, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr); /** * @throws std::overflow_error thrown on overflow or division by zero * @throws std::runtime_error thrown on invalid expressions @@ -376,7 +403,7 @@ namespace simplecpp { const std::string& file(const Location& loc) const; private: - TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename, OutputList *outputList, int /*unused*/); + TokenList(const unsigned char* data, std::size_t size, std::vector &filenames, const std::string &filename, const DUI &dui, OutputList *outputList, int /*unused*/); void combineOperators(); @@ -425,21 +452,6 @@ namespace simplecpp { long long result; // condition result }; - /** - * Command line preprocessor settings. - * On the command line these are configured by -D, -U, -I, --include, -std - */ - struct SIMPLECPP_LIB DUI { - DUI() = default; - std::list defines; - std::set undefined; - std::list includePaths; - std::list includes; - std::string std; - bool clearIncludeCache{}; - bool removeComments{}; /** remove comment tokens from included files */ - }; - struct SIMPLECPP_LIB FileData { /** The canonical filename associated with this data */ std::string filename; @@ -453,10 +465,10 @@ namespace simplecpp { ~FileDataCache(); FileDataCache(const FileDataCache &) = delete; - FileDataCache(FileDataCache &&) noexcept; + FileDataCache(FileDataCache &&) SIMPLECPP_NOEXCEPT; FileDataCache &operator=(const FileDataCache &) = delete; - FileDataCache &operator=(FileDataCache &&) noexcept; + FileDataCache &operator=(FileDataCache &&) SIMPLECPP_NOEXCEPT; /** Get the cached data for a file, or load and then return it if it isn't cached. * returns the file data and true if the file was loaded, false if it was cached. */ @@ -499,7 +511,7 @@ namespace simplecpp { return mData.cend(); } - using load_callback_type = std::function; + using load_callback_type = std::function; void set_load_callback(load_callback_type cb) { mLoadCallback = std::move(cb); @@ -512,6 +524,7 @@ namespace simplecpp { using name_map_type = std::unordered_map; std::pair tryload(name_map_type::iterator &name_it, const DUI &dui, std::vector &filenames, OutputList *outputList); + std::pair get_private(const std::string &sourcefile, const std::string &header, const DUI &dui, bool systemheader, std::vector &filenames, OutputList *outputList); container_type mData; name_map_type mNameMap; @@ -578,9 +591,15 @@ namespace simplecpp { /** Returns the C version a given standard */ SIMPLECPP_LIB cstd_t getCStd(const std::string &std); + /** Returns the name of a C standard */ + SIMPLECPP_LIB const char *getCStdName(cstd_t std); + /** Returns the C++ version a given standard */ SIMPLECPP_LIB cppstd_t getCppStd(const std::string &std); + /** Returns the name of a C++ standard */ + SIMPLECPP_LIB const char *getCppStdName(cppstd_t std); + /** Returns the __STDC_VERSION__ value for a given standard */ SIMPLECPP_LIB std::string getCStdString(const std::string &std); SIMPLECPP_LIB std::string getCStdString(cstd_t std); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 26d98c0c7b4..3c96bec64a3 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -894,16 +894,20 @@ std::size_t CppCheck::calculateHash(const Preprocessor& preprocessor, const std: unsigned int CppCheck::checkBuffer(const FileWithDetails &file, const std::string &cfgname, const char* data, std::size_t size) { - const auto f = [&file, data, size](std::vector& files, simplecpp::OutputList* outputList) { - return simplecpp::TokenList{{data, size}, files, file.spath(), outputList}; + const auto f = [&file, data, size, this](std::vector& files, simplecpp::OutputList* outputList) { + simplecpp::DUI dui; + dui.std = mSettings.standards.getStdForLanguage(file.lang()); + return simplecpp::TokenList{{data, size}, files, file.spath(), dui, outputList}; }; return checkInternal(file, cfgname, f); } unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string &cfgname) { - const auto f = [&file](std::vector& files, simplecpp::OutputList* outputList) { - return simplecpp::TokenList{file.spath(), files, outputList}; + const auto f = [&file, this](std::vector& files, simplecpp::OutputList* outputList) { + simplecpp::DUI dui; + dui.std = mSettings.standards.getStdForLanguage(file.lang()); + return simplecpp::TokenList{file.spath(), files, dui, outputList}; }; return checkInternal(file, cfgname, f); } @@ -1058,16 +1062,18 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str std::inserter(configDefines, configDefines.end()), getDefineName); - preprocessor.setLoadCallback([&](simplecpp::FileData &data) { - // Do preprocessing on included file - mLogger->addRemarkComments(preprocessor.getRemarkComments(data.tokens)); - preprocessor.inlineSuppressions(data.tokens, mSuppressions.nomsg); - Preprocessor::removeComments(data.tokens); - Preprocessor::createDirectives(data.tokens, directives); - Preprocessor::simplifyPragmaAsm(data.tokens); - // Discover new configurations from included file - if (configurations.size() < maxConfigs) - preprocessor.getConfigs(data.filename, data.tokens, configDefines, configurations); + preprocessor.setLoadCallback([&](simplecpp::FileData &data, bool loaded) { + if (loaded) { + // Do preprocessing on included file + mLogger->addRemarkComments(preprocessor.getRemarkComments(data.tokens)); + preprocessor.inlineSuppressions(data.tokens, mSuppressions.nomsg); + Preprocessor::removeComments(data.tokens); + Preprocessor::createDirectives(data.tokens, directives); + Preprocessor::simplifyPragmaAsm(data.tokens); + // Discover new configurations from included file + if (configurations.size() < maxConfigs) + preprocessor.getConfigs(data.filename, data.tokens, configDefines, configurations); + } }); preprocessor.setPlatformInfo(); diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 5c9bcaadd3f..61ef7a2d38a 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -649,7 +649,7 @@ namespace { } static bool evalCondition(const std::string& condition, const ProjectConfiguration &p) { - std::string c = '(' + condition + ")"; + std::string c = '(' + condition + ")\n"; replaceAll(c, "$(Configuration)", p.configuration); replaceAll(c, "$(Platform)", p.platformStr); diff --git a/lib/library.cpp b/lib/library.cpp index 2a198001d3c..4e542bc55ef 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -177,7 +177,7 @@ static std::vector getnames(const char *names) static void gettokenlistfromvalid(const std::string& valid, TokenList& tokenList) { - const std::string str(valid + ','); + const std::string str(valid + ",\n"); tokenList.createTokensFromBuffer(str.data(), str.size()); // TODO: check result? for (Token *tok = tokenList.front(); tok; tok = tok->next()) { if (Token::Match(tok,"- %num%")) { diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 3e0b33c7f10..8fe715db864 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -930,6 +930,8 @@ const simplecpp::Output* Preprocessor::reportOutput(const simplecpp::OutputList break; case simplecpp::Output::WARNING: case simplecpp::Output::PORTABILITY_BACKSLASH: + case simplecpp::Output::PORTABILITY_LINE_DIRECTIVE: + case simplecpp::Output::PORTABILITY_NO_EOF_NEWLINE: break; case simplecpp::Output::MISSING_HEADER: { // not considered an "error" @@ -939,6 +941,7 @@ const simplecpp::Output* Preprocessor::reportOutput(const simplecpp::OutputList missingInclude(out.location, out.msg.substr(pos1+1, pos2-pos1-1), out.msg[pos1] == '\"' ? UserHeader : SystemHeader); } break; + case simplecpp::Output::DIRECTIVE_AS_MACRO_PARAMETER: case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY: case simplecpp::Output::SYNTAX_ERROR: case simplecpp::Output::UNHANDLED_CHAR_ERROR: @@ -963,6 +966,7 @@ static std::string simplecppErrToId(simplecpp::Output::Type type) case simplecpp::Output::ERROR: return "preprocessorErrorDirective"; case simplecpp::Output::SYNTAX_ERROR: + case simplecpp::Output::DIRECTIVE_AS_MACRO_PARAMETER: return "syntaxError"; case simplecpp::Output::UNHANDLED_CHAR_ERROR: return "unhandledChar"; @@ -979,6 +983,8 @@ static std::string simplecppErrToId(simplecpp::Output::Type type) // no handled at all (warnings) case simplecpp::Output::WARNING: case simplecpp::Output::PORTABILITY_BACKSLASH: + case simplecpp::Output::PORTABILITY_LINE_DIRECTIVE: + case simplecpp::Output::PORTABILITY_NO_EOF_NEWLINE: throw std::runtime_error("unexpected simplecpp::Output type " + std::to_string(type)); } diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 9571e04ea00..142385ac641 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1937,7 +1937,7 @@ static std::shared_ptr createTokenFromExpression(const std::string& retur { std::shared_ptr tokenList = std::make_shared(settings, cpp ? Standards::Language::CPP : Standards::Language::C); { - const std::string code = "return " + returnValue + ";"; + const std::string code = "return " + returnValue + ";\n"; if (!tokenList->createTokensFromBuffer(code.data(), code.size())) return nullptr; } diff --git a/lib/standards.cpp b/lib/standards.cpp index a0ec72c1580..06b129ab8cf 100644 --- a/lib/standards.cpp +++ b/lib/standards.cpp @@ -157,3 +157,15 @@ bool Standards::setStd(const std::string& str) { return setC(str) || setCPP(str); } + +std::string Standards::getStdForLanguage(Standards::Language language) const +{ + switch (language) { + case C: + return getC(); + case CPP: + return getCPP(); + default: + return ""; + } +} diff --git a/lib/standards.h b/lib/standards.h index d2c2a2b8e01..0ab73300a9a 100644 --- a/lib/standards.h +++ b/lib/standards.h @@ -58,6 +58,7 @@ struct CPPCHECKLIB Standards { static std::string getCPP(cppstd_t std); static cppstd_t getCPP(const std::string &std); bool setStd(const std::string& str); + std::string getStdForLanguage(Language language) const; }; /// @} diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index a666c15b536..7a0148a24a2 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -8093,7 +8093,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to if (!typestr.empty()) { ValueType valuetype; TokenList tokenList(mSettings, tok->isCpp() ? Standards::Language::CPP : Standards::Language::C); - const std::string str(typestr+";"); + const std::string str(typestr+";\n"); tokenList.createTokensFromBuffer(str.data(), str.size()); // TODO: check result? tokenList.simplifyStdType(); if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings)) { @@ -8186,7 +8186,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to continue; } TokenList tokenList(mSettings, tok->isCpp() ? Standards::Language::CPP : Standards::Language::C); - const std::string str(typestr+";"); + const std::string str(typestr+";\n"); if (tokenList.createTokensFromBuffer(str.data(), str.size())) { ValueType vt; tokenList.simplifyPlatformTypes(); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index ca509904db3..384c45e406b 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -354,7 +354,9 @@ bool TokenList::createTokensFromBufferInternal(const char* data, size_t size, co #endif simplecpp::OutputList outputList; - simplecpp::TokenList tokens({data, size}, mFiles, file0, &outputList); + simplecpp::DUI dui; + dui.std = mSettings.standards.getStdForLanguage(mLang); + simplecpp::TokenList tokens({data, size}, mFiles, file0, dui, &outputList); createTokens(std::move(tokens)); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e956c92c5e0..325a55e98e5 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1817,7 +1817,8 @@ static bool isNotEqual(std::pair x, std::pair x, const std::string& y, bool cpp, const Settings& settings) { TokenList tokenList(settings, cpp ? Standards::Language::CPP : Standards::Language::C); - tokenList.createTokensFromBuffer(y.data(), y.size()); // TODO: check result? + const std::string str(y + "\n"); + tokenList.createTokensFromBuffer(str.data(), str.size()); // TODO: check result? return isNotEqual(x, std::make_pair(tokenList.front(), tokenList.back())); } static bool isNotEqual(std::pair x, const ValueType* y, bool cpp, const Settings& settings) @@ -7101,7 +7102,7 @@ static bool getMinMaxValues(const std::string& typestr, MathLib::bigint& maxvalue) { TokenList typeTokens(settings, cpp ? Standards::Language::CPP : Standards::Language::C); - const std::string str(typestr + ";"); + const std::string str(typestr + ";\n"); if (!typeTokens.createTokensFromBuffer(str.data(), str.size())) return false; typeTokens.simplifyPlatformTypes(); diff --git a/test/helpers.cpp b/test/helpers.cpp index 70437207a84..95a2dfae24b 100644 --- a/test/helpers.cpp +++ b/test/helpers.cpp @@ -113,8 +113,12 @@ ScopedFile::~ScopedFile() { void SimpleTokenizer2::preprocess(const char* code, std::size_t size, std::vector &files, const std::string& file0, Tokenizer& tokenizer, ErrorLogger& errorlogger) { + const Standards &standards = tokenizer.getSettings().standards; + const Standards::Language language = tokenizer.isCPP() ? Standards::CPP : Standards::C; simplecpp::OutputList outputList; - simplecpp::TokenList tokens1({code, size}, files, file0, &outputList); + simplecpp::DUI dui; + dui.std = standards.getStdForLanguage(language); + simplecpp::TokenList tokens1({code, size}, files, file0, dui, &outputList); Preprocessor preprocessor(tokens1, tokenizer.getSettings(), errorlogger, Path::identify(tokens1.getFiles()[0], false)); (void)preprocessor.loadFiles(files); // TODO: check result diff --git a/test/test64bit.cpp b/test/test64bit.cpp index cc96da48577..1507f15ec72 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -58,7 +58,7 @@ class Test64BitPortability : public TestFixture { check("using CharArray = char[16];\n" "void f() {\n" " CharArray foo = \"\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T { std::vector*a[2][2]; };\n" // #11560 @@ -79,7 +79,7 @@ class Test64BitPortability : public TestFixture { check("void foo()\n" "{\n" " a = p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -88,65 +88,65 @@ class Test64BitPortability : public TestFixture { "{\n" " int a = p;\n" " return a + 4;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (portability) Assigning a pointer to an integer is not portable. [AssignmentAddressToInteger]\n", errout_str()); check("int foo(int p[])\n" "{\n" " int a = p;\n" " return a + 4;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (portability) Assigning a pointer to an integer is not portable. [AssignmentAddressToInteger]\n", errout_str()); check("int foo(int p[])\n" "{\n" " int *a = p;\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (portability) Returning an address value in a function with integer return type is not portable. [CastAddressToIntegerAtReturn]\n", errout_str()); check("void foo(int x)\n" "{\n" " int *p = x;\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (portability) Assigning an integer to a pointer is not portable. [AssignmentIntegerToAddress]\n", errout_str()); check("int f(const char *p) {\n" // #4659 " return 6 + p[2] * 256;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo(int *p) {\n" // #6096 " bool a = p;\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::array f();\n" "void g() {\n" " std::array a = f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::array f(int x);\n" "void g(int i) {\n" " std::array a = f(i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("typedef std::array Array;\n" "Array f(int x);\n" "void g(int i) {\n" " Array a = f(i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("typedef std::array Array;\n" "Array f();\n" "void g(int i) {\n" " Array a = f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" // #9951 @@ -174,7 +174,7 @@ class Test64BitPortability : public TestFixture { check("struct Foo { int *p; };\n" "void f(struct Foo *foo) {\n" " int i = foo->p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (portability) Assigning a pointer to an integer is not portable. [AssignmentAddressToInteger]\n", errout_str()); check("struct S {\n" // #10145 @@ -192,7 +192,7 @@ class Test64BitPortability : public TestFixture { // Ticket #2892 check("void foo(int *p) {\n" " int a = (p != NULL);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -201,74 +201,74 @@ class Test64BitPortability : public TestFixture { check("void foo(int *p) {\n" " int x = 10;\n" " int *a = p + x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int *p) {\n" " int x = 10;\n" " int *a = x + p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int *p) {\n" " int x = 10;\n" " int *a = x * x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (portability) Assigning an integer to a pointer is not portable. [AssignmentIntegerToAddress]\n", errout_str()); check("void foo(int *start, int *end) {\n" " int len;\n" " int len = end + 10 - start;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void returnIssues() { check("void* foo(int i) {\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (portability) Returning an integer in a function with pointer return type is not portable. [CastIntegerToAddressAtReturn]\n", errout_str()); check("void* foo(int* i) {\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void* foo() {\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo(int i) {\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Foo {};\n" "\n" "int* dostuff(Foo foo) {\n" " return foo;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo(char* c) {\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (portability) Returning an address value in a function with integer return type is not portable. [CastAddressToIntegerAtReturn]\n", errout_str()); check("int foo(char* c) {\n" " return 1+c;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (portability) Returning an address value in a function with integer return type is not portable. [CastAddressToIntegerAtReturn]\n", errout_str()); check("std::string foo(char* c) {\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo(char *a, char *b) {\n" // #4486 " return a + 1 - b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct s {\n" // 4642 @@ -276,13 +276,13 @@ class Test64BitPortability : public TestFixture { "};\n" "int func(struct s *p) {\n" " return 1 + p->i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("static void __iomem *f(unsigned int port_no) {\n" " void __iomem *mmio = hpriv->mmio;\n" " return mmio + (port_no * 0x80);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #7247: don't check return statements in nested functions.. @@ -290,7 +290,7 @@ class Test64BitPortability : public TestFixture { " struct {\n" " const char * name() { return \"abc\"; }\n" " } table;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #7451: Lambdas @@ -298,7 +298,7 @@ class Test64BitPortability : public TestFixture { " auto it = std::find_if(outputs.begin(), outputs.end(),\n" " [&](int ele) { return \"test\" == text; });\n" " return nullptr;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" // #12159 diff --git a/test/testassert.cpp b/test/testassert.cpp index a76b8207445..c3c271a1bf2 100644 --- a/test/testassert.cpp +++ b/test/testassert.cpp @@ -61,7 +61,7 @@ class TestAssert : public TestFixture { " if (b) { a = 1+2 };\n" " return a;\n" "}\n" - "assert(foo() == 3);"); + "assert(foo() == 3);\n"); ASSERT_EQUALS("", errout_str()); check( @@ -69,7 +69,7 @@ class TestAssert : public TestFixture { " int b=a+1;\n" " return b;\n" "}\n" - "assert(foo(1) == 2);"); + "assert(foo(1) == 2);\n"); ASSERT_EQUALS("", errout_str()); } @@ -80,7 +80,7 @@ class TestAssert : public TestFixture { " a = 1+2;\n" " return a;\n" "}\n" - "assert(foo() == 3);"); + "assert(foo() == 3);\n"); ASSERT_EQUALS("[test.cpp:6:8]: (warning) Assert statement calls a function which may have desired side effects: 'foo'. [assertWithSideEffect]\n", errout_str()); // Ticket #4937 "false positive: Assert calls a function which may have desired side effects" @@ -92,7 +92,7 @@ class TestAssert : public TestFixture { "};\n" "void foo() {\n" " assert( !SquarePack::isRank1Or8(push2) );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct SquarePack {\n" @@ -103,7 +103,7 @@ class TestAssert : public TestFixture { "};\n" "void foo() {\n" " assert( !SquarePack::isRank1Or8(push2) );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:25]: (warning) Assert statement calls a function which may have desired side effects: 'isRank1Or8'. [assertWithSideEffect]\n", errout_str()); check("struct SquarePack {\n" @@ -114,7 +114,7 @@ class TestAssert : public TestFixture { "};\n" "void foo() {\n" " assert( !SquarePack::isRank1Or8(push2) );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:25]: (warning) Assert statement calls a function which may have desired side effects: 'isRank1Or8'. [assertWithSideEffect]\n", errout_str()); check("struct SquarePack {\n" @@ -125,7 +125,7 @@ class TestAssert : public TestFixture { "};\n" "void foo() {\n" " assert( !SquarePack::isRank1Or8(push2) );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Geometry {\n" @@ -136,7 +136,7 @@ class TestAssert : public TestFixture { "\n" "void Geometry::ReadGeometry() {\n" " assert(empty());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" // #4811 @@ -166,7 +166,7 @@ class TestAssert : public TestFixture { "};\n" "void foo(SquarePack s) {\n" " assert( s.Foo() );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:14]: (warning) Assert statement calls a function which may have desired side effects: 'Foo'. If there are no side effects, consider declaring the method const. [assertWithSideEffect]\n", errout_str()); check("struct SquarePack {\n" @@ -174,7 +174,7 @@ class TestAssert : public TestFixture { "};\n" "void foo(SquarePack* s) {\n" " assert( s->Foo() );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct SquarePack {\n" @@ -182,14 +182,14 @@ class TestAssert : public TestFixture { "};\n" "void foo(SquarePack* s) {\n" " assert( s->Foo() );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct SquarePack {\n" "};\n" "void foo(SquarePack* s) {\n" " assert( s->Foo() );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -198,54 +198,54 @@ class TestAssert : public TestFixture { " int a; a = 0;\n" " assert(a = 2);\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (warning) Assert statement modifies 'a'. [assignmentInAssert]\n", errout_str()); check("void f(int a) {\n" " assert(a == 2);\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int a, int b) {\n" " assert(a == 2 && (b = 1));\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:25]: (warning) Assert statement modifies 'b'. [assignmentInAssert]\n", errout_str()); check("void f() {\n" " int a; a = 0;\n" " assert(a += 2);\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (warning) Assert statement modifies 'a'. [assignmentInAssert]\n", errout_str()); check("void f() {\n" " int a; a = 0;\n" " assert(a *= 2);\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (warning) Assert statement modifies 'a'. [assignmentInAssert]\n", errout_str()); check("void f() {\n" " int a; a = 0;\n" " assert(a -= 2);\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (warning) Assert statement modifies 'a'. [assignmentInAssert]\n", errout_str()); check("void f() {\n" " int a = 0;\n" " assert(a--);\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (warning) Assert statement modifies 'a'. [assignmentInAssert]\n", errout_str()); check("void f() {\n" " int a = 0;\n" " assert(--a);\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (warning) Assert statement modifies 'a'. [assignmentInAssert]\n", errout_str()); check("void f() {\n" @@ -254,19 +254,19 @@ class TestAssert : public TestFixture { " auto const expected = someOtherValue;\n" " return tmp == expected;\n" " }));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void crash() { check("void foo() {\n" " assert(sizeof(struct { int a[x++]; })==sizeof(int));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" // #9790 " assert(kad_bucket_hash(&(kad_guid) { .bytes = { 0 } }, & (kad_guid){.bytes = { 0 }}) == -1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } }; diff --git a/test/testastutils.cpp b/test/testastutils.cpp index 6a6e0624587..46dde522338 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -62,29 +62,29 @@ class TestAstUtils : public TestFixture { void findLambdaEndTokenTest() { const Token* nullTok = nullptr; ASSERT(nullptr == (::findLambdaEndToken)(nullTok)); - ASSERT_EQUALS(false, findLambdaEndToken("void f() { }")); - ASSERT_EQUALS(true, findLambdaEndToken("[]{ }")); - ASSERT_EQUALS(true, findLambdaEndToken("[]{ return 0; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](){ }")); - ASSERT_EQUALS(true, findLambdaEndToken("[&](){ }")); - ASSERT_EQUALS(true, findLambdaEndToken("[&, i](){ }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) { return -1; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) { return a + b; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) mutable { return a + b; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) constexpr { return a + b; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) -> int { return -1; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> int { return -1; }")); - ASSERT_EQUALS(false, findLambdaEndToken("[](void) foo -> int { return -1; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> int { return -1; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> int* { return x; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * int { return x; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> const * int { return x; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const ** int { return x; }")); - ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * const* int { return x; }")); - ASSERT_EQUALS(false, findLambdaEndToken("int** a[] { new int*[2] { new int, new int} };", "[ ]")); - ASSERT_EQUALS(false, findLambdaEndToken("int** a[] { new int*[2] { new int, new int} };", "[ 2")); - ASSERT_EQUALS(false, findLambdaEndToken("shared_ptr sp{ new Type *[2] {new Type, new Type}, Deleter{ 2 } };", "[ 2")); - ASSERT_EQUALS(true, findLambdaEndToken("int i = 5 * []{ return 7; }();", "[", /*checkNext*/ false)); + ASSERT_EQUALS(false, findLambdaEndToken("void f() { }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[]{ }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[]{ return 0; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](){ }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[&](){ }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[&, i](){ }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) { return -1; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) { return a + b; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) mutable { return a + b; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) constexpr { return a + b; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) -> int { return -1; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> int { return -1; }\n")); + ASSERT_EQUALS(false, findLambdaEndToken("[](void) foo -> int { return -1; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> int { return -1; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> int* { return x; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * int { return x; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> const * int { return x; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const ** int { return x; }\n")); + ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * const* int { return x; }\n")); + ASSERT_EQUALS(false, findLambdaEndToken("int** a[] { new int*[2] { new int, new int} };\n", "[ ]")); + ASSERT_EQUALS(false, findLambdaEndToken("int** a[] { new int*[2] { new int, new int} };\n", "[ 2")); + ASSERT_EQUALS(false, findLambdaEndToken("shared_ptr sp{ new Type *[2] {new Type, new Type}, Deleter{ 2 } };\n", "[ 2")); + ASSERT_EQUALS(true, findLambdaEndToken("int i = 5 * []{ return 7; }();\n", "[", /*checkNext*/ false)); } #define findLambdaStartToken(...) findLambdaStartToken_(__FILE__, __LINE__, __VA_ARGS__) @@ -98,25 +98,25 @@ class TestAstUtils : public TestFixture { void findLambdaStartTokenTest() { ASSERT(nullptr == (::findLambdaStartToken)(nullptr)); - ASSERT_EQUALS(false, findLambdaStartToken("void f() { }")); - ASSERT_EQUALS(true, findLambdaStartToken("[]{ }")); - ASSERT_EQUALS(true, findLambdaStartToken("[]{ return 0; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](){ }")); - ASSERT_EQUALS(true, findLambdaStartToken("[&](){ }")); - ASSERT_EQUALS(true, findLambdaStartToken("[&, i](){ }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) { return -1; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](int a, int b) { return a + b; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](int a, int b) mutable { return a + b; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](int a, int b) constexpr { return a + b; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) -> int { return -1; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) mutable -> int { return -1; }")); - ASSERT_EQUALS(false, findLambdaStartToken("[](void) foo -> int { return -1; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> int { return -1; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> int* { return x; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> const * int { return x; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) mutable -> const * int { return x; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> const ** int { return x; }")); - ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> const * const* int { return x; }")); + ASSERT_EQUALS(false, findLambdaStartToken("void f() { }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[]{ }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[]{ return 0; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](){ }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[&](){ }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[&, i](){ }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) { return -1; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](int a, int b) { return a + b; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](int a, int b) mutable { return a + b; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](int a, int b) constexpr { return a + b; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) -> int { return -1; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) mutable -> int { return -1; }\n")); + ASSERT_EQUALS(false, findLambdaStartToken("[](void) foo -> int { return -1; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> int { return -1; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> int* { return x; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> const * int { return x; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) mutable -> const * int { return x; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> const ** int { return x; }\n")); + ASSERT_EQUALS(true, findLambdaStartToken("[](void) constexpr -> const * const* int { return x; }\n")); } #define isNullOperand(...) isNullOperand_(__FILE__, __LINE__, __VA_ARGS__) @@ -128,16 +128,16 @@ class TestAstUtils : public TestFixture { } void isNullOperandTest() { - ASSERT_EQUALS(true, isNullOperand("(void*)0;")); - ASSERT_EQUALS(true, isNullOperand("(void*)0U;")); - ASSERT_EQUALS(true, isNullOperand("(void*)0x0LL;")); - ASSERT_EQUALS(true, isNullOperand("NULL;")); - ASSERT_EQUALS(true, isNullOperand("nullptr;")); - ASSERT_EQUALS(true, isNullOperand("(void*)NULL;")); - ASSERT_EQUALS(true, isNullOperand("static_cast(0);")); - ASSERT_EQUALS(false, isNullOperand("0;")); - ASSERT_EQUALS(false, isNullOperand("(void*)0.0;")); - ASSERT_EQUALS(false, isNullOperand("(void*)1;")); + ASSERT_EQUALS(true, isNullOperand("(void*)0;\n")); + ASSERT_EQUALS(true, isNullOperand("(void*)0U;\n")); + ASSERT_EQUALS(true, isNullOperand("(void*)0x0LL;\n")); + ASSERT_EQUALS(true, isNullOperand("NULL;\n")); + ASSERT_EQUALS(true, isNullOperand("nullptr;\n")); + ASSERT_EQUALS(true, isNullOperand("(void*)NULL;\n")); + ASSERT_EQUALS(true, isNullOperand("static_cast(0);\n")); + ASSERT_EQUALS(false, isNullOperand("0;\n")); + ASSERT_EQUALS(false, isNullOperand("(void*)0.0;\n")); + ASSERT_EQUALS(false, isNullOperand("(void*)1;\n")); } #define isReturnScope(...) isReturnScope_(__FILE__, __LINE__, __VA_ARGS__) @@ -152,22 +152,22 @@ class TestAstUtils : public TestFixture { } void isReturnScopeTest() { - ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { return; } }", -2)); - ASSERT_EQUALS(true, isReturnScope("int f() { if (a) { return {}; } }", -2)); // #8891 - ASSERT_EQUALS(true, isReturnScope("std::string f() { if (a) { return std::string{}; } }", -2)); // #8891 - ASSERT_EQUALS(true, isReturnScope("std::string f() { if (a) { return std::string{\"\"}; } }", -2)); // #8891 - ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { return (ab){0}; } }", -2)); // #7103 - ASSERT_EQUALS(false, isReturnScope("void f() { if (a) { return (ab){0}; } }", -4)); // #7103 - ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { {throw new string(x);}; } }", -4)); // #7144 - ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { {throw new string(x);}; } }", -2)); // #7144 - ASSERT_EQUALS(false, isReturnScope("void f() { [=]() { return data; }; }", -1)); - ASSERT_EQUALS(true, isReturnScope("auto f() { return [=]() { return data; }; }", -1)); - ASSERT_EQUALS(true, isReturnScope("auto f() { return [=]() { return data; }(); }", -1)); - ASSERT_EQUALS(false, isReturnScope("auto f() { [=]() { return data; }(); }", -1)); - - ASSERT_EQUALS(true, isReturnScope("void negativeTokenOffset() { return; }", -1)); - ASSERT_EQUALS(false, isReturnScope("void zeroTokenOffset() { return; }", 0)); - ASSERT_EQUALS(true, isReturnScope("void positiveTokenOffset() { return; }", 7)); + ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { return; } }\n", -2)); + ASSERT_EQUALS(true, isReturnScope("int f() { if (a) { return {}; } }\n", -2)); // #8891 + ASSERT_EQUALS(true, isReturnScope("std::string f() { if (a) { return std::string{}; } }\n", -2)); // #8891 + ASSERT_EQUALS(true, isReturnScope("std::string f() { if (a) { return std::string{\"\"}; } }\n", -2)); // #8891 + ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { return (ab){0}; } }\n", -2)); // #7103 + ASSERT_EQUALS(false, isReturnScope("void f() { if (a) { return (ab){0}; } }\n", -4)); // #7103 + ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { {throw new string(x);}; } }\n", -4)); // #7144 + ASSERT_EQUALS(true, isReturnScope("void f() { if (a) { {throw new string(x);}; } }\n", -2)); // #7144 + ASSERT_EQUALS(false, isReturnScope("void f() { [=]() { return data; }; }\n", -1)); + ASSERT_EQUALS(true, isReturnScope("auto f() { return [=]() { return data; }; }\n", -1)); + ASSERT_EQUALS(true, isReturnScope("auto f() { return [=]() { return data; }(); }\n", -1)); + ASSERT_EQUALS(false, isReturnScope("auto f() { [=]() { return data; }(); }\n", -1)); + + ASSERT_EQUALS(true, isReturnScope("void negativeTokenOffset() { return; }\n", -1)); + ASSERT_EQUALS(false, isReturnScope("void zeroTokenOffset() { return; }\n", 0)); + ASSERT_EQUALS(true, isReturnScope("void positiveTokenOffset() { return; }\n", 7)); } #define isSameExpression(...) isSameExpression_(__FILE__, __LINE__, __VA_ARGS__) @@ -181,33 +181,33 @@ class TestAstUtils : public TestFixture { } void isSameExpressionTestInternal(bool cpp) { - ASSERT_EQUALS(true, isSameExpression("x = 1 + 1;", "1", "1", cpp)); - ASSERT_EQUALS(false, isSameExpression("x = 1 + 1u;", "1", "1u", cpp)); - ASSERT_EQUALS(true, isSameExpression("x = 1.0 + 1.0;", "1.0", "1.0", cpp)); - ASSERT_EQUALS(false, isSameExpression("x = 1.0f + 1.0;", "1.0f", "1.0", cpp)); - ASSERT_EQUALS(false, isSameExpression("x = 1L + 1;", "1L", "1", cpp)); - ASSERT_EQUALS(true, isSameExpression("x = 0.0f + 0x0p+0f;", "0.0f", "0x0p+0f", cpp)); - ASSERT_EQUALS(true, isSameExpression("x < x;", "x", "x", cpp)); - ASSERT_EQUALS(false, isSameExpression("x < y;", "x", "y", cpp)); - ASSERT_EQUALS(true, isSameExpression("(x + 1) < (x + 1);", "+", "+", cpp)); - ASSERT_EQUALS(false, isSameExpression("(x + 1) < (x + 1L);", "+", "+", cpp)); - ASSERT_EQUALS(!cpp, isSameExpression("(1 + x) < (x + 1);", "+", "+", cpp)); - ASSERT_EQUALS(false, isSameExpression("(1.0l + x) < (1.0 + x);", "+", "+", cpp)); - ASSERT_EQUALS(!cpp, isSameExpression("(0.0 + x) < (x + 0x0p+0);", "+", "+", cpp)); - ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; (x + y) < (x + 10.0); } ", "+", "+", cpp)); - ASSERT_EQUALS(!cpp, isSameExpression("void f() {double y = 1e1; (x + 10.0) < (y + x); } ", "+", "+", cpp)); - ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; double z = 10.0; (x + y) < (x + z); } ", "+", "+", cpp)); - ASSERT_EQUALS(true, isSameExpression("A + A", "A", "A", cpp)); + ASSERT_EQUALS(true, isSameExpression("x = 1 + 1;\n", "1", "1", cpp)); + ASSERT_EQUALS(false, isSameExpression("x = 1 + 1u;\n", "1", "1u", cpp)); + ASSERT_EQUALS(true, isSameExpression("x = 1.0 + 1.0;\n", "1.0", "1.0", cpp)); + ASSERT_EQUALS(false, isSameExpression("x = 1.0f + 1.0;\n", "1.0f", "1.0", cpp)); + ASSERT_EQUALS(false, isSameExpression("x = 1L + 1;\n", "1L", "1", cpp)); + ASSERT_EQUALS(true, isSameExpression("x = 0.0f + 0x0p+0f;\n", "0.0f", "0x0p+0f", cpp)); + ASSERT_EQUALS(true, isSameExpression("x < x;\n", "x", "x", cpp)); + ASSERT_EQUALS(false, isSameExpression("x < y;\n", "x", "y", cpp)); + ASSERT_EQUALS(true, isSameExpression("(x + 1) < (x + 1);\n", "+", "+", cpp)); + ASSERT_EQUALS(false, isSameExpression("(x + 1) < (x + 1L);\n", "+", "+", cpp)); + ASSERT_EQUALS(!cpp, isSameExpression("(1 + x) < (x + 1);\n", "+", "+", cpp)); + ASSERT_EQUALS(false, isSameExpression("(1.0l + x) < (1.0 + x);\n", "+", "+", cpp)); + ASSERT_EQUALS(!cpp, isSameExpression("(0.0 + x) < (x + 0x0p+0);\n", "+", "+", cpp)); + ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; (x + y) < (x + 10.0); } \n", "+", "+", cpp)); + ASSERT_EQUALS(!cpp, isSameExpression("void f() {double y = 1e1; (x + 10.0) < (y + x); } \n", "+", "+", cpp)); + ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; double z = 10.0; (x + y) < (x + z); } \n", "+", "+", cpp)); + ASSERT_EQUALS(true, isSameExpression("A + A\n", "A", "A", cpp)); // the remaining test cases are not valid C code if (!cpp) return; //https://trac.cppcheck.net/ticket/9700 - ASSERT_EQUALS(true, isSameExpression("A::B + A::B;", "::", "::", cpp)); - ASSERT_EQUALS(false, isSameExpression("A::B + A::C;", "::", "::", cpp)); - ASSERT_EQUALS(true, isSameExpression("A::B* get() { if(x) return new A::B(true); else return new A::B(true); }", "new", "new", cpp)); - ASSERT_EQUALS(false, isSameExpression("A::B* get() { if(x) return new A::B(true); else return new A::C(true); }", "new", "new", cpp)); + ASSERT_EQUALS(true, isSameExpression("A::B + A::B;\n", "::", "::", cpp)); + ASSERT_EQUALS(false, isSameExpression("A::B + A::C;\n", "::", "::", cpp)); + ASSERT_EQUALS(true, isSameExpression("A::B* get() { if(x) return new A::B(true); else return new A::B(true); }\n", "new", "new", cpp)); + ASSERT_EQUALS(false, isSameExpression("A::B* get() { if(x) return new A::B(true); else return new A::C(true); }\n", "new", "new", cpp)); } void isSameExpressionCpp() { @@ -233,7 +233,7 @@ class TestAstUtils : public TestFixture { (void)isVariableChanged("void f() {\n" " int b;\n" " if (b) { (int)((INTOF(8))result >> b); }\n" - "}", "if", "}"); + "}\n", "if", "}"); // #9235 ASSERT_EQUALS(false, isVariableChanged("void f() {\n" @@ -242,13 +242,13 @@ class TestAstUtils : public TestFixture { "= a", "}")); - ASSERT_EQUALS(false, isVariableChanged("void f(const A& a) { a.f(); }", "{", "}")); + ASSERT_EQUALS(false, isVariableChanged("void f(const A& a) { a.f(); }\n", "{", "}")); ASSERT_EQUALS(true, isVariableChanged("void g(int*);\n" "void f(int x) { g(&x); }\n", "{", "}")); - ASSERT_EQUALS(false, isVariableChanged("const int A[] = { 1, 2, 3 };", "[", "]")); + ASSERT_EQUALS(false, isVariableChanged("const int A[] = { 1, 2, 3 };\n", "[", "]")); } #define isVariableChangedByFunctionCall(...) isVariableChangedByFunctionCall_( __FILE__, __LINE__, __VA_ARGS__) @@ -267,7 +267,7 @@ class TestAstUtils : public TestFixture { { // #8271 - template method const char code[] = "void f(int x) {\n" " a(x);\n" - "}"; + "}\n"; bool inconclusive = false; ASSERT_EQUALS(false, isVariableChangedByFunctionCall(code, "x ) ;", &inconclusive)); ASSERT_EQUALS(true, inconclusive); @@ -431,8 +431,8 @@ class TestAstUtils : public TestFixture { void isExpressionChangedTest() { - ASSERT_EQUALS(true, isExpressionChanged("void f(std::map& m) { m[0]; }", "m [", "{", "}")); - ASSERT_EQUALS(false, isExpressionChanged("void f(const A& a) { a.f(); }", "a .", "{", "}")); + ASSERT_EQUALS(true, isExpressionChanged("void f(std::map& m) { m[0]; }\n", "m [", "{", "}")); + ASSERT_EQUALS(false, isExpressionChanged("void f(const A& a) { a.f(); }\n", "a .", "{", "}")); ASSERT_EQUALS(true, isExpressionChanged("void g(int*);\n" @@ -459,17 +459,17 @@ class TestAstUtils : public TestFixture { } void nextAfterAstRightmostLeafTest() { - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("void f(int a, int b) { int x = a + b; }", "=", "; }")); - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a); }", "=", "; }")); - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a)[b]; }", "=", "; }")); - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(g(a)[b]); }", "=", "; }")); - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(g(a)[b] + a); }", "=", "; }")); - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a)[b + 1]; }", "=", "; }")); - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("void f() { int a; int b; int x = [](int a){}; }", "=", "; }")); - - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = a + b; }", "+", "; }")); - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a)[b + 1]; }", "+", "] ; }")); - ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a + 1)[b]; }", "+", ") [")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("void f(int a, int b) { int x = a + b; }\n", "=", "; }")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a); }\n", "=", "; }")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a)[b]; }\n", "=", "; }")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(g(a)[b]); }\n", "=", "; }")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(g(a)[b] + a); }\n", "=", "; }")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a)[b + 1]; }\n", "=", "; }")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("void f() { int a; int b; int x = [](int a){}; }\n", "=", "; }")); + + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = a + b; }\n", "+", "; }")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a)[b + 1]; }\n", "+", "] ; }")); + ASSERT_EQUALS(true, nextAfterAstRightmostLeaf("int * g(int); void f(int a, int b) { int x = g(a + 1)[b]; }\n", "+", ") [")); } enum class Result : std::uint8_t {False, True, Fail}; @@ -486,37 +486,37 @@ class TestAstUtils : public TestFixture { } void isUsedAsBool() { - ASSERT(Result::True == isUsedAsBool("void f() { bool b = true; }", "b")); - ASSERT(Result::False ==isUsedAsBool("void f() { int i = true; }", "i")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (i) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; while (i) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; for (;i;) {} }", "i ; )")); - ASSERT(Result::False == isUsedAsBool("void f() { int i; for (;;i) {} }", "i )")); - ASSERT(Result::False == isUsedAsBool("void f() { int i; for (i;;) {} }", "i ; ; )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; for (int j=0; i; ++j) {} }", "i ; ++")); - ASSERT(Result::False == isUsedAsBool("void f() { int i; if (i == 2) {} }", "i ==")); - ASSERT(Result::False == isUsedAsBool("void f() { int i; if (i == true) {} }", "i ==")); - ASSERT(Result::False == isUsedAsBool("void f() { int i,j; if (i == (j&&f())) {} }", "i ==")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (!i == 0) {} }", "i ==")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (!i) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (!!i) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (i && f()) {} }", "i &&")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; int j = i && f(); }", "i &&")); - ASSERT(Result::False == isUsedAsBool("void f() { int i; if (i & f()) {} }", "i &")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (static_cast(i)) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if ((bool)i) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (1+static_cast(i)) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (1+(bool)i) {} }", "i )")); - ASSERT(Result::False == isUsedAsBool("void f() { int i; if (1+static_cast(i)) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; if (1+!static_cast(i)) {} }", "i )")); - ASSERT(Result::False == isUsedAsBool("void f() { int i; if (1+(int)i) {} }", "i )")); - ASSERT(Result::False == isUsedAsBool("void f() { int i; if (i + 2) {} }", "i +")); - ASSERT(Result::True == isUsedAsBool("void f() { int i; bool b = i; }", "i ; }")); - ASSERT(Result::True == isUsedAsBool("void f(bool b); void f() { int i; f(i); }","i )")); - ASSERT(Result::False == isUsedAsBool("void f() { int *i; if (*i) {} }", "i )")); - ASSERT(Result::True == isUsedAsBool("void f() { int *i; if (*i) {} }", "* i )")); - ASSERT(Result::True == isUsedAsBool("int g(); void h(bool); void f() { h(g()); }", "( ) )")); - ASSERT(Result::True == isUsedAsBool("int g(int); void h(bool); void f() { h(g(0)); }", "( 0 ) )")); + ASSERT(Result::True == isUsedAsBool("void f() { bool b = true; }\n", "b")); + ASSERT(Result::False ==isUsedAsBool("void f() { int i = true; }\n", "i")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (i) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; while (i) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; for (;i;) {} }\n", "i ; )")); + ASSERT(Result::False == isUsedAsBool("void f() { int i; for (;;i) {} }\n", "i )")); + ASSERT(Result::False == isUsedAsBool("void f() { int i; for (i;;) {} }\n", "i ; ; )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; for (int j=0; i; ++j) {} }\n", "i ; ++")); + ASSERT(Result::False == isUsedAsBool("void f() { int i; if (i == 2) {} }\n", "i ==")); + ASSERT(Result::False == isUsedAsBool("void f() { int i; if (i == true) {} }\n", "i ==")); + ASSERT(Result::False == isUsedAsBool("void f() { int i,j; if (i == (j&&f())) {} }\n", "i ==")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (!i == 0) {} }\n", "i ==")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (!i) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (!!i) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (i && f()) {} }\n", "i &&")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; int j = i && f(); }\n", "i &&")); + ASSERT(Result::False == isUsedAsBool("void f() { int i; if (i & f()) {} }\n", "i &")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (static_cast(i)) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if ((bool)i) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (1+static_cast(i)) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (1+(bool)i) {} }\n", "i )")); + ASSERT(Result::False == isUsedAsBool("void f() { int i; if (1+static_cast(i)) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; if (1+!static_cast(i)) {} }\n", "i )")); + ASSERT(Result::False == isUsedAsBool("void f() { int i; if (1+(int)i) {} }\n", "i )")); + ASSERT(Result::False == isUsedAsBool("void f() { int i; if (i + 2) {} }\n", "i +")); + ASSERT(Result::True == isUsedAsBool("void f() { int i; bool b = i; }\n", "i ; }")); + ASSERT(Result::True == isUsedAsBool("void f(bool b); void f() { int i; f(i); }\n","i )")); + ASSERT(Result::False == isUsedAsBool("void f() { int *i; if (*i) {} }\n", "i )")); + ASSERT(Result::True == isUsedAsBool("void f() { int *i; if (*i) {} }\n", "* i )")); + ASSERT(Result::True == isUsedAsBool("int g(); void h(bool); void f() { h(g()); }\n", "( ) )")); + ASSERT(Result::True == isUsedAsBool("int g(int); void h(bool); void f() { h(g(0)); }\n", "( 0 ) )")); } }; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 7774d7fa733..dbec2bae0a0 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -180,21 +180,21 @@ class TestAutoVariables : public TestFixture { "{\n" " int num = 2;\n" " *res = #\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); check("void func1(int **res)\n" "{\n" " int num = 2;\n" " res = #\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it? [uselessAssignmentPtrArg]\n", errout_str()); check("void func1(int **res)\n" "{\n" " int num = 2;\n" " foo.res = #\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -206,7 +206,7 @@ class TestAutoVariables : public TestFixture { "{\n" " int num = 2;\n" " *res = #\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); check("class Fred {\n" @@ -216,7 +216,7 @@ class TestAutoVariables : public TestFixture { "{\n" " int num = 2;\n" " res = #\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it? [uselessAssignmentPtrArg]\n", errout_str()); check("class Fred {\n" @@ -226,7 +226,7 @@ class TestAutoVariables : public TestFixture { "{\n" " int num = 2;\n" " foo.res = #\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -235,7 +235,7 @@ class TestAutoVariables : public TestFixture { "{\n" " int x[100];\n" " *p = x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); } @@ -244,7 +244,7 @@ class TestAutoVariables : public TestFixture { "{\n" " static int x[100];\n" " *p = x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -253,7 +253,7 @@ class TestAutoVariables : public TestFixture { "{\n" " char a;\n" " ab->a = &a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error, inconclusive) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); } @@ -262,14 +262,14 @@ class TestAutoVariables : public TestFixture { "{\n" " char a[10];\n" " x->str = a;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("void foo(struct X *x)\n" "{\n" " char a[10];\n" " x->str = a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error, inconclusive) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); } @@ -279,7 +279,7 @@ class TestAutoVariables : public TestFixture { " struct txt_scrollpane_s * scrollpane;\n" " target->parent = &scrollpane->widget;\n" " return scrollpane;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); } @@ -287,12 +287,12 @@ class TestAutoVariables : public TestFixture { check("void foo(int*& p) {\n" " int i = 0;\n" " p = &i;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); check("void foo(std::string& s) {\n" " s = foo;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); } @@ -303,7 +303,7 @@ class TestAutoVariables : public TestFixture { " FN fn;\n" " FP fp;\n" " p = &fn.i;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:6:5]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); check("struct FN {int i;};\n" @@ -312,7 +312,7 @@ class TestAutoVariables : public TestFixture { " FN fn;\n" " FP fp;\n" " p = &p_fp->i;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("struct FN {int i;};\n" @@ -321,100 +321,100 @@ class TestAutoVariables : public TestFixture { " FN fn;\n" " FP fp;\n" " p = &fp.f->i;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); } void testautovar10() { // #2930 - assignment of function parameter check("void foo(char* p) {\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it? [uselessAssignmentPtrArg]\n", errout_str()); check("void foo(int b) {\n" " b = foo(b);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Assignment of function parameter has no effect outside the function. [uselessAssignmentArg]\n", errout_str()); check("void foo(int b) {\n" " b += 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Assignment of function parameter has no effect outside the function. [uselessAssignmentArg]\n", errout_str()); check("void foo(std::string s) {\n" " s = foo(b);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Assignment of function parameter has no effect outside the function. [uselessAssignmentArg]\n", errout_str()); check("void foo(char* p) {\n" // don't warn for self assignment, there is another warning for this " p = p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char* p) {\n" " if (!p) p = buf;\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char* p) {\n" " if (!p) p = buf;\n" " do_something(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char* p) {\n" " while (!p) p = buf;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char* p) {\n" " p = 0;\n" " asm(\"somecmd\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(Foo* p) {\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it? [uselessAssignmentPtrArg]\n", errout_str()); check("class Foo {};\n" "void foo(Foo p) {\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (style) Assignment of function parameter has no effect outside the function. [uselessAssignmentArg]\n", errout_str()); check("void foo(Foo p) {\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int& p) {\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("double foo(double d) {\n" // #5005 " int i = d;\n" " d = i;\n" - " return d;" - "}",dinit(CheckOptions, $.inconclusive = false)); + " return d;\n" + "}\n",dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("void foo(int* ptr) {\n" // #4793 " ptr++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it? [uselessAssignmentPtrArg]\n", errout_str()); check("void foo(int* ptr) {\n" // #3177 " --ptr;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it? [uselessAssignmentPtrArg]\n", errout_str()); check("void foo(struct S* const x) {\n" // #7839 " ++x->n;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -425,7 +425,7 @@ class TestAutoVariables : public TestFixture { "void foo(char** p) {\n" " struct A a = bar();\n" " *p = &(*a.data)[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -434,36 +434,36 @@ class TestAutoVariables : public TestFixture { "void foo(char** p) {\n" " struct A a = bar();\n" " *p = &a.data[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:5]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); check("void f(char **out) {\n" " struct S *p = glob;\n" " *out = &p->data;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4998 check("void f(s8**out) {\n" " s8 *p;\n" // <- p is pointer => no error " *out = &p[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(s8**out) {\n" " s8 p[10];\n" // <- p is array => error " *out = &p[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); } void testautovar12() { // Ticket #5024, #5050 - Crash on invalid input - ASSERT_THROW_INTERNAL(check("void f(int* a) { a = }"), SYNTAX); + ASSERT_THROW_INTERNAL(check("void f(int* a) { a = }\n"), SYNTAX); check("struct custom_type { custom_type(int) {} };\n" "void func(int) {}\n" "int var;\n" "void init() { func(var); }\n" - "UNKNOWN_MACRO_EXPANDING_TO_SIGNATURE { custom_type a(var); }"); + "UNKNOWN_MACRO_EXPANDING_TO_SIGNATURE { custom_type a(var); }\n"); } void testautovar13() { // Ticket #5537 @@ -473,7 +473,7 @@ class TestAutoVariables : public TestFixture { " ~FileManager() {\n" " delete &UniqueRealDirs;\n" " }\n" - "};"); + "};\n"); } void testautovar14() { // Ticket #4776 @@ -483,7 +483,7 @@ class TestAutoVariables : public TestFixture { " x = x >> 1;\n" " goto label;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -496,7 +496,7 @@ class TestAutoVariables : public TestFixture { " if (lumdiff > 5.0f)\n" " return &darkOutline;\n" " return 0;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); } @@ -504,7 +504,7 @@ class TestAutoVariables : public TestFixture { check("void f(const void* ptr, bool* result) {\n" " int dummy;\n" " *result = (&dummy < ptr);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -533,7 +533,7 @@ class TestAutoVariables : public TestFixture { "{\n" " int num=2;" " arr[0]=#\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); } @@ -545,7 +545,7 @@ class TestAutoVariables : public TestFixture { "{\n" " int num=2;" " arr[0]=#\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:19]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); } @@ -596,7 +596,7 @@ class TestAutoVariables : public TestFixture { "{\n" " XPoint DropPoint;\n" " ds->location_data = (XtPointer *)&DropPoint;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error, inconclusive) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); } @@ -604,7 +604,7 @@ class TestAutoVariables : public TestFixture { check("void remove_duplicate_matches (char **matches) {\n" " char dead_slot;\n" " matches[0] = (char *)&dead_slot;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); } @@ -613,7 +613,7 @@ class TestAutoVariables : public TestFixture { "{\n" " int num=2;" " return #" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:26] -> [test.cpp:3:9] -> [test.cpp:3:26]: (error) Returning pointer to local variable 'num' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); } @@ -625,7 +625,7 @@ class TestAutoVariables : public TestFixture { "{\n" " int num=2;" " return #" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:26] -> [test.cpp:6:9] -> [test.cpp:6:26]: (error) Returning pointer to local variable 'num' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); } @@ -635,7 +635,7 @@ class TestAutoVariables : public TestFixture { "{\n" " void *&value = tls[id];" " return &value;" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -644,7 +644,7 @@ class TestAutoVariables : public TestFixture { check("void foo() {\n" " int cond2;\n" " dostuff([&cond2]() { return &cond2; });\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -681,7 +681,7 @@ class TestAutoVariables : public TestFixture { "{\n" " extern struct foo f;\n" " return &f;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -691,7 +691,7 @@ class TestAutoVariables : public TestFixture { " pcb->root0 = &root0;\n" " dostuff(pcb);\n" " pcb->root0 = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(cb* pcb) {\n" @@ -700,7 +700,7 @@ class TestAutoVariables : public TestFixture { " dostuff(pcb);\n" " if (condition) return;\n" // <- not reassigned => error " pcb->root0 = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error, inconclusive) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); check("void foo(cb* pcb) {\n" @@ -709,7 +709,7 @@ class TestAutoVariables : public TestFixture { " dostuff(pcb);\n" " if (condition)\n" " pcb->root0 = 0;\n" // <- conditional reassign => error - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error, inconclusive) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); check("struct S { int *p; };\n" @@ -721,7 +721,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " struct S s;\n" " g(&s);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:5]: (error) Address of local auto-variable assigned to a function parameter. [autoVariables]\n", errout_str()); @@ -739,7 +739,7 @@ class TestAutoVariables : public TestFixture { " delete[] (tmp4);\n" " char tmp5[256];\n" " delete[] tmp5;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (error) Deallocation of an auto-variable results in undefined behaviour. [autovarInvalidDeallocation]\n" "[test.cpp:5:12]: (error) Deallocation of an auto-variable results in undefined behaviour. [autovarInvalidDeallocation]\n" "[test.cpp:7:12]: (error) Deallocation of an auto-variable results in undefined behaviour. [autovarInvalidDeallocation]\n" @@ -748,28 +748,28 @@ class TestAutoVariables : public TestFixture { check("void func1(char * ptr) {\n" " free(ptr);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void func1() {\n" " char* tmp1[256];\n" " init(tmp1);\n" " delete tmp1[34];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void func1() {\n" " static char tmp1[256];\n" " char *p = tmp1;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (error) Deallocation of a static variable (tmp1) results in undefined behaviour. [autovarInvalidDeallocation]\n", errout_str()); check("char tmp1[256];\n" "void func1() {\n" " char *p; if (x) p = tmp1;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (error) Deallocation of a global variable (tmp1) results in undefined behaviour. [autovarInvalidDeallocation]\n", errout_str()); check("void f()\n" @@ -780,7 +780,7 @@ class TestAutoVariables : public TestFixture { " abc(0, psz_title);\n" " free(psz_title);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #2298 new check: passing stack-address to free() @@ -788,44 +788,44 @@ class TestAutoVariables : public TestFixture { " int *p = malloc(4);\n" " free(&p);\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (error) Deallocation of an auto-variable results in undefined behaviour. [autovarInvalidDeallocation]\n", errout_str()); check("int main() {\n" " int i;\n" " free(&i);\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (error) Deallocation of an auto-variable results in undefined behaviour. [autovarInvalidDeallocation]\n", errout_str()); // #5732 check("int main() {\n" " long (*pKoeff)[256] = new long[9][256];\n" " delete[] pKoeff;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int main() {\n" " long *pKoeff[256];\n" " delete[] pKoeff;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (error) Deallocation of an auto-variable results in undefined behaviour. [autovarInvalidDeallocation]\n", errout_str()); check("int main() {\n" " long *pKoeff[256];\n" " free (pKoeff);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (error) Deallocation of an auto-variable results in undefined behaviour. [autovarInvalidDeallocation]\n", errout_str()); check("void foo() {\n" " const intPtr& intref = Getter();\n" " delete intref;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test() {\n" " MyObj& obj = *new MyObj;\n" " delete &obj;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6506 @@ -837,7 +837,7 @@ class TestAutoVariables : public TestFixture { " F().free(c1);\n" " char *c2 = 0;\n" " F().free(&c2);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class foo {\n" @@ -846,14 +846,14 @@ class TestAutoVariables : public TestFixture { " char **dst_copy = NULL;\n" " free(&dst_copy);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #6551 check("bool foo( ) {\n" " SwTxtFld * pTxtFld = GetFldTxtAttrAt();\n" " delete static_cast(&pTxtFld->GetAttr());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8910 @@ -863,14 +863,14 @@ class TestAutoVariables : public TestFixture { " if (data_size > sizeof (stack)) data = malloc (data_size);\n" " else data = (RGNDATA *)stack;\n" " if ((char *)data != stack) free (data);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8923 check("void f(char **args1, char *args2[]) {\n" " free((char **)args1);\n" " free((char **)args2);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10097 @@ -985,7 +985,7 @@ class TestAutoVariables : public TestFixture { check("void f(EventPtr *eventP, ActionPtr **actionsP) {\n" " EventPtr event = *eventP;\n" " *actionsP = &event->actions;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -993,7 +993,7 @@ class TestAutoVariables : public TestFixture { check("static void function(unsigned long **datap) {\n" " struct my_s *mr = global_structure_pointer;\n" " *datap = &mr->value;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1002,7 +1002,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " int x[10];\n" " p = x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7] -> [test.cpp:3:7] -> [test.cpp:4:3]: (error) Non-local variable 'p' will use pointer to local variable 'x'. [danglingLifetime]\n", errout_str()); check("int *p;\n" @@ -1010,7 +1010,7 @@ class TestAutoVariables : public TestFixture { " int x[10];\n" " p = x;\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1019,7 +1019,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " int x;\n" " p = &x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7] -> [test.cpp:3:7] -> [test.cpp:4:3]: (error) Non-local variable 'p' will use pointer to local variable 'x'. [danglingLifetime]\n", errout_str()); check("int *p;\n" @@ -1027,7 +1027,7 @@ class TestAutoVariables : public TestFixture { " int x;\n" " p = &x;\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1038,7 +1038,7 @@ class TestAutoVariables : public TestFixture { " ptr = &x;\n" " }\n" " int *ptr;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:11] -> [test.cpp:3:9] -> [test.cpp:4:5]: (error) Non-local variable 'ptr' will use pointer to local variable 'x'. [danglingLifetime]\n", errout_str()); check("struct A {\n" @@ -1048,7 +1048,7 @@ class TestAutoVariables : public TestFixture { " ptr = 0;\n" " }\n" " int *ptr;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct R {\n" // #11393 @@ -1072,7 +1072,7 @@ class TestAutoVariables : public TestFixture { "{\n" " char str[100] = {0};\n" " return str;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:12] -> [test.cpp:3:10] -> [test.cpp:4:12]: (error) Returning pointer to local variable 'str' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -1082,7 +1082,7 @@ class TestAutoVariables : public TestFixture { " char str[100] = {0};\n" " char *p = str;\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:15] -> [test.cpp:3:10] -> [test.cpp:5:12]: (error) Returning pointer to local variable 'str' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -1094,7 +1094,7 @@ class TestAutoVariables : public TestFixture { "{\n" " char str[100] = {0};\n" " return str;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:7:12] -> [test.cpp:6:10] -> [test.cpp:7:12]: (error) Returning pointer to local variable 'str' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -1106,7 +1106,7 @@ class TestAutoVariables : public TestFixture { " char temp[42];\n" " char *tp = temp;\n" " tp = format_reg(tp);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1115,7 +1115,7 @@ class TestAutoVariables : public TestFixture { "{\n" " char str[100] = {0};\n" " return str;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class Fred {\n" @@ -1125,7 +1125,7 @@ class TestAutoVariables : public TestFixture { "{\n" " char str[100] = {0};\n" " return str;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1135,14 +1135,14 @@ class TestAutoVariables : public TestFixture { check("char *foo() {\n" " char q[] = \"AAAAAAAAAAAA\";\n" " return &q[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12] -> [test.cpp:2:10] -> [test.cpp:3:12]: (error) Returning pointer to local variable 'q' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("char *foo()\n" "{\n" " static char q[] = \"AAAAAAAAAAAA\";\n" " return &q[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("char *foo()\n" @@ -1151,7 +1151,7 @@ class TestAutoVariables : public TestFixture { "char *p;\n" "p = &q[1];\n" "return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5] -> [test.cpp:3:6] -> [test.cpp:6:8]: (error) Returning pointer to local variable 'q' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); } @@ -1159,7 +1159,7 @@ class TestAutoVariables : public TestFixture { check("char *foo() {\n" " char x[10] = {0};\n" " return x+5;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:12] -> [test.cpp:2:10] -> [test.cpp:3:13]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -1167,7 +1167,7 @@ class TestAutoVariables : public TestFixture { check("char *foo(int y) {\n" " char x[10] = {0};\n" " return (x+8)-y;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:13] -> [test.cpp:2:10] -> [test.cpp:3:17]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -1177,7 +1177,7 @@ class TestAutoVariables : public TestFixture { check("char *foo() {\n" " int x[10] = {0};\n" " return (char *)x;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:20] -> [test.cpp:2:9] -> [test.cpp:3:12]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -1188,7 +1188,7 @@ class TestAutoVariables : public TestFixture { " int x = 123;\n" " int p = &x;\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13] -> [test.cpp:2:9] -> [test.cpp:4:12]: (error) Returning object that points to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); } @@ -1198,35 +1198,35 @@ class TestAutoVariables : public TestFixture { " int s = 0;\n" " int& x = s;\n" " return x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12] -> [test.cpp:5:12]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("std::string &foo()\n" "{\n" " std::string s;\n" " return s;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("std::vector &foo()\n" "{\n" " std::vector v;\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("std::vector &foo()\n" "{\n" " static std::vector v;\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector &foo()\n" "{\n" " thread_local std::vector v;\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string hello()\n" @@ -1237,7 +1237,7 @@ class TestAutoVariables : public TestFixture { "std::string &f()\n" "{\n" " return hello();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:17]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); // make sure scope is used in function lookup @@ -1248,7 +1248,7 @@ class TestAutoVariables : public TestFixture { "};\n" "std::string &f() {\n" " return hello();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string hello() {\n" @@ -1257,7 +1257,7 @@ class TestAutoVariables : public TestFixture { "\n" "std::string &f() {\n" " return hello();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:17]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("std::string hello() {\n" @@ -1266,7 +1266,7 @@ class TestAutoVariables : public TestFixture { "\n" "std::string &f() {\n" " return hello().substr(1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:26]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("class Foo;\n" @@ -1276,7 +1276,7 @@ class TestAutoVariables : public TestFixture { "\n" "Foo& f() {\n" " return hello();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:17]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); // make sure function overloads are handled properly @@ -1291,7 +1291,7 @@ class TestAutoVariables : public TestFixture { "\n" "Foo& f() {\n" " return hello(true);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("Foo hello() {\n" @@ -1300,7 +1300,7 @@ class TestAutoVariables : public TestFixture { "\n" "Foo& f() {\n" // Unknown type - might be a reference " return hello();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1312,7 +1312,7 @@ class TestAutoVariables : public TestFixture { "{\n" " std::string s;\n" " return s;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:12]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("class Fred {\n" @@ -1322,7 +1322,7 @@ class TestAutoVariables : public TestFixture { "{\n" " std::vector v;\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:12]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("class Fred {\n" @@ -1332,7 +1332,7 @@ class TestAutoVariables : public TestFixture { "{\n" " static std::vector v;\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class Fred {\n" @@ -1345,7 +1345,7 @@ class TestAutoVariables : public TestFixture { "std::string &Fred::f()\n" "{\n" " return hello();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:17]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("class Fred {\n" @@ -1359,7 +1359,7 @@ class TestAutoVariables : public TestFixture { "std::string &Fred::f()\n" "{\n" " return hello();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:11:17]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("class Bar;\n" @@ -1368,7 +1368,7 @@ class TestAutoVariables : public TestFixture { "}\n" "Bar& bar() {\n" " return foo();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:15]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("std::map foo() {\n" @@ -1376,7 +1376,7 @@ class TestAutoVariables : public TestFixture { "}\n" "std::map& bar() {\n" " return foo();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:15]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("Bar foo() {\n" @@ -1384,13 +1384,13 @@ class TestAutoVariables : public TestFixture { "}\n" "Bar& bar() {\n" // Unknown type - might be a typedef to a reference type " return foo();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Don't crash with function in unknown scope (#4076) - check("X& a::Bar() {}" + check("X& a::Bar() {}\n" "X& foo() {" " return Bar();" - "}"); + "}\n"); } void returnReference3() { @@ -1398,7 +1398,7 @@ class TestAutoVariables : public TestFixture { " double ret = getValue();\n" " rd = ret;\n" " return rd;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); } @@ -1407,7 +1407,7 @@ class TestAutoVariables : public TestFixture { check("double a;\n" "double & f() {\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1427,7 +1427,7 @@ class TestAutoVariables : public TestFixture { " const A &ra = pb->a;\n" " return ra;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1435,7 +1435,7 @@ class TestAutoVariables : public TestFixture { check("Fred & create() {\n" " Fred &fred(*new Fred);\n" " return fred;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1444,14 +1444,14 @@ class TestAutoVariables : public TestFixture { "std::string &a(int);\n" "std::string &b() {\n" " return a(12);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string &a(int);\n" "std::string a();\n" "std::string &b() {\n" " return a(12);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1460,14 +1460,14 @@ class TestAutoVariables : public TestFixture { " std::vector::iterator it = v.begin();\n" " int& value = *it;\n" " return value;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void returnReference9() { check("int& f(bool b, int& x, int& y) {\n" " return b ? x : y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1476,14 +1476,14 @@ class TestAutoVariables : public TestFixture { "int& g() {\n" " A a;\n" " return a.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:15]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("class A { int& f() const; };\n" "int& g() {\n" " A a;\n" " return a.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1491,19 +1491,19 @@ class TestAutoVariables : public TestFixture { check("class A { static int f(); };\n" "int& g() {\n" " return A::f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("class A { static int& f(); };\n" "int& g() {\n" " return A::f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("namespace A { int& f(); }\n" "int& g() {\n" " return A::f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1511,14 +1511,14 @@ class TestAutoVariables : public TestFixture { check("class A { static int& f(); };\n" "auto g() {\n" " return &A::f;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class A { static int& f(); };\n" "auto g() {\n" " auto x = &A::f;\n" " return x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1527,14 +1527,14 @@ class TestAutoVariables : public TestFixture { "void* vp = &v;\n" "int& foo(size_t i) {\n" " return ((std::vector*)vp)->at(i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector v;\n" "void* vp = &v;\n" "int& foo(size_t i) {\n" " return static_cast*>(vp)->at(i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1547,7 +1547,7 @@ class TestAutoVariables : public TestFixture { "}\n" "void* &A::f() {\n" " return g()->m;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1560,7 +1560,7 @@ class TestAutoVariables : public TestFixture { "template \n" "const int& f(const T&) {\n" " return f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("template \n" @@ -1568,19 +1568,19 @@ class TestAutoVariables : public TestFixture { "template \n" "const int& f(const T&) {\n" " return g();\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); } void returnReference16() { check("int& f(std::tuple& x) {\n" " return std::get<0>(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int& f(int x) {\n" " return std::get<0>(std::make_tuple(x));\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); } @@ -1588,7 +1588,7 @@ class TestAutoVariables : public TestFixture { check("auto g() -> int&;\n" "int& f() {\n" " return g();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1597,7 +1597,7 @@ class TestAutoVariables : public TestFixture { "auto f(T& x) -> decltype(x);\n" "int& g(int* x) {\n" " return f(*x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1605,7 +1605,7 @@ class TestAutoVariables : public TestFixture { void returnReference19() { check("struct C : B {\n" " const B &f() const { return (const B &)*this; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1616,7 +1616,7 @@ class TestAutoVariables : public TestFixture { "};\n" "int& b() {\n" " return a()();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("auto a() {\n" @@ -1627,13 +1627,13 @@ class TestAutoVariables : public TestFixture { "}\n" "const int& c() {\n" " return a()();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::function a();\n" "int& b() {\n" " return a()();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9889 @@ -1779,7 +1779,7 @@ class TestAutoVariables : public TestFixture { "int& hello() {\n" " int x = 0;\n" " return f(x);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:1:14] -> [test.cpp:2:12] -> [test.cpp:6:12] -> [test.cpp:6:13]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); @@ -1790,7 +1790,7 @@ class TestAutoVariables : public TestFixture { "int* hello() {\n" " int x = 0;\n" " return &f(x);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:1:14] -> [test.cpp:2:12] -> [test.cpp:6:13] -> [test.cpp:6:12] -> [test.cpp:5:9] -> [test.cpp:6:12]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -1800,7 +1800,7 @@ class TestAutoVariables : public TestFixture { "}\n" "int * g(int x) {\n" " return f(&x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:14] -> [test.cpp:5:14] -> [test.cpp:4:13] -> [test.cpp:5:13]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("int* f(int * x) {\n" @@ -1809,7 +1809,7 @@ class TestAutoVariables : public TestFixture { "}\n" "int * g(int x) {\n" " return f(&x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int& a) {\n" @@ -1818,7 +1818,7 @@ class TestAutoVariables : public TestFixture { "int& hello() {\n" " int x = 0;\n" " return f(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:13]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("int& f(int a) {\n" @@ -1827,7 +1827,7 @@ class TestAutoVariables : public TestFixture { "int& hello() {\n" " int x = 0;\n" " return f(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("int f(int a) {\n" @@ -1836,14 +1836,14 @@ class TestAutoVariables : public TestFixture { "int& hello() {\n" " int x = 0;\n" " return f(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:13]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("template\n" "int& f(int& x, T y) {\n" " x += y;\n" " return x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1851,31 +1851,31 @@ class TestAutoVariables : public TestFixture { check("auto& f() {\n" " std::vector x;\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("auto& f() {\n" " std::vector x;\n" " return x.front();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14] -> [test.cpp:3:19]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("std::vector g();\n" "auto& f() {\n" " return g().front();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16] -> [test.cpp:3:21]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("auto& f() {\n" " return std::vector{1}.front();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:32] -> [test.cpp:2:37]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("struct A { int foo; };\n" "int& f(std::vector v) {\n" " auto it = v.begin();\n" " return it->foo;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:22] -> [test.cpp:4:14]: (error) Reference to local variable returned. [returnReference]\n", errout_str()); check("template \n" @@ -1909,7 +1909,7 @@ class TestAutoVariables : public TestFixture { "int& f(std::vector& v) {\n" " auto it = v.begin();\n" " return it->foo;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("static std::vector A[2];\n" @@ -1923,18 +1923,18 @@ class TestAutoVariables : public TestFixture { void returnReferenceLiteral() { check("const std::string &a() {\n" " return \"foo\";\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("const std::string a() {\n" " return \"foo\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const std::string& f(const std::string& x) { return x; }\n" "const std::string &a() {\n" " return f(\"foo\");\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:1:42] -> [test.cpp:1:53] -> [test.cpp:3:12] -> [test.cpp:3:13]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); @@ -1942,59 +1942,59 @@ class TestAutoVariables : public TestFixture { check("const char * f(const char * x) { return x; }\n" "const std::string &a() {\n" " return f(\"foo\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); } void returnReferenceCalculation() { check("const std::string &a(const std::string& str) {\n" " return \"foo\" + str;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("int& operator<<(int out, int path) {\n" " return out << path;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("std::ostream& operator<<(std::ostream& out, const std::string& path) {\n" " return out << path;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::ostream& operator<<(std::ostream* out, const std::string& path) {\n" " return *out << path;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("Unknown1& operator<<(Unknown1 out, Unknown2 path) {\n" " return out << path;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int& a(int b) {\n" " return 2*(b+1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("const std::string &a(const std::string& str) {\n" " return str;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const std::string &a(int bar) {\n" " return foo(bar + 1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const std::string a(const std::string& str) {\n" " return \"foo\" + str;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int& incValue(int& value) {\n" " return ++value;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2005,7 +2005,7 @@ class TestAutoVariables : public TestFixture { " [](const Item& lhs, const Item& rhs) {\n" " return false;\n" " });\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5844 @@ -2015,13 +2015,13 @@ class TestAutoVariables : public TestFixture { " return var;\n" " }();\n" "return s_var;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #7583 check("Command& foo() {\n" " return f([]() -> int { return 1; });\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2034,16 +2034,16 @@ class TestAutoVariables : public TestFixture { " }\n" " };\n" " return _make(_Wrapper::call, pmf);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void returnReferenceRecursive() { - check("int& f() { return f(); }"); + check("int& f() { return f(); }\n"); ASSERT_EQUALS("", errout_str()); check("int& g(int& i) { return i; }\n" - "int& f() { return g(f()); }"); + "int& f() { return g(f()); }\n"); ASSERT_EQUALS("", errout_str()); } @@ -2053,7 +2053,7 @@ class TestAutoVariables : public TestFixture { "auto f() {\n" " const int& x = h();\n" " return [&] { return x; };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18] -> [test.cpp:5:25] -> [test.cpp:4:16] -> [test.cpp:5:12]: (error) Returning lambda that captures local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("void g(int*);\n" @@ -2061,7 +2061,7 @@ class TestAutoVariables : public TestFixture { "int* f() {\n" " const int& x = h();\n" " return &x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18] -> [test.cpp:5:12] -> [test.cpp:4:16] -> [test.cpp:5:12]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("void g(int*);\n" @@ -2069,7 +2069,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " int& x = h();\n" " g(&x);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:12] -> [test.cpp:5:7] -> [test.cpp:4:15] -> [test.cpp:5:7]: (error) Using pointer that is a temporary. [danglingTemporaryLifetime]\n" "[test.cpp:4:12] -> [test.cpp:5:8]: (error) Using reference to dangling temporary. [danglingTempReference]\n", @@ -2080,7 +2080,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " const int& x = h();\n" " g(&x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Data {\n" @@ -2089,7 +2089,7 @@ class TestAutoVariables : public TestFixture { "const char* foo() {\n" " const Data& data = getData();\n" " return data.path.c_str();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2098,7 +2098,7 @@ class TestAutoVariables : public TestFixture { "{\n" " static int &r = k;\n" " return r;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19] -> [test.cpp:3:17]: (error) Non-local reference variable 'r' to local variable 'k' [danglingReference]\n", errout_str()); @@ -2106,7 +2106,7 @@ class TestAutoVariables : public TestFixture { "{\n" " static int &r = k;\n" " return r;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2274,7 +2274,7 @@ class TestAutoVariables : public TestFixture { " {\n" " pNum = apNum;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2283,28 +2283,28 @@ class TestAutoVariables : public TestFixture { check("int* foo(int y)\n" "{\n" " return &y;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:1:14] -> [test.cpp:3:10]: (error) Returning pointer to local variable 'y' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("int ** foo(int * y)\n" "{\n" " return &y;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:1:18] -> [test.cpp:3:10]: (error) Returning pointer to local variable 'y' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("const int * foo(const int & y)\n" "{\n" " return &y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int * foo(int * y)\n" "{\n" " return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -2314,7 +2314,7 @@ class TestAutoVariables : public TestFixture { "{\n" " struct s *r = f();\n" " *q = &r->p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2325,7 +2325,7 @@ class TestAutoVariables : public TestFixture { " const_tree_iterator& parent() {\n" " return const_tree_iterator(foo);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:31]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); } @@ -2336,7 +2336,7 @@ class TestAutoVariables : public TestFixture { "}\n" "void opened_cb () {\n" " g_signal_connect (G_CALLBACK (removed_cb));\n" - "}"); + "}\n"); } void danglingLifetimeLambda() { @@ -2344,30 +2344,30 @@ class TestAutoVariables : public TestFixture { " int a = 1;\n" " auto l = [&](){ return a; };\n" " return l;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:28] -> [test.cpp:2:9] -> [test.cpp:4:12]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto f() {\n" " int a = 1;\n" " return [&](){ return a; };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:26] -> [test.cpp:2:9] -> [test.cpp:3:12]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto f(int a) {\n" " return [&](){ return a; };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:26] -> [test.cpp:1:12] -> [test.cpp:2:12]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto f(int a) {\n" " auto p = &a;\n" " return [=](){ return p; };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14] -> [test.cpp:3:26] -> [test.cpp:1:12] -> [test.cpp:3:12]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto g(int& a) {\n" " int p = a;\n" " return [&](){ return p; };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:26] -> [test.cpp:2:9] -> [test.cpp:3:12]: (error) Returning lambda that captures local variable 'p' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto f() {\n" @@ -2375,7 +2375,7 @@ class TestAutoVariables : public TestFixture { " int a = 1;\n" " return [&](){ return a; };\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:30] -> [test.cpp:3:13] -> [test.cpp:4:16]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto f(int b) {\n" @@ -2383,30 +2383,30 @@ class TestAutoVariables : public TestFixture { " a += b;\n" " return [&](){ return a; };\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:30] -> [test.cpp:2:20] -> [test.cpp:4:16]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto g(int& a) {\n" " return [&](){ return a; };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("auto g(int a) {\n" " auto p = a;\n" " return [=](){ return p; };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("auto g(int& a) {\n" " auto p = a;\n" " return [=](){ return p; };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("auto g(int& a) {\n" " int& p = a;\n" " return [&](){ return p; };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("template\n" @@ -2414,7 +2414,7 @@ class TestAutoVariables : public TestFixture { "auto f() {\n" " int x;\n" " return g([&]() { return x; });\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("auto f() {\n" @@ -2487,28 +2487,28 @@ class TestAutoVariables : public TestFixture { check("auto f(const std::vector& x) {\n" " auto it = x.begin();\n" " return it;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector::iterator f() {\n" " std::vector x;\n" " auto it = x.begin();\n" " return it;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:22] -> [test.cpp:2:22] -> [test.cpp:4:12]: (error) Returning iterator to local container 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto f() {\n" " std::vector x;\n" " auto it = std::begin(x);\n" " return it;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25] -> [test.cpp:2:22] -> [test.cpp:4:12]: (error) Returning iterator to local container 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("int* f() {\n" " std::vector x;\n" " auto p = x.data();\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:20] -> [test.cpp:2:22] -> [test.cpp:4:12]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2517,7 +2517,7 @@ class TestAutoVariables : public TestFixture { " std::vector x;\n" " auto p = &x[0];\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:14] -> [test.cpp:2:22] -> [test.cpp:4:12]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2526,7 +2526,7 @@ class TestAutoVariables : public TestFixture { "int* f(std::vector v) {\n" " auto it = v.begin();\n" " return &it->foo;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:22] -> [test.cpp:4:12] -> [test.cpp:2:23] -> [test.cpp:4:12]: (error) Returning pointer to local variable 'v' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2534,14 +2534,14 @@ class TestAutoVariables : public TestFixture { check("std::vector::iterator f(std::vector x) {\n" " auto it = x.begin();\n" " return it;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22] -> [test.cpp:1:47] -> [test.cpp:3:12]: (error) Returning iterator to local container 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto f() {\n" " std::vector x;\n" " auto it = x.begin();\n" " return std::next(it);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:22] -> [test.cpp:2:22] -> [test.cpp:4:21]: (error) Returning iterator to local container 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2550,7 +2550,7 @@ class TestAutoVariables : public TestFixture { " std::vector x;\n" " auto it = x.begin();\n" " return it + 1;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:22] -> [test.cpp:2:22] -> [test.cpp:4:15]: (error) Returning iterator to local container 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2559,7 +2559,7 @@ class TestAutoVariables : public TestFixture { " std::vector x;\n" " auto it = x.begin();\n" " return std::next(it + 1);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:22] -> [test.cpp:4:25] -> [test.cpp:2:22] -> [test.cpp:4:21]: (error) Returning object that points to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2569,7 +2569,7 @@ class TestAutoVariables : public TestFixture { " std::vector v;\n" " v.push_back(&i);\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:17] -> [test.cpp:4:17] -> [test.cpp:2:9] -> [test.cpp:5:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2581,7 +2581,7 @@ class TestAutoVariables : public TestFixture { " v.push_back(&i);\n" " r.assign(v.begin(), v.end());\n" " return r;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:17] -> [test.cpp:5:17] -> [test.cpp:5:5] -> [test.cpp:3:9] -> [test.cpp:7:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2592,7 +2592,7 @@ class TestAutoVariables : public TestFixture { " int i;\n" " v.push_back(&i);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS( "[test.cpp:5:21] -> [test.cpp:5:21] -> [test.cpp:4:13] -> [test.cpp:5:9]: (error) Non-local variable 'v' will use object that points to local variable 'i'. [danglingLifetime]\n", errout_str()); @@ -2604,7 +2604,7 @@ class TestAutoVariables : public TestFixture { " int * p = &i;\n" " v.push_back(p);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS( "[test.cpp:5:19] -> [test.cpp:6:21] -> [test.cpp:4:13] -> [test.cpp:6:9]: (error) Non-local variable 'v' will use object that points to local variable 'i'. [danglingLifetime]\n", errout_str()); @@ -2617,7 +2617,7 @@ class TestAutoVariables : public TestFixture { " v.push_back(&x);\n" " m.insert(m.end(), v.begin(), v.end());\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS( "[test.cpp:6:21] -> [test.cpp:6:21] -> [test.cpp:6:9] -> [test.cpp:4:13] -> [test.cpp:7:9]: (error) Non-local variable 'm' will use object that points to local variable 'x'. [danglingLifetime]\n" "[test.cpp:6:21] -> [test.cpp:6:21] -> [test.cpp:6:9] -> [test.cpp:4:13] -> [test.cpp:7:18]: (error) Non-local variable 'm' will use object that points to local variable 'x'. [danglingLifetime]\n", // duplicate @@ -2628,7 +2628,7 @@ class TestAutoVariables : public TestFixture { " return it;\n" " }\n" " return {};\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:26] -> [test.cpp:1:47] -> [test.cpp:3:16]: (error) Returning iterator to local container 'v' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2636,7 +2636,7 @@ class TestAutoVariables : public TestFixture { check("const char * f() {\n" " std::string ba(\"hello\");\n" " return ba.c_str();\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:19] -> [test.cpp:2:16] -> [test.cpp:3:19]: (error) Returning pointer to local variable 'ba' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2658,7 +2658,7 @@ class TestAutoVariables : public TestFixture { check("std::vector g();\n" "auto f() {\n" " return g().begin();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:21] -> [test.cpp:3:21]: (error) Returning iterator that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -2666,14 +2666,14 @@ class TestAutoVariables : public TestFixture { "std::vector::iterator f() {\n" " auto it = g().begin();\n" " return it;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:24] -> [test.cpp:3:16] -> [test.cpp:4:5]: (error) Using iterator that is a temporary. [danglingTemporaryLifetime]\n", errout_str()); check("std::vector g();\n" "int& f() {\n" " return *g().begin();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:22] -> [test.cpp:3:12]: (error) Reference to temporary returned. [returnTempReference]\n", errout_str()); check("struct A {\n" @@ -2682,7 +2682,7 @@ class TestAutoVariables : public TestFixture { " char s[3];\n" " v.push_back(s);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("std::vector f() {\n" @@ -2690,46 +2690,46 @@ class TestAutoVariables : public TestFixture { " std::vector v;\n" " v.push_back(s);\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("auto f() {\n" " static std::vector x;\n" " return x.begin();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string g() {\n" " std::vector v;\n" " return v.data();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector::iterator f(std::vector* v) {\n" " return v->begin();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector::iterator f(std::vector* v) {\n" " std::vector* v = new std::vector();\n" " return v->begin();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(std::vector v) {\n" " return *v.begin();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(std::vector v) {\n" " return v.end() - v.begin();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("auto g() {\n" " std::vector v;\n" " return {v, [v]() { return v.data(); }};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("template\n" @@ -2737,7 +2737,7 @@ class TestAutoVariables : public TestFixture { "auto f() {\n" " std::vector v;\n" " return g([&]() { return v.data(); });\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector g();\n" @@ -2747,7 +2747,7 @@ class TestAutoVariables : public TestFixture { " std::vector v = g();\n" " m.insert(m.end(), v.begin(), v.end());\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" @@ -2757,7 +2757,7 @@ class TestAutoVariables : public TestFixture { " v.insert(a, a+1);\n" " }\n" " return v.back() == 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class A {\n" @@ -2768,7 +2768,7 @@ class TestAutoVariables : public TestFixture { " struct B {};\n" " std::map< S, B > m1;\n" " std::map< S, B > m2;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -2777,33 +2777,33 @@ class TestAutoVariables : public TestFixture { " void f() {\n" " v.push_back(&x);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("size_t f(const std::string& x) {\n" " std::string y = \"x\";\n" " return y.find(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string* f();\n" "const char* g() {\n" " std::string* var = f();\n" " return var->c_str();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string f() {\n" " std::vector data{};\n" " data.push_back('a');\n" " return std::string{ data.data(), data.size() };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector f() {\n" " char a = 0;\n" " return std::vector{&a};\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:31] -> [test.cpp:3:31] -> [test.cpp:2:10] -> [test.cpp:3:30]: (error) Returning object that points to local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("std::vector* g();\n" @@ -3246,20 +3246,20 @@ class TestAutoVariables : public TestFixture { " std::vector a;\n" " auto it = a.begin();\n" " return [=](){ return it; };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:22] -> [test.cpp:4:26] -> [test.cpp:2:22] -> [test.cpp:4:12]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("auto f(std::vector a) {\n" " auto it = a.begin();\n" " return [=](){ return it; };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22] -> [test.cpp:3:26] -> [test.cpp:1:25] -> [test.cpp:3:12]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); check("struct e {};\n" "e * j() {\n" " e c[20];\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:12] -> [test.cpp:3:7] -> [test.cpp:4:12]: (error) Returning pointer to local variable 'c' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3267,12 +3267,12 @@ class TestAutoVariables : public TestFixture { check("auto f(std::vector& a) {\n" " auto it = a.begin();\n" " return [=](){ return it; };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int * f(int a[]) {\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -3280,14 +3280,14 @@ class TestAutoVariables : public TestFixture { " uint32_t f[6];\n" " } d;\n" " uint32_t *a = d.f;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Don't decay std::array check("std::array f() {\n" " std::array x;\n" " return x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Make sure we don't hang @@ -3295,7 +3295,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " using T = A[3];\n" " A &&a = T{1, 2, 3}[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Make sure we don't hang @@ -3303,7 +3303,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " using T = A[3];\n" " A &&a = T{1, 2, 3}[1]();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Make sure we don't hang @@ -3311,7 +3311,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " using T = A[3];\n" " A &&a = T{1, 2, 3}[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Make sure we don't hang @@ -3319,7 +3319,7 @@ class TestAutoVariables : public TestFixture { "void f() {\n" " using T = A[3];\n" " A &&a = T{1, 2, 3}[1]();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Crash #8872 @@ -3327,14 +3327,14 @@ class TestAutoVariables : public TestFixture { " void operator()(b c) override {\n" " d(c, [&] { c->e });\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct a {\n" " void operator()(b c) override {\n" " d(c, [=] { c->e });\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct a {\n" @@ -3343,7 +3343,7 @@ class TestAutoVariables : public TestFixture { "a f() {\n" " char c[20];\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct a {\n" @@ -3353,7 +3353,7 @@ class TestAutoVariables : public TestFixture { " char c[20];\n" " a d = c;\n" " return d;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -3361,14 +3361,14 @@ class TestAutoVariables : public TestFixture { " std::vector v;\n" " auto g() { return v.end(); }\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int * f(std::vector& v) {\n" " for(int & x : v)\n" " return &x;\n" " return nullptr;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9275 @@ -3380,7 +3380,7 @@ class TestAutoVariables : public TestFixture { " char buf[1024];\n" " const char* msg = buf;\n" " m = msg;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9201 @@ -3388,14 +3388,14 @@ class TestAutoVariables : public TestFixture { " struct a { int m; };\n" " static a b{0};\n" " return &b.m;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9453 check("int *ptr;\n" "void foo(int arr[]) {\n" " ptr = &arr[2];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9639 @@ -3406,7 +3406,7 @@ class TestAutoVariables : public TestFixture { "const char * f() {\n" " const Fred &fred = getFred();\n" " return fred.s.c_str();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9534 @@ -3416,14 +3416,14 @@ class TestAutoVariables : public TestFixture { "int* f(int i, std::vector& v) {\n" " A& y = v[i];\n" " return &y.x[i];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9712 check("std::string f(const char *str) {\n" " char value[256];\n" " return value;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9770 @@ -3597,7 +3597,7 @@ class TestAutoVariables : public TestFixture { check("auto f() {\n" " int a;\n" " return std::ref(a);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:21] -> [test.cpp:2:9] -> [test.cpp:3:20]: (error) Returning object that points to local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3605,7 +3605,7 @@ class TestAutoVariables : public TestFixture { check("auto f() {\n" " int a;\n" " return std::make_tuple(std::ref(a));\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:37] -> [test.cpp:3:36] -> [test.cpp:2:9] -> [test.cpp:3:27]: (error) Returning object that points to local variable 'a' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3617,7 +3617,7 @@ class TestAutoVariables : public TestFixture { "auto g() {\n" " std::vector v;\n" " return by_value(v.begin());\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:7:28] -> [test.cpp:7:28] -> [test.cpp:3:12] -> [test.cpp:3:25] -> [test.cpp:6:22] -> [test.cpp:7:20]: (error) Returning object that points to local variable 'v' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3640,7 +3640,7 @@ class TestAutoVariables : public TestFixture { "auto f() {\n" " int i = 0;\n" " return by_ref(i);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:12] -> [test.cpp:1:19] -> [test.cpp:2:25] -> [test.cpp:6:19] -> [test.cpp:5:9] -> [test.cpp:6:18]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3658,7 +3658,7 @@ class TestAutoVariables : public TestFixture { " int a;\n" " std::tie(a) = x;\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::pair\n" @@ -3907,7 +3907,7 @@ class TestAutoVariables : public TestFixture { "A f() {\n" " int i = 0;\n" " return A{i, i};\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:7:14] -> [test.cpp:6:9] -> [test.cpp:7:13]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3919,7 +3919,7 @@ class TestAutoVariables : public TestFixture { "A f() {\n" " int i = 0;\n" " return {i, i};\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:7:13] -> [test.cpp:6:9] -> [test.cpp:7:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3932,7 +3932,7 @@ class TestAutoVariables : public TestFixture { " int i = 0;\n" " A r{i, i};\n" " return r;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:7:9] -> [test.cpp:6:9] -> [test.cpp:8:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3945,7 +3945,7 @@ class TestAutoVariables : public TestFixture { " int i = 0;\n" " A r = {i, i};\n" " return r;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:7:12] -> [test.cpp:6:9] -> [test.cpp:8:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3957,7 +3957,7 @@ class TestAutoVariables : public TestFixture { "A f(int& x) {\n" " int i = 0;\n" " return A{i, x};\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:7:14] -> [test.cpp:6:9] -> [test.cpp:7:13]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); @@ -3969,7 +3969,7 @@ class TestAutoVariables : public TestFixture { "A f(int& x) {\n" " int i = 0;\n" " return A{x, i};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -3978,14 +3978,14 @@ class TestAutoVariables : public TestFixture { "};\n" "A f(int& x) {\n" " return A{x, x};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int i; const int& j; };\n" "A f(int& x) {\n" " int y = 0;\n" " return A{y, x};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct a {\n" @@ -4086,7 +4086,7 @@ class TestAutoVariables : public TestFixture { " int i = 0;\n" " std::vector v = {&i, &i};\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:28] -> [test.cpp:3:28] -> [test.cpp:2:9] -> [test.cpp:4:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n" "[test.cpp:3:32] -> [test.cpp:3:32] -> [test.cpp:2:9] -> [test.cpp:4:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", @@ -4096,7 +4096,7 @@ class TestAutoVariables : public TestFixture { " int i = 0;\n" " std::vector v{&i, &i};\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:25] -> [test.cpp:3:25] -> [test.cpp:2:9] -> [test.cpp:4:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n" "[test.cpp:3:29] -> [test.cpp:3:29] -> [test.cpp:2:9] -> [test.cpp:4:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", @@ -4105,7 +4105,7 @@ class TestAutoVariables : public TestFixture { check("std::vector f() {\n" " int i = 0;\n" " return {&i, &i};\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:13] -> [test.cpp:3:13] -> [test.cpp:2:9] -> [test.cpp:3:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n" "[test.cpp:3:17] -> [test.cpp:3:17] -> [test.cpp:2:9] -> [test.cpp:3:12]: (error) Returning object that points to local variable 'i' that will be invalid when returning. [returnDanglingLifetime]\n", @@ -4113,7 +4113,7 @@ class TestAutoVariables : public TestFixture { check("std::vector f(int& x) {\n" " return {&x, &x};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector f() {\n" @@ -4121,7 +4121,7 @@ class TestAutoVariables : public TestFixture { " x.insert(\"1\");\n" " x.insert(\"2\");\n" " return { x.begin(), x.end() };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4130,7 +4130,7 @@ class TestAutoVariables : public TestFixture { "A f() {\n" " std::string ba(\"hello\");\n" " return ba.c_str();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { A(const char *a); };\n" @@ -4138,7 +4138,7 @@ class TestAutoVariables : public TestFixture { " std::string ba(\"hello\");\n" " A bp = ba.c_str();\n" " return bp;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { A(const char *a); };\n" @@ -4147,7 +4147,7 @@ class TestAutoVariables : public TestFixture { " std::vector v;\n" " v.push_back(ba.c_str());\n" " return v;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string f(const std::string& x) {\n" @@ -4155,7 +4155,7 @@ class TestAutoVariables : public TestFixture { " if (!x.empty())\n" " return x + c;\n" " return \"\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string f(const std::string& x) {\n" @@ -4163,7 +4163,7 @@ class TestAutoVariables : public TestFixture { " if (!x.empty())\n" " return c + 1;\n" " return \"\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4186,7 +4186,7 @@ class TestAutoVariables : public TestFixture { "void f(int& i) {\n" " int* x = &g(0);\n" " i += *x;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:1:26] -> [test.cpp:2:12] -> [test.cpp:5:15] -> [test.cpp:5:14] -> [test.cpp:5:17] -> [test.cpp:6:11]: (error) Using pointer that is a temporary. [danglingTemporaryLifetime]\n", errout_str()); @@ -4196,7 +4196,7 @@ class TestAutoVariables : public TestFixture { " const char* b = a.toStdString().c_str();\n" " QString c = b;\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:42] -> [test.cpp:3:34] -> [test.cpp:4:15]: (error) Using pointer that is a temporary. [danglingTemporaryLifetime]\n", errout_str()); @@ -4204,7 +4204,7 @@ class TestAutoVariables : public TestFixture { " const char *x = s.substr(1,2).c_str();\n" " auto i = s.substr(4,5).begin();\n" " return *i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:33] -> [test.cpp:3:22] -> [test.cpp:4:13]: (error) Using iterator that is a temporary. [danglingTemporaryLifetime]\n", errout_str()); @@ -4212,7 +4212,7 @@ class TestAutoVariables : public TestFixture { " std::stringstream tmp;\n" " const std::string &str = tmp.str();\n" " return std::string(str.c_str(), 1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int get_value();\n" @@ -4682,7 +4682,7 @@ class TestAutoVariables : public TestFixture { " f = [&]{ return b; };\n" " }\n" " f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:25] -> [test.cpp:4:13] -> [test.cpp:7:5]: (error) Using lambda that captures local variable 'b' that is out of scope. [invalidLifetime]\n", errout_str()); check("void f(bool b) {\n" @@ -4692,7 +4692,7 @@ class TestAutoVariables : public TestFixture { " x = y;\n" " }\n" " x[3];\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:9] -> [test.cpp:4:9] -> [test.cpp:7:3]: (error) Using pointer to local variable 'y' that is out of scope. [invalidLifetime]\n", errout_str()); @@ -4704,7 +4704,7 @@ class TestAutoVariables : public TestFixture { " f = [&]{ return b; };\n" " f();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct a {\n" @@ -4713,7 +4713,7 @@ class TestAutoVariables : public TestFixture { "};\n" "void a::b() {\n" " c.end()\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void b(char f[], char c[]) {\n" @@ -4721,7 +4721,7 @@ class TestAutoVariables : public TestFixture { " std::string e;\n" " b(f, e.c_str())\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" @@ -4731,11 +4731,11 @@ class TestAutoVariables : public TestFixture { " s = buf;\n" " }\n" " std::cout << s;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int &a[];\n" - "void b(){int *c = a};"); + "void b(){int *c = a};\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -4749,7 +4749,7 @@ class TestAutoVariables : public TestFixture { " return y.x;\n" " };\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("namespace test {\n" @@ -4883,7 +4883,7 @@ class TestAutoVariables : public TestFixture { " p = &x;\n" " }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9] -> [test.cpp:7:4]: (error) Using pointer to local variable 'x' that is out of scope. [invalidLifetime]\n", errout_str()); // FP: don't warn in subfunction @@ -4900,7 +4900,7 @@ class TestAutoVariables : public TestFixture { " } else {\n" " }\n" " f(tmp);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Don't warn about references (#6399) @@ -4912,7 +4912,7 @@ class TestAutoVariables : public TestFixture { " }\n" " if (former_hover != pitem)\n" " dosth();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -4923,7 +4923,7 @@ class TestAutoVariables : public TestFixture { " }\n" " if (former_hover != pitem)\n" " dosth();\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:24] -> [test.cpp:3:47] -> [test.cpp:4:26] -> [test.cpp:7:9]: (error) Using pointer to local variable 'item' that is out of scope. [invalidLifetime]\n", errout_str()); @@ -4936,7 +4936,7 @@ class TestAutoVariables : public TestFixture { " };\n" " EventReport * rep = &repData;\n" " rep->setEventType(NDB_LE_Connected);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8785 @@ -4949,7 +4949,7 @@ class TestAutoVariables : public TestFixture { " if(b && a)\n" " return *iPtr;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:16] -> [test.cpp:7:10] -> [test.cpp:4:13] -> [test.cpp:8:17]: (error) Using pointer to local variable 'x' that is out of scope. [invalidLifetime]\n", errout_str()); diff --git a/test/testbool.cpp b/test/testbool.cpp index 6074bbab46a..46365c11af3 100644 --- a/test/testbool.cpp +++ b/test/testbool.cpp @@ -96,28 +96,28 @@ class TestBool : public TestFixture { void assignBoolToPointer() { check("void foo(bool *p) {\n" " p = false;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7]: (error) Boolean value assigned to pointer. [assignBoolToPointer]\n", errout_str()); check("void foo(bool *p) {\n" " p = (x[rSize];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket #6588 (c mode) @@ -152,7 +152,7 @@ class TestBool : public TestFixture { " const int *rmat = n < 4 ? " /* OK */ " ctx->q_intra_matrix :" " ctx->q_chroma_intra_matrix;\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:3:19]: (error) Boolean value assigned to pointer. [assignBoolToPointer]\n", errout_str()); // ticket #6588 (c++ mode) @@ -162,7 +162,7 @@ class TestBool : public TestFixture { " const int *rmat = n < 4 ? " /* OK */ " ctx->q_intra_matrix :" " ctx->q_chroma_intra_matrix;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19]: (error) Boolean value assigned to pointer. [assignBoolToPointer]\n", errout_str()); // ticket #6665 @@ -171,37 +171,37 @@ class TestBool : public TestFixture { " char* m1 = compare(a, b) < 0\n" " ? (compare(b, c) < 0 ? b : (compare(a, c) < 0 ? c : a))\n" " : (compare(a, c) < 0 ? a : (compare(b, c) < 0 ? c : b));\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); // #7381 check("void foo(bool *p, bool b) {\n" " p = b;\n" " p = &b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7]: (error) Boolean value assigned to pointer. [assignBoolToPointer]\n", errout_str()); } void assignBoolToFloat() { check("void foo1() {\n" " double d = false;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style) Boolean value assigned to floating point variable. [assignBoolToFloat]\n", errout_str()); check("void foo2() {\n" " float d = true;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Boolean value assigned to floating point variable. [assignBoolToFloat]\n", errout_str()); check("void foo3() {\n" " long double d = (2>1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:19]: (style) Boolean value assigned to floating point variable. [assignBoolToFloat]\n", errout_str()); // stability - don't crash: check("void foo4() {\n" " unknown = false;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -210,7 +210,7 @@ class TestBool : public TestFixture { "void f() {\n" " S s = {0};\n" " s.p = true;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:9]: (style) Boolean value assigned to floating point variable. [assignBoolToFloat]\n", errout_str()); check("struct S {\n" @@ -219,7 +219,7 @@ class TestBool : public TestFixture { "void f() {\n" " S s = {0};\n" " *s.p[0] = true;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:13]: (style) Boolean value assigned to floating point variable. [assignBoolToFloat]\n", errout_str()); } @@ -227,50 +227,50 @@ class TestBool : public TestFixture { check("void f(int x) {\n" " if ((x && 0x0f)==6)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(int x) {\n" " if ((x && 0x0f)==0)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((x || 0x0f)==6)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(int x) {\n" " if ((x || 0x0f)==0)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((x & 0x0f)==6)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((x | 0x0f)==6)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((5 && x)==3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(int x) {\n" " if ((5 && x)==3 || (8 && x)==9)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:17]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n" "[test.cpp:2:32]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", @@ -279,39 +279,39 @@ class TestBool : public TestFixture { check("void f(int x) {\n" " if ((5 && x)!=3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(int x) {\n" " if ((5 && x) > 3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(int x) {\n" " if ((5 && x) > 0)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((5 && x) < 0)\n" " a++;\n" - "}" + "}\n" ); ASSERT_EQUALS("[test.cpp:2:18]: (warning) Comparison of a boolean expression with an integer. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(int x) {\n" " if ((5 && x) < 1)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((5 && x) > 1)\n" " a++;\n" - "}" + "}\n" ); ASSERT_EQUALS("[test.cpp:2:18]: (warning) Comparison of a boolean expression with an integer. [compareBoolExpressionWithInt]\n", errout_str()); @@ -319,91 +319,91 @@ class TestBool : public TestFixture { check("void f(int x) {\n" " if (0 < (5 && x))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (0 > (5 && x))\n" " a++;\n" - "}" + "}\n" ); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of a boolean expression with an integer. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(int x) {\n" " if (1 > (5 && x))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (1 < (5 && x))\n" " a++;\n" - "}" + "}\n" ); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of a boolean expression with an integer. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(bool x ) {\n" " if ( x > false )\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("void f(bool x ) {\n" " if ( false < x )\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("void f(bool x ) {\n" " if ( x < false )\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("void f(bool x ) {\n" " if ( false > x )\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("void f(bool x ) {\n" " if ( x >= false )\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("void f(bool x ) {\n" " if ( false >= x )\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("void f(bool x ) {\n" " if ( x <= false )\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("void f(bool x ) {\n" " if ( false <= x )\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("typedef int (*func)(bool invert);\n" "void x(int, func f);\n" "void foo(int error) {\n" " if (error == ABC) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("int f() { return !a+b1){} }"); + check("void f() { if (!!a+!!b+!!c>1){} }\n"); ASSERT_EQUALS("",errout_str()); - check("void f(int a, int b, int c) { if (a != !b || c) {} }"); + check("void f(int a, int b, int c) { if (a != !b || c) {} }\n"); ASSERT_EQUALS("",errout_str()); - check("void f(int a, int b, int c) { if (1 < !!a + !!b + !!c) {} }"); + check("void f(int a, int b, int c) { if (1 < !!a + !!b + !!c) {} }\n"); ASSERT_EQUALS("",errout_str()); - check("void f(int a, int b, int c) { if (1 < !(a+b)) {} }"); + check("void f(int a, int b, int c) { if (1 < !(a+b)) {} }\n"); ASSERT_EQUALS("[test.cpp:1:37]: (warning) Comparison of a boolean expression with an integer. [compareBoolExpressionWithInt]\n",errout_str()); } void comparisonOfBoolExpressionWithInt3() { check("int f(int x) {\n" " return t<0>() && x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -498,48 +498,48 @@ class TestBool : public TestFixture { // #5016 check("void f() {\n" " for(int i = 4; i > -1 < 5 ; --i) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:25]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(int a, int b, int c) {\n" " return (a > b) < c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int a, int b, int c) {\n" " return x(a > b) < c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int a, int b, int c) {\n" " return a > b == c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // templates check("struct Tokenizer { TokenList list; };\n" "void Tokenizer::f() {\n" " std::list locationList;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5063 - or check("void f() {\n" " return a > b or c < d;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" " return (a < b) != 0U;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" " return (a < b) != 0x0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" " return (a < b) != 42U;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); } @@ -563,7 +563,7 @@ class TestBool : public TestFixture { " }\n" " else\n" " return true;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style) Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator. [comparisonOfTwoFuncsReturningBoolError]\n", errout_str()); } @@ -588,7 +588,7 @@ class TestBool : public TestFixture { " }\n" " else\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (style) Comparison of a function returning boolean value using relational (<, >, <= or >=) operator. [comparisonOfFuncReturningBoolError]\n" "[test.cpp:11:7]: (style) Comparison of a function returning boolean value using relational (<, >, <= or >=) operator. [comparisonOfFuncReturningBoolError]\n", errout_str()); } @@ -600,7 +600,7 @@ class TestBool : public TestFixture { " printf(\"foo\");\n" " }\n" "}\n" - "bool compare(int temp);"); + "bool compare(int temp);\n"); ASSERT_EQUALS("[test.cpp:3:19]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n" "[test.cpp:3:12]: (style) Comparison of a function returning boolean value using relational (<, >, <= or >=) operator. [comparisonOfFuncReturningBoolError]\n", errout_str()); } @@ -626,7 +626,7 @@ class TestBool : public TestFixture { " }\n" " else\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Comparison of a function returning boolean value using relational (<, >, <= or >=) operator. [comparisonOfFuncReturningBoolError]\n", errout_str()); } @@ -650,7 +650,7 @@ class TestBool : public TestFixture { " }\n" " else\n" " return true;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style) Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator. [comparisonOfTwoFuncsReturningBoolError]\n", errout_str()); } @@ -664,7 +664,7 @@ class TestBool : public TestFixture { " if(compare1(temp) > compare2(temp)){\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("namespace Foo {\n" @@ -676,7 +676,7 @@ class TestBool : public TestFixture { " if(compare1(temp) > compare2(temp)){\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int compare1(int temp);\n" @@ -688,7 +688,7 @@ class TestBool : public TestFixture { " printf(\"foo\");\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:20]: (style) Comparison of a function returning boolean value using relational (<, >, <= or >=) operator. [comparisonOfFuncReturningBoolError]\n", errout_str()); check("int compare1(int temp);\n" @@ -700,7 +700,7 @@ class TestBool : public TestFixture { " printf(\"foo\");\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool compare1(int temp);\n" @@ -709,7 +709,7 @@ class TestBool : public TestFixture { " if(foo.compare1(temp) > compare2(temp)){\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -739,7 +739,7 @@ class TestBool : public TestFixture { " if(b > a){ \n" // here warning should be displayed " ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) Comparison of a variable having boolean value using relational (<, >, <= or >=) operator. [comparisonOfBoolWithBoolError]\n", errout_str()); // op: < check("int main(void){\n" @@ -748,7 +748,7 @@ class TestBool : public TestFixture { " if(b < a){ \n" // here warning should be displayed " ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) Comparison of a variable having boolean value using relational (<, >, <= or >=) operator. [comparisonOfBoolWithBoolError]\n", errout_str()); // op: >= check("int main(void){\n" @@ -757,7 +757,7 @@ class TestBool : public TestFixture { " if(b >= a){ \n" // here warning should be displayed " ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) Comparison of a variable having boolean value using relational (<, >, <= or >=) operator. [comparisonOfBoolWithBoolError]\n", errout_str()); // op: <= check("int main(void){\n" @@ -766,7 +766,7 @@ class TestBool : public TestFixture { " if(b <= a){ \n" // here warning should be displayed " ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) Comparison of a variable having boolean value using relational (<, >, <= or >=) operator. [comparisonOfBoolWithBoolError]\n", errout_str()); } @@ -778,7 +778,7 @@ class TestBool : public TestFixture { " if ( eval(argv[1]) > eval(argv[2]) )\n" " return 1;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -812,96 +812,96 @@ class TestBool : public TestFixture { void bitwiseOnBoolean() { // 3062 check("void f(_Bool a, _Bool b) {\n" " if(a & b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '&&'? [bitwiseOnBoolean]\n", errout_str()); check("void f(_Bool a, _Bool b) {\n" " if(a | b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '||'? [bitwiseOnBoolean]\n", errout_str()); check("void f(bool a, bool b) {\n" " if(a & !b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '&&'? [bitwiseOnBoolean]\n", errout_str()); check("void f(bool a, bool b) {\n" " if(a | !b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '||'? [bitwiseOnBoolean]\n", errout_str()); check("bool a, b;\n" "void f() {\n" " if(a & b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '&&'? [bitwiseOnBoolean]\n", errout_str()); check("bool a, b;\n" "void f() {\n" " if(a & !b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '&&'? [bitwiseOnBoolean]\n", errout_str()); check("bool a, b;\n" "void f() {\n" " if(a | b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '||'? [bitwiseOnBoolean]\n", errout_str()); check("bool a, b;\n" "void f() {\n" " if(a | !b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '||'? [bitwiseOnBoolean]\n", errout_str()); check("void f(bool a, int b) {\n" " if(a & b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '&&'? [bitwiseOnBoolean]\n", errout_str()); check("void f(int a, bool b) {\n" " if(a & b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Boolean expression 'b' is used in bitwise operation. Did you mean '&&'? [bitwiseOnBoolean]\n", errout_str()); check("void f(int a, int b) {\n" " if((a > 0) & (b < 0)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (style, inconclusive) Boolean expression 'a>0' is used in bitwise operation. Did you mean '&&'? [bitwiseOnBoolean]\n", errout_str()); check("void f(bool a, int b) {\n" " if(a | b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '||'? [bitwiseOnBoolean]\n", errout_str()); check("void f(int a, bool b) {\n" " if(a | b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Boolean expression 'b' is used in bitwise operation. Did you mean '||'? [bitwiseOnBoolean]\n", errout_str()); check("int f(bool a, int b) {\n" " return a | b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(bool a, int b) {\n" " return a | b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style, inconclusive) Boolean expression 'a' is used in bitwise operation. Did you mean '||'? [bitwiseOnBoolean]\n", errout_str()); check("void f(int a, int b) {\n" " if(a & b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" " foo(bar, &b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" // #9405 " class C { void foo(bool &b) {} };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f();\n" @@ -970,27 +970,27 @@ class TestBool : public TestFixture { void incrementBoolean() { check("bool bValue = true;\n" - "void f() { bValue++; }"); + "void f() { bValue++; }\n"); ASSERT_EQUALS("[test.cpp:2:12]: (style) Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead. [incrementboolean]\n", errout_str()); check("void f(bool test){\n" " test++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead. [incrementboolean]\n", errout_str()); check("void f(bool* test){\n" " (*test)++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:6]: (style) Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead. [incrementboolean]\n", errout_str()); check("void f(bool* test){\n" " test[0]++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead. [incrementboolean]\n", errout_str()); check("void f(int test){\n" " test++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -999,51 +999,51 @@ class TestBool : public TestFixture { " if (x < 10) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(bool x) {\n" " if (10 >= x) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(bool x) {\n" " if (x != 0) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool x) {\n" // #3356 " if (x == 1) {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool x) {\n" " if (x != 10) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(bool x) {\n" " if (x == 10) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); check("void f(bool x) {\n" " if (x == 0) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("DensePropertyMap visited;"); // #4075 + check("DensePropertyMap visited;\n"); // #4075 ASSERT_EQUALS("", errout_str()); } @@ -1052,28 +1052,28 @@ class TestBool : public TestFixture { " if (x == y) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x, bool y) {\n" " if (x == y) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool x, bool y) {\n" " if (x == y) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool x, fooClass y) {\n" " if (x == y) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1082,35 +1082,35 @@ class TestBool : public TestFixture { " if (y > false) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=). [comparisonOfBoolWithInvalidComparator]\n", errout_str()); check("void f(int y) {\n" " if (true == y) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool y) {\n" " if (y == true) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool y) {\n" " if (false < 5) {\n" " printf(\"foo\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Comparison of a boolean expression with an integer other than 0 or 1. [compareBoolExpressionWithInt]\n", errout_str()); } void comparisonOfBoolWithInt4() { check("void f(int x) {\n" " if (!x == 1) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1118,21 +1118,21 @@ class TestBool : public TestFixture { check("void SetVisible(int index, bool visible) {\n" " bool (SciTEBase::*ischarforsel)(char ch);\n" " if (visible != GetVisible(index)) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void comparisonOfBoolWithInt6() { // #4224 - integer is casted to bool check("void SetVisible(bool b, int i) {\n" " if (b == (bool)i) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void comparisonOfBoolWithInt7() { // #4846 - (!x==true) check("void f(int x) {\n" " if (!x == true) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1142,7 +1142,7 @@ class TestBool : public TestFixture { " auto res = Fun();\n" " if (expectedResult == res)\n" " throw 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int Fun();\n" @@ -1150,7 +1150,7 @@ class TestBool : public TestFixture { " auto res = Fun();\n" " if (expectedResult == res)\n" " throw 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool Fun();\n" @@ -1158,7 +1158,7 @@ class TestBool : public TestFixture { " auto res = Fun();\n" " if (5 + expectedResult == res)\n" " throw 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int Fun();\n" @@ -1166,7 +1166,7 @@ class TestBool : public TestFixture { " auto res = Fun();\n" " if (5 + expectedResult == res)\n" " throw 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int Fun();\n" @@ -1174,7 +1174,7 @@ class TestBool : public TestFixture { " auto res = Fun();\n" " if (expectedResult == res + 5)\n" " throw 2;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); } @@ -1185,7 +1185,7 @@ class TestBool : public TestFixture { " b = !b;\n" " }\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1210,76 +1210,76 @@ class TestBool : public TestFixture { void pointerArithBool1() { // #5126 check("void f(char *p) {\n" " if (p+1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (error) Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour. [pointerArithBool]\n", errout_str()); check("void f(char *p) {\n" " do {} while (p+1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:19]: (error) Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour. [pointerArithBool]\n", errout_str()); check("void f(char *p) {\n" " while (p-1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (error) Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour. [pointerArithBool]\n", errout_str()); check("void f(char *p) {\n" " for (int i = 0; p+1; i++) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (error) Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour. [pointerArithBool]\n", errout_str()); check("void f(char *p) {\n" " if (p && p+1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (error) Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour. [pointerArithBool]\n", errout_str()); check("void f(char *p) {\n" " if (p+2 || p) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (error) Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour. [pointerArithBool]\n", errout_str()); } void returnNonBool() { check("bool f(void) {\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(void) {\n" " return 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(void) {\n" " return 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); check("bool f(void) {\n" " return -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); check("bool f(void) {\n" " return 1 + 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); check("bool f(void) {\n" " int x = 0;\n" " return x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(void) {\n" " int x = 10;\n" " return x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); check("bool f(void) {\n" " return 2 < 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(void) {\n" @@ -1287,7 +1287,7 @@ class TestBool : public TestFixture { " if (a)\n" " ret = 1;\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(void) {\n" @@ -1295,20 +1295,20 @@ class TestBool : public TestFixture { " if (a)\n" " ret = 3;\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); check("bool f(void) {\n" " if (a)\n" " return 3;\n" " return 4;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n" "[test.cpp:4:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); check("bool f(void) {\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1316,42 +1316,42 @@ class TestBool : public TestFixture { check("bool f(void) {\n" " auto x = [](void) { return -1; };\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(void) {\n" " auto x = [](void) { return -1; };\n" " return 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); check("bool f(void) {\n" " auto x = [](void) -> int { return -1; };\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(void) {\n" " auto x = [](void) -> int { return -1; };\n" " return 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); } void returnNonBoolLogicalOp() { check("bool f(int x) {\n" " return x & 0x4;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(int x, int y) {\n" " return x | y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(int x) {\n" " return (x & 0x2);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1359,7 +1359,7 @@ class TestBool : public TestFixture { check("class X {\n" " public:\n" " bool f() { return -1;}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:20]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); check("bool f() {\n" @@ -1368,7 +1368,7 @@ class TestBool : public TestFixture { " int f() { return -1;}\n" " };\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f() {\n" @@ -1377,7 +1377,7 @@ class TestBool : public TestFixture { " int f() { return -1;}\n" " };\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f() {\n" @@ -1386,7 +1386,7 @@ class TestBool : public TestFixture { " bool f() { return -1;}\n" " };\n" " return -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:5]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n" "[test.cpp:4:24]: (style) Non-boolean value returned from function returning bool [returnNonBoolInBooleanFunction]\n", errout_str()); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 229b2883b9e..7b36dbac035 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -327,7 +327,7 @@ class TestBufferOverrun : public TestFixture { " {\n" " char str[50];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -349,7 +349,7 @@ class TestBufferOverrun : public TestFixture { "void f4(const char str[])\n" "{\n" " strcpy(buf, str);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -360,7 +360,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char data[1];\n" " return abc.data[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -370,7 +370,7 @@ class TestBufferOverrun : public TestFixture { check("static void f() {\n" " char data[100];\n" " const char *p = data + 100;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -382,7 +382,7 @@ class TestBufferOverrun : public TestFixture { " snprintf(group, 32, \"%u\", 0);\n" " struct group *gr;\n" " snprintf(group, 32, \"%u\", gr->gr_gid);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -392,14 +392,14 @@ class TestBufferOverrun : public TestFixture { " char str[0x10] = {0};\n" " str[15] = 0;\n" " str[16] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:8]: (error) Array 'str[16]' accessed at index 16, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("char f()\n" "{\n" " char str[16] = {0};\n" " return str[16];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:15]: (error) Array 'str[16]' accessed at index 16, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // test stack array @@ -409,7 +409,7 @@ class TestBufferOverrun : public TestFixture { " int y;\n" " y = x[ 4 ];\n" " return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9]: (error) Array 'x[3]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("int f()\n" @@ -418,15 +418,15 @@ class TestBufferOverrun : public TestFixture { " int y;\n" " y = x[ 2 ];\n" " return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int x[5] = {0};\n" - "int a = x[10];"); + "int a = x[10];\n"); ASSERT_EQUALS("[test.cpp:2:10]: (error) Array 'x[5]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("int x[5] = {0};\n" - "int a = (x)[10];"); + "int a = (x)[10];\n"); ASSERT_EQUALS("[test.cpp:2:12]: (error) Array 'x[5]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -437,21 +437,21 @@ class TestBufferOverrun : public TestFixture { " char *str = new char[0x10];\n" " str[i] = 0;\n" "}\n" - "void b() { a(16); }"); + "void b() { a(16); }\n"); ASSERT_EQUALS("[test.cpp:4:8]: (error) Array 'str[16]' accessed at index 16, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } void array_index_4() { - check("char c = \"abc\"[4];"); + check("char c = \"abc\"[4];\n"); ASSERT_EQUALS("[test.cpp:1:15]: (error) Array '\"abc\"[4]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); - check("p = &\"abc\"[4];"); + check("p = &\"abc\"[4];\n"); ASSERT_EQUALS("", errout_str()); - check("char c = \"\\0abc\"[2];"); + check("char c = \"\\0abc\"[2];\n"); ASSERT_EQUALS("", errout_str()); - check("char c = L\"abc\"[4];"); + check("char c = L\"abc\"[4];\n"); ASSERT_EQUALS("[test.cpp:1:16]: (error) Array 'L\"abc\"[4]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -462,7 +462,7 @@ class TestBufferOverrun : public TestFixture { " int i, sum=0;\n" " for (i = 0; i < 100; i++)\n" " sum += val[i];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:19]: (error) Array 'val[50]' accessed at index 99, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" @@ -471,7 +471,7 @@ class TestBufferOverrun : public TestFixture { " int i, sum=0;\n" " for (i = 1; i < 100; i++)\n" " sum += val[i];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:19]: (error) Array 'val[50]' accessed at index 99, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f(int a)\n" @@ -480,7 +480,7 @@ class TestBufferOverrun : public TestFixture { " int i, sum=0;\n" " for (i = a; i < 100; i++)\n" " sum += val[i];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:19]: (error) Array 'val[50]' accessed at index 99, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("typedef struct g g2[3];\n" @@ -490,21 +490,21 @@ class TestBufferOverrun : public TestFixture { " {\n" " a[i]=0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int argc)\n" "{\n" " char a[2];\n" " for (int i = 4; i < argc; i++){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a[10]) {\n" " for (int i=0;i<50;++i) {\n" " a[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (error) Array 'a[10]' accessed at index 49, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -518,7 +518,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " struct ABC abc;\n" " abc.str[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:12]: (error) Array 'abc.str[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("struct ABC\n" @@ -530,7 +530,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " struct ABC abc;\n" " return abc.str[10];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:19]: (error) Array 'abc.str[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // This is not out of bounds because it is a variable length array @@ -543,7 +543,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " struct ABC* x = malloc(sizeof(struct ABC) + 10);\n" " x->str[1] = 0;" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // This is not out of bounds because it is not a variable length array @@ -557,7 +557,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " struct ABC* x = malloc(sizeof(struct ABC) + 10);\n" " x->str[1] = 0;" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); // This is not out of bounds because it is a variable length array @@ -571,8 +571,8 @@ class TestBufferOverrun : public TestFixture { "static void f()\n" "{\n" " struct ABC* x = malloc(sizeof(struct ABC) + 10);\n" - " x->str[10] = 0;" - "}"); + " x->str[10] = 0;\n" + "}\n"); ASSERT_EQUALS("", errout_str()); // This is out of bounds because it is outside the memory allocated. @@ -585,8 +585,8 @@ class TestBufferOverrun : public TestFixture { "static void f()\n" "{\n" " struct ABC* x = malloc(sizeof(struct ABC) + 10);\n" - " x->str[11] = 0;" - "}"); + " x->str[11] = 0;\n" + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:9]: (error) Array 'str[1]' accessed at index 11, which is out of bounds.\n", "", errout_str()); // This is out of bounds if 'sizeof(ABC)' is 1 (No padding) @@ -598,8 +598,8 @@ class TestBufferOverrun : public TestFixture { "static void f()\n" "{\n" " struct ABC* x = malloc(sizeof(ABC) + 10);\n" - " x->str[11] = 0;" - "}"); + " x->str[11] = 0;\n" + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); // This is out of bounds because it is outside the memory allocated @@ -612,8 +612,8 @@ class TestBufferOverrun : public TestFixture { "static void f()\n" "{\n" " struct ABC* x = malloc(sizeof(struct ABC));\n" - " x->str[1] = 0;" - "}"); + " x->str[1] = 0;\n" + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:9]: (error) Array 'str[1]' accessed at index 1, which is out of bounds.\n", "", errout_str()); // This is out of bounds because it is outside the memory allocated @@ -626,8 +626,8 @@ class TestBufferOverrun : public TestFixture { "static void f()\n" "{\n" " struct ABC* x = malloc(sizeof(ABC));\n" - " x->str[1] = 0;" - "}"); + " x->str[1] = 0;\n" + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); // This is out of bounds because it is not a variable array @@ -639,8 +639,8 @@ class TestBufferOverrun : public TestFixture { "static void f()\n" "{\n" " struct ABC x;\n" - " x.str[1] = 0;" - "}"); + " x.str[1] = 0;\n" + "}\n"); ASSERT_EQUALS("[test.cpp:9:10]: (error) Array 'x.str[1]' accessed at index 1, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("struct foo\n" @@ -653,19 +653,19 @@ class TestBufferOverrun : public TestFixture { " foo f;\n" " for ( unsigned int i = 0; i < 64; ++i )\n" " f.str[i] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:14]: (error) Array 'f.str[10]' accessed at index 63, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("struct AB { char a[NUM]; char b[NUM]; }\n" "void f(struct AB *ab) {\n" " ab->a[0] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("union { char a[1]; int b; } ab;\n" "void f() {\n" " ab.a[2] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (error) Array 'ab.a[1]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -679,7 +679,7 @@ class TestBufferOverrun : public TestFixture { "static void f(struct ABC *abc)\n" "{\n" " abc->str[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:13]: (error) Array 'abc->str[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -698,7 +698,7 @@ class TestBufferOverrun : public TestFixture { " {\n" " abc->str[10] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:13:17]: (error) Array 'abc->str[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -713,7 +713,7 @@ class TestBufferOverrun : public TestFixture { "Fred::Fred()\n" "{\n" " str[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:8]: (error) Array 'str[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("class Fred\n" @@ -726,7 +726,7 @@ class TestBufferOverrun : public TestFixture { "char Fred::c()\n" "{\n" " return str[10];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:15]: (error) Array 'str[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -739,7 +739,7 @@ class TestBufferOverrun : public TestFixture { " if (i < 10)\n" " int x = buf[i];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -749,7 +749,7 @@ class TestBufferOverrun : public TestFixture { " int a[10];\n" " for (int i = 0; i < 10; i++)\n" " a[i+10] = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'a[10]' accessed at index 19, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -759,7 +759,7 @@ class TestBufferOverrun : public TestFixture { " int a[10];\n" " for (int i = 0; i < 10; i++)\n" " a[10+i] = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'a[10]' accessed at index 19, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -769,7 +769,7 @@ class TestBufferOverrun : public TestFixture { " int a[10];\n" " for (int i = 0; i < 10; i++)\n" " a[i+1] = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'a[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -779,7 +779,7 @@ class TestBufferOverrun : public TestFixture { " int a[10];\n" " for (int i = 0; i < 10; i++)\n" " a[i*2] = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'a[10]' accessed at index 18, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" @@ -787,7 +787,7 @@ class TestBufferOverrun : public TestFixture { " int a[12];\n" " for (int i = 0; i < 12; i+=6)\n" " a[i+5] = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -795,21 +795,21 @@ class TestBufferOverrun : public TestFixture { " int a[12];\n" " for (int i = 0; i < 12; i+=6)\n" " a[i+6] = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'a[12]' accessed at index 12, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" // #4398 " int a[2];\n" " for (int i = 0; i < 4; i+=2)\n" " a[i] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (error) Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" // #4398 " int a[2];\n" " for (int i = 0; i < 4; i+=2)\n" " do_stuff(a+i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -822,7 +822,7 @@ class TestBufferOverrun : public TestFixture { " a[i] = i;\n" " i+=1;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -833,7 +833,7 @@ class TestBufferOverrun : public TestFixture { " a[i] = i;\n" " i++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -844,7 +844,7 @@ class TestBufferOverrun : public TestFixture { " a[i] = i;\n" " ++i;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -855,7 +855,7 @@ class TestBufferOverrun : public TestFixture { " a[i] = i;\n" " i=4;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:10]: (error) Array 'a[5]' accessed at index 5, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" @@ -866,7 +866,7 @@ class TestBufferOverrun : public TestFixture { " a[i] = i;\n" " i+=1;\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Buffer overrun\n", "", errout_str()); } @@ -876,7 +876,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char a[2];\n" " char *end = &(a[2]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Getting more than one past the end is not legal @@ -884,7 +884,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char a[2];\n" " char *end = &(a[3]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (error) Array 'a[2]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -895,7 +895,7 @@ class TestBufferOverrun : public TestFixture { " int b[10];\n" " for ( int i = 0; i < 9; i++ )\n" " b[i] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -909,7 +909,7 @@ class TestBufferOverrun : public TestFixture { " for(int j=0; j<3; ++j) {\n" " int b = indices[j];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -917,7 +917,7 @@ class TestBufferOverrun : public TestFixture { check("int main() {\n" " size_t indices[2];\n" " int b = indices[2];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:18]: (error) Array 'indices[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -926,7 +926,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char c[10];\n" " c[1<<23]='a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 'c[10]' accessed at index 8388608, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -945,7 +945,7 @@ class TestBufferOverrun : public TestFixture { " int a[n];\n" // n <= SCHAR_MAX " a[-1] = 0;\n" // negative index " a[128] = 0;\n" // 128 > SCHAR_MAX - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'a[128]' accessed at index -1, which is out of bounds. [negativeIndex]\n" "[test.cpp:4:6]: (error) Array 'a[128]' accessed at index 128, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); @@ -953,7 +953,7 @@ class TestBufferOverrun : public TestFixture { " int a[n];\n" // n <= UCHAR_MAX " a[-1] = 0;\n" // negative index " a[256] = 0;\n" // 256 > UCHAR_MAX - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'a[256]' accessed at index -1, which is out of bounds. [negativeIndex]\n" "[test.cpp:4:6]: (error) Array 'a[256]' accessed at index 256, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); @@ -961,7 +961,7 @@ class TestBufferOverrun : public TestFixture { " int a[n];\n" // n <= SHRT_MAX " a[-1] = 0;\n" // negative index " a[32768] = 0;\n" // 32768 > SHRT_MAX - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'a[32768]' accessed at index -1, which is out of bounds. [negativeIndex]\n" "[test.cpp:4:6]: (error) Array 'a[32768]' accessed at index 32768, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); @@ -969,7 +969,7 @@ class TestBufferOverrun : public TestFixture { " int a[n];\n" // n <= USHRT_MAX " a[-1] = 0;\n" // negative index " a[65536] = 0;\n" // 65536 > USHRT_MAX - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'a[65536]' accessed at index -1, which is out of bounds. [negativeIndex]\n" "[test.cpp:4:6]: (error) Array 'a[65536]' accessed at index 65536, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); @@ -977,26 +977,26 @@ class TestBufferOverrun : public TestFixture { " int a[n];\n" // n <= SHRT_MAX " a[-1] = 0;\n" // negative index " a[32768] = 0;\n" // 32768 > SHRT_MAX - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'a[32768]' accessed at index -1, which is out of bounds. [negativeIndex]\n" "[test.cpp:4:6]: (error) Array 'a[32768]' accessed at index 32768, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f(int n) {\n" " int a[n];\n" // n <= INT_MAX " a[-1] = 0;\n" // negative index - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'a[2147483648]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); check("void f(unsigned int n) {\n" " int a[n];\n" // n <= UINT_MAX " a[-1] = 0;\n" // negative index - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'a[4294967296]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); check("void f(signed int n) {\n" " int a[n];\n" // n <= INT_MAX " a[-1] = 0;\n" // negative index - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'a[2147483648]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); } @@ -1004,7 +1004,7 @@ class TestBufferOverrun : public TestFixture { check("void foo()\n" "{\n" " long l[SOME_SIZE];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1014,7 +1014,7 @@ class TestBufferOverrun : public TestFixture { " int a[3];\n" " for (int i = 3; 0 <= i; i--)\n" " a[i] = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'a[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" @@ -1022,7 +1022,7 @@ class TestBufferOverrun : public TestFixture { " int a[4];\n" " for (int i = 3; 0 <= i; i--)\n" " a[i] = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1032,7 +1032,7 @@ class TestBufferOverrun : public TestFixture { " int a[10];\n" " for (int i = 0; i < 10; i++)\n" " a[i-1] = a[i];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'a[10]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); } @@ -1043,7 +1043,7 @@ class TestBufferOverrun : public TestFixture { " int i[2];\n" " int *ip = i + 1;\n" " ip[-10] = 1;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Array ip[-10] out of bounds.\n", "", errout_str()); } @@ -1055,7 +1055,7 @@ class TestBufferOverrun : public TestFixture { " int *i = iBuf + 9;" " int *ii = i + -5;" " ii[10] = 0;" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Array ii[10] out of bounds.\n", "", errout_str()); } @@ -1065,7 +1065,7 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " UINT8 x[2];\n" " x[5] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'x[2]' accessed at index 5, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -1082,7 +1082,7 @@ class TestBufferOverrun : public TestFixture { "void y() {\n" " struct s1 obj;\n" " x(obj.delay, 123);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct s1 {\n" @@ -1096,7 +1096,7 @@ class TestBufferOverrun : public TestFixture { "void y() {\n" " struct s1 obj;\n" " x(obj.delay, 123);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:6]: (error) Array 'obj.delay[3]' accessed at index 4, which is out of bounds.\n", "", errout_str()); @@ -1107,7 +1107,7 @@ class TestBufferOverrun : public TestFixture { "\n" "void f() {\n" " struct s1 *obj;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1121,14 +1121,14 @@ class TestBufferOverrun : public TestFixture { " m_x[1] = 0;\n" " }\n" " int m_x[1];\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:11]: (error) Array 'm_x[1]' accessed at index 1, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } void array_index_33() { check("void foo(char bar[][4]) {\n" " baz(bar[5]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1137,7 +1137,7 @@ class TestBufferOverrun : public TestFixture { " int y[2][2][2];\n" " y[0][2][0] = 0;\n" " y[0][0][2] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (error) Array 'y[2][2][2]' accessed at index y[0][2][0], which is out of bounds. [arrayIndexOutOfBounds]\n" "[test.cpp:4:6]: (error) Array 'y[2][2][2]' accessed at index y[0][0][2], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); @@ -1157,7 +1157,7 @@ class TestBufferOverrun : public TestFixture { " ptest->a[10] = 3;\n" " ptest->b[10][2] = 4;\n" " ptest->b[0][19] = 4;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:11]: (error) Array 'test.a[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n" "[test.cpp:10:11]: (error) Array 'test.b[10][5]' accessed at index test.b[10][2], which is out of bounds. [arrayIndexOutOfBounds]\n" "[test.cpp:11:11]: (error) Array 'test.b[10][5]' accessed at index test.b[0][19], which is out of bounds. [arrayIndexOutOfBounds]\n" @@ -1178,7 +1178,7 @@ class TestBufferOverrun : public TestFixture { " ptest = &test;\n" " ptest->a[9][5] = 4;\n" " ptest->a[0][50] = 4;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:11]: (error) Array 'test.a[10][5]' accessed at index test.a[9][5], which is out of bounds. [arrayIndexOutOfBounds]\n" "[test.cpp:9:11]: (error) Array 'test.a[10][5]' accessed at index test.a[0][50], which is out of bounds. [arrayIndexOutOfBounds]\n" "[test.cpp:12:13]: (error) Array 'ptest->a[10][5]' accessed at index ptest->a[9][5], which is out of bounds. [arrayIndexOutOfBounds]\n" @@ -1189,21 +1189,21 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " struct Struct { unsigned m_Var[1]; } s;\n" " s.m_Var[1] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (error) Array 's.m_Var[1]' accessed at index 1, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("struct Struct { unsigned m_Var[1]; };\n" "void f() {\n" " struct Struct s;\n" " s.m_Var[1] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (error) Array 's.m_Var[1]' accessed at index 1, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("struct Struct { unsigned m_Var[1]; };\n" "void f() {\n" " struct Struct * s = calloc(40);\n" " s->m_Var[1] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1215,7 +1215,7 @@ class TestBufferOverrun : public TestFixture { "};\n" "Fred::Fred(const Fred & rhs) {\n" " m_b[2] = rhs.m_b[2];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (error) Array 'm_b[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]\n" "[test.cpp:7:21]: (error) Array 'rhs.m_b[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -1227,7 +1227,7 @@ class TestBufferOverrun : public TestFixture { " for (unsigned int i = 0; i < 15; i++)\n" " i;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1246,7 +1246,7 @@ class TestBufferOverrun : public TestFixture { " }\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1255,7 +1255,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char a[10];\n" " a[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 'a[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -1264,7 +1264,7 @@ class TestBufferOverrun : public TestFixture { " char a[10];\n" " for (int i = 0; i < 10; ++i)\n" " f2(&a[i + 1]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1277,7 +1277,7 @@ class TestBufferOverrun : public TestFixture { "\n" "void b() {\n" " struct Fred { char data[3]; } fred;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void a() {\n" @@ -1288,7 +1288,7 @@ class TestBufferOverrun : public TestFixture { "void b() {\n" " struct Fred { char data[3]; } fred;\n" " fred.data[4] = 0;\n" // <- error - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:14]: (error) Array 'fred.data[3]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -1299,7 +1299,7 @@ class TestBufferOverrun : public TestFixture { " char *p; p = (char *)malloc(10);\n" " p[10] = 7;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'p[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" @@ -1307,7 +1307,7 @@ class TestBufferOverrun : public TestFixture { " float *p; p = (float *)malloc(10 * sizeof(float));\n" " p[10] = 7;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'p[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" @@ -1316,7 +1316,7 @@ class TestBufferOverrun : public TestFixture { " p[0] = 0;\n" " p[9] = 9;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -1325,7 +1325,7 @@ class TestBufferOverrun : public TestFixture { " p[0] = 0;\n" " p[9] = 9;\n" " delete [] p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -1334,7 +1334,7 @@ class TestBufferOverrun : public TestFixture { " p[0] = 0;\n" " p[9] = 9;\n" " delete [] p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -1345,11 +1345,11 @@ class TestBufferOverrun : public TestFixture { " }\n" " catch(...){\n" " return;\n" - " }" + " }\n" " p[0] = 0;\n" " p[9] = 9;\n" " delete [] p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1366,7 +1366,7 @@ class TestBufferOverrun : public TestFixture { " var[ 0 ].arr[ 2 ] = 2;\n" " y = var[ 0 ].arr[ 3 ];\n" // <-- array access out of bounds " return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:20]: (error) Array 'var[0].arr[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("int f( )\n" @@ -1380,7 +1380,7 @@ class TestBufferOverrun : public TestFixture { " var[ 0 ].arr[ 2 ] = 2;\n" " y = var[ 0 ].arr[ 2 ];\n" " return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -1396,7 +1396,7 @@ class TestBufferOverrun : public TestFixture { "var.arr[ 3 ] = 3;\n" // <-- array access out of bounds "y=var.arr[ 3 ];\n" // <-- array access out of bounds "return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:8]: (error) Array 'var.arr[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\n" "[test.cpp:11:10]: (error) Array 'var.arr[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); @@ -1410,7 +1410,7 @@ class TestBufferOverrun : public TestFixture { "var[0].var[ 1 ] = 1;\n" "var[0].var[ 2 ] = 2;\n" "var[0].var[ 4 ] = 4;\n" // <-- array access out of bounds - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:11]: (error) Array 'var[0].var[3]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f( ) {\n" @@ -1421,7 +1421,7 @@ class TestBufferOverrun : public TestFixture { "var[0].var[ 0 ] = 0;\n" "var[0].var[ 1 ] = 1;\n" "var[0].var[ 2 ] = 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // avoid FPs (modified examples taken from #3838) @@ -1430,7 +1430,7 @@ class TestBufferOverrun : public TestFixture { " struct AB ab;\n" " int * p = &ab.a[10];\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct AB { int a[10]; int b[10]; };\n" @@ -1438,7 +1438,7 @@ class TestBufferOverrun : public TestFixture { " struct AB ab[1];\n" " int * p = &ab[0].a[10];\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct AB { int a[10]; int b[10]; };\n" @@ -1446,7 +1446,7 @@ class TestBufferOverrun : public TestFixture { " struct AB ab[1];\n" " int * p = &ab[10].a[0];\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (error) Array 'ab[1]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -1460,7 +1460,7 @@ class TestBufferOverrun : public TestFixture { " {\n" " buf[i] = 1;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -1470,7 +1470,7 @@ class TestBufferOverrun : public TestFixture { " {\n" " buf[i] = 2.;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1483,7 +1483,7 @@ class TestBufferOverrun : public TestFixture { "void test() {\n" " CHAR buffer[1024];\n" " f(\"%s\", buffer);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Unnamed argument @@ -1493,7 +1493,7 @@ class TestBufferOverrun : public TestFixture { "void test() {\n" " char buffer[1024];\n" " f(buffer);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1505,7 +1505,7 @@ class TestBufferOverrun : public TestFixture { " for(int i=3; i--;) {\n" " printf(\"files(%i): %s\", 3-i, buffer[3-i]);\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array 'buffer[3]' accessed at index 3, which is out of bounds.\n", "", errout_str()); check("void f() {\n" @@ -1514,7 +1514,7 @@ class TestBufferOverrun : public TestFixture { " for(i=10; i--;) {\n" " buffer[i] = i;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:15]: (error) Array 'buffer[9]' accessed at index 9, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // Correct access limits -> i from 9 to 0 @@ -1523,7 +1523,7 @@ class TestBufferOverrun : public TestFixture { " for(unsigned long int i=10; i--;) {\n" " buffer[i] = i;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1533,7 +1533,7 @@ class TestBufferOverrun : public TestFixture { "void f() {\n" " for (int i = 2; i < 0; i++)\n" " s[i] = 5;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1546,7 +1546,7 @@ class TestBufferOverrun : public TestFixture { " printf(\" %i\", i);\n" " array[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:14]: (error) Array 'array[4]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void test(void)\n" @@ -1556,7 +1556,7 @@ class TestBufferOverrun : public TestFixture { " scanf(\"%i\", &i);\n" " array[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1570,7 +1570,7 @@ class TestBufferOverrun : public TestFixture { " i++;\n" " }\n" " arr[k];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1582,7 +1582,7 @@ class TestBufferOverrun : public TestFixture { "void g() {\n" " f(\"12345678\");\n" " f(\"12345\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1590,7 +1590,7 @@ class TestBufferOverrun : public TestFixture { check("void f(void){\n" " int k=0, dd, d[1U] = {1};\n" " for (dd=d[k]; k<10; dd=d[++k]){;}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:29]: (error) Array 'd[1]' accessed at index 1, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -1601,7 +1601,7 @@ class TestBufferOverrun : public TestFixture { " for(int i = 0, j= 11; i < j; ++i)\n" " buf[i] = 0;\n" " return buf[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:11]: (error) Array 'buf[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -1613,7 +1613,7 @@ class TestBufferOverrun : public TestFixture { " for (int i=0; i < 3; i++)\n" " for (int j = 0; j < 3; j++)\n" " M[i][j]=0.0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:15]: (error) Array 'M[3][1]' accessed at index M[*][2], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -2017,87 +2017,87 @@ class TestBufferOverrun : public TestFixture { "{\n" " char a[2][2];\n" " a[1][1] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " char a[2][2][2];\n" " a[1][1][1] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " char a[2][2];\n" " a[2][1] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'a[2][2]' accessed at index a[2][1], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " char a[2][2];\n" " a[1][2] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'a[2][2]' accessed at index a[1][2], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " char a[2][2][2];\n" " a[2][1][1] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'a[2][2][2]' accessed at index a[2][1][1], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " char a[2][2][2];\n" " a[1][2][1] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'a[2][2][2]' accessed at index a[1][2][1], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " char a[2][2][2][2];\n" " a[1][2][1][1] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'a[2][2][2][2]' accessed at index a[1][2][1][1], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " char a[2][2][2];\n" " a[1][1][2] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'a[2][2][2]' accessed at index a[1][1][2], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " char a[10][10][10];\n" " a[2*3][4*3][2] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Array 'a[10][10][10]' accessed at index a[6][12][2], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" " char a[10][10][10];\n" " a[6][40][10] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:4]: (error) Array 'a[10][10][10]' accessed at index a[6][40][10], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" " char a[1][1][1];\n" " a[2][2][2] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:4]: (error) Array 'a[1][1][1]' accessed at index a[2][2][2], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" " char a[6][6][6];\n" " a[6][6][2] = 'a';\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:4]: (error) Array 'a[6][6][6]' accessed at index a[6][6][2], which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" " int a[2][2];\n" " p = &a[2][0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // unknown dim.. @@ -2105,7 +2105,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " int a[2][countof(x)] = {{1,2},{3,4}};\n" " a[0][0] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void draw_quad(float z) {\n" @@ -2127,7 +2127,7 @@ class TestBufferOverrun : public TestFixture { " vertices[i][1][2] = 4.0;\n" " vertices[i][1][3] = 5.0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); { @@ -2136,7 +2136,7 @@ class TestBufferOverrun : public TestFixture { " const size_t B = 2;\n" " extern int stuff[A][B];\n" " return stuff[0][1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // TODO: better handling of VLAs in symboldatabase. should be @@ -2146,7 +2146,7 @@ class TestBufferOverrun : public TestFixture { " const size_t B = 2;\n" " extern int stuff[A][B];\n" " return stuff[0][1];\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); } } @@ -2167,7 +2167,7 @@ class TestBufferOverrun : public TestFixture { " break;\n" " };\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -2185,7 +2185,7 @@ class TestBufferOverrun : public TestFixture { " break;\n" " };\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:12]: (error) Array index out of bounds.\n", "", errout_str()); } @@ -2197,7 +2197,7 @@ class TestBufferOverrun : public TestFixture { " a[i] = 0;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2207,7 +2207,7 @@ class TestBufferOverrun : public TestFixture { "void f(int i) {\n" " if (i >= 0 && i < 10) {}\n" " a[i] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19] -> [test.cpp:4:4]: (warning) Either the condition 'i<10' is redundant or the array 'a[10]' is accessed at index 10, which is out of bounds. [arrayIndexOutOfBoundsCond]\n" "[test.cpp:3:9] -> [test.cpp:4:4]: (warning) Either the condition 'i>=0' is redundant or the array 'a[10]' is accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); @@ -2221,7 +2221,7 @@ class TestBufferOverrun : public TestFixture { " for (int i = 19; i < 36; ++i) {\n" " data[i/2] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13]: (error) Array 'data[8]' accessed at index 17, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // #2199 - false negative: array out of bounds in loop when there is calculation @@ -2231,7 +2231,7 @@ class TestBufferOverrun : public TestFixture { " for (int i = 0; i < 5; ++i) {\n" " arr[i + 7] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:12]: (error) Array 'arr[5]' accessed at index 11, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -2241,21 +2241,21 @@ class TestBufferOverrun : public TestFixture { "{\n" " char data[8];\n" " data[-1] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Array 'data[8]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); check("void f()\n" "{\n" " char data[8][4];\n" " data[5][-1] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Array 'data[8][4]' accessed at index data[*][-1], which is out of bounds. [negativeIndex]\n", errout_str()); // #1614 - negative index is ok for pointers check("void foo(char *p)\n" "{\n" " p[-1] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -2263,14 +2263,14 @@ class TestBufferOverrun : public TestFixture { " char s[] = \"abc\";\n" " char *p = s + strlen(s);\n" " if (p[-1]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket #1850 check("int f(const std::map > &m)\n" "{\n" " return m[0][-1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2279,7 +2279,7 @@ class TestBufferOverrun : public TestFixture { "void foo() {\n" " TEST test;\n" " test.a[-1] = 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Array 'test.a[10]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); } @@ -2295,7 +2295,7 @@ class TestBufferOverrun : public TestFixture { "void g(int i) {\n" " if( i == 0 )\n" " return f(i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2402,7 +2402,7 @@ class TestBufferOverrun : public TestFixture { " for (int i = 10; i > 0; --i) {\n" " data[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13]: (error) Array 'data[8]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" @@ -2411,7 +2411,7 @@ class TestBufferOverrun : public TestFixture { " for (unsigned int i = 3; i < 5; --i) {\n" " val[i+1] = val[i];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -2420,7 +2420,7 @@ class TestBufferOverrun : public TestFixture { " for (int i = 3; i < 5; --i) {\n" " val[i+1] = val[i];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:12]: (error) Array 'val[5]' accessed at index -9994, which is out of bounds. [negativeIndex]\n" "[test.cpp:5:23]: (error) Array 'val[5]' accessed at index -9995, which is out of bounds. [negativeIndex]\n", errout_str()); } @@ -2438,7 +2438,7 @@ class TestBufferOverrun : public TestFixture { " A a;\n" " a.data[3] = 0;\n" " a.b.data[2] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #1586 @@ -2453,7 +2453,7 @@ class TestBufferOverrun : public TestFixture { " A a;\n" " a.data[4] = 0;\n" " a.b.data[3] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:11]: (error) Array 'a.data[4]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n" "[test.cpp:11:13]: (error) Array 'a.b.data[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -2467,7 +2467,7 @@ class TestBufferOverrun : public TestFixture { " for (x = 0; x < 10 && y; x++) {\n" " data[x] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13]: (error) Array 'data[2]' accessed at index 9, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" @@ -2476,7 +2476,7 @@ class TestBufferOverrun : public TestFixture { " for (x = 0; x < 10 || y; x++) {\n" " data[x] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13]: (error) Array 'data[2]' accessed at index 9, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" @@ -2485,7 +2485,7 @@ class TestBufferOverrun : public TestFixture { " for (x = 0; x <= 10 && y; x++) {\n" " data[x] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13]: (error) Array 'data[2]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" @@ -2494,7 +2494,7 @@ class TestBufferOverrun : public TestFixture { " for (x = 0; y && x <= 10; x++) {\n" " data[x] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13]: (error) Array 'data[2]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("int f() {\n" // #9126 @@ -2506,7 +2506,7 @@ class TestBufferOverrun : public TestFixture { " c++;\n" " }\n" " return c;\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); } @@ -2520,7 +2520,7 @@ class TestBufferOverrun : public TestFixture { " }\n" " a[i - 1] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // extracttests.start: int maybe(); @@ -2532,7 +2532,7 @@ class TestBufferOverrun : public TestFixture { " }\n" " a[i - 1] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:10]: (error) Array 'a[2]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); } @@ -2545,7 +2545,7 @@ class TestBufferOverrun : public TestFixture { " }\n" " a[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:10]: (error) Array 'a[10]' accessed at index 19, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // Ticket #2385 - No false positive @@ -2557,7 +2557,7 @@ class TestBufferOverrun : public TestFixture { " a[i-10] = 0;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Ticket #3893 - start value out of bounds @@ -2567,7 +2567,7 @@ class TestBufferOverrun : public TestFixture { " for (int i = 10; maybe(); dostuff()) {\n" " a[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (error) Array 'a[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // #7686 @@ -2601,7 +2601,7 @@ class TestBufferOverrun : public TestFixture { " for (int i = 0; i != 10; ++i) {\n" " a[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (error) Array 'a[5]' accessed at index 9, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -2613,7 +2613,7 @@ class TestBufferOverrun : public TestFixture { " for (int i = 0; i != 10; ++i) {\n" " i == 0 ? 0 : a[i-1];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -2621,7 +2621,7 @@ class TestBufferOverrun : public TestFixture { " for (int i = 0; i != 10; ++i) {\n" " some_condition ? 0 : a[i-1];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:31]: (error) Array 'a[10]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); @@ -2631,7 +2631,7 @@ class TestBufferOverrun : public TestFixture { " i==0 ? 0 : a[i-1];\n" " a[i-1] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'a[10]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); } @@ -2639,7 +2639,7 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char a[10];\n" " for (i=0; i<10; i++);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2650,14 +2650,14 @@ class TestBufferOverrun : public TestFixture { " for (int i=0; i<7; ++i) {\n" " a[0] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void array_index_extern() { // Ticket #1684. FP when using 'extern'. check("extern char arr[15];\n" - "char arr[15] = \"abc\";"); + "char arr[15] = \"abc\";\n"); ASSERT_EQUALS("", errout_str()); } @@ -2671,7 +2671,7 @@ class TestBufferOverrun : public TestFixture { "void f2() {\n" " int x[2];\n" " f1(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Same type => error @@ -2681,7 +2681,7 @@ class TestBufferOverrun : public TestFixture { "void f2() {\n" " char x[2];\n" " f1(x);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:2]: (error) Array 'x[2]' accessed at index 4, which is out of bounds.\n", "", errout_str()); @@ -2691,41 +2691,41 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " const char *str = \"abc\";\n" " bar(str[10]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (error) Array 'str[4]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " const char *str = \"abc\";\n" " bar(str[4]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (error) Array 'str[4]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " const char *str = \"abc\";\n" " bar(str[3]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " const char *str = \"a\tc\";\n" " bar(str[4]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (error) Array 'str[4]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" // #6973 " const char *name = \"\";\n" " if ( name[0] == 'U' ? name[1] : 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int main(int argc, char **argv) {\n" " char str[6] = \"\\0\";\n" " unsigned short port = 65535;\n" " snprintf(str, sizeof(str), \"%hu\", port);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); check("int f(int x) {\n" // #11020 @@ -2747,7 +2747,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " struct tt *tt=x;\n" " tt->name;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // detect error @@ -2758,7 +2758,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " struct tt *tt=x;\n" " tt->name[22] = 123;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:13]: (error) Array 'tt->name[21]' accessed at index 22, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -2767,7 +2767,7 @@ class TestBufferOverrun : public TestFixture { " char str[3];\n" " str[i] = 0;\n" " if (i==10) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10] -> [test.cpp:3:8]: (warning) Either the condition 'i==10' is redundant or the array 'str[3]' is accessed at index 10, which is out of bounds. [arrayIndexOutOfBoundsCond]\n", errout_str()); check("void f(int i) {\n" @@ -2776,31 +2776,31 @@ class TestBufferOverrun : public TestFixture { " switch (i) {\n" " case 10: break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5] -> [test.cpp:3:8]: (warning) Either the switch case 'case 10' is redundant or the array 'str[3]' is accessed at index 10, which is out of bounds. [arrayIndexOutOfBoundsCond]\n", errout_str()); check("void f() {\n" " char str[3];\n" " str[((unsigned char)3) - 1] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #5416 FP " char *str[3];\n" " do_something(&str[0][5]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class X { static const int x[100]; };\n" // #6070 - "const int X::x[100] = {0};"); + "const int X::x[100] = {0};\n"); ASSERT_EQUALS("", errout_str()); check("namespace { class X { static const int x[100]; };\n" // #6232 - "const int X::x[100] = {0}; }"); + "const int X::x[100] = {0}; }\n"); ASSERT_EQUALS("", errout_str()); check("class ActorSprite { static ImageSet * targetCursorImages[2][10]; };\n" - "ImageSet *ActorSprite::targetCursorImages[2][10];"); + "ImageSet *ActorSprite::targetCursorImages[2][10];\n"); ASSERT_EQUALS("", errout_str()); check("int f(const std::size_t s) {\n" // #10130 @@ -2832,7 +2832,7 @@ class TestBufferOverrun : public TestFixture { " int a[10];\n" " int *p = a;\n" " p[20] = 0;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (error) Array 'a[10]' accessed at index 20, which is out of bounds.\n", "", errout_str()); { @@ -2841,14 +2841,14 @@ class TestBufferOverrun : public TestFixture { " int a[10];\n" " int *p = a;\n" " p[10] = 0;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4:6]: (error) Array 'a[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", "", errout_str()); check("void f() {\n" " int a[10];\n" " int *p = a;\n" " dostuff(&p[10]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2856,33 +2856,33 @@ class TestBufferOverrun : public TestFixture { " int a[X];\n" // unknown size " int *p = a;\n" " p[20] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int a[2];\n" " char *p = (char *)a;\n" // cast " p[4] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void array_index_function_parameter() { check("void f(char a[10]) {\n" " a[20] = 0;\n" // <- cppcheck warn here even though it's not a definite access out of bounds - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:4]: (error) Array 'a[10]' accessed at index 20, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f(char a[10]) {\n" // #6353 - reassign 'a' " a += 4;\n" " a[-1] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char a[10]) {\n" " a[0] = 0;\n" " a[-1] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:4]: (error) Array 'a[10]' accessed at index -1, which is out of bounds. [negativeIndex]\n", errout_str()); } @@ -2891,7 +2891,7 @@ class TestBufferOverrun : public TestFixture { "void f() {\n" " E arrE[] = { e1, e2 };\n" " arrE[sizeof(arrE)] = e1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Array 'arrE[2]' accessed at index 8, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -2899,7 +2899,7 @@ class TestBufferOverrun : public TestFixture { check("constexpr int blockLen = 10;\n" "void foo(std::array& a) {\n" " a[2] = 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2909,14 +2909,14 @@ class TestBufferOverrun : public TestFixture { " std::vector v(3);\n" " int* p = v.data();\n" " p[2] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " std::vector v(3);\n" " int* p = v.data();\n" " p[5] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:6]: (error) Array 'p[3]' accessed at index 5, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); @@ -2925,7 +2925,7 @@ class TestBufferOverrun : public TestFixture { " std::vector v(3);\n" " memset(v.data(), 0, 12);\n" " memset(v.data(), 0, 100);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (error) Buffer is accessed out of bounds: v.data() [bufferAccessOutOfBounds]\n", errout_str()); @@ -2933,7 +2933,7 @@ class TestBufferOverrun : public TestFixture { " std::vector v(3);\n" " int* p = v.data();\n" " memset(p, 0, 100);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (error) Buffer is accessed out of bounds: p [bufferAccessOutOfBounds]\n", errout_str()); @@ -2944,7 +2944,7 @@ class TestBufferOverrun : public TestFixture { " int* p = v.data();\n" " v.resize(10);\n" " memset(p, 0, 40);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ..or when the pointer is reassigned @@ -2953,7 +2953,7 @@ class TestBufferOverrun : public TestFixture { " int* p = v.data();\n" " p = q;\n" " memset(p, 0, 100);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // the buffer of c_str() includes the null terminator @@ -2961,7 +2961,7 @@ class TestBufferOverrun : public TestFixture { " std::string s = \"abc\";\n" " memcpy(dst, s.c_str(), 4);\n" " memcpy(dst, s.c_str(), 5);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:24]: (error) Buffer is accessed out of bounds: s.c_str() [bufferAccessOutOfBounds]\n", errout_str()); } @@ -2976,7 +2976,7 @@ class TestBufferOverrun : public TestFixture { " sum += val[i];\n" " if (i < 50)\n" " sum -= val[i];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool b();\n" @@ -2990,7 +2990,7 @@ class TestBufferOverrun : public TestFixture { " sum -= val[i];\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool b();\n" @@ -3002,7 +3002,7 @@ class TestBufferOverrun : public TestFixture { " sum += val[i];\n" " for (; i < 50; i++)\n" " sum -= val[i];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3089,7 +3089,7 @@ class TestBufferOverrun : public TestFixture { "static void f(struct ABC *abc)\n" "{\n" " strcpy( abc->str, \"abcdef\" );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:16]: (error) Buffer is accessed out of bounds: abc->str [bufferAccessOutOfBounds]\n", errout_str()); check("struct ABC\n" @@ -3101,7 +3101,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " struct ABC abc;\n" " strcpy( abc.str, \"abcdef\" );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:16]: (error) Buffer is accessed out of bounds: abc.str [bufferAccessOutOfBounds]\n", errout_str()); check("struct ABC\n" @@ -3112,7 +3112,7 @@ class TestBufferOverrun : public TestFixture { "static void f(struct ABC &abc)\n" "{\n" " strcpy( abc.str, \"abcdef\" );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:16]: (error) Buffer is accessed out of bounds: abc.str [bufferAccessOutOfBounds]\n", errout_str()); check("static void f()\n" @@ -3122,7 +3122,7 @@ class TestBufferOverrun : public TestFixture { " char str[5];\n" " } abc;\n" " strcpy( abc.str, \"abcdef\" );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:16]: (error) Buffer is accessed out of bounds: abc.str [bufferAccessOutOfBounds]\n", errout_str()); check("static void f()\n" @@ -3134,7 +3134,7 @@ class TestBufferOverrun : public TestFixture { " struct ABC *abc = malloc(sizeof(struct ABC));\n" " strcpy( abc->str, \"abcdef\" );\n" " free(abc);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:16]: (error) Buffer is accessed out of bounds: abc->str [bufferAccessOutOfBounds]\n", errout_str()); } @@ -3147,7 +3147,7 @@ class TestBufferOverrun : public TestFixture { " int i;\n" " for (i = 0; i <= 10; ++i)\n" " a[i] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:10]: (error) Array 'a[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("struct S { int b; } static e[1];\n" // #11052 @@ -3162,7 +3162,7 @@ class TestBufferOverrun : public TestFixture { " const char *p[2];\n" " for (int i = 0; i < 8; ++i)\n" " p[i] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Array 'p[2]' accessed at index 7, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // No false positive @@ -3171,7 +3171,7 @@ class TestBufferOverrun : public TestFixture { " const char *p[2];\n" " const char *s = y + p[1];\n" " p[1] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // There is no error here @@ -3183,7 +3183,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char s[3];\n" " f1(s,20);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:3]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); check("void f1(char *s,int size)\n" @@ -3204,7 +3204,7 @@ class TestBufferOverrun : public TestFixture { " char n[5];\n" " sprintf(n, \"d\");\n" " printf(\"hello!\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3214,21 +3214,21 @@ class TestBufferOverrun : public TestFixture { " char n[5];\n" " strcat(n, \"abc\");\n" " strcat(n, \"def\");\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Buffer is accessed out of bounds: n\n", "", errout_str()); check("void f()\n" // #12489 "{\n" " char d[3] = {};\n" " strcat(d, \"12345678\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Buffer is accessed out of bounds: d [bufferAccessOutOfBounds]\n", errout_str()); check("void f()\n" "{\n" " char d[3] = \"ab\"; \n" " strcat(d, \"c\");\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4:11]: (error) Buffer is accessed out of bounds: d [bufferAccessOutOfBounds]\n", "", errout_str()); } @@ -3238,7 +3238,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char a[2];\n" " strcpy(a, \"a\\0\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3251,7 +3251,7 @@ class TestBufferOverrun : public TestFixture { " {\n" " a[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -3261,7 +3261,7 @@ class TestBufferOverrun : public TestFixture { " {\n" " a[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3275,7 +3275,7 @@ class TestBufferOverrun : public TestFixture { " a[i] = 0;\n" " i += 100;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3288,7 +3288,7 @@ class TestBufferOverrun : public TestFixture { " {\n" " char b = a[i];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3299,7 +3299,7 @@ class TestBufferOverrun : public TestFixture { " for (float i=0; i<10.0;i=i+0.1)\n" " {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -3308,7 +3308,7 @@ class TestBufferOverrun : public TestFixture { " for (float i=0; i<10.0;i=0.1+i)\n" " {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3320,7 +3320,7 @@ class TestBufferOverrun : public TestFixture { "void A::f(int i, int ii)\n" "{\n" " strcpy(val, \"ab\") ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:12]: (error) Buffer is accessed out of bounds: val [bufferAccessOutOfBounds]\n", errout_str()); } @@ -3329,20 +3329,20 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " struct Foo foo[5];\n" " memset(foo, 0, sizeof(foo));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // ticket #2093 " gchar x[3];\n" " strcpy(x, \"12\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("extern char a[10];\n" "void f() {\n" " char b[25] = {0};\n" " std::memcpy(b, a, 10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3356,7 +3356,7 @@ class TestBufferOverrun : public TestFixture { " for (int i=0; i<6; i++) {\n" " b[i] = b[i+1];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class A {\n" @@ -3368,7 +3368,7 @@ class TestBufferOverrun : public TestFixture { " for (int i=0; i<7; i++) {\n" " b[i] = b[i+1];\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:17]: (error) Array 'b[7]' accessed at index 7, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -3381,7 +3381,7 @@ class TestBufferOverrun : public TestFixture { "\n" "A::A() {\n" " memset(buf, 0, 10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3392,7 +3392,7 @@ class TestBufferOverrun : public TestFixture { " const char *src = \"AAAAAAAAAAAAAAAAAAAAA\";\n" " for (size_t i = 0; i <= 4; i++)\n" " dst[i] = src[i];\n" - "} } }"); + "} } }\n"); ASSERT_EQUALS("[test.cpp:6:12]: (error) Array 'dst[4]' accessed at index 4, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -3404,7 +3404,7 @@ class TestBufferOverrun : public TestFixture { " for( int i = 0; i<6; ) {\n" " x += array[i];\n" " i++; }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); // ticket #4096 @@ -3414,7 +3414,7 @@ class TestBufferOverrun : public TestFixture { " for( int i = 0; i<6; ) {\n" " x += array[i++];\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); } @@ -3424,7 +3424,7 @@ class TestBufferOverrun : public TestFixture { " char inbuf[1000];\n" " char *f[10];\n" " split(inbuf, f, 10, \"\t\t\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3434,7 +3434,7 @@ class TestBufferOverrun : public TestFixture { "void main() {\n" "struct foobar x[5];\n" "abc(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3445,7 +3445,7 @@ class TestBufferOverrun : public TestFixture { "int main(){\n" " testChar tc1 = \"\";\n" " tc1[5]='a';\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3455,14 +3455,14 @@ class TestBufferOverrun : public TestFixture { check("struct S { int m[9]; };\n" "int f(S * s) {\n" " return s->m[sizeof(s->m)];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (error) Array 's->m[9]' accessed at index 36, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } void buffer_overrun_31() { check("void f(WhereInfo *pWInfo, int *aiCur) {\n" " memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3473,7 +3473,7 @@ class TestBufferOverrun : public TestFixture { " char dest[1] = \"a\";\n" " (void)strxfrm(dest,src,1);\n" " (void)strxfrm(dest,src,2);\n"// << - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:19]: (error) Buffer is accessed out of bounds: dest [bufferAccessOutOfBounds]\n", errout_str()); // destination size is too small check("void f(void) {\n" @@ -3482,7 +3482,7 @@ class TestBufferOverrun : public TestFixture { " (void)strxfrm(dest,src,1);\n" " (void)strxfrm(dest,src,2);\n" " (void)strxfrm(dest,src,3);\n" // << - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:19]: (error) Buffer is accessed out of bounds: dest [bufferAccessOutOfBounds]\n", errout_str()); // source size is too small check("void f(void) {\n" @@ -3491,7 +3491,7 @@ class TestBufferOverrun : public TestFixture { " (void)strxfrm(dest,src,1);\n" " (void)strxfrm(dest,src,2);\n" " (void)strxfrm(dest,src,3);\n" // << - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:24]: (error) Buffer is accessed out of bounds: src [bufferAccessOutOfBounds]\n", errout_str()); // source size is too small check("void f(void) {\n" @@ -3499,7 +3499,7 @@ class TestBufferOverrun : public TestFixture { " char dest[3] = \"abc\";\n" " (void)strxfrm(dest,src,1);\n" " (void)strxfrm(dest,src,2);\n" // << - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:24]: (error) Buffer is accessed out of bounds: src [bufferAccessOutOfBounds]\n", errout_str()); } @@ -3510,7 +3510,7 @@ class TestBufferOverrun : public TestFixture { " for (int j=0; j<20; j++)\n" " z[i] = 0;\n" " return z[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:12]: (error) Array 'z[16]' accessed at index 19, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -3641,12 +3641,12 @@ class TestBufferOverrun : public TestFixture { void buffer_overrun_errorpath() { setMultiline(); Settings s = settings0; - s.templateLocation = "{file}:{line}:note:{info}"; + s.templateLocation = "{file}:{line}:note:{info}\n"; check("void f() {\n" " char *p = malloc(10);\n" " memset(p, 0, 20);\n" - "}", s); + "}\n", s); ASSERT_EQUALS("[test.cpp:3:12]: error: Buffer is accessed out of bounds: p [bufferAccessOutOfBounds]\n" "[test.cpp:2:13]: note: Assign p, buffer with size 10\n" "[test.cpp:3:12]: note: Buffer overrun\n", errout_str()); @@ -3687,7 +3687,7 @@ class TestBufferOverrun : public TestFixture { "void f2() {\n" " char a[10];\n" " f1(a);" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // No false positive @@ -3699,7 +3699,7 @@ class TestBufferOverrun : public TestFixture { "void f2() {\n" " char a[10];\n" " f1(a);" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // No false negative @@ -3711,7 +3711,7 @@ class TestBufferOverrun : public TestFixture { "void f2() {\n" " char a[10];\n" " f1(a);" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:3]: (error) Array 'a[10]' accessed at index 100, which is out of bounds.\n", "", errout_str()); } @@ -3722,7 +3722,7 @@ class TestBufferOverrun : public TestFixture { "void g() {\n" " char a[2];\n" " f(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: warning: Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument [argumentSize]\n" "[test.cpp:4:5]: note: Function 'f' is called\n" "[test.cpp:1:13]: note: Declaration of 1st function argument.\n" @@ -3733,7 +3733,7 @@ class TestBufferOverrun : public TestFixture { "void g() {\n" " float a[2][3];\n" " f(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: warning: Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument [argumentSize]\n" "[test.cpp:4:5]: note: Function 'f' is called\n" "[test.cpp:1:14]: note: Declaration of 1st function argument.\n" @@ -3744,7 +3744,7 @@ class TestBufferOverrun : public TestFixture { "void g() {\n" " int a[2];\n" " f(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: warning: Buffer 'a' is too small, the function 'f' expects a bigger buffer in 1st argument [argumentSize]\n" "[test.cpp:4:5]: note: Function 'f' is called\n" "[test.cpp:1:12]: note: Declaration of 1st function argument.\n" @@ -3766,7 +3766,7 @@ class TestBufferOverrun : public TestFixture { "void foo() {\n" " unsigned char(* tree)[2048][4] = new unsigned char[256][2048][4];\n" " CreateLeafTex(tree);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int a[10]) {\n" // #10069 @@ -3794,7 +3794,7 @@ class TestBufferOverrun : public TestFixture { " memset(src, 'C', 99);\n" " src[99] = '\\0';\n" " strcat(data, src);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:6]: (warning) Possible buffer overflow if strlen(src) is larger than sizeof(data)-strlen(data).\n", "", errout_str()); check("void foo() {\n" @@ -3803,19 +3803,19 @@ class TestBufferOverrun : public TestFixture { " memset(src, 'C', 99);\n" " src[99] = '\\0';\n" " strcat(data, src);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char src[100]) {\n" " char * data = (char *)alloca(50);\n" " strcat(data, src);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) Possible buffer overflow if strlen(src) is larger than sizeof(data)-strlen(data).\n", "", errout_str()); check("void foo(char src[100]) {\n" " char * data = (char *)alloca(100);\n" " strcat(data, src);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -3824,7 +3824,7 @@ class TestBufferOverrun : public TestFixture { " memset(src, 'C', 99);\n" " src[99] = '\\0';\n" " strcpy(data, src);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:6]: (warning) Possible buffer overflow if strlen(src) is larger than or equal to sizeof(data).\n", "", errout_str()); check("void foo() {\n" @@ -3833,19 +3833,19 @@ class TestBufferOverrun : public TestFixture { " memset(src, 'C', 99);\n" " src[99] = '\\0';\n" " strcpy(data, src);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char src[100]) {\n" " char * data = (char *)alloca(50);\n" " strcpy(data, src);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) Possible buffer overflow if strlen(src) is larger than or equal to sizeof(data).\n", "", errout_str()); check("void foo(char src[100]) {\n" " char * data = (char *)alloca(100);\n" " strcpy(data, src);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3867,26 +3867,26 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " u8 str[256];\n" " mystrcpy(str, \"abcd\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " u8 str[2];\n" " mystrcpy(str, \"abcd\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); // The same for structs, where the message comes from a different check check("void f() {\n" " struct { u8 str[256]; } ms;\n" " mystrcpy(ms.str, \"abcd\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " struct { u8 str[2]; } ms;\n" " mystrcpy(ms.str, \"abcd\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:16]: (error) Buffer is accessed out of bounds: ms.str [bufferAccessOutOfBounds]\n", errout_str()); } @@ -3894,31 +3894,31 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " int i;\n" " memset(i, 0, 1000);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int i;\n" " memset(&i, 0, 1000);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: &i [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" " int i[2];\n" " memset(&i, 0, 1000);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: i [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" " int i;\n" " memset(&i, 0, sizeof(i));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int i[10];\n" " memset(&i[1], 0, 1000);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: &i[1] [bufferAccessOutOfBounds]\n", errout_str()); check("struct S { int x; };\n" // #8616 @@ -3947,7 +3947,7 @@ class TestBufferOverrun : public TestFixture { " const char *x = s;\n" " if (cond) x = \"abcde\";\n" " return x[20];\n" // <- array index out of bounds when x is "abcde" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Array 'x[6]' accessed at index 20, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -3957,40 +3957,40 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char a[10];\n" " char *p = a + 100;\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:3:17]: (portability) Undefined behaviour, pointer arithmetic 'a+100' is out of bounds. [pointerOutOfBounds]\n", errout_str()); check("char *f() {\n" " char a[10];\n" " return a + 100;\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:3:14]: (portability) Undefined behaviour, pointer arithmetic 'a+100' is out of bounds. [pointerOutOfBounds]\n", errout_str()); check("void f(int i) {\n" " char x[10];\n" " if (i == 123) {}\n" " dostuff(x+i);\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:4:14]: (portability) Undefined behaviour, when 'i' is 123 the pointer arithmetic 'x+i' is out of bounds. [pointerOutOfBoundsCond]\n", errout_str()); check("void f(int i) {\n" " char x[10];\n" " if (i == -1) {}\n" " dostuff(x+i);\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:4:14]: (portability) Undefined behaviour, when 'i' is -1 the pointer arithmetic 'x+i' is out of bounds. [pointerOutOfBoundsCond]\n", errout_str()); check("void f() {\n" // #6350 - fp when there is cast of buffer " wchar_t buf[64];\n" " p = (unsigned char *) buf + sizeof (buf);\n" - "}", settings0_p, false); + "}\n", settings0_p, false); ASSERT_EQUALS("", errout_str()); check("int f() {\n" " const char d[] = \"0123456789\";\n" " char *cp = d + 3;\n" " return cp - d;\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("", errout_str()); } @@ -3999,7 +3999,7 @@ class TestBufferOverrun : public TestFixture { " char *p = malloc(10);\n" " p += 100;\n" " free(p);" - "}", settings0_p); + "}\n", settings0_p); TODO_ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'p+100' is out of bounds.\n", "", errout_str()); check("void f() {\n" @@ -4007,7 +4007,7 @@ class TestBufferOverrun : public TestFixture { " p += 10;\n" " *p = 0;\n" " free(p);" - "}", settings0_p); + "}\n", settings0_p); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) p is out of bounds.\n", "", errout_str()); check("void f() {\n" @@ -4016,7 +4016,7 @@ class TestBufferOverrun : public TestFixture { " p -= 10;\n" " *p = 0;\n" " free(p);" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -4025,7 +4025,7 @@ class TestBufferOverrun : public TestFixture { " p = p - 1;\n" " *p = 0;\n" " free(p);" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("", errout_str()); } @@ -4033,7 +4033,7 @@ class TestBufferOverrun : public TestFixture { check("struct S { int a[10]; };\n" "void f(struct S *s) {\n" " int *p = s->a + 100;\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:3:19]: (portability) Undefined behaviour, pointer arithmetic 's->a+100' is out of bounds. [pointerOutOfBounds]\n", errout_str()); check("template class Vector\n" @@ -4056,22 +4056,22 @@ class TestBufferOverrun : public TestFixture { void pointer_out_of_bounds_4() { check("const char* f() {\n" " g(\"Hello\" + 6);\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("", errout_str()); check("const char* f() {\n" " g(\"Hello\" + 7);\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:2:15]: (portability) Undefined behaviour, pointer arithmetic '\"Hello\"+7' is out of bounds. [pointerOutOfBounds]\n", errout_str()); check("const char16_t* f() {\n" " g(u\"Hello\" + 6);\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("", errout_str()); check("const char16_t* f() {\n" " g(u\"Hello\" + 7);\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:2:16]: (portability) Undefined behaviour, pointer arithmetic 'u\"Hello\"+7' is out of bounds. [pointerOutOfBounds]\n", errout_str()); check("void f() {\n" // #4647 @@ -4118,26 +4118,26 @@ class TestBufferOverrun : public TestFixture { check("char *f() {\n" " char x[10];\n" " return x-1;\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:3:13]: (portability) Undefined behaviour, pointer arithmetic 'x-1' is out of bounds. [pointerOutOfBounds]\n", errout_str()); check("void f(int i) {\n" " char x[10];\n" " if (i == 123) {}\n" " dostuff(x-i);\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:4:14]: (portability) Undefined behaviour, when 'i' is 123 the pointer arithmetic 'x-i' is out of bounds. [pointerOutOfBoundsCond]\n", errout_str()); check("void f(int i) {\n" " char x[10];\n" " if (i == -20) {}\n" " dostuff(x-i);\n" - "}", settings0_p); + "}\n", settings0_p); TODO_ASSERT_EQUALS("[test.cpp:4]: (portability) Undefined behaviour, when 'i' is -20 the pointer arithmetic 'x-i' is out of bounds.\n", "", errout_str()); check("void f(const char *x[10]) {\n" " return x-4;\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("", errout_str()); } @@ -4147,7 +4147,7 @@ class TestBufferOverrun : public TestFixture { " struct Foo x = {0};\n" " strcat(x.a, \"aa\");\n" " strcat(x.a, \"aa\");\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); } @@ -4160,7 +4160,7 @@ class TestBufferOverrun : public TestFixture { " char str[50];\n" " str[30] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4168,7 +4168,7 @@ class TestBufferOverrun : public TestFixture { check("struct foo {\n" " void bar() { return; }\n" " type<> member[1];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4178,7 +4178,7 @@ class TestBufferOverrun : public TestFixture { "void foo()\n" "{\n" " str[3] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:8]: (error) Array 'str[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -4187,7 +4187,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char *s; s = new char[10];\n" " s[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 's[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // ticket #1670 - false negative when using return @@ -4195,7 +4195,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " int *s; s = new int[10];\n" " return s[10];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (error) Array 's[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("struct Fred { char c[10]; };\n" @@ -4203,12 +4203,12 @@ class TestBufferOverrun : public TestFixture { "{\n" " Fred *f; f = new Fred;\n" " return f->c[10];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:16]: (error) Array 'f->c[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("static const size_t MAX_SIZE = UNAVAILABLE_TO_CPPCHECK;\n" "struct Thing { char data[MAX_SIZE]; };\n" - "char f4(const Thing& t) { return !t.data[0]; }"); + "char f4(const Thing& t) { return !t.data[0]; }\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -4218,7 +4218,7 @@ class TestBufferOverrun : public TestFixture { " buf = new char[9];\n" " buf[8] = 0;\n" " delete [] buf;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -4228,7 +4228,7 @@ class TestBufferOverrun : public TestFixture { " buf = new char[9];\n" " buf[9] = 0;\n" " delete [] buf;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:6]: (error) Array 'buf[9]' accessed at index 9, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void foo()\n" @@ -4236,7 +4236,7 @@ class TestBufferOverrun : public TestFixture { " enum E { Size = 10 };\n" " char *s; s = new char[Size];\n" " s[Size] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:6]: (error) Array 's[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void foo()\n" @@ -4244,7 +4244,7 @@ class TestBufferOverrun : public TestFixture { " enum E { ZERO };\n" " E *e; e = new E[10];\n" " e[10] = ZERO;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:6]: (error) Array 'e[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -4254,14 +4254,14 @@ class TestBufferOverrun : public TestFixture { "{\n" " char *s; s = (char *)malloc(10);\n" " s[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 's[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // ticket #842 check("void f() {\n" " int *tab4 = (int *)malloc(20 * sizeof(int));\n" " tab4[20] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // ticket #1478 @@ -4270,7 +4270,7 @@ class TestBufferOverrun : public TestFixture { " free(p);\n" " p = (char *)malloc(10);\n" " p[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:6]: (error) Array 'p[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); // ticket #1134 @@ -4278,7 +4278,7 @@ class TestBufferOverrun : public TestFixture { " int *x, i;\n" " x = (int *)malloc(10 * sizeof(int));\n" " x[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 'x[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" @@ -4288,7 +4288,7 @@ class TestBufferOverrun : public TestFixture { " tab4 = malloc(21 * sizeof(int));\n" " tab4[20] = 0;\n" " free(tab4);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -4297,49 +4297,49 @@ class TestBufferOverrun : public TestFixture { " tab4 = realloc(tab4,21 * sizeof(int));\n" " tab4[20] = 0;\n" " free(tab4);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " enum E { Size = 20 };\n" " E *tab4 = (E *)malloc(Size * 4);\n" " tab4[Size] = Size;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" " enum E { Size = 20 };\n" " E *tab4 = (E *)malloc(4 * Size);\n" " tab4[Size] = Size;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" " enum E { ZERO };\n" " E *tab4 = (E *)malloc(20 * sizeof(E));\n" " tab4[20] = ZERO;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" // #8721 " unsigned char **cache = malloc(32);\n" " cache[i] = malloc(65536);\n" " cache[i][0xFFFF] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int **a = malloc(2 * sizeof(int*));\n" " for (int i = 0; i < 3; i++)\n" " a[i] = NULL;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f() {\n" " int **a = new int*[2];\n" " for (int i = 0; i < 3; i++)\n" " a[i] = NULL;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void f(const uint8_t* a) {\n" // 10421 @@ -4358,21 +4358,21 @@ class TestBufferOverrun : public TestFixture { "{\n" " const char *s = \"123\";\n" " s[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 's[4]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void foo()\n" "{\n" " char *s; s = \"\";\n" " s[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 's[1]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); check("void foo() {\n" " const char *s = \"\";\n" " s = y();\n" " s[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" // #7718 @@ -4380,7 +4380,7 @@ class TestBufferOverrun : public TestFixture { " std::string s = \"123\";\n" " s.resize(100);\n" " s[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4390,7 +4390,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char *s = (char *)alloca(10);\n" " s[10] = 0;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4:6]: (error) Array 's[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", "", errout_str()); } /* @@ -4487,13 +4487,13 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char c[10];\n" " mymemset(c, 0, 10);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c[10];\n" " mymemset(c, 0, 11);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: c [bufferAccessOutOfBounds]\n", errout_str()); check("struct S {\n" @@ -4502,13 +4502,13 @@ class TestBufferOverrun : public TestFixture { "void f() {\n" " S s;\n" " mymemset(s.a, 0, 10);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:6:15]: (error) Buffer is accessed out of bounds: s.a [bufferAccessOutOfBounds]\n", errout_str()); check("void foo() {\n" " char s[10];\n" " mymemset(s, 0, '*');\n" - "}", settings); + "}\n", settings); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) The size argument is given as a char constant.\n" "[test.cpp:3:14]: (error) Buffer is accessed out of bounds: s [bufferAccessOutOfBounds]\n", "[test.cpp:3:14]: (error) Buffer is accessed out of bounds: s [bufferAccessOutOfBounds]\n", errout_str()); @@ -4516,65 +4516,65 @@ class TestBufferOverrun : public TestFixture { check("void f(void) {\n" " char a[10];\n" " mymemset(a+5, 0, 10);\n" - "}", settings); + "}\n", settings); TODO_ASSERT_EQUALS("[test.cpp:3:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n", "", errout_str()); // Ticket #909 check("void f(void) {\n" " char str[] = \"abcd\";\n" " mymemset(str, 0, 6);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f(void) {\n" " char str[] = \"abcd\";\n" " mymemset(str, 0, 5);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f(void) {\n" " wchar_t str[] = L\"abcd\";\n" " mymemset(str, 0, 21);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f(void) {\n" " wchar_t str[] = L\"abcd\";\n" " mymemset(str, 0, 20);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); // ticket #1659 - overflowing variable when using memcpy check("void f(void) {\n" " char c;\n" " mymemset(&c, 0, 4);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &c [bufferAccessOutOfBounds]\n", errout_str()); // ticket #2121 - buffer access out of bounds when using uint32_t check("void f(void) {\n" " unknown_type_t buf[4];\n" " mymemset(buf, 0, 100);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); // #3124 - multidimensional array check("int main() {\n" " char b[5][6];\n" " mymemset(b, 0, 5 * 6);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("int main() {\n" " char b[5][6];\n" " mymemset(b, 0, 6 * 6);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: b [bufferAccessOutOfBounds]\n", errout_str()); check("int main() {\n" " char b[5][6];\n" " mymemset(b, 0, 31);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: b [bufferAccessOutOfBounds]\n", errout_str()); // #4968 - not standard function @@ -4583,26 +4583,26 @@ class TestBufferOverrun : public TestFixture { " foo.mymemset(str, 0, 100);\n" " foo::mymemset(str, 0, 100);\n" " std::mymemset(str, 0, 100);\n" - "}", settings); + "}\n", settings); TODO_ASSERT_EQUALS("[test.cpp:5:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", "", errout_str()); // #5257 - check strings check("void f() {\n" " mymemset(\"abc\", 0, 20);\n" - "}", settings); + "}\n", settings); TODO_ASSERT_EQUALS("[test.cpp:2]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); check("void f() {\n" " mymemset(temp, \"abc\", 4);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #6816 - fp when array has known string value " char c[10] = \"c\";\n" " mymemset(c, 0, 10);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); } @@ -4624,43 +4624,43 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char c[7];\n" " mystrncpy(c, \"hello\", 7);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c[6];\n" " mystrncpy(c,\"hello\",6);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c[5];\n" " mystrncpy(c,\"hello\",6);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: c [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" " char c[6];\n" " mystrncpy(c,\"hello!\",7);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:15]: (error) Buffer is accessed out of bounds: c [bufferAccessOutOfBounds]\n", errout_str()); check("void f(unsigned int addr) {\n" " memset((void *)addr, 0, 1000);\n" - "}", settings0); // TODO: use settings? + "}\n", settings0); // TODO: use settings? ASSERT_EQUALS("", errout_str()); check("struct AB { char a[10]; };\n" "void foo(AB *ab) {\n" " mystrncpy(x, ab->a, 100);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void a(char *p) { mystrncpy(p,\"hello world!\",10); }\n" // #3168 "void b() {\n" " char buf[5];\n" " a(buf);" - "}", settings); + "}\n", settings); TODO_ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (error) Buffer is accessed out of bounds: buf\n", "", errout_str()); @@ -4686,13 +4686,13 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char str[3];\n" " mysprintf(str, \"test\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" " char str[5];\n" " mysprintf(str, \"%s\", \"abcde\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("int getnumber();\n" @@ -4700,51 +4700,51 @@ class TestBufferOverrun : public TestFixture { "{\n" " char str[5];\n" " mysprintf(str, \"%d: %s\", getnumber(), \"abcde\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:5:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" " char str[5];\n" " mysprintf(str, \"test%s\", \"\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char *str = new char[5];\n" " mysprintf(str, \"abcde\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f(int condition) {\n" " char str[5];\n" " mysprintf(str, \"test%s\", condition ? \"12\" : \"34\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f(int condition) {\n" " char str[5];\n" " mysprintf(str, \"test%s\", condition ? \"12\" : \"345\");\n" - "}", settings); + "}\n", settings); TODO_ASSERT_EQUALS("error", "", errout_str()); check("struct Foo { char a[1]; };\n" "void f() {\n" " struct Foo x;\n" " mysprintf(x.a, \"aa\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:4:14]: (error) Buffer is accessed out of bounds: x.a [bufferAccessOutOfBounds]\n", errout_str()); // ticket #900 check("void f() {\n" " char *a = new char(30);\n" " mysprintf(a, \"a\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n", errout_str()); check("void f(char value) {\n" " char *a = new char(value);\n" " mysprintf(a, \"a\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n", errout_str()); // This is out of bounds if 'sizeof(ABC)' is 1 (No padding) @@ -4752,21 +4752,21 @@ class TestBufferOverrun : public TestFixture { "void f() {\n" " struct Foo *x = malloc(sizeof(Foo));\n" " mysprintf(x->a, \"aa\");\n" - "}", settings); + "}\n", settings); TODO_ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Buffer is accessed out of bounds: x.a\n", "", errout_str()); check("struct Foo { char a[1]; };\n" "void f() {\n" " struct Foo *x = malloc(sizeof(Foo) + 10);\n" " mysprintf(x->a, \"aa\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("struct Foo { char a[1]; };\n" "void f() {\n" " struct Foo x;\n" " mysprintf(x.a, \"aa\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:4:14]: (error) Buffer is accessed out of bounds: x.a [bufferAccessOutOfBounds]\n", errout_str()); check("struct Foo {\n" // #6668 - unknown size @@ -4775,7 +4775,7 @@ class TestBufferOverrun : public TestFixture { "};" "void Foo::f() {\n" " mysprintf(a, \"abcd\");\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #901 @@ -4831,13 +4831,13 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char c[5];\n" " myfread(c, 1, 5, stdin);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c[5];\n" " myfread(c, 1, 6, stdin);\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:13]: (error) Buffer is accessed out of bounds: c [bufferAccessOutOfBounds]\n", errout_str()); } @@ -4847,7 +4847,7 @@ class TestBufferOverrun : public TestFixture { check("void f()\n" "{\n" " UnknownType *a = malloc(4);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } // extracttests.disable @@ -4859,26 +4859,26 @@ class TestBufferOverrun : public TestFixture { " baz[99] = 0;\n" " strncpy(baz, bar, 100);\n" " baz[99] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo ( char *bar ) {\n" " char baz[100];\n" " strncpy(baz, bar, 100);\n" " baz[99] = '\\0';\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo ( char *bar ) {\n" " char baz[100];\n" " strncpy(baz, bar, 100);\n" " baz[x+1] = '\\0';\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Test with invalid code that there is no segfault check("char baz[100];\n" - "strncpy(baz, \"var\", 100)"); + "strncpy(baz, \"var\", 100)\n"); ASSERT_EQUALS("", errout_str()); // Test that there are no duplicate error messages @@ -4887,7 +4887,7 @@ class TestBufferOverrun : public TestFixture { " strncpy(baz, bar, 100);\n" " foo(baz);\n" " foo(baz);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning, inconclusive) The buffer 'baz' may not be null-terminated after the call to strncpy(). [terminateStrncpy]\n", errout_str()); } @@ -4897,7 +4897,7 @@ class TestBufferOverrun : public TestFixture { " strncpy(baz, bar, 100);\n" " bar[99] = 0;\n" " return strdup(baz);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning, inconclusive) The buffer 'baz' may not be null-terminated after the call to strncpy(). [terminateStrncpy]\n", errout_str()); } @@ -4920,13 +4920,13 @@ class TestBufferOverrun : public TestFixture { check("void bar() {\n" " char buf[4];\n" " strncpy(buf, \"ab\", 4);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void bar() {\n" " char buf[4];\n" " strncpy(buf, \"abcde\", 4);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning, inconclusive) The buffer 'buf' may not be null-terminated after the call to strncpy(). [terminateStrncpy]\n", errout_str()); } @@ -4952,13 +4952,13 @@ class TestBufferOverrun : public TestFixture { check("void foo() {\n" " char c[6];\n" " strncpy(&c, \"hello!\", 6);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (warning, inconclusive) The buffer 'c' may not be null-terminated after the call to strncpy(). [terminateStrncpy]\n", errout_str()); check("void foo() {\n" " char c[6];\n" " strncpy(&c, \"hello\\0\", 6);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4986,7 +4986,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char a[10];\n" " f2(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5002,7 +5002,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " struct A *str;\n" " str = malloc(4);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5014,12 +5014,12 @@ class TestBufferOverrun : public TestFixture { "void b() {\n" " char arr[64];\n" " a(arr);\n" - "}"); + "}\n"); } void crash3() { check("struct b { unknown v[0]; };\n" - "void d() { struct b *f; f = malloc(108); }"); + "void d() { struct b *f; f = malloc(108); }\n"); } void crash4() { // #8679 @@ -5027,13 +5027,13 @@ class TestBufferOverrun : public TestFixture { "int main() { " " thread_local_var = malloc(1337); " " return 0; " - "}"); + "}\n"); check("thread_local void *thread_local_var; " "int main() { " " thread_local_var = malloc(1337); " " return 0; " - "}"); + "}\n"); } void crash5() { // 8644 - token has varId() but variable() is null @@ -5041,19 +5041,19 @@ class TestBufferOverrun : public TestFixture { " void b(char **dst) {\n" " *dst = malloc(50);\n" " }\n" - "}"); + "}\n"); } void crash6() { check("void start(char* name) {\n" "char snapname[64] = { 0 };\n" "strncpy(snapname, \"snapshot\", arrayLength(snapname));\n" - "}"); + "}\n"); } void crash7() { // 9073 - [ has no astParent check("char x[10];\n" - "void f() { x[10]; }"); + "void f() { x[10]; }\n"); } void insecureCmdLineArgs() { @@ -5067,7 +5067,7 @@ class TestBufferOverrun : public TestFixture { " free(p);\n" " }\n" " return 0;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char *argv[])\n" @@ -5080,112 +5080,112 @@ class TestBufferOverrun : public TestFixture { " free(p);\n" " }\n" " return 0;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(const int argc, char* argv[])\n" "{\n" " char prog[10];\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, const char* argv[])\n" "{\n" " char prog[10];\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(const int argc, const char* argv[])\n" "{\n" " char prog[10];\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char* argv[])\n" "{\n" " char prog[10] = {'\\0'};\n" " strcat(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char **argv, char **envp)\n" "{\n" " char prog[10];\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, const char *const *const argv, char **envp)\n" "{\n" " char prog[10];\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(const int argc, const char *const *const argv, const char *const *const envp)\n" "{\n" " char prog[10];\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char **argv, char **envp)\n" "{\n" " char prog[10] = {'\\0'};\n" " strcat(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(const int argc, const char **argv, char **envp)\n" "{\n" " char prog[10] = {'\\0'};\n" " strcat(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, const char **argv, char **envp)\n" "{\n" " char prog[10] = {'\\0'};\n" " strcat(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(const int argc, char **argv, char **envp)\n" "{\n" " char prog[10] = {'\\0'};\n" " strcat(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char **options)\n" "{\n" " char prog[10];\n" " strcpy(prog, options[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char **options)\n" "{\n" " char prog[10] = {'\\0'};\n" " strcat(prog, options[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char **options)\n" "{\n" " char prog[10];\n" " strcpy(prog, *options);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char **options)\n" "{\n" " char prog[10];\n" " strcpy(prog+3, *options);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); check("int main(int argc, char **argv, char **envp)\n" @@ -5193,7 +5193,7 @@ class TestBufferOverrun : public TestFixture { " char prog[10];\n" " if (strlen(argv[0]) < 10)\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int main(int argc, char **argv, char **envp)\n" @@ -5201,7 +5201,7 @@ class TestBufferOverrun : public TestFixture { " char prog[10] = {'\\0'};\n" " if (10 > strlen(argv[0]))\n" " strcat(prog, argv[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int main(int argc, char **argv, char **envp)\n" @@ -5209,7 +5209,7 @@ class TestBufferOverrun : public TestFixture { " char prog[10];\n" " argv[0][0] = '\\0';\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5835 @@ -5217,18 +5217,18 @@ class TestBufferOverrun : public TestFixture { " char prog[10];\n" " strcpy(prog, argv[0]);\n" " strcpy(prog, argv[0]);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Buffer overrun possible for long command line arguments.\n" "[test.cpp:4]: (error) Buffer overrun possible for long command line arguments.\n", "", errout_str()); // #7964 check("int main(int argc, char *argv[]) {\n" " char *strcpy();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int main(int argc, char *argv[]) {\n" " char *strcat();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5236,33 +5236,33 @@ class TestBufferOverrun : public TestFixture { check("void f(char *a) {\n" " char *b = new char[strlen(a)];\n" " strcpy(b, a);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); check("void f(char *a) {\n" " char *b = new char[strlen(a) + 1];\n" " strcpy(b, a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char *a) {\n" " char *b = new char[strlen(a)];\n" " a[0] = '\\0';\n" " strcpy(b, a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char *a) {\n" " char *b = (char *)malloc(strlen(a));\n" " b = realloc(b, 10000);\n" " strcpy(b, a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char *a) {\n" " char *b = (char *)malloc(strlen(a));\n" " strcpy(b, a);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); check("void f(char *a) {\n" @@ -5270,31 +5270,31 @@ class TestBufferOverrun : public TestFixture { " {\n" " strcpy(b, a);\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); check("void f(char *a) {\n" " char *b = (char *)malloc(strlen(a) + 1);\n" " strcpy(b, a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char *a, char *c) {\n" " char *b = (char *)realloc(c, strlen(a));\n" " strcpy(b, a);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); check("void f(char *a, char *c) {\n" " char *b = (char *)realloc(c, strlen(a) + 1);\n" " strcpy(b, a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char *a) {\n" " char *b = (char *)malloc(strlen(a));\n" " strcpy(b, a);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); } @@ -5308,7 +5308,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " X x;\n" " x.buf[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class A {\n" @@ -5320,7 +5320,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " A::X x;\n" " x.buf[10] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:10]: (error) Array 'x.buf[10]' accessed at index 10, which is out of bounds. [arrayIndexOutOfBounds]\n", errout_str()); } @@ -5339,68 +5339,68 @@ class TestBufferOverrun : public TestFixture { check("void f(const char s[]) {\n" " if (s[i] == 'x' && i < y) {\n" " }" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // No message because i is unknown and thus gets no varid. Avoid an internalError here. check("void f(const char s[], int i) {\n" " if (s[i] == 'x' && i < y) {\n" " }" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) Array index 'i' is used before limits check. [arrayIndexThenCheck]\n", errout_str()); check("void f(const char s[]) {\n" " for (int i = 0; s[i] == 'x' && i < y; ++i) {\n" " }" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (style) Array index 'i' is used before limits check. [arrayIndexThenCheck]\n", errout_str()); check("void f(const int a[], unsigned i) {\n" " if((a[i] < 2) && (i <= 42)) {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) Array index 'i' is used before limits check. [arrayIndexThenCheck]\n", errout_str()); check("void f(const int a[], unsigned i) {\n" " if((a[i] < 2) && (42 >= i)) {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) Array index 'i' is used before limits check. [arrayIndexThenCheck]\n", errout_str()); // extracttests.start: int elen; check("void f(char* e, int y) {\n" " if (e[y] == '/' && elen > y + 1 && e[y + 1] == '?') {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // extracttests.start: int foo(int); int func(int); check("void f(const int a[], unsigned i) {\n" " if(a[i] < func(i) && i <= 42) {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Array index 'i' is used before limits check. [arrayIndexThenCheck]\n", errout_str()); check("void f(const int a[], unsigned i) {\n" " if (i <= 42 && a[i] < func(i)) {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const int a[], unsigned i) {\n" " if (foo(a[i] + 3) < func(i) && i <= 42) {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style) Array index 'i' is used before limits check. [arrayIndexThenCheck]\n", errout_str()); check("void f(int i) {\n" // sizeof " sizeof(a)/sizeof(a[i]) && i < 10;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // extracttests.start: extern int buf[]; check("void f(int i) {\n" // ?: " if ((i < 10 ? buf[i] : 1) && (i < 5 ? buf[i] : 5)){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5423,19 +5423,19 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char c[6];\n" " strncpy(c,\"hello!\",6);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning, inconclusive) The buffer 'c' may not be null-terminated after the call to strncpy(). [terminateStrncpy]\n", errout_str()); check("void f() {\n" " char c[6];\n" " memcpy(c,\"hello!\",6);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) The buffer 'c' may not be null-terminated after the call to memcpy().\n", "", errout_str()); check("void f() {\n" " char c[6];\n" " memmove(c,\"hello!\",6);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) The buffer 'c' may not be null-terminated after the call to memmove().\n", "", errout_str()); } @@ -5445,7 +5445,7 @@ class TestBufferOverrun : public TestFixture { " int *a;\n" " a = new int[-1];\n" " delete [] a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:8]: (error) Memory allocation size is negative. [negativeMemoryAllocationSize]\n", errout_str()); check("void f()\n" @@ -5453,7 +5453,7 @@ class TestBufferOverrun : public TestFixture { " int *a;\n" " a = (int *)malloc( -10 );\n" " free(a);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4:8]: (error) Memory allocation size is negative. [negativeMemoryAllocationSize]\n", "", errout_str()); check("void f()\n" @@ -5461,14 +5461,14 @@ class TestBufferOverrun : public TestFixture { " int *a;\n" " a = (int *)malloc( -10);\n" " free(a);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4:8]: (error) Memory allocation size is negative. [negativeMemoryAllocationSize]\n", "", errout_str()); check("void f()\n" "{\n" " int *a;\n" " a = (int *)alloca( -10 );\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4:8]: (error) Memory allocation size is negative. [negativeMemoryAllocationSize]\n", "", errout_str()); check("int* f(int n) {\n" // #11145 @@ -5485,14 +5485,14 @@ class TestBufferOverrun : public TestFixture { check("void f(int sz) {\n" // #1760 - VLA " int a[sz];\n" "}\n" - "void x() { f(-100); }"); + "void x() { f(-100); }\n"); ASSERT_EQUALS("[test.cpp:2:8]: (error) Declaration of array 'a' with negative size is undefined behaviour [negativeArraySize]\n", errout_str()); // don't warn for constant sizes -> this is a compiler error so this is used for static assertions for instance check("int x, y;\n" "int a[-1];\n" "int b[x?1:-1];\n" - "int c[x?y:-1];"); + "int c[x?y:-1];\n"); ASSERT_EQUALS("", errout_str()); } @@ -5500,7 +5500,7 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char arr[10];\n" " char *p = arr + 20;\n" - "}", settings0_p); + "}\n", settings0_p); ASSERT_EQUALS("[test.cpp:3:19]: (portability) Undefined behaviour, pointer arithmetic 'arr+20' is out of bounds. [pointerOutOfBounds]\n", errout_str()); check("char(*g())[1];\n" // #7950 @@ -5540,7 +5540,7 @@ class TestBufferOverrun : public TestFixture { "int main() {\n" " char *s = malloc(4);\n" " dostuff(s);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:11] -> [test.cpp:7:10] -> [test.cpp:2:3]: (error) Array index out of bounds; buffer 'p' is accessed at offset -3. [ctuArrayIndex]\n", errout_str()); ctu("void dostuff(char *p) {\n" @@ -5550,7 +5550,7 @@ class TestBufferOverrun : public TestFixture { "int main() {\n" " char *s = malloc(4);\n" " dostuff(s);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:11] -> [test.cpp:7:10] -> [test.cpp:2:3]: (error) Array index out of bounds; 'p' buffer size is 4 and it is accessed at offset 4. [ctuArrayIndex]\n", errout_str()); ctu("void f(int* p) {\n" // #10415 @@ -5582,7 +5582,7 @@ class TestBufferOverrun : public TestFixture { "int main() {\n" " char str[4];\n" " dostuff(str);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:10] -> [test.cpp:2:5]: (error) Array index out of bounds; 'p' buffer size is 4 and it is accessed at offset 10. [ctuArrayIndex]\n", errout_str()); ctu("static void memclr( char *data )\n" @@ -5594,7 +5594,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char str[5];\n" " memclr( str );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:11] -> [test.cpp:3:5]: (error) Array index out of bounds; 'data' buffer size is 5 and it is accessed at offset 10. [ctuArrayIndex]\n", errout_str()); ctu("static void memclr( int i, char *data )\n" @@ -5606,7 +5606,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char str[5];\n" " memclr( 0, str );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:11] -> [test.cpp:3:5]: (error) Array index out of bounds; 'data' buffer size is 5 and it is accessed at offset 10. [ctuArrayIndex]\n", errout_str()); ctu("static void memclr( int i, char *data )\n" @@ -5618,7 +5618,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char str[5];\n" " memclr( 10, str );\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (possible error) Array index out of bounds.\n", "", errout_str()); @@ -5633,7 +5633,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " char str[5];\n" " memclr( str, 5 );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #2097 @@ -5647,7 +5647,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " int p[3];\n" " foo(p+1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9112 @@ -5660,7 +5660,7 @@ class TestBufferOverrun : public TestFixture { "{\n" " u8 macstrbuf[17] = { 0 };\n" " get_mac_address(macstrbuf);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9788 @@ -5717,7 +5717,7 @@ class TestBufferOverrun : public TestFixture { "int main() {\n" " int x = 4;\n" " dostuff(&x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:10] -> [test.cpp:2:5]: (error) Array index out of bounds; 'p' buffer size is 4 and it is accessed at offset 40. [ctuArrayIndex]\n", errout_str()); } @@ -5726,7 +5726,7 @@ class TestBufferOverrun : public TestFixture { "int main() {\n" " int x[3];\n" " dostuff(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10] -> [test.cpp:1:28]: (error) Pointer arithmetic overflow; 'p' buffer size is 12 [ctuPointerArith]\n", errout_str()); ctu("void f(const char *p) {\n" // #11361 @@ -5745,7 +5745,7 @@ class TestBufferOverrun : public TestFixture { "void f() {\n" " char a[10] = {};\n" " g(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: error: Pointer arithmetic overflow; 'p' buffer size is 10 [ctuPointerArith]\n" "[test.cpp:6:6]: note: Calling function g, 1st argument is accessed out of bounds\n" "[test.cpp:2:12]: note: Using argument p\n", @@ -5756,7 +5756,7 @@ class TestBufferOverrun : public TestFixture { check("int f() {\n" " int i;\n" " return (&i)[1];\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:13] -> [test.cpp:3:16]: (error) The address of variable 'i' is accessed at non-zero index. [objectIndex]\n", errout_str()); @@ -5764,7 +5764,7 @@ class TestBufferOverrun : public TestFixture { check("int f(int j) {\n" " int i;\n" " return (&i)[j];\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:13] -> [test.cpp:3:16]: (warning) The address of variable 'i' might be accessed at non-zero index. [objectIndex]\n", errout_str()); @@ -5772,34 +5772,34 @@ class TestBufferOverrun : public TestFixture { check("int f() {\n" " int i;\n" " return (&i)[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int * i) {\n" " return i[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(std::vector i) {\n" " return i[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(std::vector i) {\n" " return i.data()[1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int* f(std::vector& i) {\n" " return &(i[1]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int i; int j; };\n" "int f() {\n" " A x;\n" " return (&x.i)[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int i; int j; };\n" @@ -5807,7 +5807,7 @@ class TestBufferOverrun : public TestFixture { " A x;\n" " int * i = &x.i;\n" " return i[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -5815,7 +5815,7 @@ class TestBufferOverrun : public TestFixture { " std::map m;\n" " m[0] = &x;\n" " m[1] = &x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" @@ -5823,7 +5823,7 @@ class TestBufferOverrun : public TestFixture { " std::map m;\n" " m[0] = &x;\n" " return m[0][1];\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:10] -> [test.cpp:5:14]: (error) The address of variable 'x' is accessed at non-zero index. [objectIndex]\n", errout_str()); @@ -5833,7 +5833,7 @@ class TestBufferOverrun : public TestFixture { " std::map m;\n" " m[0] = &x;\n" " return m[0][1];\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:10] -> [test.cpp:5:14]: (error) The address of variable 'x' is accessed at non-zero index. [objectIndex]\n", errout_str()); @@ -5844,7 +5844,7 @@ class TestBufferOverrun : public TestFixture { " m[0] = &x;\n" " m[1] = y;\n" " return m[1][1];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void print(char** test);\n" @@ -5914,7 +5914,7 @@ class TestBufferOverrun : public TestFixture { "void h() {\n" " const uint8_t u = 4;\n" " f(&u, N);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("uint32_t f(uint32_t u) {\n" // #10154 @@ -6008,7 +6008,7 @@ class TestBufferOverrun : public TestFixture { "if (pipe(pipefd) == -1) {\n" " return;\n" " }\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: pipefd [bufferAccessOutOfBounds]\n", errout_str()); check("void f(){\n" @@ -6016,7 +6016,7 @@ class TestBufferOverrun : public TestFixture { "if (pipe(pipefd) == -1) {\n" " return;\n" " }\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); check("void f(){\n" @@ -6024,7 +6024,7 @@ class TestBufferOverrun : public TestFixture { "if (pipe((int*)pipefd) == -1) {\n" " return;\n" " }\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: (int*)pipefd [bufferAccessOutOfBounds]\n", errout_str()); check("void f(){\n" @@ -6032,7 +6032,7 @@ class TestBufferOverrun : public TestFixture { "if (pipe((int*)pipefd) == -1) {\n" " return;\n" " }\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); } }; diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index 7d4a17489fc..0c9c8dd4b5b 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -57,7 +57,7 @@ class TestCharVar : public TestFixture { "{\n" " unsigned char ch = 0x80;\n" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int buf[256];\n" @@ -65,7 +65,7 @@ class TestCharVar : public TestFixture { "{\n" " char ch = 0x80;\n" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (portability) 'char' type used as array index. [unknownSignCharArrayIndex]\n", errout_str()); check("int buf[256];\n" @@ -73,7 +73,7 @@ class TestCharVar : public TestFixture { "{\n" " char ch = 0;\n" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int buf[256];\n" @@ -81,7 +81,7 @@ class TestCharVar : public TestFixture { "{\n" " signed char ch = 0;\n" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int buf[256];\n" @@ -89,67 +89,67 @@ class TestCharVar : public TestFixture { "{\n" " char ch = 0x80;\n" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (portability) 'char' type used as array index. [unknownSignCharArrayIndex]\n", errout_str()); check("int buf[256];\n" "void foo(signed char ch)\n" "{\n" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int buf[256];\n" "void foo(char ch)\n" "{\n" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char* buf)\n" "{\n" " char ch = 0x80;" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:24]: (portability) 'char' type used as array index. [unknownSignCharArrayIndex]\n", errout_str()); check("void foo(char* buf)\n" "{\n" " char ch = 0;" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char* buf)\n" "{\n" " buf['A'] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char* buf, char ch)\n" "{\n" " buf[ch] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int flags[256];\n" "void foo(const char* str)\n" "{\n" " flags[*str] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int flags[256];\n" "void foo(const char* str)\n" "{\n" " flags[(unsigned char)*str] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const char str[])\n" "{\n" " map[str] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -159,7 +159,7 @@ class TestCharVar : public TestFixture { "void bar(int i) {\n" " const char *s = \"abcde\";\n" " foo(s[i]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -167,32 +167,32 @@ class TestCharVar : public TestFixture { check("void foo(int *result) {\n" " signed char ch = -1;\n" " *result = a | ch;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (warning) When using 'char' variables in bit operations, sign extension can generate unexpected results. [charBitOp]\n", errout_str()); check("void foo(int *result) {\n" " unsigned char ch = -1;\n" " *result = a | ch;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char *result) {\n" " signed char ch = -1;\n" " *result = a | ch;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // 0x03 & .. check("void foo(int *result) {\n" " signed char ch = -1;\n" " *result = 0x03 | ch;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:20]: (warning) When using 'char' variables in bit operations, sign extension can generate unexpected results. [charBitOp]\n", errout_str()); check("void foo(int *result) {\n" " signed char ch = -1;\n" " *result = 0x03 & ch;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } }; diff --git a/test/testclass.cpp b/test/testclass.cpp index 457ab5932fe..451502c2164 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -282,25 +282,25 @@ class TestClass : public TestFixture { "{\n" " A(const A& other) { }\n" " A& operator=(const A& other) { return *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyCtorAndEqOperator("class A\n" "{\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyCtorAndEqOperator("class A\n" "{\n" " A(const A& other) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyCtorAndEqOperator("class A\n" "{\n" " A& operator=(const A& other) { return *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -308,7 +308,7 @@ class TestClass : public TestFixture { "{\n" " A(const A& other) { }\n" " int x;\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:1]: (warning) The class 'A' has 'copy constructor' but lack of 'operator='.\n", "", errout_str()); // TODO the error message should be clarified. It should say something like 'copy constructor is empty and will not assign i and therefore the behaviour is different to the default assignment operator' @@ -316,7 +316,7 @@ class TestClass : public TestFixture { "{\n" " A& operator=(const A& other) { return *this; }\n" " int x;\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:1]: (warning) The class 'A' has 'operator=' but lack of 'copy constructor'.\n", "", errout_str()); // TODO the error message should be clarified. It should say something like 'assignment operator does not assign i and therefore the behaviour is different to the default copy constructor' @@ -324,7 +324,7 @@ class TestClass : public TestFixture { "{\n" " A& operator=(const int &x) { this->x = x; return *this; }\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyCtorAndEqOperator("class A {\n" @@ -344,7 +344,7 @@ class TestClass : public TestFixture { " B(const B & b) :A(b) { }\n" "private:\n" " static int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #7987 - Don't show warning when there is a move constructor @@ -355,14 +355,14 @@ class TestClass : public TestFixture { " test = std::move(s.test);\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #8337 - False positive in copy constructor detection checkCopyCtorAndEqOperator("struct StaticListNode {\n" " StaticListNode(StaticListNode*& prev) : m_next(0) {}\n" " StaticListNode* m_next;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -386,7 +386,7 @@ class TestClass : public TestFixture { " explicit Class(int i) { }\n" " explicit Class(const std::string&) { }\n" " Class(int a, int b) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkExplicitConstructors("class Class {\n" @@ -394,7 +394,7 @@ class TestClass : public TestFixture { " explicit Class(const Class& other) { }\n" " explicit Class(Class&& other) { }\n" " virtual int i() = 0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkExplicitConstructors("class Class {\n" @@ -402,37 +402,37 @@ class TestClass : public TestFixture { " Class(const Class& other) = delete;\n" " Class(Class&& other) = delete;\n" " virtual int i() = 0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkExplicitConstructors("class Class {\n" " Class(int i) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Class 'Class' has a constructor with 1 argument that is not explicit. [noExplicitConstructor]\n", errout_str()); checkExplicitConstructors("class Class {\n" " Class(const Class& other) { }\n" " virtual int i() = 0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkExplicitConstructors("class Class {\n" " Class(Class&& other) { }\n" " virtual int i() = 0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #6585 checkExplicitConstructors("class Class {\n" " private: Class(const Class&);\n" " virtual int i() = 0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkExplicitConstructors("class Class {\n" " public: Class(const Class&);\n" " virtual int i() = 0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #7465: Error properly reported in templates @@ -443,7 +443,7 @@ class TestClass : public TestFixture { "int main() {\n" " Test test;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (style) Struct 'Test < int >' has a constructor with 1 argument that is not explicit. [noExplicitConstructor]\n", errout_str()); // #7465: No error for copy or move constructors @@ -456,7 +456,7 @@ class TestClass : public TestFixture { "int main() {\n" " Test test;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8600 @@ -464,12 +464,12 @@ class TestClass : public TestFixture { "struct A::B {\n" " B() = default;\n" " B(const B&) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkExplicitConstructors("struct A{" - " A(int, int y=2) {}" - "};"); + " A(int, int y=2) {}\n" + "};\n"); ASSERT_EQUALS("[test.cpp:1:14]: (style) Struct 'A' has a constructor with 1 argument that is not explicit. [noExplicitConstructor]\n", errout_str()); checkExplicitConstructors("struct Foo {\n" // #10515 @@ -541,7 +541,7 @@ class TestClass : public TestFixture { "};\n" "struct Derived : Base {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkDuplInheritedMembers("class Base {\n" @@ -550,7 +550,7 @@ class TestClass : public TestFixture { "};\n" "struct Derived : Base {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:6:8]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base'. [duplInheritedMember]\n", errout_str()); checkDuplInheritedMembers("class Base {\n" @@ -559,7 +559,7 @@ class TestClass : public TestFixture { "};\n" "struct Derived : public Base {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:6:8]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base'. [duplInheritedMember]\n", errout_str()); checkDuplInheritedMembers("class Base0 {\n" @@ -570,7 +570,7 @@ class TestClass : public TestFixture { "};\n" "struct Derived : Base0, Base1 {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkDuplInheritedMembers("class Base0 {\n" @@ -582,7 +582,7 @@ class TestClass : public TestFixture { "};\n" "struct Derived : Base0, Base1 {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:9:8]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base0'. [duplInheritedMember]\n", errout_str()); checkDuplInheritedMembers("class Base0 {\n" @@ -595,7 +595,7 @@ class TestClass : public TestFixture { "};\n" "struct Derived : Base0, Base1 {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:10:8]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base0'. [duplInheritedMember]\n" "[test.cpp:7:8] -> [test.cpp:10:8]: (warning) The struct 'Derived' defines member variable with name 'x' also defined in its parent class 'Base1'. [duplInheritedMember]\n", errout_str()); @@ -604,7 +604,7 @@ class TestClass : public TestFixture { "};\n" "struct Derived : Base {\n" " int y;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkDuplInheritedMembers("class A {\n" @@ -612,20 +612,20 @@ class TestClass : public TestFixture { "};\n" "struct B {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // Unknown 'Base' class checkDuplInheritedMembers("class Derived : public UnknownBase {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkDuplInheritedMembers("class Base {\n" " int x;\n" "};\n" "class Derived : public Base {\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #6692 @@ -637,7 +637,7 @@ class TestClass : public TestFixture { " struct SWibble : public test1::wibble {\n" " int Value;\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9957 @@ -651,12 +651,12 @@ class TestClass : public TestFixture { "};\n" "class Derived2 : public Derived1 {\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:13] -> [test.cpp:10:9]: (warning) The class 'Derived2' defines member variable with name 'i' also defined in its parent class 'Base'. [duplInheritedMember]\n", errout_str()); // don't crash on recursive template checkDuplInheritedMembers("template\n" - "struct BitInt : public BitInt { };"); + "struct BitInt : public BitInt { };\n"); ASSERT_EQUALS("", errout_str()); // don't crash on recursive template @@ -671,7 +671,7 @@ class TestClass : public TestFixture { " template \n" " struct fn_traits\n" " : public fn_traits {};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10594 @@ -776,7 +776,7 @@ class TestClass : public TestFixture { " }\n" " F&operator=(const F&);\n" " ~F();\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:5]: (warning) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory.\n", "", errout_str()); checkCopyConstructor("class F {\n" @@ -789,7 +789,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:4:7]: (warning) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory. [copyCtorPointerCopying]\n" "[test.cpp:3] -> [test.cpp:7]: (warning) Copy constructor does not allocate memory for member 'p' although memory has been allocated in other constructors.\n", "[test.cpp:4:7]: (warning) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory. [copyCtorPointerCopying]\n" @@ -809,7 +809,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:5]: (warning) Value of pointer 'p', which points to allocated memory, is copied in copy constructor instead of allocating new memory.\n" "[test.cpp:5] -> [test.cpp:10]: (warning) Copy constructor does not allocate memory for member 'p' although memory has been allocated in other constructors.\n", "" @@ -839,7 +839,7 @@ class TestClass : public TestFixture { " }\n" " ~kalci();\n" " kalci& operator=(const kalci&kalci);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("class F\n" @@ -864,7 +864,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:14] -> [test.cpp:11]: (warning) Copy constructor does not allocate memory for member 'd' although memory has been allocated in other constructors.\n", "", errout_str()); checkCopyConstructor("class F {\n" @@ -878,7 +878,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("class F {\n" @@ -892,7 +892,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:4]: (warning) Copy constructor does not allocate memory for member 'd' although memory has been allocated in other constructors.\n", "", errout_str()); checkCopyConstructor("class F\n" @@ -907,7 +907,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:8]: (warning) Class 'F' does not have a copy constructor which is recommended since it has dynamic memory/resource management.\n", "", errout_str()); checkCopyConstructor("class F\n" @@ -931,7 +931,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("class F : E\n" @@ -942,7 +942,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("class E { E(E&); };\n" // non-copyable @@ -954,7 +954,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("class E {};\n" @@ -965,7 +965,7 @@ class TestClass : public TestFixture { " }\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:7]: (warning) Class 'F' does not have a copy constructor which is recommended since it has dynamic memory/resource management. [noCopyConstructor]\n", errout_str()); checkCopyConstructor("class F {\n" @@ -976,7 +976,7 @@ class TestClass : public TestFixture { " F(F& f);\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("class F {\n" @@ -984,7 +984,7 @@ class TestClass : public TestFixture { " F() : p(malloc(100)) {}\n" " ~F();\n" " F& operator=(const F&f);\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (warning) Class 'F' does not have a copy constructor which is recommended since it has dynamic memory/resource management. [noCopyConstructor]\n", errout_str()); // #7198 @@ -993,7 +993,7 @@ class TestClass : public TestFixture { " F() {\n" " p = malloc(100);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1010,7 +1010,7 @@ class TestClass : public TestFixture { " ~Vector();\n" " Vector& operator=(const Vector&v);\n" " _Tp* _M_finish;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1021,7 +1021,7 @@ class TestClass : public TestFixture { " F(const F &f) = delete;\n" " F&operator=(const F &f);\n" " ~F();\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("struct F {\n" @@ -1030,7 +1030,7 @@ class TestClass : public TestFixture { " F(const F &f) = default;\n" " F&operator=(const F &f);\n" " ~F();\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (warning) Struct 'F' has dynamic memory/resource allocation(s). The copy constructor is explicitly defaulted but the default copy constructor does not work well. It is recommended to define or delete the copy constructor. [noCopyConstructor]\n", errout_str()); } @@ -1053,7 +1053,7 @@ class TestClass : public TestFixture { " ~Foo() { delete m_ptr; }\n" "private:\n" " int* m_ptr;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1066,7 +1066,7 @@ class TestClass : public TestFixture { " ~Foo() { delete m_ptr; }\n" "private:\n" " int* m_ptr;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("class Copyable {};\n" @@ -1077,7 +1077,7 @@ class TestClass : public TestFixture { " ~Foo() { delete m_ptr; }\n" "private:\n" " int* m_ptr;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1148,7 +1148,7 @@ class TestClass : public TestFixture { " F() { c = malloc(100); }\n" " F(const F &f);\n" " ~F();\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (warning) Struct 'F' does not have a operator= which is recommended since it has dynamic memory/resource management. [noOperatorEq]\n", errout_str()); // defaulted operator= @@ -1158,7 +1158,7 @@ class TestClass : public TestFixture { " F(const F &f);\n" " F &operator=(const F &f) = default;\n" " ~F();\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (warning) Struct 'F' has dynamic memory/resource allocation(s). The operator= is explicitly defaulted but the default operator= does not work well. It is recommended to define or delete the operator=. [noOperatorEq]\n", errout_str()); // deleted operator= @@ -1168,7 +1168,7 @@ class TestClass : public TestFixture { " F(const F &f);\n" " F &operator=(const F &f) = delete;\n" " ~F();\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // base class deletes operator= @@ -1177,7 +1177,7 @@ class TestClass : public TestFixture { " F() { c = malloc(100); }\n" " F(const F &f);\n" " ~F();\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("struct S {\n" @@ -1196,7 +1196,7 @@ class TestClass : public TestFixture { " F() { c = malloc(100); }\n" " F(const F &f);\n" " F&operator=(const F&);" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (warning) Struct 'F' does not have a destructor which is recommended since it has dynamic memory/resource management. [noDestructor]\n", errout_str()); checkCopyConstructor("struct F {\n" @@ -1204,7 +1204,7 @@ class TestClass : public TestFixture { " F() { c = new C; }\n" " F(const F &f);\n" " F&operator=(const F&);" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkCopyConstructor("struct F {\n" @@ -1212,7 +1212,7 @@ class TestClass : public TestFixture { " F() { i = new int(); }\n" " F(const F &f);\n" " F& operator=(const F&);" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (warning) Struct 'F' does not have a destructor which is recommended since it has dynamic memory/resource management. [noDestructor]\n", errout_str()); checkCopyConstructor("struct Data { int x; int y; };\n" @@ -1221,7 +1221,7 @@ class TestClass : public TestFixture { " F() { c = new Data; }\n" " F(const F &f);\n" " F&operator=(const F&);" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:10]: (warning) Struct 'F' does not have a destructor which is recommended since it has dynamic memory/resource management. [noDestructor]\n", errout_str()); // defaulted destructor @@ -1231,7 +1231,7 @@ class TestClass : public TestFixture { " F(const F &f);\n" " F &operator=(const F &f);\n" " ~F() = default;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (warning) Struct 'F' has dynamic memory/resource allocation(s). The destructor is explicitly defaulted but the default destructor does not work well. It is recommended to define the destructor. [noDestructor]\n", errout_str()); // deleted destructor @@ -1241,7 +1241,7 @@ class TestClass : public TestFixture { " F(const F &f);\n" " F &operator=(const F &f);\n" " ~F() = delete;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1264,7 +1264,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " A & operator=(const A &a) { return *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1272,7 +1272,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " A & operator=(const A &a) { return a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:9]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1281,7 +1281,7 @@ class TestClass : public TestFixture { "public:\n" " A & operator=(const A &);\n" "};\n" - "A & A::operator=(const A &a) { return *this; }"); + "A & A::operator=(const A &a) { return *this; }\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1290,7 +1290,7 @@ class TestClass : public TestFixture { "public:\n" " A & operator=(const A &a);\n" "};\n" - "A & A::operator=(const A &a) { return *this; }"); + "A & A::operator=(const A &a) { return *this; }\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1299,7 +1299,7 @@ class TestClass : public TestFixture { "public:\n" " A & operator=(const A &);\n" "};\n" - "A & A::operator=(const A &a) { return a; }"); + "A & A::operator=(const A &a) { return a; }\n"); ASSERT_EQUALS("[test.cpp:6:8]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1308,7 +1308,7 @@ class TestClass : public TestFixture { "public:\n" " A & operator=(const A &a);\n" "};\n" - "A & A::operator=(const A &a) { return a; }"); + "A & A::operator=(const A &a) { return a; }\n"); ASSERT_EQUALS("[test.cpp:6:8]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1320,7 +1320,7 @@ class TestClass : public TestFixture { " public:\n" " B & operator=(const B &b) { return *this; }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1332,7 +1332,7 @@ class TestClass : public TestFixture { " public:\n" " B & operator=(const B &b) { return b; }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:13]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1345,7 +1345,7 @@ class TestClass : public TestFixture { " B & operator=(const B &);\n" " };\n" "};\n" - "A::B & A::B::operator=(const A::B &b) { return *this; }"); + "A::B & A::B::operator=(const A::B &b) { return *this; }\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1358,7 +1358,7 @@ class TestClass : public TestFixture { " B & operator=(const B &);\n" " };\n" "};\n" - "A::B & A::B::operator=(const A::B &b) { return b; }"); + "A::B & A::B::operator=(const A::B &b) { return b; }\n"); ASSERT_EQUALS("[test.cpp:10:14]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1368,7 +1368,7 @@ class TestClass : public TestFixture { "class A::B\n" "{\n" " B & operator=(const B & b) { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:7]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1379,7 +1379,7 @@ class TestClass : public TestFixture { "{\n" " B & operator=(const B &);\n" "};\n" - "A::B & A::B::operator=(const A::B & b) { return b; }"); + "A::B & A::B::operator=(const A::B & b) { return b; }\n"); ASSERT_EQUALS("[test.cpp:8:14]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1389,7 +1389,7 @@ class TestClass : public TestFixture { "class A::B\n" "{\n" " A::B & operator=(const A::B & b) { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:10]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1400,7 +1400,7 @@ class TestClass : public TestFixture { "{\n" " A::B & operator=(const A::B &);\n" "};\n" - "A::B & A::B::operator=(const A::B & b) { return b; }"); + "A::B & A::B::operator=(const A::B & b) { return b; }\n"); ASSERT_EQUALS("[test.cpp:8:14]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1410,7 +1410,7 @@ class TestClass : public TestFixture { "class A::B\n" "{\n" " B & operator=(const B & b) { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:7]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1421,7 +1421,7 @@ class TestClass : public TestFixture { "{\n" " B & operator=(const B &);\n" "};\n" - "A::B & A::B::operator=(const A::B & b) { return b; }"); + "A::B & A::B::operator=(const A::B & b) { return b; }\n"); ASSERT_EQUALS("[test.cpp:8:14]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1431,7 +1431,7 @@ class TestClass : public TestFixture { "class A::B\n" "{\n" " A::B & operator=(const A::B & b) { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:10]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1442,7 +1442,7 @@ class TestClass : public TestFixture { "{\n" " A::B & operator=(const A::B &);\n" "};\n" - "A::B & A::B::operator=(const A::B & b) { return b; }"); + "A::B & A::B::operator=(const A::B & b) { return b; }\n"); ASSERT_EQUALS("[test.cpp:8:14]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( // #11380 @@ -1462,7 +1462,7 @@ class TestClass : public TestFixture { "class szp\n" "{\n" " szp &operator =(int *other) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:8]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1470,7 +1470,7 @@ class TestClass : public TestFixture { "{\n" " szp &operator =(int *other);\n" "};\n" - "szp &szp::operator =(int *other) {}"); + "szp &szp::operator =(int *other) {}\n"); ASSERT_EQUALS("[test.cpp:5:11]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1480,7 +1480,7 @@ class TestClass : public TestFixture { "class NS::szp\n" "{\n" " szp &operator =(int *other) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:8]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1491,7 +1491,7 @@ class TestClass : public TestFixture { "{\n" " szp &operator =(int *other);\n" "};\n" - "NS::szp &NS::szp::operator =(int *other) {}"); + "NS::szp &NS::szp::operator =(int *other) {}\n"); ASSERT_EQUALS("[test.cpp:8:19]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1501,7 +1501,7 @@ class TestClass : public TestFixture { "class NS::szp\n" "{\n" " NS::szp &operator =(int *other) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:12]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1512,7 +1512,7 @@ class TestClass : public TestFixture { "{\n" " NS::szp &operator =(int *other);\n" "};\n" - "NS::szp &NS::szp::operator =(int *other) {}"); + "NS::szp &NS::szp::operator =(int *other) {}\n"); ASSERT_EQUALS("[test.cpp:8:19]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1522,7 +1522,7 @@ class TestClass : public TestFixture { "class A::szp\n" "{\n" " szp &operator =(int *other) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:8]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1533,7 +1533,7 @@ class TestClass : public TestFixture { "{\n" " szp &operator =(int *other);\n" "};\n" - "A::szp &A::szp::operator =(int *other) {}"); + "A::szp &A::szp::operator =(int *other) {}\n"); ASSERT_EQUALS("[test.cpp:8:17]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1543,7 +1543,7 @@ class TestClass : public TestFixture { "class A::szp\n" "{\n" " A::szp &operator =(int *other) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:11]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1554,7 +1554,7 @@ class TestClass : public TestFixture { "{\n" " A::szp &operator =(int *other);\n" "};\n" - "A::szp &A::szp::operator =(int *other) {}"); + "A::szp &A::szp::operator =(int *other) {}\n"); ASSERT_EQUALS("[test.cpp:8:17]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); } @@ -1565,7 +1565,7 @@ class TestClass : public TestFixture { "public:\n" " inline A &operator =(int *other) { return (*this); };\n" " inline A &operator =(long *other) { return (*this = 0); };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1575,7 +1575,7 @@ class TestClass : public TestFixture { " A &operator =(long *other);\n" "};\n" "A &A::operator =(int *other) { return (*this); };\n" - "A &A::operator =(long *other) { return (*this = 0); };"); + "A &A::operator =(long *other) { return (*this = 0); };\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1583,7 +1583,7 @@ class TestClass : public TestFixture { "public:\n" " inline A &operator =(int *other) { return (*this); };\n" " inline A &operator =(long *other) { return operator = (*(int *)other); };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1593,7 +1593,7 @@ class TestClass : public TestFixture { " A &operator =(long *other);\n" "};\n" "A &A::operator =(int *other) { return (*this); };\n" - "A &A::operator =(long *other) { return operator = (*(int *)other); };"); + "A &A::operator =(long *other) { return operator = (*(int *)other); };\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( @@ -1603,7 +1603,7 @@ class TestClass : public TestFixture { " A &operator =(long *other);\n" "};\n" "A &A::operator =(int *other) { return (*this); };\n" - "A &A::operator =(long *other) { return this->operator = (*(int *)other); };"); + "A &A::operator =(long *other) { return this->operator = (*(int *)other); };\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqRetRefThis( // #9045 @@ -1615,7 +1615,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1625,7 +1625,7 @@ class TestClass : public TestFixture { "P& P::operator = (const P& pc)\n" "{\n" " return (P&)(*this += pc);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1635,21 +1635,21 @@ class TestClass : public TestFixture { "class A {\n" "public:\n" " A & operator=(const A &a) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); checkOpertorEqRetRefThis( "class A {\n" "protected:\n" " A & operator=(const A &a) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( "class A {\n" "private:\n" " A & operator=(const A &a) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) 'operator=' should return reference to 'this' instance. [operatorEqRetRefThis]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1659,7 +1659,7 @@ class TestClass : public TestFixture { " rand();\n" " throw std::exception();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) 'operator=' should either return reference to 'this' instance or be declared private and left unimplemented. [operatorEqShouldBeLeftUnimplemented]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1669,7 +1669,7 @@ class TestClass : public TestFixture { " rand();\n" " abort();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) 'operator=' should either return reference to 'this' instance or be declared private and left unimplemented. [operatorEqShouldBeLeftUnimplemented]\n", errout_str()); checkOpertorEqRetRefThis( @@ -1677,7 +1677,7 @@ class TestClass : public TestFixture { "public:\n" " A & operator=(const A &a);\n" "};\n" - "A & A :: operator=(const A &a) { }"); + "A & A :: operator=(const A &a) { }\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) No 'return' statement in non-void function causes undefined behavior. [operatorEqMissingReturnStatement]\n", errout_str()); } @@ -1694,7 +1694,7 @@ class TestClass : public TestFixture { "}\n" "UString& UString::operator=( const UString& s ) {\n" " return assign( s );\n" - "}"); + "}\n"); } void operatorEqRetRefThis7() { // ticket #5782 Endless recursion in CheckClass::checkReturnPtrThis() @@ -1712,7 +1712,7 @@ class TestClass : public TestFixture { " basic_fbstring& replace() {\n" " return replaceImplDiscr();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1736,7 +1736,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " A & operator=(const A &a) { if (&a != this) { } return *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test doesn't have an assignment test but it is not needed @@ -1745,7 +1745,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " A & operator=(const A &a) { return *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test needs an assignment test and has it @@ -1763,7 +1763,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this class needs an assignment test but doesn't have it @@ -1778,7 +1778,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:9]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // this test has an assignment test but doesn't need it @@ -1788,7 +1788,7 @@ class TestClass : public TestFixture { "public:\n" " A & operator=(const A &);\n" "};\n" - "A & A::operator=(const A &a) { if (&a != this) { } return *this; }"); + "A & A::operator=(const A &a) { if (&a != this) { } return *this; }\n"); ASSERT_EQUALS("", errout_str()); // this test doesn't have an assignment test but doesn't need it @@ -1798,7 +1798,7 @@ class TestClass : public TestFixture { "public:\n" " A & operator=(const A &);\n" "};\n" - "A & A::operator=(const A &a) { return *this; }"); + "A & A::operator=(const A &a) { return *this; }\n"); ASSERT_EQUALS("", errout_str()); // this test needs an assignment test and has it @@ -1817,7 +1817,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // this test needs an assignment test and has the inverse test @@ -1836,7 +1836,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // this test needs an assignment test and has the inverse test @@ -1855,7 +1855,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // this test needs an assignment test and has the inverse test @@ -1874,7 +1874,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // this test needs an assignment test and has the inverse test @@ -1893,7 +1893,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // this test needs an assignment test and has the inverse test @@ -1912,7 +1912,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // this test needs an assignment test and has the inverse test @@ -1934,7 +1934,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // this test needs an assignment test and has the inverse test @@ -1955,7 +1955,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); @@ -1972,7 +1972,7 @@ class TestClass : public TestFixture { " free(s);\n" " s = strdup(a.s);\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // ticket #1224 @@ -1990,7 +1990,7 @@ class TestClass : public TestFixture { " tree = new CodeTree(b);\n" " delete oldtree;\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2006,7 +2006,7 @@ class TestClass : public TestFixture { " public:\n" " B & operator=(const B &b) { if (&b != this) { } return *this; }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test doesn't have an assignment test but doesn't need it @@ -2019,7 +2019,7 @@ class TestClass : public TestFixture { " public:\n" " B & operator=(const B &b) { return *this; }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test needs an assignment test but has it @@ -2039,7 +2039,7 @@ class TestClass : public TestFixture { " return *this;\n" " }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test needs an assignment test but doesn't have it @@ -2058,7 +2058,7 @@ class TestClass : public TestFixture { " return *this;\n" " }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:13]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); // this test has an assignment test but doesn't need it @@ -2072,7 +2072,7 @@ class TestClass : public TestFixture { " B & operator=(const B &);\n" " };\n" "};\n" - "A::B & A::B::operator=(const A::B &b) { if (&b != this) { } return *this; }"); + "A::B & A::B::operator=(const A::B &b) { if (&b != this) { } return *this; }\n"); ASSERT_EQUALS("", errout_str()); // this test doesn't have an assignment test but doesn't need it @@ -2086,7 +2086,7 @@ class TestClass : public TestFixture { " B & operator=(const B &);\n" " };\n" "};\n" - "A::B & A::B::operator=(const A::B &b) { return *this; }"); + "A::B & A::B::operator=(const A::B &b) { return *this; }\n"); ASSERT_EQUALS("", errout_str()); // this test needs an assignment test and has it @@ -2109,7 +2109,7 @@ class TestClass : public TestFixture { " s = strdup(b.s);\n" " }\n" " return *this;\n" - " }"); + " }\n"); ASSERT_EQUALS("", errout_str()); // this test needs an assignment test but doesn't have it @@ -2129,7 +2129,7 @@ class TestClass : public TestFixture { " free(s);\n" " s = strdup(b.s);\n" " return *this;\n" - " }"); + " }\n"); ASSERT_EQUALS("[test.cpp:11:14]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); } @@ -2140,7 +2140,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " A & operator=(const A &a) { return *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it @@ -2155,7 +2155,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it @@ -2165,7 +2165,7 @@ class TestClass : public TestFixture { "public:\n" " A & operator=(const A &);\n" "};\n" - "A & A::operator=(const A &a) { return *this; }"); + "A & A::operator=(const A &a) { return *this; }\n"); ASSERT_EQUALS("", errout_str()); // this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it @@ -2181,7 +2181,7 @@ class TestClass : public TestFixture { " free(s);\n" " s = strdup(a.s);\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2196,7 +2196,7 @@ class TestClass : public TestFixture { " public:\n" " B & operator=(const B &b) { return *this; }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it @@ -2215,7 +2215,7 @@ class TestClass : public TestFixture { " return *this;\n" " }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // this test has multiple inheritance so there is no trivial way to test for self assignment but doesn't need it @@ -2229,7 +2229,7 @@ class TestClass : public TestFixture { " B & operator=(const B &);\n" " };\n" "};\n" - "A::B & A::B::operator=(const A::B &b) { return *this; }"); + "A::B & A::B::operator=(const A::B &b) { return *this; }\n"); ASSERT_EQUALS("", errout_str()); // this test has multiple inheritance and needs an assignment test but there is no trivial way to test for it @@ -2249,7 +2249,7 @@ class TestClass : public TestFixture { " free(s);\n" " s = strdup(b.s);\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2269,7 +2269,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2286,7 +2286,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2303,7 +2303,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2320,7 +2320,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2337,7 +2337,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2354,7 +2354,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2371,7 +2371,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2388,7 +2388,7 @@ class TestClass : public TestFixture { " }\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2406,7 +2406,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2424,7 +2424,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2442,7 +2442,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2460,7 +2460,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2478,7 +2478,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2496,7 +2496,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2514,7 +2514,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2532,7 +2532,7 @@ class TestClass : public TestFixture { " s = strdup(a.s);\n" " }\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOpertorEqToSelf( @@ -2544,7 +2544,7 @@ class TestClass : public TestFixture { " free(s);\n" " s = strdup(a.s);\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2563,7 +2563,7 @@ class TestClass : public TestFixture { " }\n" "private:\n" " char * data;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:9]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); checkOpertorEqToSelf( @@ -2580,7 +2580,7 @@ class TestClass : public TestFixture { " data = new char[strlen(a.data) + 1];\n" " strcpy(data, a.data);\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); checkOpertorEqToSelf( @@ -2596,7 +2596,7 @@ class TestClass : public TestFixture { " }\n" "private:\n" " char * data;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:9]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); checkOpertorEqToSelf( @@ -2613,7 +2613,7 @@ class TestClass : public TestFixture { " data = new char;\n" " *data = *a.data;\n" " return *this;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:8]: (warning) 'operator=' should check for assignment to self to avoid problems with dynamic memory. [operatorEqToSelf]\n", errout_str()); } @@ -2630,7 +2630,7 @@ class TestClass : public TestFixture { " {\n" " return assign(a);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2649,7 +2649,7 @@ class TestClass : public TestFixture { "FMat& FMat::operator=(const FMat& in)\n" "{\n" " return copy(in);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2668,7 +2668,7 @@ class TestClass : public TestFixture { "Foo& Foo::operator=(Foo& other)\n" "{\n" " return Foo::operator=(&other);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2697,12 +2697,12 @@ class TestClass : public TestFixture { checkVirtualDestructor("class Derived : public Base { };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("", errout_str()); checkVirtualDestructor("class Derived : Base { };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("", errout_str()); } @@ -2710,27 +2710,27 @@ class TestClass : public TestFixture { // Base class doesn't have a destructor checkVirtualDestructor("class Base { };\n" - "class Derived : public Base { public: ~Derived() { (void)11; } };" + "class Derived : public Base { public: ~Derived() { (void)11; } };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); checkVirtualDestructor("class Base { };\n" - "class Derived : protected Base { public: ~Derived() { (void)11; } };" + "class Derived : protected Base { public: ~Derived() { (void)11; } };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); checkVirtualDestructor("class Base { };\n" - "class Derived : private Base { public: ~Derived() { (void)11; } };" + "class Derived : private Base { public: ~Derived() { (void)11; } };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("", errout_str()); checkVirtualDestructor("class Base { };\n" - "class Derived : Base { public: ~Derived() { (void)11; } };" + "class Derived : Base { public: ~Derived() { (void)11; } };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("", errout_str()); // #9104 @@ -2751,7 +2751,7 @@ class TestClass : public TestFixture { "{\n" " Base* p = new Derived();\n" " delete p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); checkVirtualDestructor("using namespace std;\n" @@ -2772,7 +2772,7 @@ class TestClass : public TestFixture { "{\n" " Base* p = new Derived();\n" " delete p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); } @@ -2780,21 +2780,21 @@ class TestClass : public TestFixture { // Base class has a destructor, but it's not virtual checkVirtualDestructor("class Base { public: ~Base(); };\n" - "class Derived : public Base { public: ~Derived() { (void)11; } };" + "class Derived : public Base { public: ~Derived() { (void)11; } };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); checkVirtualDestructor("class Base { public: ~Base(); };\n" - "class Derived : protected Base { public: ~Derived() { (void)11; } };" + "class Derived : protected Base { public: ~Derived() { (void)11; } };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); checkVirtualDestructor("class Base { public: ~Base(); };\n" - "class Derived : private Fred, public Base { public: ~Derived() { (void)11; } };" + "class Derived : private Fred, public Base { public: ~Derived() { (void)11; } };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); } @@ -2802,15 +2802,15 @@ class TestClass : public TestFixture { // Derived class doesn't have a destructor => undefined behaviour according to paragraph 3 in [expr.delete] checkVirtualDestructor("class Base { public: ~Base(); };\n" - "class Derived : public Base { };" + "class Derived : public Base { };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); checkVirtualDestructor("class Base { public: ~Base(); };\n" - "class Derived : private Fred, public Base { };" + "class Derived : private Fred, public Base { };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); } @@ -2818,15 +2818,15 @@ class TestClass : public TestFixture { // Derived class has empty destructor => undefined behaviour according to paragraph 3 in [expr.delete] checkVirtualDestructor("class Base { public: ~Base(); };\n" - "class Derived : public Base { public: ~Derived() {} };" + "class Derived : public Base { public: ~Derived() {} };\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); checkVirtualDestructor("class Base { public: ~Base(); };\n" - "class Derived : public Base { public: ~Derived(); }; Derived::~Derived() {}" + "class Derived : public Base { public: ~Derived(); }; Derived::~Derived() {}\n" "Base *base = new Derived;\n" - "delete base;"); + "delete base;\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); } @@ -2835,7 +2835,7 @@ class TestClass : public TestFixture { // points at derived class checkVirtualDestructor("class Base { public: ~Base(); };\n" - "class Derived : public Base { public: ~Derived() { (void)11; } };"); + "class Derived : public Base { public: ~Derived() { (void)11; } };\n"); ASSERT_EQUALS("", errout_str()); } @@ -2852,7 +2852,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " ~B() { int a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2873,7 +2873,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " ~B() { int a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // class A inherits virtual destructor from struct Base -> no error @@ -2891,7 +2891,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " ~B() { int a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // Unknown Base class -> it could have virtual destructor, so ignore @@ -2905,7 +2905,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " ~B() { int a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // Virtual destructor is inherited -> no error @@ -2926,7 +2926,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " ~B() { int a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // class A doesn't inherit virtual destructor from class Base -> error @@ -2945,7 +2945,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " ~B() { int a; }\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Class 'Base' which is inherited by class 'B' does not have a virtual destructor.\n", "", errout_str()); } @@ -2967,7 +2967,7 @@ class TestClass : public TestFixture { " ~B(){int a;}\n" "};\n" "\n" - "AA *p = new B; delete p;"); + "AA *p = new B; delete p;\n"); ASSERT_EQUALS("[test.cpp:9:3]: (error) Class 'AA < double >' which is inherited by class 'B' does not have a virtual destructor. [virtualDestructor]\n", errout_str()); } @@ -3037,7 +3037,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(Fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("class Fred\n" @@ -3048,7 +3048,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(Fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("class Fred\n" @@ -3059,7 +3059,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(Fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("class Fred\n" @@ -3070,7 +3070,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(Fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:5]: (error) Using 'memset' on class that contains a 'std::string'. [memsetClass]\n", errout_str()); checkNoMemset("class Fred\n" @@ -3081,7 +3081,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(Fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:5]: (error) Using 'memset' on class that contains a 'std::string'. [memsetClass]\n", errout_str()); checkNoMemset("class Fred {\n" @@ -3090,7 +3090,7 @@ class TestClass : public TestFixture { "};\n" "void Fred::f() {\n" " memset(this, 0, sizeof(*this));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:5]: (error) Using 'memset' on class that contains a 'std::string'. [memsetClass]\n", errout_str()); checkNoMemset("class Fred\n" @@ -3100,7 +3100,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("class Fred\n" @@ -3111,7 +3111,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:5]: (error) Using 'memset' on class that contains a 'std::string'. [memsetClass]\n", errout_str()); checkNoMemset("class Fred\n" @@ -3123,7 +3123,7 @@ class TestClass : public TestFixture { "{\n" " Pebbles pebbles;\n" " memset(&pebbles, 0, sizeof(pebbles));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:5]: (error) Using 'memset' on class that contains a 'std::string'. [memsetClass]\n", errout_str()); checkNoMemset("class Fred\n" @@ -3134,7 +3134,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:5]: (error) Using 'memset' on class that contains a virtual function. [memsetClass]\n", errout_str()); checkNoMemset("class Fred\n" @@ -3145,7 +3145,7 @@ class TestClass : public TestFixture { "{\n" " static Fred fred;\n" " memset(&fred, 0, sizeof(fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:5]: (error) Using 'memset' on class that contains a virtual function. [memsetClass]\n", errout_str()); checkNoMemset("class Fred\n" @@ -3160,7 +3160,7 @@ class TestClass : public TestFixture { "{\n" " Pebbles pebbles;\n" " memset(&pebbles, 0, sizeof(pebbles));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:12:5]: (error) Using 'memset' on class that contains a virtual function. [memsetClass]\n", errout_str()); // Fred not defined in scope @@ -3174,7 +3174,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(Fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Fred with namespace qualifier @@ -3188,7 +3188,7 @@ class TestClass : public TestFixture { "{\n" " n1::Fred fred;\n" " memset(&fred, 0, sizeof(n1::Fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:5]: (error) Using 'memset' on class that contains a 'std::string'. [memsetClass]\n", errout_str()); // Fred with namespace qualifier @@ -3202,7 +3202,7 @@ class TestClass : public TestFixture { "{\n" " n1::Fred fred;\n" " memset(&fred, 0, sizeof(fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:5]: (error) Using 'memset' on class that contains a 'std::string'. [memsetClass]\n", errout_str()); checkNoMemset("class A {\n" @@ -3213,7 +3213,7 @@ class TestClass : public TestFixture { " const int N = 10;\n" " A** arr = new A*[N];\n" " memset(arr, 0, N * sizeof(A*));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("class A {\n" // #5116 - nested class data is mixed in the SymbolDatabase @@ -3222,7 +3222,7 @@ class TestClass : public TestFixture { "};\n" "void f(A::B *b) {\n" " memset(b,0,4);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4461 Warn about memset/memcpy on class with references as members @@ -3232,7 +3232,7 @@ class TestClass : public TestFixture { "void f() {\n" " A a;\n" " memset(&a, 0, sizeof(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:3]: (error) Using 'memset' on class that contains a reference. [memsetClassReference]\n", errout_str()); checkNoMemset("class A {\n" " const B&b;\n" @@ -3240,7 +3240,7 @@ class TestClass : public TestFixture { "void f() {\n" " A a;\n" " memset(&a, 0, sizeof(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:3]: (error) Using 'memset' on class that contains a reference. [memsetClassReference]\n", errout_str()); // #7456 @@ -3254,7 +3254,7 @@ class TestClass : public TestFixture { "void func() {\n" " B b[4];\n" " memset(b, 0, sizeof(b));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8619 @@ -3309,11 +3309,11 @@ class TestClass : public TestFixture { " } vid;\n" " };\n" " } hdr;\n" - "};" + "};\n" "void parseHeader() {\n" " ASFStreamHeader strhdr;\n" " memset(&strhdr, 0, sizeof(strhdr));\n" - "}"); + "}\n"); } void memsetOnStruct() { @@ -3324,7 +3324,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("struct A\n" @@ -3334,7 +3334,7 @@ class TestClass : public TestFixture { "{\n" " struct A a;\n" " memset(&a, 0, sizeof(struct A));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("struct A\n" @@ -3344,14 +3344,14 @@ class TestClass : public TestFixture { "{\n" " struct A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("void f()\n" "{\n" " struct sockaddr_in6 fail;\n" " memset(&fail, 0, sizeof(struct sockaddr_in6));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("struct A\n" @@ -3364,7 +3364,7 @@ class TestClass : public TestFixture { "{\n" " struct A fail;\n" " memset(&fail, 0, sizeof(struct A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:2]: (error) Using 'memset' on struct that contains a 'std::string'. [memsetClass]\n", errout_str()); checkNoMemset("struct Fred\n" @@ -3375,7 +3375,7 @@ class TestClass : public TestFixture { "{\n" " Fred fred;\n" " memset(&fred, 0, sizeof(fred));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:5]: (error) Using 'memset' on struct that contains a 'std::string'. [memsetClass]\n", errout_str()); checkNoMemset("struct Stringy {\n" @@ -3387,7 +3387,7 @@ class TestClass : public TestFixture { "int main() {\n" " Foo foo;\n" " memset(&foo, 0, sizeof(Foo));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:5]: (error) Using 'memset' on struct that contains a 'std::string'. [memsetClass]\n", errout_str()); } @@ -3400,7 +3400,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Using 'memset' on class that contains a 'std::vector'. [memsetClass]\n", errout_str()); checkNoMemset("struct A\n" @@ -3410,7 +3410,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Using 'memset' on struct that contains a 'std::vector'. [memsetClass]\n", errout_str()); checkNoMemset("struct A\n" @@ -3420,7 +3420,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(struct A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Using 'memset' on struct that contains a 'std::vector'. [memsetClass]\n", errout_str()); checkNoMemset("struct A\n" @@ -3430,7 +3430,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Using 'memset' on struct that contains a 'std::vector'. [memsetClass]\n", errout_str()); checkNoMemset("class A\n" @@ -3440,7 +3440,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Using 'memset' on class that contains a 'std::vector'. [memsetClass]\n", errout_str()); checkNoMemset("struct A\n" @@ -3450,7 +3450,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Using 'memset' on struct that contains a 'std::vector'. [memsetClass]\n", errout_str()); checkNoMemset("struct A\n" @@ -3460,7 +3460,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Using 'memset' on struct that contains a 'std::vector'. [memsetClass]\n", errout_str()); checkNoMemset("struct A\n" @@ -3470,7 +3470,7 @@ class TestClass : public TestFixture { "{\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Using 'memset' on struct that contains a 'std::vector'. [memsetClass]\n", errout_str()); checkNoMemset("struct A {\n" @@ -3480,7 +3480,7 @@ class TestClass : public TestFixture { "void f() {\n" " A a;\n" " memset(a, 0, 100);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4460 checkNoMemset("struct C {\n" @@ -3498,7 +3498,7 @@ class TestClass : public TestFixture { " memset(*c4, 0, 10);\n" " memset(c2, 0, 10);\n" " memset(c3, 0, 10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:5]: (error) Using 'memset' on struct that contains a 'std::string'. [memsetClass]\n" "[test.cpp:11:5]: (error) Using 'memset' on struct that contains a 'std::string'. [memsetClass]\n" "[test.cpp:12:5]: (error) Using 'memset' on struct that contains a 'std::string'. [memsetClass]\n" @@ -3514,7 +3514,7 @@ class TestClass : public TestFixture { " multilevel_data *d = (multilevel_data *) malloc(sizeof(multilevel_data));\n" " memset(d, 0, sizeof(multilevel_data));\n" " return (void*) d;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:3]: (portability) Using memset() on struct which contains a floating point number. [memsetClassFloat]\n", errout_str()); } @@ -3532,7 +3532,7 @@ class TestClass : public TestFixture { "void f() {\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // std::array is POD (#5481) checkNoMemset("struct st {\n" @@ -3543,7 +3543,7 @@ class TestClass : public TestFixture { "void f() {\n" " st s;\n" " std::memset(&s, 0, sizeof(st));\n" - "}", settings); + "}\n", settings); ASSERT_EQUALS("", errout_str()); } @@ -3554,7 +3554,7 @@ class TestClass : public TestFixture { "void f() {\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:5]: (portability) Using memset() on struct which contains a floating point number. [memsetClassFloat]\n", errout_str()); checkNoMemset("struct A {\n" @@ -3563,7 +3563,7 @@ class TestClass : public TestFixture { "void f() {\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:5]: (portability) Using memset() on struct which contains a floating point number. [memsetClassFloat]\n", errout_str()); checkNoMemset("struct A {\n" @@ -3572,7 +3572,7 @@ class TestClass : public TestFixture { "void f(const A& b) {\n" " A a;\n" " memcpy(&a, &b, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("struct A {\n" @@ -3581,7 +3581,7 @@ class TestClass : public TestFixture { "void f() {\n" " A a;\n" " memset(&a, 0, sizeof(A));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3589,7 +3589,7 @@ class TestClass : public TestFixture { checkNoMemset("void clang_tokenize(CXToken **Tokens) {\n" " *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());\n" " memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3597,49 +3597,49 @@ class TestClass : public TestFixture { checkNoMemset("class C { C() {} };\n" "void foo(C*& p) {\n" " p = malloc(sizeof(C));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5] -> [test.cpp:1:1]: (warning) Memory for class instance allocated with malloc(), but class provides constructors. [mallocOnClassWarning]\n", errout_str()); checkNoMemset("class C { C(int z, Foo bar) { bar(); } };\n" "void foo(C*& p) {\n" " p = malloc(sizeof(C));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5] -> [test.cpp:1:1]: (warning) Memory for class instance allocated with malloc(), but class provides constructors. [mallocOnClassWarning]\n", errout_str()); checkNoMemset("struct C { C() {} };\n" "void foo(C*& p) {\n" " p = realloc(p, sizeof(C));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5] -> [test.cpp:1:1]: (warning) Memory for class instance allocated with realloc(), but class provides constructors. [mallocOnClassWarning]\n", errout_str()); checkNoMemset("struct C { virtual void bar(); };\n" "void foo(C*& p) {\n" " p = malloc(sizeof(C));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:1:1]: (error) Memory for class instance allocated with malloc(), but class contains a virtual function. [mallocOnClassError]\n", errout_str()); checkNoMemset("struct C { std::string s; };\n" "void foo(C*& p) {\n" " p = malloc(sizeof(C));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:1:1]: (error) Memory for class instance allocated with malloc(), but class contains a 'std::string'. [mallocOnClassError]\n", errout_str()); checkNoMemset("class C { };\n" // C-Style class/struct "void foo(C*& p) {\n" " p = malloc(sizeof(C));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("struct C { C() {} };\n" "void foo(C*& p) {\n" " p = new C();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("class C { C() {} };\n" "void foo(D*& p) {\n" // Unknown type " p = malloc(sizeof(C));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("class AutoCloseFD {\n" @@ -3650,7 +3650,7 @@ class TestClass : public TestFixture { "};\n" "void f() {\n" " AutoCloseFD fd = open(\"abc\", O_RDONLY | O_CLOEXEC);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkNoMemset("struct C {\n" // #12313 @@ -3659,7 +3659,7 @@ class TestClass : public TestFixture { "};\n" "void f() {\n" " C c = strdup(\"abc\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3676,19 +3676,19 @@ class TestClass : public TestFixture { } void this_subtraction() { - checkThisSubtraction("; this-x ;"); + checkThisSubtraction("; this-x ;\n"); ASSERT_EQUALS("[test.cpp:1:3]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? [thisSubtraction]\n", errout_str()); - checkThisSubtraction("; *this = *this-x ;"); + checkThisSubtraction("; *this = *this-x ;\n"); ASSERT_EQUALS("", errout_str()); checkThisSubtraction("; *this = *this-x ;\n" - "this-x ;"); + "this-x ;\n"); ASSERT_EQUALS("[test.cpp:2:1]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? [thisSubtraction]\n", errout_str()); checkThisSubtraction("; *this = *this-x ;\n" "this-x ;\n" - "this-x ;"); + "this-x ;\n"); ASSERT_EQUALS("[test.cpp:2:1]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? [thisSubtraction]\n" "[test.cpp:3:1]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? [thisSubtraction]\n", errout_str()); } @@ -3719,18 +3719,18 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int a;\n" " int getA() { return a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style, inconclusive) Technically the member function 'Fred::getA' can be const. [functionConst]\n", errout_str()); checkConst("class Fred {\n" " const std::string foo() { return \"\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:23]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); checkConst("class Fred {\n" " std::string s;\n" " const std::string & foo() { return \"\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:25]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); // constructors can't be const.. @@ -3738,14 +3738,14 @@ class TestClass : public TestFixture { " int a;\n" "public:\n" " Fred() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment through |=.. checkConst("class Fred {\n" " int a;\n" " int setA() { a |= true; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // functions with a call to a member function can only be const, if that member function is const, too.. (#1305) @@ -3754,7 +3754,7 @@ class TestClass : public TestFixture { " int x;\n" " void a() { x = 1; }\n" " void b() { a(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" @@ -3762,14 +3762,14 @@ class TestClass : public TestFixture { " int x;\n" " int a() const { return x; }\n" " void b() { a(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:10]: (style, inconclusive) Technically the member function 'Fred::b' can be const. [functionConst]\n", errout_str()); checkConst("class Fred {\n" "public:\n" " int x;\n" " void b() { a(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) The member function 'Fred::b' can be static. [functionStatic]\n", errout_str()); // static functions can't be const.. @@ -3778,12 +3778,12 @@ class TestClass : public TestFixture { "public:\n" " static unsigned get()\n" " { return 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " const std::string foo() const throw() { return \"\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:23]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); } @@ -3793,49 +3793,49 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " std::string s;\n" " void foo() { s = \"\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment to function argument reference can be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string & a) { a = s; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // assignment to variable can't be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string & a) { s = a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment to function argument references can be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string & a, std::string & b) { a = s; b = s; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // assignment to variable, can't be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string & a, std::string & b) { s = a; s = b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable, can't be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string & a, std::string & b) { s = a; b = a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable, can't be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string & a, std::string & b) { a = s; s = b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3844,42 +3844,42 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int s;\n" " void foo(int * a) { *a = s; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // assignment to variable, can't be const checkConst("class Fred {\n" " int s;\n" " void foo(int * a) { s = *a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment to function argument pointers can be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string * a, std::string * b) { *a = s; *b = s; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // assignment to variable, can't be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string * a, std::string * b) { s = *a; s = *b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable, can't be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string * a, std::string * b) { s = *a; *b = s; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable, can't be const checkConst("class Fred {\n" " std::string s;\n" " void foo(std::string * a, std::string * b) { *a = s; s = b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3888,14 +3888,14 @@ class TestClass : public TestFixture { " int a;\n" " int getA();\n" "};\n" - "int Fred::getA() { return a; }"); + "int Fred::getA() { return a; }\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:5:11]: (style, inconclusive) Technically the member function 'Fred::getA' can be const. [functionConst]\n", errout_str()); checkConst("class Fred {\n" " std::string s;\n" " const std::string & foo();\n" "};\n" - "const std::string & Fred::foo() { return \"\"; }"); + "const std::string & Fred::foo() { return \"\"; }\n"); ASSERT_EQUALS("[test.cpp:3:25] -> [test.cpp:5:27]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); // functions with a function call to a non-const member can't be const.. (#1305) @@ -3906,7 +3906,7 @@ class TestClass : public TestFixture { " void a() { x = 1; }\n" " void b();\n" "};\n" - "void Fred::b() { a(); }"); + "void Fred::b() { a(); }\n"); ASSERT_EQUALS("", errout_str()); // static functions can't be const.. @@ -3915,7 +3915,7 @@ class TestClass : public TestFixture { "public:\n" " static unsigned get();\n" "};\n" - "static unsigned Fred::get() { return 0; }"); + "static unsigned Fred::get() { return 0; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable can't be const @@ -3923,7 +3923,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo();\n" "};\n" - "void Fred::foo() { s = \"\"; }"); + "void Fred::foo() { s = \"\"; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to function argument reference can be const @@ -3931,7 +3931,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string & a);\n" "};\n" - "void Fred::foo(std::string & a) { a = s; }"); + "void Fred::foo(std::string & a) { a = s; }\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:5:12]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // assignment to variable can't be const @@ -3939,7 +3939,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string & a);\n" "};\n" - "void Fred::foo(std::string & a) { s = a; }"); + "void Fred::foo(std::string & a) { s = a; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to function argument references can be const @@ -3947,7 +3947,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string & a, std::string & b);\n" "};\n" - "void Fred::foo(std::string & a, std::string & b) { a = s; b = s; }"); + "void Fred::foo(std::string & a, std::string & b) { a = s; b = s; }\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:5:12]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // assignment to variable, can't be const @@ -3955,7 +3955,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string & a, std::string & b);\n" "};\n" - "void Fred::foo(std::string & a, std::string & b) { s = a; s = b; }"); + "void Fred::foo(std::string & a, std::string & b) { s = a; s = b; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable, can't be const @@ -3963,7 +3963,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string & a, std::string & b);\n" "};\n" - "void Fred::foo(std::string & a, std::string & b) { s = a; b = a; }"); + "void Fred::foo(std::string & a, std::string & b) { s = a; b = a; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable, can't be const @@ -3971,7 +3971,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string & a, std::string & b);\n" "};\n" - "void Fred::foo(std::string & a, std::string & b) { a = s; s = b; }"); + "void Fred::foo(std::string & a, std::string & b) { a = s; s = b; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to function argument pointer can be const @@ -3979,7 +3979,7 @@ class TestClass : public TestFixture { " int s;\n" " void foo(int * a);\n" "};\n" - "void Fred::foo(int * a) { *a = s; }"); + "void Fred::foo(int * a) { *a = s; }\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:5:12]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // assignment to variable, can't be const @@ -3987,7 +3987,7 @@ class TestClass : public TestFixture { " int s;\n" " void foo(int * a);\n" "};\n" - "void Fred::foo(int * a) { s = *a; }"); + "void Fred::foo(int * a) { s = *a; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to function argument pointers can be const @@ -3995,7 +3995,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string * a, std::string * b);\n" "};\n" - "void Fred::foo(std::string * a, std::string * b) { *a = s; *b = s; }"); + "void Fred::foo(std::string * a, std::string * b) { *a = s; *b = s; }\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:5:12]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // assignment to variable, can't be const @@ -4003,7 +4003,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string * a, std::string * b);\n" "};\n" - "void Fred::foo(std::string * a, std::string * b) { s = *a; s = *b; }"); + "void Fred::foo(std::string * a, std::string * b) { s = *a; s = *b; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable, can't be const @@ -4011,7 +4011,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string * a, std::string * b);\n" "};\n" - "void Fred::foo(std::string * a, std::string * b) { s = *a; *b = s; }"); + "void Fred::foo(std::string * a, std::string * b) { s = *a; *b = s; }\n"); ASSERT_EQUALS("", errout_str()); // assignment to variable, can't be const @@ -4019,7 +4019,7 @@ class TestClass : public TestFixture { " std::string s;\n" " void foo(std::string * a, std::string * b);\n" "};\n" - "void Fred::foo(std::string * a, std::string * b) { *a = s; s = b; }"); + "void Fred::foo(std::string * a, std::string * b) { *a = s; s = b; }\n"); ASSERT_EQUALS("", errout_str()); // check functions with same name @@ -4029,11 +4029,11 @@ class TestClass : public TestFixture { " void foo(std::string & a);\n" " void foo(const std::string & a);\n" "};\n" - "void Fred::foo() { }" - "void Fred::foo(std::string & a) { a = s; }" - "void Fred::foo(const std::string & a) { s = a; }"); + "void Fred::foo() { }\n" + "void Fred::foo(std::string & a) { a = s; }\n" + "void Fred::foo(const std::string & a) { s = a; }\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:7:12]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n" - "[test.cpp:4:10] -> [test.cpp:7:32]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); + "[test.cpp:4:10] -> [test.cpp:8:12]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // check functions with different or missing parameter names checkConst("class Fred {\n" @@ -4048,7 +4048,7 @@ class TestClass : public TestFixture { "void Fred::foo2(int c, int d) { }\n" "void Fred::foo3(int a, int b) { }\n" "void Fred::foo4(int a, int b) { }\n" - "void Fred::foo5(int, int) { }"); + "void Fred::foo5(int, int) { }\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:9:12]: (style) The member function 'Fred::foo1' can be static. [functionStatic]\n" "[test.cpp:4:10] -> [test.cpp:10:12]: (style) The member function 'Fred::foo2' can be static. [functionStatic]\n" "[test.cpp:5:10] -> [test.cpp:11:12]: (style) The member function 'Fred::foo3' can be static. [functionStatic]\n" @@ -4061,7 +4061,7 @@ class TestClass : public TestFixture { " int a;\n" " int getA() { return a; }\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style, inconclusive) Technically the member function 'Fred::A::getA' can be const. [functionConst]\n", errout_str()); checkConst("class Fred {\n" @@ -4070,7 +4070,7 @@ class TestClass : public TestFixture { " int getA();\n" " };\n" " int A::getA() { return a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:13] -> [test.cpp:6:12]: (style, inconclusive) Technically the member function 'Fred::A::getA' can be const. [functionConst]\n", errout_str()); checkConst("class Fred {\n" @@ -4079,7 +4079,7 @@ class TestClass : public TestFixture { " int getA();\n" " };\n" "};\n" - "int Fred::A::getA() { return a; }"); + "int Fred::A::getA() { return a; }\n"); ASSERT_EQUALS("[test.cpp:4:13] -> [test.cpp:7:14]: (style, inconclusive) Technically the member function 'Fred::A::getA' can be const. [functionConst]\n", errout_str()); // check deeply nested classes @@ -4092,7 +4092,7 @@ class TestClass : public TestFixture { " int getA() { return a; }\n" " };\n" " };\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style, inconclusive) Technically the member function 'Fred::B::getB' can be const. [functionConst]\n" "[test.cpp:7:17]: (style, inconclusive) Technically the member function 'Fred::B::A::getA' can be const. [functionConst]\n" , errout_str()); @@ -4108,7 +4108,7 @@ class TestClass : public TestFixture { " int A::getA() { return a; }\n" " };\n" " int B::getB() { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:13] -> [test.cpp:11:12]: (style, inconclusive) Technically the member function 'Fred::B::getB' can be const. [functionConst]\n" "[test.cpp:7:17] -> [test.cpp:9:16]: (style, inconclusive) Technically the member function 'Fred::B::A::getA' can be const. [functionConst]\n", errout_str()); @@ -4123,7 +4123,7 @@ class TestClass : public TestFixture { " };\n" " int B::A::getA() { return a; }\n" " int B::getB() { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:13] -> [test.cpp:11:12]: (style, inconclusive) Technically the member function 'Fred::B::getB' can be const. [functionConst]\n" "[test.cpp:7:17] -> [test.cpp:10:15]: (style, inconclusive) Technically the member function 'Fred::B::A::getA' can be const. [functionConst]\n", errout_str()); @@ -4138,7 +4138,7 @@ class TestClass : public TestFixture { " };\n" "};\n" "int Fred::B::A::getA() { return a; }\n" - "int Fred::B::getB() { return b; }"); + "int Fred::B::getB() { return b; }\n"); ASSERT_EQUALS("[test.cpp:4:13] -> [test.cpp:12:14]: (style, inconclusive) Technically the member function 'Fred::B::getB' can be const. [functionConst]\n" "[test.cpp:7:17] -> [test.cpp:11:17]: (style, inconclusive) Technically the member function 'Fred::B::A::getA' can be const. [functionConst]\n", errout_str()); } @@ -4148,7 +4148,7 @@ class TestClass : public TestFixture { checkConst("struct Fred {\n" " int a;\n" " bool operator<(const Fred &f) { return a < f.a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'Fred::operator<' can be const. [functionConst]\n", errout_str()); } @@ -4163,7 +4163,7 @@ class TestClass : public TestFixture { " {\n" " foo << 123;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct Foo {\n" @@ -4175,7 +4175,7 @@ class TestClass : public TestFixture { " {\n" " std::cout << foo << 123;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:10]: (style, inconclusive) Technically the member function 'Fred::x' can be const. [functionConst]\n", errout_str()); } @@ -4184,13 +4184,13 @@ class TestClass : public TestFixture { " int array[10];\n" " int const & operator [] (unsigned int index) const { return array[index]; }\n" " int & operator [] (unsigned int index) { return array[index]; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct Fred {\n" " int array[10];\n" " int const & operator [] (unsigned int index) { return array[index]; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style, inconclusive) Technically the member function 'Fred::operator[]' can be const. [functionConst]\n", errout_str()); } @@ -4200,14 +4200,14 @@ class TestClass : public TestFixture { " int c;\n" "public:\n" " operator int*() { return &c; };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" " int c;\n" "public:\n" " operator const int*() { return &c; };\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (style, inconclusive) Technically the member function 'A::operatorconstint*' can be const. [functionConst]\n", errout_str()); // #2375 @@ -4215,14 +4215,14 @@ class TestClass : public TestFixture { " int array[10];\n" " typedef int* (Fred::*UnspecifiedBoolType);\n" " operator UnspecifiedBoolType() { };\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::operatorint**' can be const.\n", "", errout_str()); checkConst("struct Fred {\n" " int array[10];\n" " typedef int* (Fred::*UnspecifiedBoolType);\n" " operator UnspecifiedBoolType() { array[0] = 0; };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4231,21 +4231,21 @@ class TestClass : public TestFixture { " int c;\n" "public:\n" " operator int& () {return c}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" " int c;\n" "public:\n" " operator const int& () {return c}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (style, inconclusive) Technically the member function 'A::operatorconstint&' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" " int c;\n" "public:\n" " operator int () {return c}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (style, inconclusive) Technically the member function 'A::operatorint' can be const. [functionConst]\n", errout_str()); } @@ -4253,7 +4253,7 @@ class TestClass : public TestFixture { checkConst("class A {\n" " int c;\n" " void f() { os >> *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4267,7 +4267,7 @@ class TestClass : public TestFixture { " same = (i == a);\n" " return same;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'A::foo' can be const. [functionConst]\n", errout_str()); } @@ -4276,14 +4276,14 @@ class TestClass : public TestFixture { checkConst("class foo {\n" "public:\n" "};\n" - "void bar() {}"); + "void bar() {}\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred\n" "{\n" "public:\n" " void foo() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); checkConst("struct fast_string\n" @@ -4297,7 +4297,7 @@ class TestClass : public TestFixture { "inline void fast_string::set_type(char t)\n" "{\n" " buff[10] = t;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4308,7 +4308,7 @@ class TestClass : public TestFixture { " void set(int i) { a = i; }\n" " void set(const foo & f) { *this = f; }\n" "};\n" - "void bar() {}"); + "void bar() {}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4320,7 +4320,7 @@ class TestClass : public TestFixture { " std::string strGetString() { return m_strValue; }\n" "private:\n" " std::string m_strValue;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:17]: (style, inconclusive) Technically the member function 'A::strGetString' can be const. [functionConst]\n", errout_str()); } @@ -4331,7 +4331,7 @@ class TestClass : public TestFixture { " void SetExitCode(wxThread::ExitCode exitcode) { m_exitcode = exitcode; }\n" "private:\n" " wxThread::ExitCode m_exitcode;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4342,7 +4342,7 @@ class TestClass : public TestFixture { " int foo() { return x = 0; }\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" @@ -4350,7 +4350,7 @@ class TestClass : public TestFixture { " int foo() { return x ? x : x = 0; }\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" @@ -4358,7 +4358,7 @@ class TestClass : public TestFixture { " int foo() { return x ? x = 0 : x; }\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4369,7 +4369,7 @@ class TestClass : public TestFixture { " void set(struct tm time) { m_time = time; }\n" "private:\n" " struct tm m_time;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4380,7 +4380,7 @@ class TestClass : public TestFixture { " int foo() { x = 0; }\n" "private:\n" " mutable int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style, inconclusive) Technically the member function 'A::foo' can be const. [functionConst]\n", errout_str()); } @@ -4394,7 +4394,7 @@ class TestClass : public TestFixture { "private:\n" " std::vector m_vec;\n" " std::pair m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:22]: (style, inconclusive) Technically the member function 'A::GetVec' can be const. [functionConst]\n" "[test.cpp:5:27]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); @@ -4406,7 +4406,7 @@ class TestClass : public TestFixture { "private:\n" " std::vector m_vec;\n" " std::pair m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:30]: (style, inconclusive) Technically the member function 'A::GetVec' can be const. [functionConst]\n" "[test.cpp:5:35]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); } @@ -4419,7 +4419,7 @@ class TestClass : public TestFixture { " std::pair,double> GetPair() {return m_pair;}\n" "private:\n" " std::pair,double> m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:40]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4428,7 +4428,7 @@ class TestClass : public TestFixture { " const std::pair,double>& GetPair() {return m_pair;}\n" "private:\n" " std::pair,double> m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:47]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4437,7 +4437,7 @@ class TestClass : public TestFixture { " std::pair,double>& GetPair() {return m_pair;}\n" "private:\n" " std::pair,double> m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -4448,7 +4448,7 @@ class TestClass : public TestFixture { " pair GetPair() {return m_pair;}\n" "private:\n" " pair m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:23]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("using namespace std;" @@ -4458,7 +4458,7 @@ class TestClass : public TestFixture { " const pair & GetPair() {return m_pair;}\n" "private:\n" " pair m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:31]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("using namespace std;" @@ -4468,7 +4468,7 @@ class TestClass : public TestFixture { " pair & GetPair() {return m_pair;}\n" "private:\n" " pair m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -4478,7 +4478,7 @@ class TestClass : public TestFixture { " std::pair< int,std::vector > GetPair() {return m_pair;}\n" "private:\n" " std::pair< int,std::vector > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:40]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4487,7 +4487,7 @@ class TestClass : public TestFixture { " const std::pair< int,std::vector >& GetPair() {return m_pair;}\n" "private:\n" " std::pair< int,std::vector > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:47]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4496,7 +4496,7 @@ class TestClass : public TestFixture { " std::pair< int,std::vector >& GetPair() {return m_pair;}\n" "private:\n" " std::pair< int,std::vector > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -4507,7 +4507,7 @@ class TestClass : public TestFixture { " pair< vector, int > GetPair() {return m_pair;}\n" "private:\n" " pair< vector, int > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:31]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("using namespace std;" @@ -4517,7 +4517,7 @@ class TestClass : public TestFixture { " const pair< vector, int >& GetPair() {return m_pair;}\n" "private:\n" " pair< vector, int > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:38]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("using namespace std;" @@ -4527,7 +4527,7 @@ class TestClass : public TestFixture { " pair< vector, int >& GetPair() {return m_pair;}\n" "private:\n" " pair< vector, int > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" @@ -4536,7 +4536,7 @@ class TestClass : public TestFixture { " std::pair< std::vector,std::vector > GetPair() {return m_pair;}\n" "private:\n" " std::pair< std::vector,std::vector > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:53]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4545,7 +4545,7 @@ class TestClass : public TestFixture { " const std::pair< std::vector,std::vector >& GetPair() {return m_pair;}\n" "private:\n" " std::pair< std::vector,std::vector > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:60]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4554,7 +4554,7 @@ class TestClass : public TestFixture { " std::pair< std::vector,std::vector >& GetPair() {return m_pair;}\n" "private:\n" " std::pair< std::vector,std::vector > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -4565,7 +4565,7 @@ class TestClass : public TestFixture { " std::pair< std::pair < int, char > , int > GetPair() {return m_pair;}\n" "private:\n" " std::pair< std::pair < int, char > , int > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:49]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4574,7 +4574,7 @@ class TestClass : public TestFixture { " const std::pair< std::pair < int, char > , int > & GetPair() {return m_pair;}\n" "private:\n" " std::pair< std::pair < int, char > , int > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:56]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4583,7 +4583,7 @@ class TestClass : public TestFixture { " std::pair< std::pair < int, char > , int > & GetPair() {return m_pair;}\n" "private:\n" " std::pair< std::pair < int, char > , int > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -4593,7 +4593,7 @@ class TestClass : public TestFixture { " std::pair< int , std::pair < int, char > > GetPair() {return m_pair;}\n" "private:\n" " std::pair< int , std::pair < int, char > > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:49]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4602,7 +4602,7 @@ class TestClass : public TestFixture { " const std::pair< int , std::pair < int, char > >& GetPair() {return m_pair;}\n" "private:\n" " std::pair< int , std::pair < int, char > > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:56]: (style, inconclusive) Technically the member function 'A::GetPair' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -4611,7 +4611,7 @@ class TestClass : public TestFixture { " std::pair< int , std::pair < int, char > >& GetPair() {return m_pair;}\n" "private:\n" " std::pair< int , std::pair < int, char > > m_pair;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -4622,7 +4622,7 @@ class TestClass : public TestFixture { " vector GetVec() {return m_Vec;}\n" "private:\n" " vector m_Vec;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:18]: (style, inconclusive) Technically the member function 'A::GetVec' can be const. [functionConst]\n", errout_str()); checkConst("using namespace std;" @@ -4632,7 +4632,7 @@ class TestClass : public TestFixture { " const vector& GetVec() {return m_Vec;}\n" "private:\n" " vector m_Vec;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:25]: (style, inconclusive) Technically the member function 'A::GetVec' can be const. [functionConst]\n", errout_str()); checkConst("using namespace std;" @@ -4642,7 +4642,7 @@ class TestClass : public TestFixture { " vector& GetVec() {return m_Vec;}\n" "private:\n" " vector m_Vec;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -4651,7 +4651,7 @@ class TestClass : public TestFixture { " int * * foo() { return &x; }\n" "private:\n" " const int * x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" @@ -4659,7 +4659,7 @@ class TestClass : public TestFixture { " const int ** foo() { return &x; }\n" "private:\n" " const int * x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:18]: (style, inconclusive) Technically the member function 'A::foo' can be const. [functionConst]\n", errout_str()); } @@ -4667,7 +4667,7 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " unsigned long long int a;\n" " unsigned long long int getA() { return a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:28]: (style, inconclusive) Technically the member function 'Fred::getA' can be const. [functionConst]\n", errout_str()); // constructors can't be const.. @@ -4675,14 +4675,14 @@ class TestClass : public TestFixture { " unsigned long long int a;\n" "public:\n" " Fred() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // assignment through |=.. checkConst("class Fred {\n" " unsigned long long int a;\n" " unsigned long long int setA() { a |= true; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // static functions can't be const.. @@ -4691,7 +4691,7 @@ class TestClass : public TestFixture { "public:\n" " static unsigned long long int get()\n" " { return 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4700,7 +4700,7 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int a;\n" " void set(int i) { Fred::a = i; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4711,7 +4711,7 @@ class TestClass : public TestFixture { " void set(int i, int j) { a[i].k = i; }\n" "private:\n" " struct { int k; } a[4];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4720,7 +4720,7 @@ class TestClass : public TestFixture { "static int x;\n" "public:\n" " void set(int i) { x = i; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) The member function 'Fred::set' can be static. [functionStatic]\n", errout_str()); } @@ -4732,7 +4732,7 @@ class TestClass : public TestFixture { " std::string s;\n" "public:\n" " void set(std::string ss) { s = ss; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4742,35 +4742,35 @@ class TestClass : public TestFixture { " int x : 3;\n" "public:\n" " void set(int i) { x = i; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " list x;\n" "public:\n" " list get() { return x; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " list x;\n" "public:\n" " list get() { return x; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:23]: (style, inconclusive) Technically the member function 'Fred::get' can be const. [functionConst]\n", errout_str()); checkConst("class Fred {\n" " std::list x;\n" "public:\n" " std::list get() { return x; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " std::list x;\n" "public:\n" " std::list get() { return x; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:36]: (style, inconclusive) Technically the member function 'Fred::get' can be const. [functionConst]\n", errout_str()); } @@ -4786,7 +4786,7 @@ class TestClass : public TestFixture { " for (int i = 0 ; i < 10; l1[i] = NULL, i++);\n" " }\n" " void f1() { l1[0] = \"Hello\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4797,7 +4797,7 @@ class TestClass : public TestFixture { " B::C * v1;\n" "public:\n" " void f1() { v1 = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A\n" @@ -4806,7 +4806,7 @@ class TestClass : public TestFixture { " B::C * v1[0];\n" "public:\n" " void f1() { v1[0] = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4818,7 +4818,7 @@ class TestClass : public TestFixture { " void set_member(Type2 m) { _m = m; }\n" "private:\n" " Type2 _m;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4831,7 +4831,7 @@ class TestClass : public TestFixture { "}\n" "private:\n" " std::map *m_pSettings;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4846,7 +4846,7 @@ class TestClass : public TestFixture { "{return m_strVal.c_str();}\n" "private:\n" "std::string m_strVal;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A{\n" @@ -4856,7 +4856,7 @@ class TestClass : public TestFixture { "{return m_strVal.c_str();}\n" "private:\n" "std::string m_strVal;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style, inconclusive) Technically the member function 'A::strGetString' can be const. [functionConst]\n", errout_str()); checkConst("class A{\n" @@ -4866,7 +4866,7 @@ class TestClass : public TestFixture { "{return m_strVal.c_str();}\n" "private:\n" "std::string m_strVal;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:19]: (style, inconclusive) Technically the member function 'A::strGetString1' can be const. [functionConst]\n", errout_str()); checkConst("class A{\n" @@ -4876,7 +4876,7 @@ class TestClass : public TestFixture { "{return m_strVec.size();}\n" "private:\n" "std::vector m_strVec;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:8]: (style, inconclusive) Technically the member function 'A::strGetSize' can be const. [functionConst]\n", errout_str()); checkConst("class A{\n" @@ -4886,7 +4886,7 @@ class TestClass : public TestFixture { "{return m_strVec.empty();}\n" "private:\n" "std::vector m_strVec;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:6]: (style, inconclusive) Technically the member function 'A::strGetEmpty' can be const. [functionConst]\n", errout_str()); } @@ -4897,7 +4897,7 @@ class TestClass : public TestFixture { " std::swap(delays_[index1], delays_[index2]);\n" "}\n" "float delays_[4];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct DelayBase {\n" @@ -4905,7 +4905,7 @@ class TestClass : public TestFixture { " return delays_[index1];\n" " }\n" " float delays_[4];\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style, inconclusive) Technically the member function 'DelayBase::swapSpecificDelays' can be const. [functionConst]\n", errout_str()); } @@ -4923,7 +4923,7 @@ class TestClass : public TestFixture { " if( m_d != 0 )\n" " return m_iRealVal / m_d;\n" " return dRet;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:12] -> [test.cpp:9:12]: (style, inconclusive) Technically the member function 'A::dGetValue' can be const. [functionConst]\n", errout_str()); } @@ -4940,7 +4940,7 @@ class TestClass : public TestFixture { " x=xPos;\n" " y=yPos;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class AA : public P {\n" @@ -4950,7 +4950,7 @@ class TestClass : public TestFixture { " {\n" " UnknownScope::x = x_;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class AA {\n" @@ -4960,7 +4960,7 @@ class TestClass : public TestFixture { " {\n" " UnknownScope::x = x_;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:17]: (style) The member function 'AA::vSetXPos' can be static. [functionStatic]\n", errout_str()); } @@ -4985,7 +4985,7 @@ class TestClass : public TestFixture { "char* test::get()\n" "{\n" " return value_;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5000,7 +5000,7 @@ class TestClass : public TestFixture { " int get() {\n" " return a;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:9]: (style, inconclusive) Technically the member function 'Derived::get' can be const. [functionConst]\n", errout_str()); checkConst("class Base1 {\n" @@ -5019,7 +5019,7 @@ class TestClass : public TestFixture { " int getB() {\n" " return b;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:11:9]: (style, inconclusive) Technically the member function 'Derived::getA' can be const. [functionConst]\n" "[test.cpp:14:9]: (style, inconclusive) Technically the member function 'Derived::getB' can be const. [functionConst]\n", errout_str()); @@ -5033,7 +5033,7 @@ class TestClass : public TestFixture { " int get() {\n" " return a;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:9]: (style, inconclusive) Technically the member function 'Derived2::get' can be const. [functionConst]\n", errout_str()); checkConst("class Base {\n" @@ -5048,7 +5048,7 @@ class TestClass : public TestFixture { " int get() {\n" " return a;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:10:9]: (style, inconclusive) Technically the member function 'Derived4::get' can be const. [functionConst]\n", errout_str()); // check for false positives @@ -5061,7 +5061,7 @@ class TestClass : public TestFixture { " int get() const {\n" " return a;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Base1 {\n" @@ -5080,7 +5080,7 @@ class TestClass : public TestFixture { " int getB() const {\n" " return b;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Base {\n" @@ -5093,7 +5093,7 @@ class TestClass : public TestFixture { " int get() const {\n" " return a;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Base {\n" @@ -5108,7 +5108,7 @@ class TestClass : public TestFixture { " int get() const {\n" " return a;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5118,7 +5118,7 @@ class TestClass : public TestFixture { "public:\n" " int a;\n" " int get() { return a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:9]: (style, inconclusive) Technically the member function 'Fred::get' can be const. [functionConst]\n", errout_str()); } @@ -5127,7 +5127,7 @@ class TestClass : public TestFixture { "public:\n" " std::string a[10];\n" " void seta() { a[0] = \"\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5135,7 +5135,7 @@ class TestClass : public TestFixture { checkConst("class derived : public base {\n" "public:\n" " void f(){}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) Either there is a missing 'override', or the member function 'derived::f' can be static. [functionStatic]\n", errout_str()); } @@ -5144,7 +5144,7 @@ class TestClass : public TestFixture { " void init(Foo * foo) {\n" " foo.bar = this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5163,7 +5163,7 @@ class TestClass : public TestFixture { " int getResourceName() { return var; }\n" " int var;\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:12:21]: (style, inconclusive) Technically the member function 'N::Derived::getResourceName' can be const. [functionConst]\n", errout_str()); checkConst("namespace N\n" @@ -5175,7 +5175,7 @@ class TestClass : public TestFixture { " int var;\n" " };\n" "}\n" - "int N::Base::getResourceName() { return var; }"); + "int N::Base::getResourceName() { return var; }\n"); ASSERT_EQUALS("[test.cpp:6:21] -> [test.cpp:10:14]: (style, inconclusive) Technically the member function 'N::Base::getResourceName' can be const. [functionConst]\n", errout_str()); checkConst("namespace N\n" @@ -5190,7 +5190,7 @@ class TestClass : public TestFixture { "namespace N\n" "{\n" " int Base::getResourceName() { return var; }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:21] -> [test.cpp:12:19]: (style, inconclusive) Technically the member function 'N::Base::getResourceName' can be const. [functionConst]\n", errout_str()); checkConst("namespace N\n" @@ -5203,7 +5203,7 @@ class TestClass : public TestFixture { " };\n" "}\n" "using namespace N;\n" - "int Base::getResourceName() { return var; }"); + "int Base::getResourceName() { return var; }\n"); ASSERT_EQUALS("[test.cpp:6:21] -> [test.cpp:11:11]: (style, inconclusive) Technically the member function 'N::Base::getResourceName' can be const. [functionConst]\n", errout_str()); } @@ -5215,7 +5215,7 @@ class TestClass : public TestFixture { " {\n" " m_MaxQueueSize = a_MaxQueueSize;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5230,7 +5230,7 @@ class TestClass : public TestFixture { " }\n" "private:\n" " std::string m_str;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:17]: (style, inconclusive) Technically the member function 'A::operator+' can be const. [functionConst]\n", errout_str()); checkConst("class Fred\n" @@ -5244,7 +5244,7 @@ class TestClass : public TestFixture { " bool isValid() {\n" " return (x == 0x11224488);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:9:10]: (style, inconclusive) Technically the member function 'Fred::isValid' can be const. [functionConst]\n", errout_str()); } @@ -5260,7 +5260,7 @@ class TestClass : public TestFixture { "void Foo::MyMethod()\n" "{\n" " (*oArq) << \"\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5280,7 +5280,7 @@ class TestClass : public TestFixture { "int * Foo::f()\n" "{\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5297,7 +5297,7 @@ class TestClass : public TestFixture { " {\n" " pView = aView;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5311,7 +5311,7 @@ class TestClass : public TestFixture { " {\n" " m_name = name;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -5323,7 +5323,7 @@ class TestClass : public TestFixture { " {\n" " pNum = apNum;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -5338,7 +5338,7 @@ class TestClass : public TestFixture { " {\n" " pNum = apNum;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -5355,7 +5355,7 @@ class TestClass : public TestFixture { " {\n" " pNum = apNum;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -5373,7 +5373,7 @@ class TestClass : public TestFixture { " {\n" " pNum = apNum;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5387,7 +5387,7 @@ class TestClass : public TestFixture { "};\n" "bool Fred::f(Fred::AB * ab)\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10] -> [test.cpp:7:12]: (style) The member function 'Fred::f' can be static. [functionStatic]\n", errout_str()); @@ -5401,7 +5401,7 @@ class TestClass : public TestFixture { "};\n" "bool Fred::f(Fred::AB::CD * cd)\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:10] -> [test.cpp:9:12]: (style) The member function 'Fred::f' can be static. [functionStatic]\n", errout_str()); @@ -5417,7 +5417,7 @@ class TestClass : public TestFixture { " bool Fred::f(Fred::AB::CD * cd)\n" " {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:10:16]: (style) The member function 'NS::Fred::f' can be static. [functionStatic]\n", errout_str()); @@ -5433,7 +5433,7 @@ class TestClass : public TestFixture { "}\n" "bool NS::Fred::f(NS::Fred::AB::CD * cd)\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:11:16]: (style) The member function 'NS::Fred::f' can be static. [functionStatic]\n", errout_str()); @@ -5449,7 +5449,7 @@ class TestClass : public TestFixture { "};\n" "bool Foo::Fred::f(Foo::Fred::AB::CD * cd)\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:11:17]: (style) The member function 'Foo::Fred::f' can be static. [functionStatic]\n", errout_str()); } @@ -5464,7 +5464,7 @@ class TestClass : public TestFixture { "void A::foo( AA::BB::CC::DD b )\n" "{\n" " a = b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -5488,7 +5488,7 @@ class TestClass : public TestFixture { " {\n" " a = b;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -5508,7 +5508,7 @@ class TestClass : public TestFixture { " {\n" " a = b;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5521,7 +5521,7 @@ class TestClass : public TestFixture { " {\n" " return 0 != (bOn = bOn);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5538,7 +5538,7 @@ class TestClass : public TestFixture { " {\n" " }\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:13]: (style) The member function 'tools::WorkspaceControl::toGrid' can be static. [functionStatic]\n", errout_str()); } @@ -5553,7 +5553,7 @@ class TestClass : public TestFixture { " int fun2() {\n" " b++;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) The member function 'Altren::fun1' can be static. [functionStatic]\n" "[test.cpp:7:9]: (style) The member function 'Altren::fun2' can be static. [functionStatic]\n", errout_str()); @@ -5565,7 +5565,7 @@ class TestClass : public TestFixture { " void foo() { delete this; }\n" " void foo(int i) const { }\n" " void bar() { foo(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:8]: (style) The member function 'Altren::foo' can be static. [functionStatic]\n", errout_str()); @@ -5574,7 +5574,7 @@ class TestClass : public TestFixture { " void foo() { delete this; }\n" " void foo(int i) const { }\n" " void bar() { foo(1); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:8]: (style) The member function 'Altren::foo' can be static. [functionStatic]\n" "[test.cpp:5:8]: (style, inconclusive) Technically the member function 'Altren::bar' can be const. [functionConst]\n", errout_str()); @@ -5597,7 +5597,7 @@ class TestClass : public TestFixture { "};\n" "bool TextIterator::setTagColour() {\n" " mSave = mCurrent;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5612,7 +5612,7 @@ class TestClass : public TestFixture { " {\n" " return _hash[key];\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5627,7 +5627,7 @@ class TestClass : public TestFixture { "{\n" " if (mTileSize.height > 0) return;\n" " if (mEmptyView) return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5641,7 +5641,7 @@ class TestClass : public TestFixture { " void SetSection(uint num) { pesdata()[6] = num; }\n" "private:\n" " unsigned char *_pesdata;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class PESPacket {\n" @@ -5656,7 +5656,7 @@ class TestClass : public TestFixture { "{\n" "public:\n" " void SetSection(uint num) { pesdata()[6] = num; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5666,7 +5666,7 @@ class TestClass : public TestFixture { " void DoSomethingElse() { DoSomething(bar); }\n" "private:\n" " int bar;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'foo::DoSomething' can be static. [functionStatic]\n", errout_str()); } @@ -5682,7 +5682,7 @@ class TestClass : public TestFixture { " public:\n" " B() {};\n" " bool One(bool b = false) { return false; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5690,7 +5690,7 @@ class TestClass : public TestFixture { checkConst("class Example {\n" " public:\n" " void Clear(void) { Example tmp; (*this) = tmp; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5700,7 +5700,7 @@ class TestClass : public TestFixture { " MyObject() : tmp(0) {}\n" "public:\n" " void set(std::stringstream &in) { in >> tmp; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5710,7 +5710,7 @@ class TestClass : public TestFixture { " void foo(int x) {\n" " switch (x) { }\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'MyObject::foo' can be static. [functionStatic]\n", errout_str()); checkConst("class A\n" @@ -5750,7 +5750,7 @@ class TestClass : public TestFixture { " }\n" "\n" " return RET_NOK;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:24] -> [test.cpp:9:19]: (style) The member function 'A::f' can be static. [functionStatic]\n", errout_str()); checkConst("class MyObject {\n" @@ -5758,7 +5758,7 @@ class TestClass : public TestFixture { " void foo(int x) {\n" " for (int i = 0; i < 5; i++) { }\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'MyObject::foo' can be static. [functionStatic]\n", errout_str()); } @@ -5783,7 +5783,7 @@ class TestClass : public TestFixture { " }\n" "private:\n" " MyGUI::IntCoord mCoordValue;\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:7:13]: (style) The member function 'MyGUI::types::TCoord::size' can be static. [functionStatic]\n" "[test.cpp:15]: (style, inconclusive) Technically the member function 'SelectorControl::getSize' can be const.\n", "[test.cpp:7:13]: (style) The member function 'MyGUI::types::TCoord::size' can be static. [functionStatic]\n", errout_str()); @@ -5793,7 +5793,7 @@ class TestClass : public TestFixture { " void foo(Foo f) {\n" " b.run();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct Bar {\n" @@ -5805,7 +5805,7 @@ class TestClass : public TestFixture { " void foo(Foo f) {\n" " b.run();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct Bar {\n" @@ -5816,7 +5816,7 @@ class TestClass : public TestFixture { " void foo(Foo f) {\n" " b.run();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'Bar::run' can be static. [functionStatic]\n" "[test.cpp:6:10]: (style, inconclusive) Technically the member function 'Foo::foo' can be const. [functionConst]\n", errout_str()); } @@ -5826,14 +5826,14 @@ class TestClass : public TestFixture { " void foo(Foo f) {\n" " f.clear();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'MyObject::foo' can be static. [functionStatic]\n", errout_str()); checkConst("struct MyObject {\n" " int foo(Foo f) {\n" " return f.length();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) The member function 'MyObject::foo' can be static. [functionStatic]\n", errout_str()); checkConst("struct MyObject {\n" @@ -5841,7 +5841,7 @@ class TestClass : public TestFixture { " int foo() {\n" " return f.length();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct MyObject {\n" @@ -5849,7 +5849,7 @@ class TestClass : public TestFixture { " int foo() {\n" " return f.length();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style, inconclusive) Technically the member function 'MyObject::foo' can be const. [functionConst]\n", errout_str()); } @@ -5861,7 +5861,7 @@ class TestClass : public TestFixture { "protected:\n" " int re;\n" " int im;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5876,7 +5876,7 @@ class TestClass : public TestFixture { " MyString append( const MyString& str )\n" " { return operator+=( str ); }\n" " char *m_ptr;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class MyString {\n" "public:\n" @@ -5885,7 +5885,7 @@ class TestClass : public TestFixture { " MyString append( const MyString& str )\n" " { return operator+=( str ); }\n" " char *m_ptr;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5896,14 +5896,14 @@ class TestClass : public TestFixture { "};\n" "int MixerParticipant::GetAudioFrame() {\n" " return 0;\n" - "}"); + "}\n"); // this code is invalid so a false negative is OK checkConst("class MixerParticipant : public MixerParticipant {\n" " bool InitializeFileReader() {\n" " printf(\"music\");\n" " }\n" - "};"); + "};\n"); // Based on an example from SVN source code causing an endless recursion within CheckClass::isConstMemberFunc() // A more complete example including a template declaration like @@ -5936,7 +5936,7 @@ class TestClass : public TestFixture { " {\n" " return _hash[key];\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -5947,7 +5947,7 @@ class TestClass : public TestFixture { " std::string* p = &s;\n" " p->clear();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct A {\n" @@ -5956,7 +5956,7 @@ class TestClass : public TestFixture { " std::string& r = s;\n" " r.clear();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct A {\n" @@ -5965,7 +5965,7 @@ class TestClass : public TestFixture { " std::string& r = sth; r = s;\n" " r.clear();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'A::clear' can be const. [functionConst]\n", errout_str()); checkConst("struct A {\n" @@ -5974,7 +5974,7 @@ class TestClass : public TestFixture { " const std::string* p = &s;\n" " p->somefunction();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'A::clear' can be const. [functionConst]\n", errout_str()); checkConst("struct A {\n" @@ -5983,7 +5983,7 @@ class TestClass : public TestFixture { " const std::string& r = s;\n" " r.somefunction();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'A::clear' can be const. [functionConst]\n", errout_str()); } @@ -5998,7 +5998,7 @@ class TestClass : public TestFixture { " }\n" " ::B::D::DKIPtr membervariable;\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -6017,7 +6017,7 @@ class TestClass : public TestFixture { " TemplateClass a;\n" " TemplateClass b;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -6027,7 +6027,7 @@ class TestClass : public TestFixture { " void f(int v) { g((char *) &v); }\n" " void g(char *) { n++; }\n" " int n;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -6041,7 +6041,7 @@ class TestClass : public TestFixture { "public:\n" " const std::list>& get() { return m_test.m_list; }\n" " TestList> m_test;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:44]: (style, inconclusive) Technically the member function 'Test::get' can be const. [functionConst]\n", errout_str()); } @@ -6071,7 +6071,7 @@ class TestClass : public TestFixture { " call();\n" " call(1, 2, 3);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -6084,7 +6084,7 @@ class TestClass : public TestFixture { " void test() {\n" " call(1, 2);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -6219,7 +6219,7 @@ class TestClass : public TestFixture { " void bar(void) {\n" " for(std::vector::const_iterator it = m_str.begin(); it != m_str.end(); ++it) {;}\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:10]: (style, inconclusive) Technically the member function 'A::bar' can be const. [functionConst]\n", errout_str()); // Don't crash @@ -7074,7 +7074,7 @@ class TestClass : public TestFixture { " int bar6() {\n" " return foo3();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:11:9]: (style) The member function 'Foo::bar3' can be static. [functionStatic]\n" "[test.cpp:14:9]: (style) The member function 'Foo::bar4' can be static. [functionStatic]\n", errout_str()); } @@ -7085,7 +7085,7 @@ class TestClass : public TestFixture { " Bar b;\n" " b.takeFoo(this);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct Foo {\n" @@ -7093,7 +7093,7 @@ class TestClass : public TestFixture { " Foo f;\n" " f.foo();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'Foo::foo' can be static. [functionStatic]\n", errout_str()); checkConst("struct A;\n" // #5839 - operator() @@ -7104,7 +7104,7 @@ class TestClass : public TestFixture { " void dostuff() {\n" " B()(this);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7116,7 +7116,7 @@ class TestClass : public TestFixture { " {\n" " v = 0;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7128,7 +7128,7 @@ class TestClass : public TestFixture { " {\n" " v[0] = \"Happy new year!\";\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7137,49 +7137,49 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int a;\n" " void nextA() { return ++a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a;\n" " void nextA() { return --a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a;\n" " void nextA() { return a++; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a;\n" " void nextA() { return a--; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return ++a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return --a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a++; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a--; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct S {\n" // #10077 @@ -7195,61 +7195,61 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int a;\n" " void nextA() { return a=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a;\n" " void nextA() { return a-=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a;\n" " void nextA() { return a+=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a;\n" " void nextA() { return a*=-1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a;\n" " void nextA() { return a/=-2; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a-=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a+=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a*=-1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a/=-2; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); } @@ -7257,90 +7257,90 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " struct A { int a; } s;\n" " void nextA() { return s.a=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " struct A { int a; } s;\n" " void nextA() { return s.a-=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " struct A { int a; } s;\n" " void nextA() { return s.a+=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " struct A { int a; } s;\n" " void nextA() { return s.a*=-1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a-=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a+=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a*=-1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a/=-2; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; };\n" "class Fred {\n" " A s;\n" " void nextA() { return s.a=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct A { int a; };\n" "class Fred {\n" " A s;\n" " void nextA() { return s.a-=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct A { int a; };\n" "class Fred {\n" " A s;\n" " void nextA() { return s.a+=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct A { int a; };\n" "class Fred {\n" " A s;\n" " void nextA() { return s.a*=-1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("struct A { int a; };\n" "class Fred {\n" " A s;\n" " void nextA() { return s.a/=-2; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7349,49 +7349,49 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return ++a[0]; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return --a[0]; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return a[0]++; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return a[0]--; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return ++a[0]; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return --a[0]; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]++; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]--; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); } @@ -7399,61 +7399,61 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return a[0]=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return a[0]-=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return a[0]+=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return a[0]*=-1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class Fred {\n" " int a[2];\n" " void nextA() { return a[0]/=-2; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]-=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]+=1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]*=-1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]/=-2; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); } @@ -7462,8 +7462,8 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int a;\n" " int &getR() { return a; }\n" - " int *getP() { return &a; }" - "};"); + " int *getP() { return &a; }\n" + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7472,7 +7472,7 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " int *a;\n" " void clean() { delete a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7480,14 +7480,14 @@ class TestClass : public TestFixture { void constLPVOID() { checkConst("class Fred {\n" " UNKNOWN a() { return 0; };\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:2]: (style) The member function 'Fred::a' can be static.\n", "", errout_str()); // #1579 - HDC checkConst("class Fred {\n" " foo bar;\n" " UNKNOWN a() { return b; };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7496,7 +7496,7 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " void f() const { };\n" " void a() { f(); };\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'Fred::f' can be static. [functionStatic]\n" "[test.cpp:3:10]: (style, inconclusive) Technically the member function 'Fred::a' can be const. [functionConst]\n", errout_str()); @@ -7507,7 +7507,7 @@ class TestClass : public TestFixture { "public:\n" " A(){}\n" " unsigned int GetVecSize() {return m_v.size();}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:17]: (style, inconclusive) Technically the member function 'A::GetVecSize' can be const. [functionConst]\n", errout_str()); checkConst("class A\n" @@ -7516,7 +7516,7 @@ class TestClass : public TestFixture { "public:\n" " A(){}\n" " bool GetVecEmpty() {return m_v.empty();}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:9]: (style, inconclusive) Technically the member function 'A::GetVecEmpty' can be const. [functionConst]\n", errout_str()); } @@ -7528,7 +7528,7 @@ class TestClass : public TestFixture { "public:\n" " B() : b(0) { }\n" " int func() { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:8]: (style, inconclusive) Technically the member function 'B::func' can be const. [functionConst]\n", errout_str()); checkConst("class A { };\n" @@ -7538,7 +7538,7 @@ class TestClass : public TestFixture { " B() : b(0) { }\n" " int func();\n" "};\n" - "int B::func() { return b; }"); + "int B::func() { return b; }\n"); ASSERT_EQUALS("[test.cpp:6:8] -> [test.cpp:8:8]: (style, inconclusive) Technically the member function 'B::func' can be const. [functionConst]\n", errout_str()); // base class has no virtual function @@ -7551,7 +7551,7 @@ class TestClass : public TestFixture { "public:\n" " B() : b(0) { }\n" " int func() { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:9:9]: (style, inconclusive) Technically the member function 'B::func' can be const. [functionConst]\n", errout_str()); checkConst("class A {\n" @@ -7564,7 +7564,7 @@ class TestClass : public TestFixture { " B() : b(0) { }\n" " int func();\n" "};\n" - "int B::func() { return b; }"); + "int B::func() { return b; }\n"); ASSERT_EQUALS("[test.cpp:9:9] -> [test.cpp:11:8]: (style, inconclusive) Technically the member function 'B::func' can be const. [functionConst]\n", errout_str()); // base class has virtual function @@ -7577,7 +7577,7 @@ class TestClass : public TestFixture { "public:\n" " B() : b(0) { }\n" " int func() { return b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" @@ -7590,7 +7590,7 @@ class TestClass : public TestFixture { " B() : b(0) { }\n" " int func();\n" "};\n" - "int B::func() { return b; }"); + "int B::func() { return b; }\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" @@ -7603,7 +7603,7 @@ class TestClass : public TestFixture { " B() : b(0) { }\n" " int func();\n" "};\n" - "int B::func() { return b; }"); + "int B::func() { return b; }\n"); ASSERT_EQUALS("", errout_str()); // base class has no virtual function @@ -7624,7 +7624,7 @@ class TestClass : public TestFixture { "public:\n" " C() : c(0) { }\n" " int func() { return c; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:9]: (style, inconclusive) Technically the member function 'A::func' can be const. [functionConst]\n" "[test.cpp:11:9]: (style, inconclusive) Technically the member function 'B::func' can be const. [functionConst]\n" "[test.cpp:17:9]: (style, inconclusive) Technically the member function 'C::func' can be const. [functionConst]\n", errout_str()); @@ -7649,7 +7649,7 @@ class TestClass : public TestFixture { " C() : c(0) { }\n" " int func();\n" "};\n" - "int C::func() { return c; }"); + "int C::func() { return c; }\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:7:8]: (style, inconclusive) Technically the member function 'A::func' can be const. [functionConst]\n" "[test.cpp:12:9] -> [test.cpp:14:8]: (style, inconclusive) Technically the member function 'B::func' can be const. [functionConst]\n" "[test.cpp:19:9] -> [test.cpp:21:8]: (style, inconclusive) Technically the member function 'C::func' can be const. [functionConst]\n", errout_str()); @@ -7672,7 +7672,7 @@ class TestClass : public TestFixture { "public:\n" " C() : c(0) { }\n" " int func() { return c; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkConst("class A {\n" @@ -7695,7 +7695,7 @@ class TestClass : public TestFixture { " C() : c(0) { }\n" " int func();\n" "};\n" - "int C::func() { return c; }"); + "int C::func() { return c; }\n"); ASSERT_EQUALS("", errout_str()); // ticket #1311 @@ -7716,7 +7716,7 @@ class TestClass : public TestFixture { "public:\n" " Z(int x, int y, int z) : Y(x, y), z(z) { }\n" " int getZ() { return z; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:9]: (style, inconclusive) Technically the member function 'X::getX' can be const. [functionConst]\n" "[test.cpp:11:9]: (style, inconclusive) Technically the member function 'Y::getY' can be const. [functionConst]\n" "[test.cpp:17:9]: (style, inconclusive) Technically the member function 'Z::getZ' can be const. [functionConst]\n", errout_str()); @@ -7741,7 +7741,7 @@ class TestClass : public TestFixture { " Z(int x, int y, int z) : Y(x, y), z(z) { }\n" " int getZ();\n" "};\n" - "int Z::getZ() { return z; }"); + "int Z::getZ() { return z; }\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:7:8]: (style, inconclusive) Technically the member function 'X::getX' can be const. [functionConst]\n" "[test.cpp:12:9] -> [test.cpp:14:8]: (style, inconclusive) Technically the member function 'Y::getY' can be const. [functionConst]\n" "[test.cpp:19:9] -> [test.cpp:21:8]: (style, inconclusive) Technically the member function 'Z::getZ' can be const. [functionConst]\n", errout_str()); @@ -7755,7 +7755,7 @@ class TestClass : public TestFixture { //" i = 4;\n" //"endif\n" " }\n" - "};"; + "};\n"; checkConst(code); ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'foo::f' can be static. [functionStatic]\n", errout_str()); @@ -7767,7 +7767,7 @@ class TestClass : public TestFixture { void constFriend() { // ticket #1921 const char code[] = "class foo {\n" " friend void f() { }\n" - "};"; + "};\n"; checkConst(code); ASSERT_EQUALS("", errout_str()); } @@ -7782,7 +7782,7 @@ class TestClass : public TestFixture { " void setf(float x) {\n" " d.f = x;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7799,7 +7799,7 @@ class TestClass : public TestFixture { " T c() {\n" " return y[1][6];\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:10:7]: (style, inconclusive) Technically the member function 'foo::c' can be const. [functionConst]\n", errout_str()); } @@ -7819,7 +7819,7 @@ class TestClass : public TestFixture { " for (decltype(auto) e : array)\n" " foo(e);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:10]: (style, inconclusive) Technically the member function 'Fred::f2' can be const. [functionConst]\n", errout_str()); checkConst("struct T {\n" // #14390 @@ -7844,7 +7844,7 @@ class TestClass : public TestFixture { " std::shared_ptr data;\n" "};\n" "\n" - "std::shared_ptr Fred::getData() { return data; }"); + "std::shared_ptr Fred::getData() { return data; }\n"); ASSERT_EQUALS("", errout_str()); } @@ -7852,7 +7852,7 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" "public:\n" " const char *const *data;\n" - " const char *const *getData() { return data; }\n}"); + " const char *const *getData() { return data; }\n}\n"); ASSERT_EQUALS("[test.cpp:4:24]: (style, inconclusive) Technically the member function 'Fred::getData' can be const. [functionConst]\n", errout_str()); } @@ -7860,7 +7860,7 @@ class TestClass : public TestFixture { checkConst("struct A {\n" " int x = 1;\n" " auto get() -> int & { return x; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7919,7 +7919,7 @@ class TestClass : public TestFixture { " int a, b, c;\n" "public:\n" " Fred() : c(0), b(0), a(0) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:20] -> [test.cpp:2:12]: (style, inconclusive) Member variable 'Fred::b' is in the wrong place in the initializer list. [initializerList]\n" "[test.cpp:4:26] -> [test.cpp:2:9]: (style, inconclusive) Member variable 'Fred::a' is in the wrong place in the initializer list. [initializerList]\n", errout_str()); @@ -7927,14 +7927,14 @@ class TestClass : public TestFixture { " int a, b, c;\n" "public:\n" " Fred() : c{0}, b{0}, a{0} { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:20] -> [test.cpp:2:12]: (style, inconclusive) Member variable 'Fred::b' is in the wrong place in the initializer list. [initializerList]\n" "[test.cpp:4:26] -> [test.cpp:2:9]: (style, inconclusive) Member variable 'Fred::a' is in the wrong place in the initializer list. [initializerList]\n", errout_str()); checkInitializerListOrder("struct S {\n" " S() : b(a = 1) {}\n" " int a, b;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("struct S {\n" @@ -7957,7 +7957,7 @@ class TestClass : public TestFixture { " : B(\"abc\", s.nRows(), s.nCols())\n" " , m_i(_i)\n" " {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -7968,41 +7968,41 @@ class TestClass : public TestFixture { " C() : b(&a) {}\n" " B b;\n" " const A a;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:11] -> [test.cpp:5:7]: (style, inconclusive) Member variable 'C::b' uses an uninitialized argument 'a' due to the order of declarations. [initializerList]\n", errout_str()); checkInitializerListOrder("struct S {\n" " S(const std::string& f, std::string i, int b, int c) : a(0), b(b), c(c) {}\n" " int a, b, c;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("struct S {\n" " S() : p(a) {}\n" " int* p;\n" " int a[1];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("struct S {\n" " S() : p(&i) {}\n" " int* p;\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("struct S {\n" " S() : a(b = 1) {}\n" " int a, b;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("struct S {\n" " S() : r(i) {}\n" " int& r;\n" " int i{};\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("struct B {\n" @@ -8011,7 +8011,7 @@ class TestClass : public TestFixture { "struct D : B {\n" " D() : B(), j(b) {}\n" " int j;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("struct S {\n" @@ -8019,13 +8019,13 @@ class TestClass : public TestFixture { " int a;\n" " static int i;\n" "};\n" - "int S::i = 0;"); + "int S::i = 0;\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("struct S {\n" " S(int b) : a(b) {}\n" " int a, b{};\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializerListOrder("class Foo {\n" // #3524 @@ -8075,113 +8075,113 @@ class TestClass : public TestFixture { " int* b;\n" // No message for pointers: No performance gain " Enum c;\n" // No message for enums: No performance gain " Fred() { a = 0; b = 0; c = C; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class Fred {\n" " std::string s;\n" " Fred() { a = 0; s = \"foo\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:21]: (performance) Variable 's' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]\n", errout_str()); checkInitializationListUsage("class Fred {\n" " std::string& s;\n" // Message is invalid for references, since their initialization in initializer list is required anyway and behaves different from assignment (#5004) " Fred(const std::string& s_) : s(s_) { s = \"foo\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class Fred {\n" " std::vector v;\n" " Fred() { v = unknown; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:14]: (performance) Variable 'v' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]\n", errout_str()); checkInitializationListUsage("class C { std::string s; };\n" "class Fred {\n" " C c;\n" " Fred() { c = unknown; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:14]: (performance) Variable 'c' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]\n", errout_str()); checkInitializationListUsage("class C;\n" "class Fred {\n" " C c;\n" " Fred() { c = unknown; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:14]: (performance) Variable 'c' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]\n", errout_str()); checkInitializationListUsage("class C;\n" "class Fred {\n" " C c;\n" " Fred(Fred const & other) { c = other.c; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:32]: (performance) Variable 'c' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]\n", errout_str()); checkInitializationListUsage("class C;\n" "class Fred {\n" " C c;\n" " Fred(Fred && other) { c = other.c; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:27]: (performance) Variable 'c' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]\n", errout_str()); checkInitializationListUsage("class C;\n" "class Fred {\n" " C a;\n" " Fred() { initB(); a = b; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class C;\n" "class Fred {\n" " C a;\n" " Fred() : a(0) { if(b) a = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class C;\n" "class Fred {\n" " C a[5];\n" " Fred() { for(int i = 0; i < 5; i++) a[i] = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class C;\n" "class Fred {\n" " C a; int b;\n" " Fred() : b(5) { a = b; }\n" // Don't issue a message here: You actually could move it to the initialization list, but it would cause problems if you change the order of the variable declarations. - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class C;\n" "class Fred {\n" " C a;\n" " Fred() { try { a = new int; } catch(...) {} }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class Fred {\n" " std::string s;\n" " Fred() { s = toString((size_t)this); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class Fred {\n" " std::string a;\n" " std::string foo();\n" " Fred() { a = foo(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class Fred {\n" " std::string a;\n" " Fred() { a = foo(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:14]: (performance) Variable 'a' is assigned in constructor body. Consider performing initialization in initialization list. [useInitializationList]\n", errout_str()); checkInitializationListUsage("class Fred {\n" // #4332 " static std::string s;\n" " Fred() { s = \"foo\"; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class Fred {\n" // #5640 @@ -8192,7 +8192,7 @@ class TestClass : public TestFixture { " str[1] = 0;\n" " s = str;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class B {\n" // #5640 @@ -8200,7 +8200,7 @@ class TestClass : public TestFixture { " B(const B& other) : _d(std::make_shared()) {\n" " *_d = *other._d;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class Bar {\n" // #8466 @@ -8209,7 +8209,7 @@ class TestClass : public TestFixture { " explicit Bar(const char s) : s{s} {}\n" "private:\n" " char s;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("unsigned bar(std::string);\n" // #8291 @@ -8218,7 +8218,7 @@ class TestClass : public TestFixture { " int a_, b_;\n" " Foo(int a, int b) : a_(a), b_(b) {}\n" " Foo(int a, const std::string& b) : Foo(a, bar(b)) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class Fred {\n" // #8111 @@ -8228,7 +8228,7 @@ class TestClass : public TestFixture { " ostr << x;\n" " a = ostr.str();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // bailout: multi line lambda in rhs => do not warn @@ -8239,7 +8239,7 @@ class TestClass : public TestFixture { " return 1;\n" " };\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // don't warn if some other instance's members are assigned to @@ -8248,7 +8248,7 @@ class TestClass : public TestFixture { " C(C& c) : m_i(c.m_i) { c.m_i = (Foo)-1; }\n" "private:\n" " Foo m_i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("class A {\n" // #9821 - delegate constructor @@ -8261,7 +8261,7 @@ class TestClass : public TestFixture { "\n" "private:\n" " std::string st;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkInitializationListUsage("struct S {\n" // #14189 @@ -8276,7 +8276,7 @@ class TestClass : public TestFixture { " p = std::make_unique(s);\n" " }\n" " std::unique_ptr p;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -8297,14 +8297,14 @@ class TestClass : public TestFixture { " int i;\n" " Fred() : i(i) {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:12]: (error) Member variable 'i' is initialized by itself. [selfInitialization]\n", errout_str()); checkSelfInitialization("class Fred {\n" " int i;\n" " Fred() : i{i} {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:12]: (error) Member variable 'i' is initialized by itself. [selfInitialization]\n", errout_str()); checkSelfInitialization("class Fred {\n" @@ -8312,7 +8312,7 @@ class TestClass : public TestFixture { " Fred();\n" "};\n" "Fred::Fred() : i(i) {\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:14]: (error) Member variable 'i' is initialized by itself. [selfInitialization]\n", errout_str()); checkSelfInitialization("class A {\n" // #10427 @@ -8335,56 +8335,56 @@ class TestClass : public TestFixture { " std::string s;\n" " Fred() : s(s) {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:12]: (error) Member variable 's' is initialized by itself. [selfInitialization]\n", errout_str()); checkSelfInitialization("class Fred {\n" " int x;\n" " Fred(int x);\n" "};\n" - "Fred::Fred(int x) : x(x) { }"); + "Fred::Fred(int x) : x(x) { }\n"); ASSERT_EQUALS("", errout_str()); checkSelfInitialization("class Fred {\n" " int x;\n" " Fred(int x);\n" "};\n" - "Fred::Fred(int x) : x{x} { }"); + "Fred::Fred(int x) : x{x} { }\n"); ASSERT_EQUALS("", errout_str()); checkSelfInitialization("class Fred {\n" " std::string s;\n" " Fred(const std::string& s) : s(s) {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkSelfInitialization("class Fred {\n" " std::string s;\n" " Fred(const std::string& s) : s{s} {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkSelfInitialization("struct Foo : Bar {\n" " int i;\n" " Foo(int i)\n" " : Bar(\"\"), i(i) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkSelfInitialization("struct Foo : std::Bar {\n" // #6073 " int i;\n" " Foo(int i)\n" " : std::Bar(\"\"), i(i) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkSelfInitialization("struct Foo : std::Bar {\n" // #6073 " int i;\n" " Foo(int i)\n" " : std::Bar(\"\"), i{i} {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -8409,21 +8409,21 @@ class TestClass : public TestFixture { " A();\n" "};\n" "A::A()\n" - "{f();}"); + "{f();}\n"); ASSERT_EQUALS("[test.cpp:7:2] -> [test.cpp:3:17]: (style) Virtual function 'f' is called from constructor 'A()' at line 7. Dynamic binding is not used. [virtualCallInConstructor]\n", errout_str()); checkVirtualFunctionCall("class A {\n" " virtual int f();\n" " A() {f();}\n" "};\n" - "int A::f() { return 1; }"); + "int A::f() { return 1; }\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:2:17]: (style) Virtual function 'f' is called from constructor 'A()' at line 3. Dynamic binding is not used. [virtualCallInConstructor]\n", errout_str()); checkVirtualFunctionCall("class A : B {\n" " int f() override;\n" " A() {f();}\n" "};\n" - "int A::f() { return 1; }"); + "int A::f() { return 1; }\n"); ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:2:9]: (style) Virtual function 'f' is called from constructor 'A()' at line 3. Dynamic binding is not used. [virtualCallInConstructor]\n", errout_str()); checkVirtualFunctionCall("class B {\n" @@ -8433,14 +8433,14 @@ class TestClass : public TestFixture { " int f();\n" // <- not explicitly virtual " A() {f();}\n" "};\n" - "int A::f() { return 1; }"); + "int A::f() { return 1; }\n"); ASSERT_EQUALS("", errout_str()); checkVirtualFunctionCall("class A\n" "{\n" " A() { A::f(); }\n" " virtual void f() {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkVirtualFunctionCall("class A : B {\n" @@ -8526,7 +8526,7 @@ class TestClass : public TestFixture { " A();\n" "};\n" "A::A()\n" - "{pure();}"); + "{pure();}\n"); ASSERT_EQUALS("[test.cpp:7:2] -> [test.cpp:3:18]: (warning) Call of pure virtual function 'pure' in constructor. [pureVirtualCall]\n", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8536,7 +8536,7 @@ class TestClass : public TestFixture { " int m;\n" "};\n" "A::A():m(A::pure())\n" - "{}"); + "{}\n"); ASSERT_EQUALS("[test.cpp:7:13] -> [test.cpp:3:17]: (warning) Call of pure virtual function 'pure' in constructor. [pureVirtualCall]\n", errout_str()); checkVirtualFunctionCall("namespace N {\n" @@ -8557,7 +8557,7 @@ class TestClass : public TestFixture { " int m;\n" "};\n" "A::~A()\n" - "{pure();}"); + "{pure();}\n"); ASSERT_EQUALS("[test.cpp:8:2] -> [test.cpp:3:18]: (warning) Call of pure virtual function 'pure' in destructor. [pureVirtualCall]\n", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8568,7 +8568,7 @@ class TestClass : public TestFixture { " A();\n" "};\n" "A::A()\n" - "{nonpure();}"); + "{nonpure();}\n"); ASSERT_EQUALS("[test.cpp:9:2] -> [test.cpp:5:6] -> [test.cpp:3:18]: (warning) Call of pure virtual function 'pure' in constructor. [pureVirtualCall]\n", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8580,7 +8580,7 @@ class TestClass : public TestFixture { " int m;\n" "};\n" "A::A():m(nonpure())\n" - "{}"); + "{}\n"); TODO_ASSERT_EQUALS("[test.cpp:9:2] -> [test.cpp:5:6] -> [test.cpp:3:18]: (warning) Call of pure virtual function 'pure' in constructor. [pureVirtualCall]\n", "", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8592,7 +8592,7 @@ class TestClass : public TestFixture { " int m;\n" "};\n" "A::~A()\n" - "{nonpure();}"); + "{nonpure();}\n"); ASSERT_EQUALS("[test.cpp:10:2] -> [test.cpp:5:6] -> [test.cpp:3:18]: (warning) Call of pure virtual function 'pure' in destructor. [pureVirtualCall]\n", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8601,7 +8601,7 @@ class TestClass : public TestFixture { " A(bool b);\n" "};\n" "A::A(bool b)\n" - "{if (b) pure();}"); + "{if (b) pure();}\n"); ASSERT_EQUALS("[test.cpp:7:9] -> [test.cpp:3:18]: (warning) Call of pure virtual function 'pure' in constructor. [pureVirtualCall]\n", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8611,7 +8611,7 @@ class TestClass : public TestFixture { " int m;\n" "};\n" "A::~A()\n" - "{if (b) pure();}"); + "{if (b) pure();}\n"); ASSERT_EQUALS("[test.cpp:8:9] -> [test.cpp:3:18]: (warning) Call of pure virtual function 'pure' in destructor. [pureVirtualCall]\n", errout_str()); // #5831 @@ -8619,7 +8619,7 @@ class TestClass : public TestFixture { "public:\n" " virtual ~abc() throw() {}\n" " virtual void def(void* g) throw () = 0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #4992 @@ -8630,7 +8630,7 @@ class TestClass : public TestFixture { " m_callback = [this]() { return VirtualMethod(); };\n" " }\n" " virtual void VirtualMethod() = 0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #10559 @@ -8649,7 +8649,7 @@ class TestClass : public TestFixture { " A(const A & a);\n" "};\n" "A::A(const A & a)\n" - "{a.pure();}"); + "{a.pure();}\n"); ASSERT_EQUALS("", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8662,7 +8662,7 @@ class TestClass : public TestFixture { " virtual void pure()=0;\n" "};\n" "A::A()\n" - "{B b; b.pure();}"); + "{B b; b.pure();}\n"); ASSERT_EQUALS("", errout_str()); } @@ -8675,7 +8675,7 @@ class TestClass : public TestFixture { "A::A()\n" "{pureWithBody();}\n" "void A::pureWithBody()\n" - "{}"); + "{}\n"); ASSERT_EQUALS("", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8688,7 +8688,7 @@ class TestClass : public TestFixture { "A::A()\n" "{nonpure();}\n" "void A::pureWithBody()\n" - "{}"); + "{}\n"); ASSERT_EQUALS("", errout_str()); } @@ -8702,7 +8702,7 @@ class TestClass : public TestFixture { " A();\n" "};\n" "A::A()\n" - "{nonpure(false);}"); + "{nonpure(false);}\n"); ASSERT_EQUALS("", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8713,7 +8713,7 @@ class TestClass : public TestFixture { " A();\n" "};\n" "A::A()\n" - "{nonpure(false);}"); + "{nonpure(false);}\n"); ASSERT_EQUALS("", errout_str()); checkVirtualFunctionCall("class A\n" @@ -8728,7 +8728,7 @@ class TestClass : public TestFixture { " A();\n" "};\n" "A::A()\n" - "{nonpure(false);}"); + "{nonpure(false);}\n"); ASSERT_EQUALS("", errout_str()); } @@ -8749,15 +8749,15 @@ class TestClass : public TestFixture { void override1() { checkOverride("class Base { virtual void f(); };\n" - "class Derived : Base { virtual void f(); };"); + "class Derived : Base { virtual void f(); };\n"); ASSERT_EQUALS("[test.cpp:1:27] -> [test.cpp:2:37]: (style) The function 'f' overrides a function in a base class but is not marked with a 'override' specifier. [missingOverride]\n", errout_str()); checkOverride("class Base { virtual void f(); };\n" - "class Derived : Base { virtual void f() override; };"); + "class Derived : Base { virtual void f() override; };\n"); ASSERT_EQUALS("", errout_str()); checkOverride("class Base { virtual void f(); };\n" - "class Derived : Base { virtual void f() final; };"); + "class Derived : Base { virtual void f() final; };\n"); ASSERT_EQUALS("", errout_str()); checkOverride("class Base {\n" @@ -8769,7 +8769,7 @@ class TestClass : public TestFixture { "public :\n" " auto foo( ) const -> size_t { return 0; }\n" " auto bar( ) const -> size_t override { return 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:18] -> [test.cpp:8:10]: (style) The function 'foo' overrides a function in a base class but is not marked with a 'override' specifier. [missingOverride]\n", errout_str()); checkOverride("namespace Test {\n" @@ -8781,7 +8781,7 @@ class TestClass : public TestFixture { "class C : Test::C {\n" "public:\n" " ~C();\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:18] -> [test.cpp:9:6]: (style) The destructor '~C' overrides a destructor in a base class but is not marked with a 'override' specifier. [missingOverride]\n", errout_str()); checkOverride("struct Base {\n" @@ -8791,7 +8791,7 @@ class TestClass : public TestFixture { "struct Derived: public Base {\n" " void foo() override;\n" " void foo(int);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOverride("struct B {\n" // #9092 @@ -8929,19 +8929,19 @@ class TestClass : public TestFixture { void overrideCVRefQualifiers() { checkOverride("class Base { virtual void f(); };\n" - "class Derived : Base { void f() const; }"); + "class Derived : Base { void f() const; }\n"); ASSERT_EQUALS("", errout_str()); checkOverride("class Base { virtual void f(); };\n" - "class Derived : Base { void f() volatile; }"); + "class Derived : Base { void f() volatile; }\n"); ASSERT_EQUALS("", errout_str()); checkOverride("class Base { virtual void f(); };\n" - "class Derived : Base { void f() &; }"); + "class Derived : Base { void f() &; }\n"); ASSERT_EQUALS("", errout_str()); checkOverride("class Base { virtual void f(); };\n" - "class Derived : Base { void f() &&; }"); + "class Derived : Base { void f() &&; }\n"); ASSERT_EQUALS("", errout_str()); } @@ -8963,51 +8963,51 @@ class TestClass : public TestFixture { checkUselessOverride("struct B { virtual int f() { return 5; } };\n" // #11757 "struct D : B {\n" " int f() override { return B::f(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:1:24] -> [test.cpp:3:9]: (style) The function 'f' overrides a function in a base class but just delegates back to the base class. [uselessOverride]\n", errout_str()); checkUselessOverride("struct B { virtual void f(); };\n" "struct D : B {\n" " void f() override { B::f(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:1:25] -> [test.cpp:3:10]: (style) The function 'f' overrides a function in a base class but just delegates back to the base class. [uselessOverride]\n", errout_str()); checkUselessOverride("struct B { virtual int f() = 0; };\n" "int B::f() { return 5; }\n" "struct D : B {\n" " int f() override { return B::f(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct B { virtual int f(int i); };\n" "struct D : B {\n" " int f(int i) override { return B::f(i); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:1:24] -> [test.cpp:3:9]: (style) The function 'f' overrides a function in a base class but just delegates back to the base class. [uselessOverride]\n", errout_str()); checkUselessOverride("struct B { virtual int f(int i); };\n" "struct D : B {\n" " int f(int i) override { return B::f(i + 1); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct B { virtual int f(int i, int j); };\n" "struct D : B {\n" " int f(int i, int j) override { return B::f(j, i); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct B { virtual int f(); };\n" "struct I { virtual int f() = 0; };\n" "struct D : B, I {\n" " int f() override { return B::f(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct S { virtual void f(); };\n" "struct D : S {\n" " void f() final { S::f(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct S {\n" @@ -9017,7 +9017,7 @@ class TestClass : public TestFixture { "struct D : S {\n" "public:\n" " void f() override { S::f(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct B { virtual void f(int, int, int) const; };\n" // #11799 @@ -9027,7 +9027,7 @@ class TestClass : public TestFixture { "};\n" "void D::f(int a, int b, int c) const {\n" " B::f(a, b, m);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct B {\n" // #11803 @@ -9038,7 +9038,7 @@ class TestClass : public TestFixture { " void f() override { B::f(); }\n" " void f(int i) override;\n" " void g() { f(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct B { virtual void f(); };\n" // #11808 @@ -9047,7 +9047,7 @@ class TestClass : public TestFixture { " void f() override {\n" " B::f();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkUselessOverride("struct B {\n" @@ -9061,7 +9061,7 @@ class TestClass : public TestFixture { " int g() override { return 7; }\n" " int h(int j, int i) override { return i + j; }\n" " int j(int i, int j) override { return i + j; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:17] -> [test.cpp:9:9]: (style) The function 'g' overrides a function in a base class but is identical to the overridden function [uselessOverride]\n" "[test.cpp:5:17] -> [test.cpp:11:9]: (style) The function 'j' overrides a function in a base class but is identical to the overridden function [uselessOverride]\n", errout_str()); @@ -9150,7 +9150,7 @@ class TestClass : public TestFixture { } void unsafeClassRefMember() { - checkUnsafeClassRefMember("class C { C(const std::string &s) : s(s) {} const std::string &s; };"); + checkUnsafeClassRefMember("class C { C(const std::string &s) : s(s) {} const std::string &s; };\n"); ASSERT_EQUALS("[test.cpp:1:37]: (warning) Unsafe class: The const reference member 'C::s' is initialized by a const reference constructor argument. You need to be careful about lifetime issues. [unsafeClassRefMember]\n", errout_str()); } @@ -9177,7 +9177,7 @@ class TestClass : public TestFixture { "private:\n" " static C *mInstance;\n" " void hello() {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:38]: warning: Calling method 'hello()' when 'this' might be invalid [thisUseAfterFree]\n" "[test.cpp:5:13]: note: Assuming 'mInstance' is used as 'this'\n" "[test.cpp:3:20]: note: Delete 'mInstance', invalidating 'this'\n" @@ -9190,7 +9190,7 @@ class TestClass : public TestFixture { "private:\n" " static std::shared_ptr mInstance;\n" " void hello() {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:39]: warning: Calling method 'hello()' when 'this' might be invalid [thisUseAfterFree]\n" "[test.cpp:5:29]: note: Assuming 'mInstance' is used as 'this'\n" "[test.cpp:3:20]: note: Delete 'mInstance', invalidating 'this'\n" @@ -9204,7 +9204,7 @@ class TestClass : public TestFixture { " static std::shared_ptr mInstance;\n" " void hello();\n" " void reset() { mInstance.reset(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:29]: warning: Calling method 'hello()' when 'this' might be invalid [thisUseAfterFree]\n" "[test.cpp:5:29]: note: Assuming 'mInstance' is used as 'this'\n" "[test.cpp:7:18]: note: Delete 'mInstance', invalidating 'this'\n" @@ -9218,7 +9218,7 @@ class TestClass : public TestFixture { "private:\n" " static C *self;\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:33]: warning: Using member 'x' when 'this' might be invalid [thisUseAfterFree]\n" "[test.cpp:5:13]: note: Assuming 'self' is used as 'this'\n" "[test.cpp:3:20]: note: Delete 'self', invalidating 'this'\n" @@ -9231,7 +9231,7 @@ class TestClass : public TestFixture { "private:\n" " static C *self;\n" " std::map x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:33]: warning: Using member 'x' when 'this' might be invalid [thisUseAfterFree]\n" "[test.cpp:5:13]: note: Assuming 'self' is used as 'this'\n" "[test.cpp:3:20]: note: Delete 'self', invalidating 'this'\n" @@ -9246,7 +9246,7 @@ class TestClass : public TestFixture { "private:\n" " std::shared_ptr mInstance;\n" " void hello() {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:39]: warning: Calling method 'hello()' when 'this' might be invalid [thisUseAfterFree]\n" "[test.cpp:6:22]: note: Assuming 'mInstance' is used as 'this'\n" "[test.cpp:4:20]: note: Delete 'mInstance', invalidating 'this'\n" @@ -9260,7 +9260,7 @@ class TestClass : public TestFixture { "private:\n" " C *self;\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkThisUseAfterFree("class C {\n" @@ -9270,7 +9270,7 @@ class TestClass : public TestFixture { "private:\n" " std::shared_ptr mInstance;\n" " void hello() {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkThisUseAfterFree("class C\n" @@ -9287,7 +9287,7 @@ class TestClass : public TestFixture { " static C* instanceSingleton;\n" "};\n" "\n" - "C* C::instanceSingleton;"); + "C* C::instanceSingleton;\n"); ASSERT_EQUALS("", errout_str()); // Avoid false positive when pointer is deleted in lambda @@ -9303,7 +9303,7 @@ class TestClass : public TestFixture { " auto done = [this] () { delete p; };\n" " dostuff();\n" " done();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkThisUseAfterFree("class C {\n" // #13311 @@ -9319,7 +9319,7 @@ class TestClass : public TestFixture { " if (self)\n" " delete self;\n" " self = new C();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -9348,19 +9348,19 @@ class TestClass : public TestFixture { } void ctuOneDefinitionRule() { - ctu({"class C { C() { std::cout << 0; } };", "class C { C() { std::cout << 1; } };"}); + ctu({"class C { C() { std::cout << 0; } };\n", "class C { C() { std::cout << 1; } };\n"}); ASSERT_EQUALS("[1.cpp:1:1] -> [0.cpp:1:1]: (error) The one definition rule is violated, different classes/structs have the same name 'C' [ctuOneDefinitionRuleViolation]\n", errout_str()); - ctu({"class C { C(); }; C::C() { std::cout << 0; }", "class C { C(); }; C::C() { std::cout << 1; }"}); + ctu({"class C { C(); }; C::C() { std::cout << 0; }\n", "class C { C(); }; C::C() { std::cout << 1; }\n"}); ASSERT_EQUALS("[1.cpp:1:1] -> [0.cpp:1:1]: (error) The one definition rule is violated, different classes/structs have the same name 'C' [ctuOneDefinitionRuleViolation]\n", errout_str()); ctu({"class C { C() {} };\n", "class C { C() {} };\n"}); ASSERT_EQUALS("", errout_str()); - ctu({"class C { C(); }; C::C(){}", "class C { C(); }; C::C(){}"}); + ctu({"class C { C(); }; C::C(){}\n", "class C { C(); }; C::C(){}\n"}); ASSERT_EQUALS("", errout_str()); - ctu({"class A::C { C() { std::cout << 0; } };", "class B::C { C() { std::cout << 1; } };"}); + ctu({"class A::C { C() { std::cout << 0; } };\n", "class B::C { C() { std::cout << 1; } };\n"}); ASSERT_EQUALS("", errout_str()); // 11435 - template specialisations @@ -9386,8 +9386,8 @@ class TestClass : public TestFixture { } void testGetFileInfo() { - getFileInfo("void foo() { union { struct { }; }; }"); // don't crash - getFileInfo("struct sometype { sometype(); }; sometype::sometype() = delete;"); // don't crash + getFileInfo("void foo() { union { struct { }; }; }\n"); // don't crash + getFileInfo("struct sometype { sometype(); }; sometype::sometype() = delete;\n"); // don't crash } #define checkReturnByReference(...) checkReturnByReference_(__FILE__, __LINE__, __VA_ARGS__) diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 8567d9b11a7..6d62b644043 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -172,59 +172,59 @@ class TestCondition : public TestFixture { "{\n" " int y = x & 4;\n" " if (y == 3);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:4:8]: (style) Mismatching assignment and comparison, comparison 'y==3' is always false. [assignIfError]\n", errout_str()); check("void foo(int x)\n" "{\n" " int y = x & 4;\n" " if (y != 3);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:4:8]: (style) Mismatching assignment and comparison, comparison 'y!=3' is always true. [assignIfError]\n", errout_str()); // | check("void foo(int x) {\n" " int y = x | 0x14;\n" " if (y == 0x710);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:8]: (style) Mismatching assignment and comparison, comparison 'y==0x710' is always false. [assignIfError]\n", errout_str()); check("void foo(int x) {\n" " int y = x | 0x14;\n" " if (y == 0x71f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // various simple assignments check("void foo(int x) {\n" " int y = (x+1) | 1;\n" " if (y == 2);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:8]: (style) Mismatching assignment and comparison, comparison 'y==2' is always false. [assignIfError]\n", errout_str()); check("void foo() {\n" " int y = 1 | x();\n" " if (y == 2);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:8]: (style) Mismatching assignment and comparison, comparison 'y==2' is always false. [assignIfError]\n", errout_str()); // multiple conditions check("void foo(int x) {\n" " int y = x & 4;\n" " if ((y == 3) && (z == 1));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:9]: (style) Mismatching assignment and comparison, comparison 'y==3' is always false. [assignIfError]\n", errout_str()); check("void foo(int x) {\n" " int y = x & 4;\n" " if ((x==123) || ((y == 3) && (z == 1)));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:22]: (style) Mismatching assignment and comparison, comparison 'y==3' is always false. [assignIfError]\n", errout_str()); check("void f(int x) {\n" " int y = x & 7;\n" " if (setvalue(&y) && y != 8);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // recursive checking into scopes @@ -232,20 +232,20 @@ class TestCondition : public TestFixture { " int y = x & 7;\n" " if (z) y=0;\n" " else { if (y==8); }\n" // always false - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:4:15]: (style) Mismatching assignment and comparison, comparison 'y==8' is always false. [assignIfError]\n", errout_str()); // while check("void f(int x) {\n" " int y = x & 7;\n" " while (y==8);\n" // local variable => always false - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:11]: (style) Mismatching assignment and comparison, comparison 'y==8' is always false. [assignIfError]\n", errout_str()); check("void f(int x) {\n" " extern int y; y = x & 7;\n" " while (y==8);\n" // non-local variable => no error - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" @@ -254,7 +254,7 @@ class TestCondition : public TestFixture { " int y = 16 | a;\n" " while (y != 0) y--;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int x);\n" @@ -264,7 +264,7 @@ class TestCondition : public TestFixture { " int y = 16 | a;\n" " while (y != 0) g(y);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:15] -> [test.cpp:6:15]: (style) Mismatching assignment and comparison, comparison 'y!=0' is always true. [assignIfError]\n", errout_str()); @@ -276,7 +276,7 @@ class TestCondition : public TestFixture { " int y = 16 | a;\n" " while (y != 0) g(y);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // calling function @@ -284,14 +284,14 @@ class TestCondition : public TestFixture { " int y = x & 7;\n" " do_something();\n" " if (y==8);\n" // local variable => always false - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:4:8]: (style) Mismatching assignment and comparison, comparison 'y==8' is always false. [assignIfError]\n", errout_str()); check("void f(int x) {\n" " int y = x & 7;\n" " do_something(&y);\n" // passing variable => no error " if (y==8);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void do_something(int);\n" @@ -299,14 +299,14 @@ class TestCondition : public TestFixture { " int y = x & 7;\n" " do_something(y);\n" " if (y==8);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:5:8]: (style) Mismatching assignment and comparison, comparison 'y==8' is always false. [assignIfError]\n", errout_str()); check("void f(int x) {\n" " extern int y; y = x & 7;\n" " do_something();\n" " if (y==8);\n" // non-local variable => no error - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4434 : false positive: ?: @@ -314,28 +314,28 @@ class TestCondition : public TestFixture { " x = x & 1;\n" " x = x & 1 ? 1 : -1;\n" " if(x != -1) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4735 check("void f() {\n" " int x = *(char*)&0x12345678;\n" " if (x==18) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // bailout: no variable info check("void foo(int x) {\n" " y = 2 | x;\n" // y not declared => no error " if(y == 1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // bailout: negative number check("void foo(int x) {\n" " int y = -2 | x;\n" // negative number => no error " if (y==1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // bailout: pass variable to function @@ -343,7 +343,7 @@ class TestCondition : public TestFixture { " int y = 2 | x;\n" " bar(&y);\n" // pass variable to function => no error " if (y==1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // no crash on unary operator& (#5643) @@ -351,7 +351,7 @@ class TestCondition : public TestFixture { check("SdrObject* ApplyGraphicToObject() {\n" " if (&rHitObject) {}\n" " else if (rHitObject.IsClosedObj() && !&rHitObject) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Condition '&rHitObject' is always true [knownConditionTrueFalse]\n" "[test.cpp:3:42]: (style) Condition '!&rHitObject' is always false [knownConditionTrueFalse]\n", errout_str()); @@ -364,7 +364,7 @@ class TestCondition : public TestFixture { " if (c == 4)\n" " c = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int a) {\n" // #6662 @@ -372,7 +372,7 @@ class TestCondition : public TestFixture { " while (x <= 4) {\n" " if (x != 5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:8]: (style) Mismatching assignment and comparison, comparison 'x!=5' is always true. [assignIfError]\n", errout_str()); check("void f(int a) {\n" // #6662 @@ -380,7 +380,7 @@ class TestCondition : public TestFixture { " while ((x += 4) < 10) {\n" " if (x != 5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -388,7 +388,7 @@ class TestCondition : public TestFixture { " while (x) {\n" " g(x);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int x);\n" @@ -397,7 +397,7 @@ class TestCondition : public TestFixture { " while (x) {\n" " g(x);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (style) Condition 'x' is always true [knownConditionTrueFalse]\n", errout_str()); check("void g(int & x);\n" @@ -406,7 +406,7 @@ class TestCondition : public TestFixture { " while (x) {\n" " g(x);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -415,13 +415,13 @@ class TestCondition : public TestFixture { check("void f(int a) {\n" " int b = a & 0xf0;\n" " b &= 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:5]: (style) Mismatching bitmasks. Result is always 0 (X = Y & 0xf0; Z = X & 0x1; => Z=0). [mismatchingBitAnd]\n", errout_str()); check("void f(int a) {\n" " int b = a & 0xf0;\n" " int c = b & 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:9]: (style) Mismatching bitmasks. Result is always 0 (X = Y & 0xf0; Z = X & 0x1; => Z=0). [mismatchingBitAnd]\n", errout_str()); check("void f(int a) {\n" @@ -430,67 +430,67 @@ class TestCondition : public TestFixture { " case 1: b &= 1; break;\n" " case 2: b &= 2; break;\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void comparison() { // CheckCondition::comparison test cases // '==' - check("void f(int a) {\n assert( (a & 0x07) == 8U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) == 8U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X & 0x7) == 0x8' is always false. [comparisonError]\n",errout_str()); - check("void f(int a) {\n assert( (a & b & 4 & c ) == 3 );\n}"); + check("void f(int a) {\n assert( (a & b & 4 & c ) == 3 );\n}\n"); ASSERT_EQUALS("[test.cpp:2:21]: (style) Expression '(X & 0x4) == 0x3' is always false. [comparisonError]\n", errout_str()); - check("void f(int a) {\n assert( (a | 0x07) == 8U );\n}"); + check("void f(int a) {\n assert( (a | 0x07) == 8U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X | 0x7) == 0x8' is always false. [comparisonError]\n",errout_str()); - check("void f(int a) {\n assert( (a & 0x07) == 7U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) == 7U );\n}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int a) {\n assert( (a | 0x01) == -15 );\n}"); + check("void f(int a) {\n assert( (a | 0x01) == -15 );\n}\n"); ASSERT_EQUALS("", errout_str()); // '!=' - check("void f(int a) {\n assert( (a & 0x07) != 8U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) != 8U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X & 0x7) != 0x8' is always true. [comparisonError]\n",errout_str()); - check("void f(int a) {\n assert( (a | 0x07) != 8U );\n}"); + check("void f(int a) {\n assert( (a | 0x07) != 8U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X | 0x7) != 0x8' is always true. [comparisonError]\n",errout_str()); - check("void f(int a) {\n assert( (a & 0x07) != 7U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) != 7U );\n}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int a) {\n assert( (a | 0x07) != 7U );\n}"); + check("void f(int a) {\n assert( (a | 0x07) != 7U );\n}\n"); ASSERT_EQUALS("", errout_str()); // '>=' - check("void f(int a) {\n assert( (a & 0x07) >= 8U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) >= 8U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X & 0x7) >= 0x8' is always false. [comparisonError]\n",errout_str()); - check("void f(unsigned int a) {\n assert( (a | 0x7) >= 7U );\n}"); + check("void f(unsigned int a) {\n assert( (a | 0x7) >= 7U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X | 0x7) >= 0x7' is always true. [comparisonError]\n",errout_str()); - check("void f(int a) {\n assert( (a & 0x07) >= 7U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) >= 7U );\n}\n"); ASSERT_EQUALS("",errout_str()); - check("void f(int a) {\n assert( (a | 0x07) >= 8U );\n}"); + check("void f(int a) {\n assert( (a | 0x07) >= 8U );\n}\n"); ASSERT_EQUALS("",errout_str()); //correct for negative 'a' // '>' - check("void f(int a) {\n assert( (a & 0x07) > 7U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) > 7U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X & 0x7) > 0x7' is always false. [comparisonError]\n",errout_str()); - check("void f(unsigned int a) {\n assert( (a | 0x7) > 6U );\n}"); + check("void f(unsigned int a) {\n assert( (a | 0x7) > 6U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X | 0x7) > 0x6' is always true. [comparisonError]\n",errout_str()); - check("void f(int a) {\n assert( (a & 0x07) > 6U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) > 6U );\n}\n"); ASSERT_EQUALS("",errout_str()); - check("void f(int a) {\n assert( (a | 0x07) > 7U );\n}"); + check("void f(int a) {\n assert( (a | 0x07) > 7U );\n}\n"); ASSERT_EQUALS("",errout_str()); //correct for negative 'a' // '<=' - check("void f(int a) {\n assert( (a & 0x07) <= 7U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) <= 7U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X & 0x7) <= 0x7' is always true. [comparisonError]\n",errout_str()); - check("void f(unsigned int a) {\n assert( (a | 0x08) <= 7U );\n}"); + check("void f(unsigned int a) {\n assert( (a | 0x08) <= 7U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X | 0x8) <= 0x7' is always false. [comparisonError]\n",errout_str()); - check("void f(int a) {\n assert( (a & 0x07) <= 6U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) <= 6U );\n}\n"); ASSERT_EQUALS("",errout_str()); - check("void f(int a) {\n assert( (a | 0x08) <= 7U );\n}"); + check("void f(int a) {\n assert( (a | 0x08) <= 7U );\n}\n"); ASSERT_EQUALS("",errout_str()); //correct for negative 'a' // '<' - check("void f(int a) {\n assert( (a & 0x07) < 8U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) < 8U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X & 0x7) < 0x8' is always true. [comparisonError]\n",errout_str()); - check("void f(unsigned int a) {\n assert( (a | 0x07) < 7U );\n}"); + check("void f(unsigned int a) {\n assert( (a | 0x07) < 7U );\n}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Expression '(X | 0x7) < 0x7' is always false. [comparisonError]\n",errout_str()); - check("void f(int a) {\n assert( (a & 0x07) < 3U );\n}"); + check("void f(int a) {\n assert( (a & 0x07) < 3U );\n}\n"); ASSERT_EQUALS("",errout_str()); - check("void f(int a) {\n assert( (a | 0x07) < 7U );\n}"); + check("void f(int a) {\n assert( (a | 0x07) < 7U );\n}\n"); ASSERT_EQUALS("",errout_str()); //correct for negative 'a' check("void f(int i) {\n" // #11998 @@ -536,14 +536,14 @@ class TestCondition : public TestFixture { "{\n" " if (x & 7);\n" " else { if (x == 1); }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (style) Expression is always false because 'else if' condition matches previous condition at line 3. [multiCondition]\n", errout_str()); check("void foo(int x)\n" "{\n" " if (x & 7);\n" " else { if (x & 1); }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (style) Expression is always false because 'else if' condition matches previous condition at line 3. [multiCondition]\n", errout_str()); check("extern int bar() __attribute__((pure));\n" @@ -551,7 +551,7 @@ class TestCondition : public TestFixture { "{\n" " if ( bar() >1 && b) {}\n" " else if (bar() >1 && b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:23]: (style) Expression is always false because 'else if' condition matches previous condition at line 4. [multiCondition]\n", errout_str()); checkPureFunction("extern int bar();\n" @@ -559,14 +559,14 @@ class TestCondition : public TestFixture { "{\n" " if ( bar() >1 && b) {}\n" " else if (bar() >1 && b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:23]: (style) Expression is always false because 'else if' condition matches previous condition at line 4. [multiCondition]\n", errout_str()); // 7284 check("void foo() {\n" " if (a) {}\n" " else if (!!a) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); // #11059 @@ -593,53 +593,53 @@ class TestCondition : public TestFixture { check("void f(int a, int &b) {\n" " if (a) { b = 1; }\n" " else { if (a) { b = 2; } }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(int a, int &b) {\n" " if (a) { b = 1; }\n" " else { if (a) { b = 2; } }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(int a, int &b) {\n" " if (a == 1) { b = 1; }\n" " else { if (a == 2) { b = 2; }\n" " else { if (a == 1) { b = 3; } } }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(int a, int &b) {\n" " if (a == 1) { b = 1; }\n" " else { if (a == 2) { b = 2; }\n" " else { if (a == 2) { b = 3; } } }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (style) Expression is always false because 'else if' condition matches previous condition at line 3. [multiCondition]\n", errout_str()); check("void f(int a, int &b) {\n" " if (a++) { b = 1; }\n" " else { if (a++) { b = 2; }\n" " else { if (a++) { b = 3; } } }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int a, int &b) {\n" " if (!strtok(NULL, \" \")) { b = 1; }\n" " else { if (!strtok(NULL, \" \")) { b = 2; } }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); { check("void f(Class &c) {\n" " if (c.dostuff() == 3) {}\n" " else { if (c.dostuff() == 3) {} }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const Class &c) {\n" " if (c.dostuff() == 3) {}\n" " else { if (c.dostuff() == 3) {} }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:28]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); } @@ -647,13 +647,13 @@ class TestCondition : public TestFixture { " x = x / 2;\n" " if (x < 100) { b = 1; }\n" " else { x = x / 2; if (x < 100) { b = 2; } }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int64_t i) {\n" " if(i == 0x02e2000000 || i == 0xa0c6000000)\n" " foo(i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket 3689 ( avoid false positive ) @@ -675,13 +675,13 @@ class TestCondition : public TestFixture { " return -1;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(WIDGET *widget) {\n" " if (dynamic_cast(widget)){}\n" " else if (dynamic_cast(widget)){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class B { virtual void v() {} };\n" // #11037 @@ -698,67 +698,67 @@ class TestCondition : public TestFixture { check("void f(int x) {\n" // #6482 " if (x & 1) {}\n" " else if (x == 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x & 15) {}\n" " else if (x == 40) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(int x) {\n" " if (x == sizeof(double)) {}\n" - " else { if (x == sizeof(long double)) {} }" - "}"); + " else { if (x == sizeof(long double)) {} }\n" + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x & 0x08) {}\n" " else if (x & 0xF8) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x & 0xF8) {}\n" " else if (x & 0x08) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(bool a, bool b) {\n" " if(a && b){}\n" " else if( !!b && !!a){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(bool a, bool b) {\n" " if(a && b){}\n" " else if( !!b && a){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(bool a, bool b) {\n" " if(a && b){}\n" " else if( b && !!a){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:15]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(bool a, bool b) {\n" " if(a && b){}\n" " else if( b && !(!a)){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:15]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(bool a, bool b) {\n" " if(a && b){}\n" " else if( !!b && !(!a)){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style) Expression is always false because 'else if' condition matches previous condition at line 2. [multiCondition]\n", errout_str()); check("void f(bool a, bool b) {\n" " if(a && b){}\n" " else if( !!(b) && !!(a+b)){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8168 @@ -770,7 +770,7 @@ class TestCondition : public TestFixture { "void TestFunction(int value) {\n" " if ( value & (int)Value1 ) {}\n" " else if ( value & (int)Value2 ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(size_t x) {\n" @@ -792,7 +792,7 @@ class TestCondition : public TestFixture { check("void f(int x) {\n" " if (x) {}\n" " else if (!x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: style: Expression is always true because 'else if' condition is opposite to previous condition at line 2. [multiCondition]\n" "[test.cpp:2:9]: note: first condition\n" "[test.cpp:3:14]: note: else if condition is opposite to first condition\n", errout_str()); @@ -801,7 +801,7 @@ class TestCondition : public TestFixture { " int y = x;\n" " if (x) {}\n" " else if (!y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:14]: style: Expression is always true because 'else if' condition is opposite to previous condition at line 3. [multiCondition]\n" "[test.cpp:2:13]: note: 'y' is assigned value 'x' here.\n" "[test.cpp:3:9]: note: first condition\n" @@ -812,31 +812,31 @@ class TestCondition : public TestFixture { check("bool f(int x) {\n" " bool b = x | 0x02;\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("bool f(int x) {\n" " bool b = 0x02 | x;\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:19]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("int f(int x) {\n" " int b = x | 0x02;\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(int x) {\n" " bool b = x & 0x02;\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(int x) {\n" " if(x | 0x02)\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("bool f(int x) {\n" @@ -844,27 +844,27 @@ class TestCondition : public TestFixture { " if(b) y = 0;\n" " if(x | y)\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(int x) {\n" " foo(a && (x | 0x02));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("int f(int x) {\n" " return (x | 0x02) ? 0 : 5;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("int f(int x) {\n" " return x ? (x | 0x02) : 5;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(int x) {\n" " return x | 0x02;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("bool f(int x) {\n" @@ -872,19 +872,19 @@ class TestCondition : public TestFixture { " return x | 0x02;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("const bool f(int x) {\n" " return x | 0x02;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("struct F {\n" " static const bool f(int x) {\n" " return x | 0x02;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:16]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("struct F {\n" @@ -892,12 +892,12 @@ class TestCondition : public TestFixture { "};\n" "F::b_t f(int x) {\n" " return x | 0x02;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:12]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'? [badBitmaskCheck]\n", errout_str()); check("int f(int x) {\n" " return x | 0x02;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void create_rop_masks_4( rop_mask_bits *bits) {\n" @@ -905,7 +905,7 @@ class TestCondition : public TestFixture { "BYTE *and_bits = bits->and;\n" "rop_mask *rop_mask;\n" "and_bits[mask_offset] |= (rop_mask->and & 0x0f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(unsigned a, unsigned b) {\n" @@ -913,7 +913,7 @@ class TestCondition : public TestFixture { " if (cmd1 | a) {\n" " if (b == 0x0C) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int i) {\n" // #11082 @@ -941,7 +941,7 @@ class TestCondition : public TestFixture { "#if BAR_ENABLED\n" " FEATURE_BAR |\n" "#endif\n" - " 0;"); + " 0;\n"); ASSERT_EQUALS("", errout_str()); check("enum precedence { PC0, UNARY };\n" @@ -960,84 +960,84 @@ class TestCondition : public TestFixture { check("void f(int x) {\n" " if ((x != 1) || (x != 3))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (warning) Logical disjunction always evaluates to true: x != 1 || x != 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (1 != x || 3 != x)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical disjunction always evaluates to true: x != 1 || x != 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x<0 && !x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Logical conjunction always evaluates to false: x < 0 && !x. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x==0 && x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (warning) Logical conjunction always evaluates to false: x == 0 && x. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" // ast.. " if (y == 1 && x == 1 && x == 7) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:26]: (warning) Logical conjunction always evaluates to false: x == 1 && x == 7. [incorrectLogicOperator]\n", errout_str()); check("void f(int x, int y) {\n" " if (x != 1 || y != 1)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x, int y) {\n" " if ((y == 1) && (x != 1) || (x != 3))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x, int y) {\n" " if ((x != 1) || (x != 3) && (y == 1))\n" " a++;\n" - "}" + "}\n" ); ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:2:24]: (style) Condition 'x!=3' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" " if ((x != 1) && (x != 3))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((x == 1) || (x == 3))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x, int y) {\n" " if ((x != 1) || (y != 3))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x, int y) {\n" " if ((x != hotdog) || (y != hotdog))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x, int y) {\n" " if ((x != 5) || (y != 5))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((x != 5) || (x != 6))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (warning) Logical disjunction always evaluates to true: x != 5 || x != 6. [incorrectLogicOperator]\n", errout_str()); check("void f(unsigned int a, unsigned int b, unsigned int c) {\n" @@ -1046,7 +1046,7 @@ class TestCondition : public TestFixture { " return true;\n" " }\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:23] -> [test.cpp:2:35]: (style) Condition 'c!=a' is always false [knownConditionTrueFalse]\n", errout_str()); } @@ -1054,224 +1054,224 @@ class TestCondition : public TestFixture { check("void f(float x) {\n" " if ((x == 1) && (x == 1.0))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((x == 1) && (x == 0x00000001))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:2:24]: (style) Condition 'x==0x00000001' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" " if (x == 1 && x == 3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical conjunction always evaluates to false: x == 1 && x == 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x == 1.0 && x == 3.0)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // float comparisons with == and != are not checked right now - such comparison is a bad idea check("void f(float x) {\n" " if (x == 1 && x == 1.0)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void bar(float f) {\n" // #5246 " if ((f > 0) && (f < 1)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x < 1 && x > 1)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 1. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x < 1.0 && x > 1.0)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (warning) Logical conjunction always evaluates to false: x < 1.0 && x > 1.0. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x < 1 && x > 1.0)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 1.0. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x >= 1.0 && x <= 1.001)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x < 1 && x > 3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3. [incorrectLogicOperator]\n", errout_str()); check("void f(float x) {\n" " if (x < 1.0 && x > 3.0)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (warning) Logical conjunction always evaluates to false: x < 1.0 && x > 3.0. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (1 > x && 3 < x)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x < 3 && x > 1)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x > 3 || x < 10)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical disjunction always evaluates to true: x > 3 || x < 10. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x >= 3 || x <= 10)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical disjunction always evaluates to true: x >= 3 || x <= 10. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x >= 3 || x < 10)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical disjunction always evaluates to true: x >= 3 || x < 10. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x > 3 || x <= 10)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical disjunction always evaluates to true: x > 3 || x <= 10. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x > 3 || x < 3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x >= 3 || x <= 3)\n" " a++;\n" - "}" + "}\n" ); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical disjunction always evaluates to true: x >= 3 || x <= 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x >= 3 || x < 3)\n" " a++;\n" - "}" + "}\n" ); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical disjunction always evaluates to true: x >= 3 || x < 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x > 3 || x <= 3)\n" " a++;\n" - "}" + "}\n" ); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical disjunction always evaluates to true: x > 3 || x <= 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if((x==3) && (x!=4))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style) Redundant condition: The condition 'x != 4' is redundant since 'x == 3' is sufficient. [redundantCondition]\n", errout_str()); check("void f(const std::string &s) {\n" // #8860 " const std::size_t p = s.find(\"42\");\n" " const std::size_t * const ptr = &p;\n" " if(p != std::string::npos && p == 0 && *ptr != 1){;}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:36] -> [test.cpp:4:49]: (style) Condition '*ptr!=1' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" " if ((x!=4) && (x==3))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (style) Redundant condition: The condition 'x != 4' is redundant since 'x == 3' is sufficient. [redundantCondition]\n", errout_str()); check("void f(int x) {\n" " if ((x==3) || (x!=4))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (style) Redundant condition: The condition 'x == 3' is redundant since 'x != 4' is sufficient. [redundantCondition]\n", errout_str()); check("void f(int x) {\n" " if ((x!=4) || (x==3))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (style) Redundant condition: The condition 'x == 3' is redundant since 'x != 4' is sufficient. [redundantCondition]\n", errout_str()); check("void f(int x) {\n" " if ((x==3) && (x!=3))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical conjunction always evaluates to false: x == 3 && x != 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if ((x==6) || (x!=6))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical disjunction always evaluates to true: x == 6 || x != 6. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x > 10 || x < 3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x > 5 && x == 1)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x > 5 && x == 1. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x > 5 && x == 6)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (style) Redundant condition: The condition 'x > 5' is redundant since 'x == 6' is sufficient. [redundantCondition]\n", errout_str()); // #3419 check("void f() {\n" " if ( &q != &a && &q != &b ) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3676 check("void f(int m_x2, int w, int x) {\n" " if (x + w - 1 > m_x2 || m_x2 < 0 )\n" " m_x2 = x + w - 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(float x) {\n" // x+1 => x " if (x <= 1.0e20 && x >= -1.0e20) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(float x) {\n" // x+1 => x " if (x >= 1.0e20 && x <= 1.0e21) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(float x) {\n" // x+1 => x " if (x <= -1.0e20 && x >= -1.0e21) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1281,7 +1281,7 @@ class TestCondition : public TestFixture { " c = x < 1 && x == 3;\n" " d = x >= 5 && x == 1;\n" " e = x <= 1 && x == 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x > 5 && x == 1. [incorrectLogicOperator]\n" "[test.cpp:3:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x == 3. [incorrectLogicOperator]\n" "[test.cpp:4:16]: (warning) Logical conjunction always evaluates to false: x >= 5 && x == 1. [incorrectLogicOperator]\n" @@ -1292,7 +1292,7 @@ class TestCondition : public TestFixture { check("#define ZERO 0\n" "void f(int x) {\n" " if (x && x != ZERO) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int N) {\n" // #9789 @@ -1307,7 +1307,7 @@ class TestCondition : public TestFixture { void incorrectLogicOperator5() { // complex expressions check("void f(int x) {\n" " if (x+3 > 2 || x+3 < 10) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical disjunction always evaluates to true: x+3 > 2 || x+3 < 10. [incorrectLogicOperator]\n", errout_str()); } @@ -1315,51 +1315,51 @@ class TestCondition : public TestFixture { const Settings s = settingsBuilder(settings0).certainty(Certainty::inconclusive).build(); check("void f(char x) {\n" " if (x == '1' || x == '2') {}\n" - "}", s); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f(char x) {\n" " if (x == '1' && x == '2') {}\n" - "}", s); + "}\n", s); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical conjunction always evaluates to false: x == '1' && x == '2'. [incorrectLogicOperator]\n", errout_str()); check("int f(char c) {\n" " return (c >= 'a' && c <= 'z');\n" - "}", s); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("int f(char c) {\n" " return (c <= 'a' && c >= 'z');\n" - "}", s); + "}\n", s); ASSERT_EQUALS("[test.cpp:2:20]: (warning, inconclusive) Logical conjunction always evaluates to false: c <= 'a' && c >= 'z'. [incorrectLogicOperator]\n", errout_str()); check("int f(char c) {\n" " return (c <= 'a' && c >= 'z');\n" - "}"); // TODO: use s? + "}\n"); // TODO: use s? ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:2:25]: (style) Return value 'c>='z'' is always false [knownConditionTrueFalse]\n", errout_str()); } void incorrectLogicOperator7() { // opposite expressions check("void f(int i) {\n" " if (i || !i) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (warning) Logical disjunction always evaluates to true: i || !(i). [incorrectLogicOperator]\n", errout_str()); check("void f(int a, int b) {\n" " if (a>b || a<=b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Logical disjunction always evaluates to true: a > b || a <= b. [incorrectLogicOperator]\n", errout_str()); check("void f(int a, int b) {\n" " if (a>b || a T icdf( const T uniform ) {\n" " if ((0(obj));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1394,21 +1394,21 @@ class TestCondition : public TestFixture { "void f(Type_t t) {\n" " if ((t == A) && (t == B))\n" " {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:18]: (warning) Logical conjunction always evaluates to false: t == 0 && t == 1. [incorrectLogicOperator]\n", errout_str()); } void incorrectLogicOperator11() { - check("void foo(int i, const int n) { if ( i < n && i == n ) {} }"); + check("void foo(int i, const int n) { if ( i < n && i == n ) {} }\n"); ASSERT_EQUALS("[test.cpp:1:43]: (warning) Logical conjunction always evaluates to false: i < n && i == n. [incorrectLogicOperator]\n", errout_str()); - check("void foo(int i, const int n) { if ( i > n && i == n ) {} }"); + check("void foo(int i, const int n) { if ( i > n && i == n ) {} }\n"); ASSERT_EQUALS("[test.cpp:1:43]: (warning) Logical conjunction always evaluates to false: i > n && i == n. [incorrectLogicOperator]\n", errout_str()); - check("void foo(int i, const int n) { if ( i == n && i > n ) {} }"); + check("void foo(int i, const int n) { if ( i == n && i > n ) {} }\n"); ASSERT_EQUALS("[test.cpp:1:44]: (warning) Logical conjunction always evaluates to false: i == n && i > n. [incorrectLogicOperator]\n", errout_str()); - check("void foo(int i, const int n) { if ( i == n && i < n ) {} }"); + check("void foo(int i, const int n) { if ( i == n && i < n ) {} }\n"); ASSERT_EQUALS("[test.cpp:1:44]: (warning) Logical conjunction always evaluates to false: i == n && i < n. [incorrectLogicOperator]\n", errout_str()); } @@ -1422,7 +1422,7 @@ class TestCondition : public TestFixture { " y.f();\n" " if (a > x && a < y)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:9] -> [test.cpp:6:9] -> [test.cpp:8:13]: (warning) Logical conjunction always evaluates to false: a > x && a < y. [incorrectLogicOperator]\n", errout_str()); @@ -1436,7 +1436,7 @@ class TestCondition : public TestFixture { " y.f();\n" " if (a > x && a < y)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(A a, A b) {\n" @@ -1445,7 +1445,7 @@ class TestCondition : public TestFixture { " y.f();\n" " if (a > x && a < y)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(A a, A b) {\n" @@ -1454,7 +1454,7 @@ class TestCondition : public TestFixture { " y.f();\n" " if (a > x && a < y)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:15] -> [test.cpp:3:15] -> [test.cpp:5:13]: (warning) Logical conjunction always evaluates to false: a > x && a < y. [incorrectLogicOperator]\n", errout_str()); @@ -1468,7 +1468,7 @@ class TestCondition : public TestFixture { " y.f();\n" " if (a > x && a < y)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:9]: (style) Condition 'a>x' is always false [knownConditionTrueFalse]\n" "[test.cpp:8:18]: (style) Condition 'a x && a < y)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:9]: (style) Condition 'a>x' is always false [knownConditionTrueFalse]\n", errout_str()); check("void foo(A a) {\n" @@ -1491,7 +1491,7 @@ class TestCondition : public TestFixture { " y.f();\n" " if (a > x && a < y)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9]: (style) Condition 'a>x' is always false [knownConditionTrueFalse]\n", errout_str()); check("void foo(A a) {\n" @@ -1500,7 +1500,7 @@ class TestCondition : public TestFixture { " y.f();\n" " if (a > x && a < y)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9]: (style) Condition 'a>x' is always false [knownConditionTrueFalse]\n" "[test.cpp:5:18]: (style) Condition 'a [test.cpp:3:18]: (warning) Logical conjunction always evaluates to false: v == 1 && x == 2. [incorrectLogicOperator]\n", errout_str()); check("void f2(const int *v) {\n" " const int *x=v;\n" " if ((*v == 1) && (*x == 2)) {;}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18] -> [test.cpp:3:19]: (warning) Logical conjunction always evaluates to false: *(v) == 1 && *(x) == 2. [incorrectLogicOperator]\n", errout_str()); } @@ -1724,7 +1724,7 @@ class TestCondition : public TestFixture { " if (f && g)\n" " ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:200:11] -> [test.cpp:200:16]: (style) Condition 'g' is always true [knownConditionTrueFalse]\n", errout_str()); } @@ -1780,31 +1780,31 @@ class TestCondition : public TestFixture { check("void f(void) {\n" // #8892 " const char c[1] = { \'x\' }; \n" " if(c[0] == \'x\'){;}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (style) Condition 'c[0]=='x'' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" " if (x > 5 && x != 1)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (style) Redundant condition: The condition 'x != 1' is redundant since 'x > 5' is sufficient. [redundantCondition]\n", errout_str()); check("void f(int x) {\n" " if (x > 5 && x != 6)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if ((x > 5) && (x != 1))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) Redundant condition: The condition 'x != 1' is redundant since 'x > 5' is sufficient. [redundantCondition]\n", errout_str()); check("void f(int x) {\n" " if ((x > 5) && (x != 6))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x, bool& b) {\n" @@ -1812,7 +1812,7 @@ class TestCondition : public TestFixture { " c = x < 5 || x == 4;\n" " d = x >= 3 || x == 4;\n" " e = x <= 5 || x == 4;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (style) Redundant condition: The condition 'x == 4' is redundant since 'x > 3' is sufficient. [redundantCondition]\n" "[test.cpp:3:15]: (style) Redundant condition: The condition 'x == 4' is redundant since 'x < 5' is sufficient. [redundantCondition]\n" "[test.cpp:4:16]: (style) Redundant condition: The condition 'x == 4' is redundant since 'x >= 3' is sufficient. [redundantCondition]\n" @@ -1824,7 +1824,7 @@ class TestCondition : public TestFixture { " c = x < 1 || x != 3;\n" " d = x >= 5 || x != 1;\n" " e = x <= 1 || x != 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (style) Redundant condition: The condition 'x > 5' is redundant since 'x != 1' is sufficient. [redundantCondition]\n" "[test.cpp:3:15]: (style) Redundant condition: The condition 'x < 1' is redundant since 'x != 3' is sufficient. [redundantCondition]\n" "[test.cpp:4:16]: (style) Redundant condition: The condition 'x >= 5' is redundant since 'x != 1' is sufficient. [redundantCondition]\n" @@ -1836,7 +1836,7 @@ class TestCondition : public TestFixture { " c = x > 5 || x > 6;\n" " d = x < 6 && x < 5;\n" " e = x < 5 || x < 6;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (style) Redundant condition: The condition 'x > 5' is redundant since 'x > 6' is sufficient. [redundantCondition]\n" "[test.cpp:3:15]: (style) Redundant condition: The condition 'x > 6' is redundant since 'x > 5' is sufficient. [redundantCondition]\n" "[test.cpp:4:15]: (style) Redundant condition: The condition 'x < 6' is redundant since 'x < 5' is sufficient. [redundantCondition]\n" @@ -1848,7 +1848,7 @@ class TestCondition : public TestFixture { " c = x > 5.5 || x > 6.5;\n" " d = x < 6.5 && x < 5.5;\n" " e = x < 5.5 || x < 6.5;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) Redundant condition: The condition 'x > 5.5' is redundant since 'x > 6.5' is sufficient. [redundantCondition]\n" "[test.cpp:3:17]: (style) Redundant condition: The condition 'x > 6.5' is redundant since 'x > 5.5' is sufficient. [redundantCondition]\n" "[test.cpp:4:17]: (style) Redundant condition: The condition 'x < 6.5' is redundant since 'x < 5.5' is sufficient. [redundantCondition]\n" @@ -1866,49 +1866,49 @@ class TestCondition : public TestFixture { check("void f(int x) {\n" " if (x < 1 && x > 3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (1 > x && x > 3)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x < 1 && 3 < x)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (1 > x && 3 < x)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x > 3 && x < 1)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x > 3 && x < 1. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (3 < x && x < 1)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x > 3 && x < 1. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (x > 3 && 1 > x)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x > 3 && x < 1. [incorrectLogicOperator]\n", errout_str()); check("void f(int x) {\n" " if (3 < x && 1 > x)\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Logical conjunction always evaluates to false: x > 3 && x < 1. [incorrectLogicOperator]\n", errout_str()); } @@ -1918,7 +1918,7 @@ class TestCondition : public TestFixture { " b2 = a % c == 100000;\n" " b3 = a % 5 == c;\n" " return a % 5 == 5-p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(bool& b1, bool& b2, bool& b3, bool& b4, bool& b5) {\n" @@ -1928,7 +1928,7 @@ class TestCondition : public TestFixture { " b4 = a % 5 != 5;\n" " b5 = a % 5 >= 5;\n" " return a % 5 > 5;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:16]: (warning) Comparison of modulo result is predetermined, because it is always less than 5. [moduloAlwaysTrueFalse]\n" "[test.cpp:3:16]: (warning) Comparison of modulo result is predetermined, because it is always less than 5. [moduloAlwaysTrueFalse]\n" @@ -1942,7 +1942,7 @@ class TestCondition : public TestFixture { " b1 = bar() % 5 < 889;\n" " if(x[593] % 5 <= 5)\n" " b2 = x.a % 5 == 5;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:20]: (warning) Comparison of modulo result is predetermined, because it is always less than 5. [moduloAlwaysTrueFalse]\n" "[test.cpp:3:19]: (warning) Comparison of modulo result is predetermined, because it is always less than 5. [moduloAlwaysTrueFalse]\n" @@ -1952,7 +1952,7 @@ class TestCondition : public TestFixture { check("void f() {\n" " if (a % 2 + b % 2 == 2)\n" " foo();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1961,21 +1961,21 @@ class TestCondition : public TestFixture { " if(a==b)\n" " if(a!=b)\n" " cout << a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:13]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("bool foo(int a, int b) {\n" " if(a==b)\n" " return a!=b;\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:17]: (warning) Opposite inner 'return' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void foo(int a, int b) {\n" " if(a==b)\n" " if(b!=a)\n" " cout << a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:13]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void foo(int a) {\n" @@ -1985,7 +1985,7 @@ class TestCondition : public TestFixture { " else\n" " cout << 100;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10] -> [test.cpp:3:14]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); // #4186 @@ -1996,7 +1996,7 @@ class TestCondition : public TestFixture { " else\n" " cout << 100;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // 4170 @@ -2015,7 +2015,7 @@ class TestCondition : public TestFixture { " }\n" " void next();\n" " const char *tok;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int i)\n" @@ -2026,7 +2026,7 @@ class TestCondition : public TestFixture { " cout << a;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int& i) {\n" @@ -2038,7 +2038,7 @@ class TestCondition : public TestFixture { " if(i<5) {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int& i);\n" @@ -2049,7 +2049,7 @@ class TestCondition : public TestFixture { " if(i<5) {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int i);\n" @@ -2059,7 +2059,7 @@ class TestCondition : public TestFixture { " if(i<5) {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:5:13]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void foo(const int &i);\n" @@ -2069,7 +2069,7 @@ class TestCondition : public TestFixture { " if(i<5) {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:5:13]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void foo(int i);\n" @@ -2080,7 +2080,7 @@ class TestCondition : public TestFixture { " if(i<5) {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:6:13]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("class C { void f(int &i) const; };\n" // #7028 - variable is changed by const method @@ -2089,7 +2089,7 @@ class TestCondition : public TestFixture { " c.f(i);\n" " if (i != 5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // see linux revision 1f80c0cc @@ -2103,7 +2103,7 @@ class TestCondition : public TestFixture { " err = rc;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:11] -> [test.cpp:7:14]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); @@ -2114,7 +2114,7 @@ class TestCondition : public TestFixture { " array[0] += 5;\n" " if (array[0] > 2) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6227 - FP caused by simplifications of casts and known variables @@ -2123,7 +2123,7 @@ class TestCondition : public TestFixture { " B *b = dynamic_cast(a);\n" " if(!b) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a) {\n" @@ -2131,7 +2131,7 @@ class TestCondition : public TestFixture { " int b = a;\n" " if(!b) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16] -> [test.cpp:2:7] -> [test.cpp:4:11]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void foo(unsigned u) {\n" @@ -2141,7 +2141,7 @@ class TestCondition : public TestFixture { " u = x;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8186 @@ -2149,7 +2149,7 @@ class TestCondition : public TestFixture { " for (int i=0;i<4;i++) {\n" " if (i==5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17] -> [test.cpp:3:10]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); // #8938 @@ -2158,7 +2158,7 @@ class TestCondition : public TestFixture { " GetActiveCell(&(upperleft.Col), &(upperleft.Row));\n" " if (upperleft.Row == -1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9702 @@ -2171,7 +2171,7 @@ class TestCondition : public TestFixture { " }\n" " bool IsSet() const { return m_value; }\n" " bool m_value = false;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #12725 @@ -2193,7 +2193,7 @@ class TestCondition : public TestFixture { " err = rc;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void Fred::f() {\n" // daca: ace @@ -2201,7 +2201,7 @@ class TestCondition : public TestFixture { " this->next_ = n;\n" " if (this->next_ != map_man_->table_) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test(float *f) {\n" // #7405 @@ -2209,13 +2209,13 @@ class TestCondition : public TestFixture { " (*f) += 0.1f;\n" " if(*f<10) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int * f(int * x, int * y) {\n" " if(!x) return x;\n" " return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2227,7 +2227,7 @@ class TestCondition : public TestFixture { " fred.dostuff();\n" " if (!fred.isValid()) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19] -> [test.cpp:5:9]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("class Fred { public: bool isValid() const; void dostuff() const; };\n" @@ -2237,7 +2237,7 @@ class TestCondition : public TestFixture { " fred.dostuff();\n" // <- dostuff() is const, warn " if (!fred.isValid()) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:19] -> [test.cpp:6:9]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void f() {\n" @@ -2246,7 +2246,7 @@ class TestCondition : public TestFixture { " fred.dostuff();\n" " if (!fred.isValid()) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6385 "crash in Variable::getFlag()" @@ -2257,14 +2257,14 @@ class TestCondition : public TestFixture { " qApp->removeTranslator(mTranslator);\n" " }\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // just don't crash... check("bool f(std::ofstream &CFileStream) {\n" // #8198 " if(!CFileStream.good()) { return; }\n" " CFileStream << \"abc\";\n" " if (!CFileStream.good()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2275,7 +2275,7 @@ class TestCondition : public TestFixture { " x = do_something();\n" " if (x != -1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5750 - another fp when undeclared variable is used @@ -2284,7 +2284,7 @@ class TestCondition : public TestFixture { " r += 3;\n" " if (r > w) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6574 - another fp when undeclared variable is used @@ -2293,7 +2293,7 @@ class TestCondition : public TestFixture { " i++;\n" " if(!i) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // undeclared array @@ -2302,7 +2302,7 @@ class TestCondition : public TestFixture { " a[x] -= dt;\n" " if (a[x] < 0) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6313 - false positive: opposite conditions in nested if blocks when condition changed @@ -2312,7 +2312,7 @@ class TestCondition : public TestFixture { " if(!var){}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // daca hyphy @@ -2321,7 +2321,7 @@ class TestCondition : public TestFixture { " rec.Delete(i);\n" " if (rec.lLength!=0) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2335,7 +2335,7 @@ class TestCondition : public TestFixture { " doStuff(&s);\n" " if (hasFailed) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:7]: (style) Condition '!hasFailed' is always true [knownConditionTrueFalse]\n", errout_str()); } @@ -2346,7 +2346,7 @@ class TestCondition : public TestFixture { " if (x<4) {\n" " if (x==5) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void f(int x) {\n" @@ -2354,14 +2354,14 @@ class TestCondition : public TestFixture { " if (x<4) {\n" " if (x!=5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x!=5' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" "\n" " if (x<4) {\n" " if (x>5) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void f(int x) {\n" @@ -2369,7 +2369,7 @@ class TestCondition : public TestFixture { " if (x<4) {\n" " if (x>=5) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void f(int x) {\n" @@ -2377,14 +2377,14 @@ class TestCondition : public TestFixture { " if (x<4) {\n" " if (x<5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x<5' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" "\n" " if (x<4) {\n" " if (x<=5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x<=5' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" @@ -2392,49 +2392,49 @@ class TestCondition : public TestFixture { " if (x<5) {\n" " if (x==4) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" "\n" " if (x<5) {\n" " if (x!=4) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" "\n" " if (x<5) {\n" " if (x!=6) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x!=6' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" "\n" " if (x<5) {\n" " if (x>4) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x>4' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" "\n" " if (x<5) {\n" " if (x>=4) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" "\n" " if (x<5) {\n" " if (x<4) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" "\n" " if (x<5) {\n" " if (x<=4) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x<=4' is always true [knownConditionTrueFalse]\n", errout_str()); // first comparison: > @@ -2443,35 +2443,35 @@ class TestCondition : public TestFixture { " if (x>4) {\n" " if (x==5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" "\n" " if (x>4) {\n" " if (x>5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" "\n" " if (x>4) {\n" " if (x>=5) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x>=5' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" "\n" " if (x>4) {\n" " if (x<5) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x<5' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" "\n" " if (x>4) {\n" " if (x<=5) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" @@ -2479,7 +2479,7 @@ class TestCondition : public TestFixture { " if (x>5) {\n" " if (x==4) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void f(int x) {\n" @@ -2487,21 +2487,21 @@ class TestCondition : public TestFixture { " if (x>5) {\n" " if (x>4) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x>4' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" "\n" " if (x>5) {\n" " if (x>=4) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (style) Condition 'x>=4' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" "\n" " if (x>5) {\n" " if (x<4) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void f(int x) {\n" @@ -2509,7 +2509,7 @@ class TestCondition : public TestFixture { " if (x>5) {\n" " if (x<=4) {}\n" // <- Warning " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:4:10]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); @@ -2517,62 +2517,62 @@ class TestCondition : public TestFixture { " if (x < 4) {\n" " if (10 < x) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:12]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); } void oppositeInnerCondition3() { - check("void f3(char c) { if(c=='x') if(c=='y') {}}"); + check("void f3(char c) { if(c=='x') if(c=='y') {}}\n"); ASSERT_EQUALS("[test.cpp:1:23] -> [test.cpp:1:34]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f4(char *p) { if(*p=='x') if(*p=='y') {}}"); + check("void f4(char *p) { if(*p=='x') if(*p=='y') {}}\n"); ASSERT_EQUALS("[test.cpp:1:25] -> [test.cpp:1:37]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f5(const char * const p) { if(*p=='x') if(*p=='y') {}}"); + check("void f5(const char * const p) { if(*p=='x') if(*p=='y') {}}\n"); ASSERT_EQUALS("[test.cpp:1:38] -> [test.cpp:1:50]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f5(const char * const p) { if('x'==*p) if('y'==*p) {}}"); + check("void f5(const char * const p) { if('x'==*p) if('y'==*p) {}}\n"); ASSERT_EQUALS("[test.cpp:1:39] -> [test.cpp:1:51]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f6(char * const p) { if(*p=='x') if(*p=='y') {}}"); + check("void f6(char * const p) { if(*p=='x') if(*p=='y') {}}\n"); ASSERT_EQUALS("[test.cpp:1:32] -> [test.cpp:1:44]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f7(const char * p) { if(*p=='x') if(*p=='y') {}}"); + check("void f7(const char * p) { if(*p=='x') if(*p=='y') {}}\n"); ASSERT_EQUALS("[test.cpp:1:32] -> [test.cpp:1:44]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f8(int i) { if(i==4) if(i==2) {}}"); + check("void f8(int i) { if(i==4) if(i==2) {}}\n"); ASSERT_EQUALS("[test.cpp:1:22] -> [test.cpp:1:31]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f9(int *p) { if (*p==4) if(*p==2) {}}"); + check("void f9(int *p) { if (*p==4) if(*p==2) {}}\n"); ASSERT_EQUALS("[test.cpp:1:25] -> [test.cpp:1:35]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f10(int * const p) { if (*p==4) if(*p==2) {}}"); + check("void f10(int * const p) { if (*p==4) if(*p==2) {}}\n"); ASSERT_EQUALS("[test.cpp:1:33] -> [test.cpp:1:43]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f11(const int *p) { if (*p==4) if(*p==2) {}}"); + check("void f11(const int *p) { if (*p==4) if(*p==2) {}}\n"); ASSERT_EQUALS("[test.cpp:1:32] -> [test.cpp:1:42]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f12(const int * const p) { if (*p==4) if(*p==2) {}}"); + check("void f12(const int * const p) { if (*p==4) if(*p==2) {}}\n"); ASSERT_EQUALS("[test.cpp:1:39] -> [test.cpp:1:49]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("struct foo {\n" " int a;\n" " int b;\n" "};\n" - "void f(foo x) { if(x.a==4) if(x.b==2) {}}"); + "void f(foo x) { if(x.a==4) if(x.b==2) {}}\n"); ASSERT_EQUALS("", errout_str()); check("struct foo {\n" " int a;\n" " int b;\n" "};\n" - "void f(foo x) { if(x.a==4) if(x.b==4) {}}"); + "void f(foo x) { if(x.a==4) if(x.b==4) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f3(char a, char b) { if(a==b) if(a==0) {}}"); + check("void f3(char a, char b) { if(a==b) if(a==0) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int x) { if (x == 1) if (x != 1) {} }"); + check("void f(int x) { if (x == 1) if (x != 1) {} }\n"); ASSERT_EQUALS("[test.cpp:1:23] -> [test.cpp:1:35]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); } @@ -2580,8 +2580,8 @@ class TestCondition : public TestFixture { check("void f(int x) {\n" " if (a>3 && x > 100) {\n" " if (x < 10) {}\n" - " }" - "}"); + " }\n" + "}\n"); ASSERT_EQUALS("[test.cpp:2:16] -> [test.cpp:3:11]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void f(bool x, const int a, const int b) {\n" @@ -2632,69 +2632,69 @@ class TestCondition : public TestFixture { } void oppositeInnerConditionEmpty() { - check("void f1(const std::string &s) { if(s.size() > 42) if(s.empty()) {}}"); + check("void f1(const std::string &s) { if(s.size() > 42) if(s.empty()) {}}\n"); ASSERT_EQUALS("[test.cpp:1:45] -> [test.cpp:1:61]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f1(const std::string &s) { if(s.size() > 0) if(s.empty()) {}}"); + check("void f1(const std::string &s) { if(s.size() > 0) if(s.empty()) {}}\n"); ASSERT_EQUALS("[test.cpp:1:45] -> [test.cpp:1:60]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f1(const std::string &s) { if(s.size() < 0) if(s.empty()) {}} "); // <- CheckOther reports: checking if unsigned expression is less than zero + check("void f1(const std::string &s) { if(s.size() < 0) if(s.empty()) {}} \n"); // <- CheckOther reports: checking if unsigned expression is less than zero ASSERT_EQUALS("[test.cpp:1:45] -> [test.cpp:1:60]: (style) Condition 's.empty()' is always false [knownConditionTrueFalse]\n", errout_str()); - check("void f1(const std::string &s) { if(s.empty()) if(s.size() > 42) {}}"); + check("void f1(const std::string &s) { if(s.empty()) if(s.size() > 42) {}}\n"); ASSERT_EQUALS("[test.cpp:1:43] -> [test.cpp:1:59]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("template void f1(const T &s) { if(s.size() > 42) if(s.empty()) {}}"); + check("template void f1(const T &s) { if(s.size() > 42) if(s.empty()) {}}\n"); ASSERT_EQUALS("", errout_str()); //We don't know the type of T so we don't know the relationship between size() and empty(). e.g. s might be a 50 tonne truck with nothing in it. - check("void f2(const std::wstring &s) { if(s.empty()) if(s.size() > 42) {}}"); + check("void f2(const std::wstring &s) { if(s.empty()) if(s.size() > 42) {}}\n"); ASSERT_EQUALS("[test.cpp:1:44] -> [test.cpp:1:60]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f1(QString s) { if(s.isEmpty()) if(s.length() > 42) {}}"); + check("void f1(QString s) { if(s.isEmpty()) if(s.length() > 42) {}}\n"); ASSERT_EQUALS("[test.cpp:1:34] -> [test.cpp:1:52]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f1(const std::string &s, bool b) { if(s.empty() || ((s.size() == 1) && b)) {}}"); + check("void f1(const std::string &s, bool b) { if(s.empty() || ((s.size() == 1) && b)) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string &x, const std::string &y) { if(x.size() > 42) if(y.empty()) {}}"); + check("void f1(const std::string &x, const std::string &y) { if(x.size() > 42) if(y.empty()) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string &x, const std::string &y) { if(y.empty()) if(x.size() > 42) {}}"); + check("void f1(const std::string &x, const std::string &y) { if(y.empty()) if(x.size() > 42) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string v[10]) { if(v[0].size() > 42) if(v[1].empty()) {}}"); + check("void f1(const std::string v[10]) { if(v[0].size() > 42) if(v[1].empty()) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string &s) { if(s.size() <= 1) if(s.empty()) {}}"); + check("void f1(const std::string &s) { if(s.size() <= 1) if(s.empty()) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string &s) { if(s.size() <= 2) if(s.empty()) {}}"); + check("void f1(const std::string &s) { if(s.size() <= 2) if(s.empty()) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string &s) { if(s.size() < 2) if(s.empty()) {}}"); + check("void f1(const std::string &s) { if(s.size() < 2) if(s.empty()) {}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string &s) { if(s.size() >= 0) if(s.empty()) {}} "); // CheckOther says: Unsigned expression 's.size()' can't be negative so it is unnecessary to test it. [unsignedPositive] + check("void f1(const std::string &s) { if(s.size() >= 0) if(s.empty()) {}} \n"); // CheckOther says: Unsigned expression 's.size()' can't be negative so it is unnecessary to test it. [unsignedPositive] ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string &s) { if(42 < s.size()) if(s.empty()) {}}"); + check("void f1(const std::string &s) { if(42 < s.size()) if(s.empty()) {}}\n"); ASSERT_EQUALS("[test.cpp:1:39] -> [test.cpp:1:61]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); - check("void f1(const std::string &s) { if(s.empty()) if(42 < s.size()) {}}"); + check("void f1(const std::string &s) { if(s.empty()) if(42 < s.size()) {}}\n"); ASSERT_EQUALS("[test.cpp:1:43] -> [test.cpp:1:53]: (warning) Opposite inner 'if' condition leads to a dead code block. [oppositeInnerCondition]\n", errout_str()); check("void f(const std::string& s, int n) {\n" // #14716 " if (s.size() < n)\n" " if (s.empty()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // TODO: These are identical condition since size cannot be negative - check("void f1(const std::string &s) { if(s.size() <= 0) if(s.empty()) {}}"); + check("void f1(const std::string &s) { if(s.size() <= 0) if(s.empty()) {}}\n"); ASSERT_EQUALS("", errout_str()); // TODO: These are identical condition since size cannot be negative - check("void f1(const std::string &s) { if(s.size() < 1) if(s.empty()) {}}"); + check("void f1(const std::string &s) { if(s.size() < 1) if(s.empty()) {}}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2709,7 +2709,7 @@ class TestCondition : public TestFixture { " }\n" " void bar();\n" " int get() const;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct CD {\n" @@ -2737,7 +2737,7 @@ class TestCondition : public TestFixture { " bool b = f();\n" " x += 1;\n" " if (!b && f()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(double d) {\n" @@ -2766,10 +2766,10 @@ class TestCondition : public TestFixture { } void identicalInnerCondition() { - check("void f1(int a, int b) { if(a==b) if(a==b) {}}"); + check("void f1(int a, int b) { if(a==b) if(a==b) {}}\n"); ASSERT_EQUALS("[test.cpp:1:29] -> [test.cpp:1:38]: (warning) Identical inner 'if' condition is always true. [identicalInnerCondition]\n", errout_str()); - check("void f2(int a, int b) { if(a!=b) if(a!=b) {}}"); + check("void f2(int a, int b) { if(a!=b) if(a!=b) {}}\n"); ASSERT_EQUALS("[test.cpp:1:29] -> [test.cpp:1:38]: (warning) Identical inner 'if' condition is always true. [identicalInnerCondition]\n", errout_str()); // #6645 false negative: condition is always false @@ -2778,38 +2778,38 @@ class TestCondition : public TestFixture { " if(a) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:6] -> [test.cpp:3:9]: (warning) Identical inner 'if' condition is always true. [identicalInnerCondition]\n", errout_str()); check("bool f(int a, int b) {\n" " if(a == b) { return a == b; }\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10] -> [test.cpp:2:27]: (warning) Identical inner 'return' condition is always true. [identicalInnerCondition]\n", errout_str()); check("bool f(bool a) {\n" " if(a) { return a; }\n" " return false;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int* f(int* a, int * b) {\n" " if(a) { return a; }\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int* f(std::shared_ptr a, std::shared_ptr b) {\n" " if(a.get()) { return a.get(); }\n" " return b.get();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int * x; };\n" "int* f(A a, int * b) {\n" " if(a.x) { return a.x; }\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -2821,7 +2821,7 @@ class TestCondition : public TestFixture { " get_value (&value);\n" " if ((value >> 28) & 1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkP("#define TYPE_1 \"a\"\n" // #13202 @@ -2833,7 +2833,7 @@ class TestCondition : public TestFixture { " if (s == TYPE_2) {}\n" " else if (s == TYPE_3) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const int* p, const int* e) {\n" // #14595 @@ -2856,7 +2856,7 @@ class TestCondition : public TestFixture { " if (a[0] == 1) {\n" " if (a[0] == 1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14] -> [test.cpp:4:18]: (warning) Identical inner 'if' condition is always true. [identicalInnerCondition]\n", errout_str()); } @@ -2865,53 +2865,53 @@ class TestCondition : public TestFixture { check("void f(int x) {\n" // #8137 " if (x > 100) { return; }\n" " if (x > 100) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:9]: (warning) Identical condition 'x>100', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("bool f(int x) {\n" " if (x > 100) { return false; }\n" " return x > 100;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:12]: (warning) Identical condition and return expression 'x>100', return value is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("void f(int x) {\n" " if (x > 100) { return; }\n" " if (x > 100 || y > 100) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:9]: (warning) Identical condition 'x>100', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("void f(int x) {\n" " if (x > 100) { return; }\n" " if (x > 100 && y > 100) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:9]: (warning) Identical condition 'x>100', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("void f(int x) {\n" " if (x > 100) { return; }\n" " if (abc) {}\n" " if (x > 100) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:9]: (warning) Identical condition 'x>100', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("void f(int x) {\n" " if (x > 100) { return; }\n" " while (abc) { y = x; }\n" " if (x > 100) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:9]: (warning) Identical condition 'x>100', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); ASSERT_THROW_INTERNAL(check("void f(int x) {\n" // #8217 - crash for incomplete code " if (x > 100) { return; }\n" " X(do);\n" " if (x > 100) {}\n" - "}"), + "}\n"), SYNTAX); check("void f(const int *i) {\n" " if (!i) return;\n" " if (!num1tok) { *num1 = *num2; }\n" " if (!i) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7] -> [test.cpp:4:7]: (warning) Identical condition '!i', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("void C::f(Tree &coreTree) {\n" // daca @@ -2919,7 +2919,7 @@ class TestCondition : public TestFixture { " return;\n" " coreTree.dostuff();\n" " if(!coreTree.build()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct C { void f(const Tree &coreTree); };\n" @@ -2928,7 +2928,7 @@ class TestCondition : public TestFixture { " return;\n" " coreTree.dostuff();\n" " if(!coreTree.build()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6] -> [test.cpp:6:6]: (warning) Identical condition '!coreTree.build()', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("void f(int x) {\n" // daca: labplot @@ -2941,7 +2941,7 @@ class TestCondition : public TestFixture { " else return 4;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("static int failed = 0;\n" @@ -2949,14 +2949,14 @@ class TestCondition : public TestFixture { " if (failed) return;\n" " checkBuffer();\n" " if (failed) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // daca icu check("void f(const uint32_t *section, int32_t start) {\n" " if(10<=section[start]) { return; }\n" " if(++start<100 && 10<=section[start]) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // daca iqtree @@ -2966,7 +2966,7 @@ class TestCondition : public TestFixture { " if (ch != '|') return;\n" " in >> ch;\n" " if (ch != '|') {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8924 @@ -2977,7 +2977,7 @@ class TestCondition : public TestFixture { " if (this->FileIndex < 0) return;\n" " }\n" " int FileIndex;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:29]: (style) Condition 'this->FileIndex<0' is always false [knownConditionTrueFalse]\n", errout_str()); // #8858 - #if @@ -2989,7 +2989,7 @@ class TestCondition : public TestFixture { " ret = bar2();\n" "#endif\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10456 @@ -3027,7 +3027,7 @@ class TestCondition : public TestFixture { " x += y;\n" " if (x == 0) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" @@ -3035,7 +3035,7 @@ class TestCondition : public TestFixture { " x += y;\n" " if (x == 1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int * x, int * y) {\n" @@ -3043,7 +3043,7 @@ class TestCondition : public TestFixture { " (*y)++;\n" " if (x[*y] == 0) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int[]);\n" // #14724 @@ -3052,7 +3052,7 @@ class TestCondition : public TestFixture { " g(a);\n" " if (a[0] == 1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3061,14 +3061,14 @@ class TestCondition : public TestFixture { " if (x == 1) {\n" " if (x & 7) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:15]: (warning) Overlapping inner 'if' condition is always true. [overlappingInnerCondition]\n", errout_str()); check("void f(int x) {\n" " if (x & 7) {\n" " if (x == 1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3076,102 +3076,102 @@ class TestCondition : public TestFixture { void clarifyCondition1() { check("void f() {\n" " if (x = b() < 0) {}\n" // don't simplify and verify this code - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:8]: (style) Suspicious condition (assignment + comparison); Clarify expression with parentheses. [clarifyCondition]\n", errout_str()); check("void f(int i) {\n" " for (i = 0; i < 10; i++) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " x = a(); if (x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " if (x = b < 0 ? 1 : 2) {}\n" // don't simplify and verify this code - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int y = rand(), z = rand();\n" " if (y || (!y && z));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (style) Redundant condition: !y. 'y || (!y && z)' is equivalent to 'y || z' [redundantCondition]\n", errout_str()); check("void f() {\n" " int y = rand(), z = rand();\n" " if (y || !y && z);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (style) Redundant condition: !y. 'y || (!y && z)' is equivalent to 'y || z' [redundantCondition]\n", errout_str()); check("void f() {\n" " if (!a || a && b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (style) Redundant condition: a. '!a || (a && b)' is equivalent to '!a || b' [redundantCondition]\n", errout_str()); check("void f(const Token *tok) {\n" " if (!tok->next()->function() ||\n" " (tok->next()->function() && tok->next()->function()->isConstructor()));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:34]: (style) Redundant condition: tok->next()->function(). '!A || (A && B)' is equivalent to '!A || B' [redundantCondition]\n", errout_str()); check("void f() {\n" " if (!tok->next()->function() ||\n" " (!tok->next()->function() && tok->next()->function()->isConstructor()));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " if (!tok->next()->function() ||\n" " (!tok2->next()->function() && tok->next()->function()->isConstructor()));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const Token *tok) {\n" " if (!tok->next(1)->function(1) ||\n" " (tok->next(1)->function(1) && tok->next(1)->function(1)->isConstructor()));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:36]: (style) Redundant condition: tok->next(1)->function(1). '!A || (A && B)' is equivalent to '!A || B' [redundantCondition]\n", errout_str()); check("void f() {\n" " if (!tok->next()->function(1) ||\n" " (tok->next()->function(2) && tok->next()->function()->isConstructor()));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int y = rand(), z = rand();\n" " if (y==0 || y!=0 && z);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (style) Redundant condition: y!=0. 'y==0 || (y!=0 && z)' is equivalent to 'y==0 || z' [redundantCondition]\n", errout_str()); check("void f() {\n" " if (x>0 || (x<0 && y)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Test Token::expressionString, TODO move this test check("void f() {\n" " if (!dead || (dead && (*it).ticks > 0)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Redundant condition: dead. '!dead || (dead && (*it).ticks>0)' is equivalent to '!dead || (*it).ticks>0' [redundantCondition]\n", errout_str()); check("void f() {\n" " if (!x || (x && (2>(y-1)))) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) Redundant condition: x. '!x || (x && 2>(y-1))' is equivalent to '!x || 2>(y-1)' [redundantCondition]\n", errout_str()); check("void f(bool a, bool b) {\n" " if (a || (a && b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Redundant condition: a. 'a || (a && b)' is equivalent to 'a' [redundantCondition]\n", errout_str()); check("void f(bool a, bool b) {\n" " if (a && (a || b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Redundant condition: a. 'a && (a || b)' is equivalent to 'a' [redundantCondition]\n", errout_str()); } @@ -3179,14 +3179,14 @@ class TestCondition : public TestFixture { void clarifyCondition2() { check("void f() {\n" " if (x & 3 == 2) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:8]: (style) Suspicious condition (bitwise operator + comparison); Clarify expression with parentheses. [clarifyCondition]\n" "[test.cpp:2:11]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses. [clarifyCondition]\n" "[test.cpp:2:11]: (style) Condition 'x&3==2' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " if (a & fred1.x == fred2.y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:8]: (style) Suspicious condition (bitwise operator + comparison); Clarify expression with parentheses. [clarifyCondition]\n" "[test.cpp:2:11]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses. [clarifyCondition]\n" , errout_str()); @@ -3196,50 +3196,50 @@ class TestCondition : public TestFixture { void clarifyCondition3() { check("void f(int w) {\n" " if(!w & 0x8000) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses. [clarifyCondition]\n", errout_str()); check("void f(int w) {\n" " if((!w) & 0x8000) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " if (x == foo() & 2) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses. [clarifyCondition]\n", errout_str()); check("void f() {\n" " if (2 & x == foo()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses. [clarifyCondition]\n", errout_str()); check("void f() {\n" " if (2 & (x == foo())) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(std::list &ints) { }"); + check("void f(std::list &ints) { }\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { A a; }"); + check("void f() { A a; }\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { a(x there are never templates + check("void f() { a(x there are never templates ASSERT_EQUALS("[test.c:1:17]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses. [clarifyCondition]\n", errout_str()); - check("class A;"); + check("class A;\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " if (result != (char *)&inline_result) { }\n" // don't simplify and verify cast - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8495 check("void f(bool a, bool b) {\n" " C & a & b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3254,13 +3254,13 @@ class TestCondition : public TestFixture { " {\n" " return left.first < right.first;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void clarifyCondition5() { // ticket #3609 (using | in template instantiation) check("template struct CWinTraits;\n" - "CWinTraits::GetWndStyle(0);"); + "CWinTraits::GetWndStyle(0);\n"); ASSERT_EQUALS("", errout_str()); } @@ -3269,7 +3269,7 @@ class TestCondition : public TestFixture { "SharedPtr& operator=( SharedPtr const & r ) {\n" " px = r.px;\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3278,7 +3278,7 @@ class TestCondition : public TestFixture { check("void f(bool error) {\n" " bool & withoutSideEffects=found.first->second;\n" // Declaring a reference to a boolean; & is no operator at all " execute(secondExpression, &programMemory, &result, &error);\n" // Unary & - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3288,24 +3288,24 @@ class TestCondition : public TestFixture { check("bool a();\n" "bool f(bool b) {\n" " return (a() & b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(bool *a, bool b) {\n" " return (a[10] & b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { bool a; };\n" "bool f(struct A a, bool b) {\n" " return (a.a & b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { bool a; };\n" "bool f(struct A a, bool b) {\n" " return (A::a & b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3313,7 +3313,7 @@ class TestCondition : public TestFixture { check("void png_parse(uint64_t init, int buf_size) {\n" " if (init == 0x89504e470d0a1a0a || init == 0x8a4d4e470d0a1a0a)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3322,7 +3322,7 @@ class TestCondition : public TestFixture { "void foo() {\n" " if( ( value >= 0x7ff0000000000001ULL )\n" " && ( value <= 0x7fffffffffffffffULL ) );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3332,7 +3332,7 @@ class TestCondition : public TestFixture { " int x1 = s->x;\n" " int x2 = s->x;\n" " if (x1 == 10 && x2 == 10) {}\n" // << - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10] -> [test.cpp:4:22]: (style) Condition 'x2==10' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f ()\n"// #8220 @@ -3348,27 +3348,27 @@ class TestCondition : public TestFixture { " a ++;\n" " }\n" " ret = b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:27] -> [test.cpp:8:40]: (style) Condition '8 [test.cpp:2:30]: (style) Return value 'x==0' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" // #6898 (Token::expressionString) " int x = 0;\n" " A(x++ == 1);\n" " A(x++ == 2);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) Condition 'x++==1' is always false [knownConditionTrueFalse]\n" "[test.cpp:4:9]: (style) Condition 'x++==2' is always false [knownConditionTrueFalse]\n", errout_str()); @@ -3380,68 +3380,68 @@ class TestCondition : public TestFixture { " if (bar == 2)\n" " ret = true;\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("void f1(const std::string &s) { if(s.empty()) if(s.size() == 0) {}}"); + check("void f1(const std::string &s) { if(s.empty()) if(s.size() == 0) {}}\n"); ASSERT_EQUALS("[test.cpp:1:43] -> [test.cpp:1:59]: (style) Condition 's.size()==0' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " int buf[42];\n" " if( buf != 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (style) Condition 'buf!=0' is always true [knownConditionTrueFalse]\n", errout_str()); // #8924 check("void f() {\n" " int buf[42];\n" " if( !buf ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8]: (style) Condition '!buf' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " int buf[42];\n" " bool b = buf;\n" " if( b ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:8]: (style) Condition 'b' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " int buf[42];\n" " bool b = buf;\n" " if( !b ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:8]: (style) Condition '!b' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " int buf[42];\n" " int * p = nullptr;\n" " if( buf == p ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (style) Condition 'buf==p' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(bool x) {\n" " int buf[42];\n" " if( buf || x ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8]: (style) Condition 'buf' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int * p) {\n" " int buf[42];\n" " if( buf == p ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int buf[42];\n" " int p[42];\n" " if( buf == p ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int buf[42];\n" " if( buf == 1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Avoid FP when condition comes from macro @@ -3450,7 +3450,7 @@ class TestCondition : public TestFixture { " int x = 0;\n" " if (a) { return; }\n" // <- this is just here to fool simplifyKnownVariabels " if (NOT x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("#define M x != 0\n" @@ -3458,27 +3458,27 @@ class TestCondition : public TestFixture { " int x = 0;\n" " if (a) { return; }\n" // <- this is just here to fool simplifyKnownVariabels " if (M) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("#define IF(X) if (X && x())\n" "void f() {\n" " IF(1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Avoid FP for sizeof condition check("void f() {\n" " if (sizeof(char) != 123) {}\n" " if (123 != sizeof(char)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int x = 123;\n" " if (sizeof(char) != x) {}\n" " if (x != sizeof(char)) {}\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'sizeof(char)!=x' is always true\n" "[test.cpp:4]: (style) Condition 'x!=sizeof(char)' is always true\n", "", errout_str()); @@ -3487,7 +3487,7 @@ class TestCondition : public TestFixture { check("void f() {\n" " int x = 0;\n" " assert(x == 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9363 - do not warn about value passed to function @@ -3495,7 +3495,7 @@ class TestCondition : public TestFixture { " if (b) {\n" " if (bar(!b)) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -3510,7 +3510,7 @@ class TestCondition : public TestFixture { " assert((int)(0==0));\n" " assert((int)(0==0) && \"bla\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #7750 char literals in boolean expressions @@ -3519,7 +3519,7 @@ class TestCondition : public TestFixture { " if(L'b'){}\n" " if(1 && 'c'){}\n" " int x = 'd' ? 1 : 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8206 - knownCondition always false @@ -3527,26 +3527,26 @@ class TestCondition : public TestFixture { "{\n" " if(i > 4)\n" " for( int x = 0; i < 3; ++x){}\n" // << - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14] -> [test.cpp:4:29]: (style) Condition 'i<3' is always false [knownConditionTrueFalse]\n", errout_str()); // Skip literals - check("void f() { if(true) {} }"); + check("void f() { if(true) {} }\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { if(false) {} }"); + check("void f() { if(false) {} }\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { if(!true) {} }"); + check("void f() { if(!true) {} }\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { if(!false) {} }"); + check("void f() { if(!false) {} }\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { if(0) {} }"); + check("void f() { if(0) {} }\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { if(1) {} }"); + check("void f() { if(1) {} }\n"); ASSERT_EQUALS("", errout_str()); check("void f(int i) {\n" @@ -3555,36 +3555,36 @@ class TestCondition : public TestFixture { " else if (!b && i == 1) {}\n" " if (b)\n" " {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:14]: (style) Condition '!b' is always true [knownConditionTrueFalse]\n", errout_str()); - check("bool f() { return nullptr; }"); + check("bool f() { return nullptr; }\n"); ASSERT_EQUALS("", errout_str()); check("enum E { A };\n" - "bool f() { return A; }"); + "bool f() { return A; }\n"); ASSERT_EQUALS("", errout_str()); check("bool f() {\n" " const int x = 0;\n" " return x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("int f(void){return 1/abs(10);}"); + check("int f(void){return 1/abs(10);}\n"); ASSERT_EQUALS("", errout_str()); check("bool f() {\n" " int x = 0;\n" " return x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f() {\n" " const int a = 50;\n" " const int b = 52;\n" " return a+b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Return value 'a+b' is always true [knownConditionTrueFalse]\n", errout_str()); check("int f() {\n" @@ -3593,7 +3593,7 @@ class TestCondition : public TestFixture { " a++;\n" " b++;\n" " return a+b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool& g();\n" @@ -3601,7 +3601,7 @@ class TestCondition : public TestFixture { " bool & b = g();\n" " b = false;\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -3610,13 +3610,13 @@ class TestCondition : public TestFixture { " b = false;\n" " return b;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("bool f(long maxtime) {\n" " if (std::time(0) > maxtime)\n" " return std::time(0) > maxtime;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(double param) {\n" @@ -3626,7 +3626,7 @@ class TestCondition : public TestFixture { " }\n" " if (param<0.)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int i) {\n" @@ -3636,7 +3636,7 @@ class TestCondition : public TestFixture { " }\n" " if (cond && (42==i))\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // 8842 crash @@ -3646,15 +3646,15 @@ class TestCondition : public TestFixture { " void f() {\n" " if (b) return;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("void f(const char* x, const char* t) {\n" " if (!(strcmp(x, y) == 0)) { return; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const int a[]){ if (a == 0){} }"); + check("void f(const int a[]){ if (a == 0){} }\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -3665,7 +3665,7 @@ class TestCondition : public TestFixture { " bool c = s [test.cpp:3:9]: (style) Condition 'handle' is always true [knownConditionTrueFalse]\n", errout_str()); check("int f(void *handle) {\n" " if (handle == 0) return 0;\n" " if (handle) return 1;\n" " else return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) Condition 'handle' is always true [knownConditionTrueFalse]\n", errout_str()); check("int f(void *handle) {\n" " if (handle != 0) return 0;\n" " if (handle) return 1;\n" " else return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16] -> [test.cpp:3:9]: (warning) Identical condition 'handle!=0', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("int f(void *handle) {\n" " if (handle != nullptr) return 0;\n" " if (handle) return 1;\n" " else return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16] -> [test.cpp:3:9]: (warning) Identical condition 'handle!=nullptr', second condition is always false [identicalConditionAfterEarlyExit]\n", errout_str()); check("void f(const char* p) {\n" // #13716 @@ -3710,7 +3710,7 @@ class TestCondition : public TestFixture { " if (p == NULL) {}\n" " if (p == nullptr) {}\n" " if (p == 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:11]: (style) The if condition is the same as the previous if condition [duplicateCondition]\n", errout_str()); @@ -3718,7 +3718,7 @@ class TestCondition : public TestFixture { " if (p) {}\n" " else if (!p) {}\n" " else if (p == NULL) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:14]: (style) Expression is always true because 'else if' condition is opposite to previous condition at line 2. [multiCondition]\n" "[test.cpp:4:16]: (style) Expression is always false because 'else if' condition matches previous condition at line 3. [multiCondition]\n", errout_str()); @@ -3728,7 +3728,7 @@ class TestCondition : public TestFixture { " return;\n" " if (x == nullptr || y == nullptr)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void* g();\n" @@ -3739,7 +3739,7 @@ class TestCondition : public TestFixture { " break;\n" " }\n" " if (a) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void* g();\n" @@ -3748,26 +3748,26 @@ class TestCondition : public TestFixture { " a = g();\n" " }\n" " if (a) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12] -> [test.cpp:6:9]: (style) Condition 'a' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(int * x, bool b) {\n" " if (!x && b) {}\n" " else if (x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " const std::string x=\"xyz\";\n" " if(!x.empty()){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8]: (style) Condition '!x.empty()' is always true [knownConditionTrueFalse]\n", errout_str()); check("std::string g();\n" "void f() {\n" " const std::string msg = g();\n" " if(!msg.empty()){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *array, int size ) {\n" @@ -3776,7 +3776,7 @@ class TestCondition : public TestFixture { " continue;\n" " if(array){}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:12]: (style) Condition 'array' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int *array, int size ) {\n" @@ -3785,7 +3785,7 @@ class TestCondition : public TestFixture { " continue;\n" " else if(array){}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:17]: (style) Condition 'array' is always true [knownConditionTrueFalse]\n", errout_str()); // #9277 @@ -3795,7 +3795,7 @@ class TestCondition : public TestFixture { " return 0;\n" " else\n" " return 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9954 @@ -3817,7 +3817,7 @@ class TestCondition : public TestFixture { " bool x = false;\n" " g({0, 1}, x);\n" " if (x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9318 @@ -3828,7 +3828,7 @@ class TestCondition : public TestFixture { " return;\n" " auto b = dynamic_cast(x);\n" " if (b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo() {\n" @@ -3846,7 +3846,7 @@ class TestCondition : public TestFixture { check("bool g();\n" "void f(bool x) {\n" " if (x) while(x) x = g();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // isLikelyStream @@ -3856,7 +3856,7 @@ class TestCondition : public TestFixture { " iss >> x;\n" " if (!iss) break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9332 @@ -3868,14 +3868,14 @@ class TestCondition : public TestFixture { " void* c = a.g();\n" " if (!c) return;\n" " bool compare = c == b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9361 check("void f(char c) {\n" " if (c == '.') {}\n" " else if (isdigit(c) != 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9351 @@ -3883,7 +3883,7 @@ class TestCondition : public TestFixture { " const bool b = x < 42;\n" " if(b) return b?0:-1;\n" " return 42;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:3:18]: (style) Condition 'b' is always true [knownConditionTrueFalse]\n", errout_str()); // #9362 @@ -3893,7 +3893,7 @@ class TestCondition : public TestFixture { " if((v != 0x00)) {\n" " if( (v & 0x01) == 0x00) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9367 @@ -3902,25 +3902,25 @@ class TestCondition : public TestFixture { " return;\n" " if (x % 360L == 0)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int a, int b) {\n" " static const int x = 10;\n" " return x == 1 ? a : b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const bool x = false;\n" "void f() {\n" " if (x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const bool x = false;\n" "void f() {\n" " if (!x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9709 @@ -3931,7 +3931,7 @@ class TestCondition : public TestFixture { " if (r != nullptr)\n" " ok = a != 0;\n" " if (ok) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9816 @@ -4120,7 +4120,7 @@ class TestCondition : public TestFixture { check("void foo(unsigned int max) {\n" " unsigned int num = max - 1;\n" " if (num < 0) {}\n" // <- do not report knownConditionTrueFalse - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10297 @@ -4459,7 +4459,7 @@ class TestCondition : public TestFixture { ASSERT_EQUALS("", errout_str()); // #8358 - check("void f(double d) { if ((d * 0) != 0) {} }"); + check("void f(double d) { if ((d * 0) != 0) {} }\n"); ASSERT_EQUALS("", errout_str()); // #6870 @@ -4819,7 +4819,7 @@ class TestCondition : public TestFixture { " return 9;\n" " \n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int g();\n" // #10561 @@ -4834,7 +4834,7 @@ class TestCondition : public TestFixture { " }\n" " catch (...) {}\n" " return b ? 1 : 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -4990,10 +4990,10 @@ class TestCondition : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:2:10] -> [test.cpp:4:14]: (style) Condition 'x==y' is always false [knownConditionTrueFalse]\n", errout_str()); - check("void f(bool a, bool b) { if (a == b && a && !b){} }"); + check("void f(bool a, bool b) { if (a == b && a && !b){} }\n"); ASSERT_EQUALS("[test.cpp:1:41] -> [test.cpp:1:46]: (style) Condition '!b' is always false [knownConditionTrueFalse]\n", errout_str()); - check("bool f(bool a, bool b) { if(a && b && (!a)){} }"); + check("bool f(bool a, bool b) { if(a && b && (!a)){} }\n"); ASSERT_EQUALS("[test.cpp:1:29] -> [test.cpp:1:40]: (style) Condition '!a' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(int x, int y) {\n" @@ -5205,7 +5205,7 @@ class TestCondition : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); - check("struct A { int x; int y; };" + check("struct A { int x; int y; };\n" "void use(int);\n" "void test(A a) {\n" " int i = a.x;\n" @@ -5214,10 +5214,10 @@ class TestCondition : public TestFixture { " if (i == j) {}\n" " if (i == a.x) {}\n" " if (j == a.x) {}\n" - "}"); - ASSERT_EQUALS("[test.cpp:6:11]: (style) Condition 'i==j' is always true [knownConditionTrueFalse]\n" - "[test.cpp:7:11]: (style) Condition 'i==a.x' is always true [knownConditionTrueFalse]\n" - "[test.cpp:8:11]: (style) Condition 'j==a.x' is always true [knownConditionTrueFalse]\n", + "}\n"); + ASSERT_EQUALS("[test.cpp:7:11]: (style) Condition 'i==j' is always true [knownConditionTrueFalse]\n" + "[test.cpp:8:11]: (style) Condition 'i==a.x' is always true [knownConditionTrueFalse]\n" + "[test.cpp:9:11]: (style) Condition 'j==a.x' is always true [knownConditionTrueFalse]\n", errout_str()); check("struct S { int i; };\n" // #12795 @@ -5258,7 +5258,7 @@ class TestCondition : public TestFixture { " x++;\n" " if (x == 1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:4:15]: (style) Condition 'x==1' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" @@ -5266,7 +5266,7 @@ class TestCondition : public TestFixture { " x++;\n" " if (x != 1) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:4:15]: (style) Condition 'x!=1' is always true [knownConditionTrueFalse]\n", errout_str()); // #6890 @@ -5278,7 +5278,7 @@ class TestCondition : public TestFixture { " if (x == -1) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:6:15]: (style) Condition 'x==-1' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(int i) {\n" @@ -5289,7 +5289,7 @@ class TestCondition : public TestFixture { " if (x != -1) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:6:15]: (style) Condition 'x!=-1' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int i) {\n" @@ -5300,7 +5300,7 @@ class TestCondition : public TestFixture { " if (x >= -1) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:6:15]: (style) Condition 'x>=-1' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int i) {\n" @@ -5311,7 +5311,7 @@ class TestCondition : public TestFixture { " if (x > -1) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:6:15]: (style) Condition 'x>-1' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int i) {\n" @@ -5322,7 +5322,7 @@ class TestCondition : public TestFixture { " if (x < -1) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:6:15]: (style) Condition 'x<-1' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(int i) {\n" @@ -5333,7 +5333,7 @@ class TestCondition : public TestFixture { " if (x <= -1) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:6:15]: (style) Condition 'x<=-1' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f(int i) {\n" @@ -5344,7 +5344,7 @@ class TestCondition : public TestFixture { " if (x > 7) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:6:15]: (style) Condition 'x>7' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(int i) {\n" @@ -5355,7 +5355,7 @@ class TestCondition : public TestFixture { " if (x > 9) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int i) {\n" @@ -5366,7 +5366,7 @@ class TestCondition : public TestFixture { " if (x > 10) {}\n" " else {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #11100 @@ -5391,7 +5391,7 @@ class TestCondition : public TestFixture { " if(pos > 0)\n" " --pos;\n" " return pos;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:5:16]: (style) Condition 'pos>0' is always true [knownConditionTrueFalse]\n", errout_str()); // #9721 @@ -5400,7 +5400,7 @@ class TestCondition : public TestFixture { " if ( (x>255) || (-128>x) )\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:30]: (style) Condition '-128>x' is always false [knownConditionTrueFalse]\n", errout_str()); // #8778 @@ -5414,7 +5414,7 @@ class TestCondition : public TestFixture { check("void f() {\n" " for(int x = 0; x < 3; ++x)\n" " if(x == -5) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (style) Condition 'x==-5' is always false [knownConditionTrueFalse]\n", errout_str()); // #8407 @@ -5423,7 +5423,7 @@ class TestCondition : public TestFixture { " if(i == 0) return 1; \n" // << " else return 0;\n" " return -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (style) Condition 'i==0' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f(unsigned int u1, unsigned int u2) {\n" @@ -5495,7 +5495,7 @@ class TestCondition : public TestFixture { " c2(g );\n" " if ( !g.empty() )\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int flag) {\n" @@ -5506,7 +5506,7 @@ class TestCondition : public TestFixture { " c2(g );\n" " if ( !g.empty() )\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -5717,7 +5717,7 @@ class TestCondition : public TestFixture { " {;}\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:20] -> [test.cpp:7:27]: (style) Condition 'i==1' is always true [knownConditionTrueFalse]\n", errout_str()); // #10863 @@ -5831,7 +5831,7 @@ class TestCondition : public TestFixture { void alwaysTruePremiumMisra() { const char code[] = "void f() {\n" " if (3 > 2) {}\n" - "}"; + "}\n"; check(code); ASSERT_EQUALS("", errout_str()); @@ -5847,7 +5847,7 @@ class TestCondition : public TestFixture { " int val = 0;\n" " if (val < 0) continue;\n" " if (val > 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -5855,7 +5855,7 @@ class TestCondition : public TestFixture { " if (val < 0) {\n" " if (val > 0) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -5863,7 +5863,7 @@ class TestCondition : public TestFixture { " if (val < 0) {\n" " if (val < 0) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -5871,7 +5871,7 @@ class TestCondition : public TestFixture { " int foo = 0;\n" " if (activate) {}\n" " else if (foo) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: (style) Condition 'activate' is always false [knownConditionTrueFalse]\n" "[test.cpp:5:12]: (style) Condition 'foo' is always false [knownConditionTrueFalse]\n", errout_str()); @@ -5879,7 +5879,7 @@ class TestCondition : public TestFixture { check("void f() {\n" " const int b[2] = { 1,0 };\n" " if(b[1] == 2) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (style) Condition 'b[1]==2' is always false [knownConditionTrueFalse]\n", errout_str()); // #9878 @@ -5896,40 +5896,40 @@ class TestCondition : public TestFixture { check("void f(bool x) {\n" " if(x) {}\n" " if(x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:8] -> [test.cpp:3:8]: (style) The if condition is the same as the previous if condition [duplicateCondition]\n", errout_str()); check("void f(int x) {\n" " if(x == 1) {}\n" " if(x == 1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10] -> [test.cpp:3:10]: (style) The if condition is the same as the previous if condition [duplicateCondition]\n", errout_str()); check("void f(int x) {\n" " if(x == 1) {}\n" " if(x == 2) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if(x == 1) {}\n" " if(x != 1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool x) {\n" " if(x) {}\n" " g();\n" " if(x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if(x == 1) { x++; }\n" " if(x == 1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8996 @@ -5941,7 +5941,7 @@ class TestCondition : public TestFixture { " g(d);\n" " if (a) {}\n" " if (b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9311 @@ -5956,7 +5956,7 @@ class TestCondition : public TestFixture { " g(d);\n" " if (a) {}\n" " if (b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8993 @@ -5964,7 +5964,7 @@ class TestCondition : public TestFixture { " auto y = x;\n" " if (x.empty()) y = \"1\";\n" " if (y.empty()) return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9106 @@ -5972,7 +5972,7 @@ class TestCondition : public TestFixture { "void f(A a, int c) {\n" " if (a.b) a.b = c;\n" " if (a.b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -6094,7 +6094,7 @@ class TestCondition : public TestFixture { " ;\n" " if (other.mPA.cols > 0 && other.mPA.rows > 0)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" // #11202 @@ -6143,27 +6143,27 @@ class TestCondition : public TestFixture { void checkInvalidTestForOverflow() { check("void f(char *p, unsigned int x) {\n" " assert((p + x) < p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (warning) Invalid test for overflow '(p+x)= p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (warning) Invalid test for overflow '(p+x)>=p'; pointer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always true. [invalidTestForOverflow]\n", errout_str()); check("void f(char *p, unsigned int x) {\n" " assert(p > (p + x));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (warning) Invalid test for overflow 'p>(p+x)'; pointer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always false. [invalidTestForOverflow]\n", errout_str()); check("void f(char *p, unsigned int x) {\n" " assert(p <= (p + x));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (warning) Invalid test for overflow 'p<=(p+x)'; pointer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always true. [invalidTestForOverflow]\n", errout_str()); check("void f(signed int x) {\n" // unsigned overflow => don't warn " assert(x + 100U < x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -6171,57 +6171,57 @@ class TestCondition : public TestFixture { #define MSG(EXPR, RESULT) "[test.cpp:1:30]: (warning) Invalid test for overflow '" EXPR "'; signed integer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always " RESULT ". [invalidTestForOverflow]\n" - check("int f(int x) { return x + 10 > x; }"); + check("int f(int x) { return x + 10 > x; }\n"); ASSERT_EQUALS(MSG("x+10>x", "true"), errout_str()); - check("int f(int x) { return x + 10 >= x; }"); + check("int f(int x) { return x + 10 >= x; }\n"); ASSERT_EQUALS(MSG("x+10>=x", "true"), errout_str()); - check("int f(int x) { return x + 10 < x; }"); + check("int f(int x) { return x + 10 < x; }\n"); ASSERT_EQUALS(MSG("x+10 x; }"); + check("int f(int x) { return x - 10 > x; }\n"); ASSERT_EQUALS(MSG("x-10>x", "false"), errout_str()); - check("int f(int x) { return x - 10 >= x; }"); + check("int f(int x) { return x - 10 >= x; }\n"); ASSERT_EQUALS(MSG("x-10>=x", "false"), errout_str()); - check("int f(int x) { return x - 10 < x; }"); + check("int f(int x) { return x - 10 < x; }\n"); ASSERT_EQUALS(MSG("x-10 x; }"); + check("int f(int x, int y) { return x + y > x; }\n"); ASSERT_EQUALS(MSG("x+y>x", "y>0"), errout_str()); - check("int f(int x, int y) { return x + y >= x; }"); + check("int f(int x, int y) { return x + y >= x; }\n"); ASSERT_EQUALS(MSG("x+y>=x", "y>=0"), errout_str()); // x - y < x - check("int f(int x, int y) { return x - y < x; }"); + check("int f(int x, int y) { return x - y < x; }\n"); ASSERT_EQUALS(MSG("x-y0"), errout_str()); - check("int f(int x, int y) { return x - y <= x; }"); + check("int f(int x, int y) { return x - y <= x; }\n"); ASSERT_EQUALS(MSG("x-y<=x", "y>=0"), errout_str()); - check("int f(int x, int y) { return x - y > x; }"); + check("int f(int x, int y) { return x - y > x; }\n"); ASSERT_EQUALS(MSG("x-y>x", "y<0"), errout_str()); - check("int f(int x, int y) { return x - y >= x; }"); + check("int f(int x, int y) { return x - y >= x; }\n"); ASSERT_EQUALS(MSG("x-y>=x", "y<=0"), errout_str()); } @@ -6230,55 +6230,55 @@ class TestCondition : public TestFixture { " enum states {A,B,C};\n" " const unsigned g_flags = B|C;\n" " if(g_flags & A) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (style) Condition 'g_flags&A' is always false [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " int a = 5;" " if(a) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (style) Condition 'a' is always true [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " int a = 5;" " while(a + 1) { a--; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int a = 5;" " while(a + 1) { return; }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:27]: (style) Condition 'a+1' is always true [knownConditionTrueFalse]\n", errout_str()); } void alwaysTrueFalseInLogicalOperators() { check("bool f();\n" - "void foo() { bool x = true; if(x||f()) {}}"); + "void foo() { bool x = true; if(x||f()) {}}\n"); ASSERT_EQUALS("[test.cpp:2:32]: (style) Condition 'x' is always true [knownConditionTrueFalse]\n", errout_str()); - check("void foo(bool b) { bool x = true; if(x||b) {}}"); + check("void foo(bool b) { bool x = true; if(x||b) {}}\n"); ASSERT_EQUALS("[test.cpp:1:38]: (style) Condition 'x' is always true [knownConditionTrueFalse]\n", errout_str()); - check("void foo(bool b) { if(true||b) {}}"); + check("void foo(bool b) { if(true||b) {}}\n"); ASSERT_EQUALS("", errout_str()); check("bool f();\n" - "void foo() { bool x = false; if(x||f()) {}}"); + "void foo() { bool x = false; if(x||f()) {}}\n"); ASSERT_EQUALS("[test.cpp:2:33]: (style) Condition 'x' is always false [knownConditionTrueFalse]\n", errout_str()); check("bool f();\n" - "void foo() { bool x = false; if(x&&f()) {}}"); + "void foo() { bool x = false; if(x&&f()) {}}\n"); ASSERT_EQUALS("[test.cpp:2:33]: (style) Condition 'x' is always false [knownConditionTrueFalse]\n", errout_str()); - check("void foo(bool b) { bool x = false; if(x&&b) {}}"); + check("void foo(bool b) { bool x = false; if(x&&b) {}}\n"); ASSERT_EQUALS("[test.cpp:1:39]: (style) Condition 'x' is always false [knownConditionTrueFalse]\n", errout_str()); - check("void foo(bool b) { if(false&&b) {}}"); + check("void foo(bool b) { if(false&&b) {}}\n"); ASSERT_EQUALS("", errout_str()); check("bool f();\n" - "void foo() { bool x = true; if(x&&f()) {}}"); + "void foo() { bool x = true; if(x&&f()) {}}\n"); ASSERT_EQUALS("[test.cpp:2:32]: (style) Condition 'x' is always true [knownConditionTrueFalse]\n", errout_str()); // #9578 @@ -6303,7 +6303,7 @@ class TestCondition : public TestFixture { " if (!b) {\n" " bool x = a || b;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:18]: (style) Condition '!b' is always false [knownConditionTrueFalse]\n" "[test.cpp:7:9] -> [test.cpp:8:23]: (style) Condition 'b' is always false [knownConditionTrueFalse]\n", errout_str()); @@ -6312,7 +6312,7 @@ class TestCondition : public TestFixture { void pointerAdditionResultNotNull() { check("void f(char *ptr) {\n" " if (ptr + 1 != 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning) Comparison is wrong. Result of 'ptr+1' can't be 0 unless there is pointer overflow, and pointer overflow is undefined behaviour. [pointerAdditionResultNotNull]\n", errout_str()); } @@ -6322,7 +6322,7 @@ class TestCondition : public TestFixture { check("void f(int& x, int y) {\n" " if (x == y)\n" " x = y;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: style: Assignment 'x=y' is redundant with condition 'x==y'. [duplicateConditionalAssign]\n" "[test.cpp:2:11]: note: Condition 'x==y'\n" "[test.cpp:3:11]: note: Assignment 'x=y' is redundant\n", errout_str()); @@ -6330,7 +6330,7 @@ class TestCondition : public TestFixture { check("void f(int& x, int y) {\n" " if (x != y)\n" " x = y;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: style: The statement 'if (x!=y) x=y' is logically equivalent to 'x=y'. [duplicateConditionalAssign]\n" "[test.cpp:3:11]: note: Assignment 'x=y'\n" "[test.cpp:2:11]: note: Condition 'x!=y' is redundant\n", errout_str()); @@ -6340,7 +6340,7 @@ class TestCondition : public TestFixture { " x = y;\n" " else\n" " x = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: style: Assignment 'x=y' is redundant with condition 'x==y'. [duplicateConditionalAssign]\n" "[test.cpp:2:11]: note: Condition 'x==y'\n" "[test.cpp:3:11]: note: Assignment 'x=y' is redundant\n", errout_str()); @@ -6350,13 +6350,13 @@ class TestCondition : public TestFixture { " x = y;\n" " else\n" " x = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int& x, int y) {\n" " if (x == y)\n" " x = y + 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g();\n" @@ -6365,7 +6365,7 @@ class TestCondition : public TestFixture { " x = y;\n" " g();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(bool b) {\n" @@ -6411,12 +6411,12 @@ class TestCondition : public TestFixture { void checkAssignmentInCondition() { check("void f(std::string s) {\n" " if (s=\"123\"){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) Suspicious assignment in condition. Condition 's=\"123\"' is always true. [assignmentInCondition]\n", errout_str()); check("void f(std::string *p) {\n" " if (p=foo()){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(uint32_t u) {\n" // #2490 @@ -6432,65 +6432,65 @@ class TestCondition : public TestFixture { check("void f(unsigned char c) {\n" " if (c == 256) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:12]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(unsigned char* b, int i) {\n" // #6372 " if (b[i] == 256) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:15]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(unsigned char c) {\n" " if (c == 255) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" " if (b == true) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("", errout_str()); // #10372 check("void f(signed char x) {\n" " if (x == 0xff) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:12]: (style) Comparing expression of type 'signed char' against value 255. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(short x) {\n" " if (x == 0xffff) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:12]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(int x) {\n" " if (x == 0xffffffff) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f(long x) {\n" " if (x == ~0L) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f(long long x) {\n" " if (x == ~0LL) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("int f(int x) {\n" " const int i = 0xFFFFFFFF;\n" " if (x == i) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c;\n" " if ((c = foo()) != -1) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x < 3000000000) {}\n" - "}", settingsUnix64); + "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:11]: (style) Comparing expression of type 'signed int' against value 3000000000. Condition is always true. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(const signed char i) {\n" // #8545 @@ -6624,7 +6624,7 @@ class TestCondition : public TestFixture { " }\n" "\n" " S1 mS;\n" - "};" + "};\n" ); ASSERT_EQUALS("[test.cpp:13:11] -> [test.cpp:18:13]: (style) Condition 'mS.b' is always false [knownConditionTrueFalse]\n", errout_str()); } diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 5f2fd228dc4..4de49f54311 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -240,21 +240,21 @@ class TestConstructors : public TestFixture { "{\n" "public:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" "{\n" "private:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:1:1]: (style) The class 'Fred' does not declare a constructor although it has private member variables which likely require initialization. [noConstructor]\n", errout_str()); check("struct Fred\n" "{\n" "private:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:1:1]: (style) The struct 'Fred' does not declare a constructor although it has private member variables which likely require initialization. [noConstructor]\n", errout_str()); } @@ -267,7 +267,7 @@ class TestConstructors : public TestFixture { " Fred(Fred const & other) : i(other.i) {}\n" " Fred(Fred && other) : i(other.i) {}\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -277,7 +277,7 @@ class TestConstructors : public TestFixture { " Fred(Fred const & other) {i=other.i}\n" " Fred(Fred && other) {i=other.i}\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -287,7 +287,7 @@ class TestConstructors : public TestFixture { " Fred(Fred const & other) {}\n" " Fred(Fred && other) {}\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Fred::i' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:5:5]: (warning) Member variable 'Fred::i' is not initialized in the copy constructor. [uninitMemberVar]\n" "[test.cpp:6:5]: (warning) Member variable 'Fred::i' is not initialized in the move constructor. [uninitMemberVar]\n", errout_str()); @@ -298,7 +298,7 @@ class TestConstructors : public TestFixture { " Fred(Fred const & other) {}\n" " Fred(Fred && other) {}\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'Fred::i' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:4:5]: (warning) Member variable 'Fred::i' is not initialized in the copy constructor. [uninitMemberVar]\n" "[test.cpp:5:5]: (warning) Member variable 'Fred::i' is not initialized in the move constructor. [uninitMemberVar]\n", errout_str()); @@ -312,7 +312,7 @@ class TestConstructors : public TestFixture { " int i;\n" "};\n" "Fred::Fred() :i(0)\n" - "{ }"); + "{ }\n"); ASSERT_EQUALS("", errout_str()); check("struct Fred\n" @@ -321,7 +321,7 @@ class TestConstructors : public TestFixture { " int i;\n" "};\n" "Fred::Fred()\n" - "{ i = 0; }"); + "{ i = 0; }\n"); ASSERT_EQUALS("", errout_str()); check("struct Fred\n" @@ -330,7 +330,7 @@ class TestConstructors : public TestFixture { " int i;\n" "};\n" "Fred::Fred()\n" - "{ }"); + "{ }\n"); ASSERT_EQUALS("[test.cpp:6:7]: (warning) Member variable 'Fred::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -365,7 +365,7 @@ class TestConstructors : public TestFixture { " }\n" "private:\n" " int mValue;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -375,7 +375,7 @@ class TestConstructors : public TestFixture { " A(const T & t) { x = t.x; }\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("template struct A {\n" @@ -383,7 +383,7 @@ class TestConstructors : public TestFixture { " A(const T & t) : x(t.x) { }\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("template struct A {\n" @@ -392,7 +392,7 @@ class TestConstructors : public TestFixture { "private:\n" " int x;\n" " int y;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) Member variable 'A::y' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:3:5]: (warning) Member variable 'A::y' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -401,14 +401,14 @@ class TestConstructors : public TestFixture { check("class Fred;\n" "struct Fred {\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } void simple8() { check("struct Fred { int x; };\n" "class Barney { Fred fred; };\n" - "class Wilma { struct Betty { int x; } betty; };"); + "class Wilma { struct Betty { int x; } betty; };\n"); ASSERT_EQUALS("[test.cpp:2:1]: (style) The class 'Barney' does not declare a constructor although it has private member variables which likely require initialization. [noConstructor]\n" "[test.cpp:3:1]: (style) The class 'Wilma' does not declare a constructor although it has private member variables which likely require initialization. [noConstructor]\n", errout_str()); } @@ -419,7 +419,7 @@ class TestConstructors : public TestFixture { " Fred() : x(0) { }\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -429,7 +429,7 @@ class TestConstructors : public TestFixture { " Fred() = default;\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'Fred::x' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct S {\n" // #9391 @@ -457,7 +457,7 @@ class TestConstructors : public TestFixture { " int b{1}, c{2};\n" " int d, e{3};\n" " int f{4}, g;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'Fred::d' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:3:5]: (warning) Member variable 'Fred::g' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -469,7 +469,7 @@ class TestConstructors : public TestFixture { " Fred() { Init(); }\n" " void Init(int i = 0);\n" "};\n" - "void Fred::Init(int i) { x = i; }"); + "void Fred::Init(int i) { x = i; }\n"); ASSERT_EQUALS("", errout_str()); check("class Fred {\n" @@ -479,7 +479,7 @@ class TestConstructors : public TestFixture { " Fred() { Init(0); }\n" " void Init(int i, int j = 0);\n" "};\n" - "void Fred::Init(int i, int j) { x = i; y = j; }"); + "void Fred::Init(int i, int j) { x = i; y = j; }\n"); ASSERT_EQUALS("", errout_str()); } @@ -487,7 +487,7 @@ class TestConstructors : public TestFixture { check("class Fred {\n" " int x=1;\n" " int *y=0;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -500,7 +500,7 @@ class TestConstructors : public TestFixture { " {}\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred : public Base {" @@ -511,7 +511,7 @@ class TestConstructors : public TestFixture { " {}\n" "private:\n" " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -590,7 +590,7 @@ class TestConstructors : public TestFixture { check("class Fred\n" "{\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:1:1]: (style) The class 'Fred' does not declare a constructor although it has private member variables which likely require initialization. [noConstructor]\n", errout_str()); } @@ -602,7 +602,7 @@ class TestConstructors : public TestFixture { "};\n" "\n" "void Fred::foobar()\n" - "{ }"); + "{ }\n"); ASSERT_EQUALS("", errout_str()); } @@ -611,7 +611,7 @@ class TestConstructors : public TestFixture { "{\n" "private:\n" " static int foobar;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -620,7 +620,7 @@ class TestConstructors : public TestFixture { "{\n" "public:\n" " int foobar;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -628,7 +628,7 @@ class TestConstructors : public TestFixture { check("namespace Foo\n" "{\n" " int i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -642,14 +642,14 @@ class TestConstructors : public TestFixture { "private:\n" " cpucyclesT m_v;\n" " bool m_b;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } void noConstructor7() { // ticket #4391 check("short bar;\n" - "class foo;"); + "class foo;\n"); ASSERT_EQUALS("", errout_str()); } @@ -657,7 +657,7 @@ class TestConstructors : public TestFixture { // ticket #4404 check("class LineSegment;\n" "class PointArray { };\n" - "void* tech_ = NULL;"); + "void* tech_ = NULL;\n"); ASSERT_EQUALS("", errout_str()); } @@ -668,7 +668,7 @@ class TestConstructors : public TestFixture { " CGreeting() : CGreetingBase(), MessageSet(false) {}\n" "private:\n" " bool MessageSet;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -688,28 +688,28 @@ class TestConstructors : public TestFixture { " virtual ~A();\n" "private:\n" " wxTimer *WxTimer1;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } void noConstructor11() { // #3552 check("class Fred { int x; };\n" - "union U { int y; Fred fred; };"); + "union U { int y; Fred fred; };\n"); ASSERT_EQUALS("", errout_str()); } void noConstructor12() { // #8951 - check("class Fred { int x{0}; };"); + check("class Fred { int x{0}; };\n"); ASSERT_EQUALS("", errout_str()); - check("class Fred { int x=0; };"); + check("class Fred { int x=0; };\n"); ASSERT_EQUALS("", errout_str()); - check("class Fred { int x[1]={0}; };"); // #8850 + check("class Fred { int x[1]={0}; };\n"); // #8850 ASSERT_EQUALS("", errout_str()); - check("class Fred { int x[1]{0}; };"); + check("class Fred { int x[1]{0}; };\n"); ASSERT_EQUALS("", errout_str()); } @@ -803,15 +803,15 @@ class TestConstructors : public TestFixture { // ticket #3190 "SymbolDatabase: Parse of sub class constructor fails" void forwardDeclaration() { check("class foo;\n" - "int bar;"); + "int bar;\n"); ASSERT_EQUALS("", errout_str()); check("class foo;\n" - "class foo;"); + "class foo;\n"); ASSERT_EQUALS("", errout_str()); check("class foo{};\n" - "class foo;"); + "class foo;\n"); ASSERT_EQUALS("", errout_str()); } @@ -821,7 +821,7 @@ class TestConstructors : public TestFixture { " Fred()\n" " { this->i = 0; }\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -836,7 +836,7 @@ class TestConstructors : public TestFixture { " i = 1;\n" " }\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -855,7 +855,7 @@ class TestConstructors : public TestFixture { "\n" " const Fred & operator=(const Fred &fred)\n" " { i = fred.i; return *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct Fred {\n" @@ -866,7 +866,7 @@ class TestConstructors : public TestFixture { "\n" " const Fred & operator=(const Fred &fred)\n" " { i = fred.i; return *this; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct A\n" @@ -881,7 +881,7 @@ class TestConstructors : public TestFixture { "\n" " int i;\n" " int j;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -892,7 +892,7 @@ class TestConstructors : public TestFixture { " Fred() { i = 0; }\n" " void operator=(const Fred &fred) { }\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:10]: (warning) Member variable 'Fred::i' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); } @@ -904,7 +904,7 @@ class TestConstructors : public TestFixture { "private:\n" " void Init() { i = 0; }\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -921,7 +921,7 @@ class TestConstructors : public TestFixture { " }\n" " return *this\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:12]: (warning) Member variable 'Fred::i' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); check("class Fred\n" @@ -936,7 +936,7 @@ class TestConstructors : public TestFixture { " }\n" " return *this\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:12]: (warning) Member variable 'Fred::i' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); check("class Fred\n" @@ -951,7 +951,7 @@ class TestConstructors : public TestFixture { " }\n" " return *this\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:12]: (warning) Member variable 'Fred::i' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); check("class Fred\n" @@ -966,7 +966,7 @@ class TestConstructors : public TestFixture { " }\n" " return *this\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -981,7 +981,7 @@ class TestConstructors : public TestFixture { " Fred(rhs).swap(*this);\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -991,7 +991,7 @@ class TestConstructors : public TestFixture { " Fred & operator=(const Fred &rhs) {\n" " return *this;\n" " }\n" - "};",dinit(CheckOptions, $.inconclusive = true)); + "};\n",dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:3:12]: (warning, inconclusive) Member variable 'Fred::data' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); check("struct Fred {\n" @@ -999,7 +999,7 @@ class TestConstructors : public TestFixture { " Fred & operator=(const Fred &rhs) {\n" " return *this;\n" " }\n" - "};",dinit(CheckOptions, $.inconclusive = true)); + "};\n",dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:3:12]: (warning, inconclusive) Member variable 'Fred::ints' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); check("struct Fred {\n" @@ -1007,7 +1007,7 @@ class TestConstructors : public TestFixture { " Fred & operator=(const Fred &rhs) {\n" " return *this;\n" " }\n" - "};",dinit(CheckOptions, $.inconclusive = true)); + "};\n",dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:3:12]: (warning, inconclusive) Member variable 'Fred::data' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); } @@ -1113,7 +1113,7 @@ class TestConstructors : public TestFixture { " int b;\n" " Fred() { b = 0; }\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -1133,7 +1133,7 @@ class TestConstructors : public TestFixture { " int b;\n" " Fred() { b = 0; }\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -1153,7 +1153,7 @@ class TestConstructors : public TestFixture { " int b;\n" " Fred() { b = 0; }\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -1175,7 +1175,7 @@ class TestConstructors : public TestFixture { " Fred() { b = 0; }\n" " };\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -1197,7 +1197,7 @@ class TestConstructors : public TestFixture { " Fred() { }\n" " };\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:13]: (warning) Member variable 'Fred::a' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:16:13]: (warning) Member variable 'Fred::b' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -1217,7 +1217,7 @@ class TestConstructors : public TestFixture { "c::c()\n" "{\n" " m_iMyInt1 = m_iMyInt2 = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1250,7 +1250,7 @@ class TestConstructors : public TestFixture { "void c::InitInt()\n" "{\n" " m_iMyInt = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1263,7 +1263,7 @@ class TestConstructors : public TestFixture { " Fred();\n" "};\n" "Fred::Fred() : s(NULL)\n" - "{ }"); + "{ }\n"); ASSERT_EQUALS("", errout_str()); check("struct Fred\n" @@ -1272,7 +1272,7 @@ class TestConstructors : public TestFixture { " Fred();\n" "};\n" "Fred::Fred()\n" - "{ s = NULL; }"); + "{ s = NULL; }\n"); ASSERT_EQUALS("", errout_str()); check("struct Fred\n" @@ -1281,7 +1281,7 @@ class TestConstructors : public TestFixture { " Fred();\n" "};\n" "Fred::Fred()\n" - "{ }"); + "{ }\n"); ASSERT_EQUALS("[test.cpp:6:7]: (warning) Member variable 'Fred::s' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -1293,7 +1293,7 @@ class TestConstructors : public TestFixture { "private:\n" " void update() const;\n" " mutable int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1304,7 +1304,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred() { }\n" " static void *p;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1317,7 +1317,7 @@ class TestConstructors : public TestFixture { "\n" "private:\n" " std::map * values_{};\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1335,7 +1335,7 @@ class TestConstructors : public TestFixture { " {\n" " U.a = 0;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -1349,7 +1349,7 @@ class TestConstructors : public TestFixture { " Fred()\n" " {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:9:5]: (warning) Member variable 'Fred::U' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -1360,7 +1360,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int n) { }\n" " A() : A(42) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'A::number' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:5:5]: (warning) Member variable 'A::number' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -1369,7 +1369,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int n) { number = n; }\n" " A() : A(42) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A {\n" @@ -1377,7 +1377,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int n) : A() { }\n" " A() {}\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'A::number' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:5:5]: (warning, inconclusive) Member variable 'A::number' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -1386,7 +1386,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int n) : A() { }\n" " A() { number = 42; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A {\n" @@ -1394,7 +1394,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int n) { }\n" " A() : A{42} {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'A::number' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:5:5]: (warning) Member variable 'A::number' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -1403,7 +1403,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int n) { number = n; }\n" " A() : A{42} {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A {\n" @@ -1411,7 +1411,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int n) : A{} { }\n" " A() {}\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'A::number' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:5:5]: (warning, inconclusive) Member variable 'A::number' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -1420,7 +1420,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int n) : A{} { }\n" " A() { number = 42; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // Ticket #6675 @@ -1430,7 +1430,7 @@ class TestConstructors : public TestFixture { " int foo_;\n" "};\n" "Foo::Foo() : Foo(0) {}\n" - "Foo::Foo(int foo) : foo_(foo) {}"); + "Foo::Foo(int foo) : foo_(foo) {}\n"); ASSERT_EQUALS("", errout_str()); // Noexcept ctors @@ -1442,7 +1442,7 @@ class TestConstructors : public TestFixture { " A() noexcept;\n" "};\n" "\n" - "A::A() noexcept: A(0) {}"); + "A::A() noexcept: A(0) {}\n"); ASSERT_EQUALS("", errout_str()); // Ticket #8581 @@ -1452,7 +1452,7 @@ class TestConstructors : public TestFixture { "public:\n" " A(int a) : _a(a) {}\n" " A(float a) : A(int(a)) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // Ticket #8258 @@ -1464,7 +1464,7 @@ class TestConstructors : public TestFixture { " int _a;\n" " int _b;\n" " F _f;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1488,7 +1488,7 @@ class TestConstructors : public TestFixture { " : a(true)\n" " , b(0)\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1503,7 +1503,7 @@ class TestConstructors : public TestFixture { "public:\n" " Derived() {}\n" " void foo() override;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:9:3]: (warning) Member variable 'Base::x' is not initialized in the constructor. Maybe it should be initialized directly in the class Base? [uninitDerivedMemberVar]\n", errout_str()); check("struct A {\n" // #3462 @@ -1590,7 +1590,7 @@ class TestConstructors : public TestFixture { "class C : public S {\n" "public:\n" " C() { all = 0; tick = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -1606,7 +1606,7 @@ class TestConstructors : public TestFixture { "class C : public S {\n" "public:\n" " C() { flag1 = flag2 = 0; tick = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -1622,7 +1622,7 @@ class TestConstructors : public TestFixture { "class C : public S {\n" "public:\n" " C() {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:13:5]: (warning) Member variable 'S::all' is not initialized in the constructor. Maybe it should be initialized directly in the class S? [uninitDerivedMemberVar]\n" "[test.cpp:13:5]: (warning) Member variable 'S::flag1' is not initialized in the constructor. Maybe it should be initialized directly in the class S? [uninitDerivedMemberVar]\n" "[test.cpp:13:5]: (warning) Member variable 'S::flag2' is not initialized in the constructor. Maybe it should be initialized directly in the class S? [uninitDerivedMemberVar]\n", errout_str()); @@ -1638,7 +1638,7 @@ class TestConstructors : public TestFixture { " Fred();\n" "};\n" "Fred::Fred()\n" - "{ }", s); + "{ }\n", s); ASSERT_EQUALS("[test.cpp:7:7]: (warning) Member variable 'Fred::var' is not initialized in the constructor. [uninitMemberVarPrivate]\n", errout_str()); } @@ -1651,7 +1651,7 @@ class TestConstructors : public TestFixture { " Fred();\n" "};\n" "Fred::Fred()\n" - "{ }", s); + "{ }\n", s); ASSERT_EQUALS("", errout_str()); } } @@ -1673,7 +1673,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred() { };\n" " Fred(const Fred &) { };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -1683,7 +1683,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred() { };\n" " Fred(const Fred &) { };\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:7:5]: (warning, inconclusive) Member variable 'Fred::var' is not assigned in the copy constructor. Should it be copied? [missingMemberCopy]\n", errout_str()); check("class Fred\n" @@ -1731,7 +1731,7 @@ class TestConstructors : public TestFixture { "A::A(){}\n" "A::B::B(int x){}\n" "A::B::C::C(int y){}\n" - "A::B::C::D::D(int z){}"); + "A::B::C::D::D(int z){}\n"); // Note that the example code is not compilable. The A constructor must // explicitly initialize A::b. A warning for A::b is not necessary. ASSERT_EQUALS("[test.cpp:20:4]: (warning) Member variable 'A::a' is not initialized in the constructor. [uninitMemberVar]\n" @@ -1761,7 +1761,7 @@ class TestConstructors : public TestFixture { "A::A(){}\n" "A::B::B(int x){}\n" "A::B::C::C(int y){}\n" - "A::B::C::D::D(const A::B::C::D & d){}"); + "A::B::C::D::D(const A::B::C::D & d){}\n"); // Note that the example code is not compilable. The A constructor must // explicitly initialize A::b. A warning for A::b is not necessary. ASSERT_EQUALS("[test.cpp:20:4]: (warning) Member variable 'A::a' is not initialized in the constructor. [uninitMemberVar]\n" @@ -1792,7 +1792,7 @@ class TestConstructors : public TestFixture { "A::A(){}\n" "A::B::B(int x){}\n" "A::B::C::C(int y){}\n" - "A::B::C::D::D(const A::B::C::D::E & e){}"); + "A::B::C::D::D(const A::B::C::D::E & e){}\n"); // Note that the example code is not compilable. The A constructor must // explicitly initialize A::b. A warning for A::b is not necessary. ASSERT_EQUALS("[test.cpp:21:4]: (warning) Member variable 'A::a' is not initialized in the constructor. [uninitMemberVar]\n" @@ -1814,7 +1814,7 @@ class TestConstructors : public TestFixture { " A(const A&){}\n" " A(A &&){}\n" " const A& operator=(const A&){return *this;}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class B\n" @@ -1829,7 +1829,7 @@ class TestConstructors : public TestFixture { " A(const A&){}\n" " A(A &&){}\n" " const A& operator=(const A&){return *this;}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class B\n" @@ -1846,7 +1846,7 @@ class TestConstructors : public TestFixture { " A(const A&){}\n" " A(A &&){}\n" " const A& operator=(const A&){return *this;}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class B\n" @@ -1862,7 +1862,7 @@ class TestConstructors : public TestFixture { " A(const A&){}\n" " A(A &&){}\n" " const A& operator=(const A&){return *this;}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A : public std::vector\n" @@ -1878,7 +1878,7 @@ class TestConstructors : public TestFixture { " B(const B&){}\n" " B(B &&){}\n" " const B& operator=(const B&){return *this;}\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:11:5]: (warning, inconclusive) Member variable 'B::a' is not assigned in the copy constructor. Should it be copied? [missingMemberCopy]\n" "[test.cpp:12:5]: (warning, inconclusive) Member variable 'B::a' is not assigned in the move constructor. Should it be moved? [missingMemberCopy]\n" "[test.cpp:13:14]: (warning, inconclusive) Member variable 'B::a' is not assigned a value in 'B::operator='. [operatorEqVarError]\n", @@ -1898,7 +1898,7 @@ class TestConstructors : public TestFixture { " A(const A&){}\n" " A(A &&){}\n" " const A& operator=(const A&){return *this;}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:13:5]: (warning) Member variable 'A::m_SemVar' is not initialized in the move constructor. [uninitMemberVar]\n", errout_str()); check("class B\n" @@ -1916,7 +1916,7 @@ class TestConstructors : public TestFixture { " A(const A&){}\n" " A(A &&){}\n" " const A& operator=(const A&){return *this;}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A\n" @@ -1926,7 +1926,7 @@ class TestConstructors : public TestFixture { " A(){}\n" " A(const A&){}\n" " const A& operator=(const A&){return *this;}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1944,7 +1944,7 @@ class TestConstructors : public TestFixture { " A(){}\n" " A(const A&){}\n" " const A& operator=(const A&){return *this;}\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("class B\n" @@ -1961,7 +1961,7 @@ class TestConstructors : public TestFixture { " A(){}\n" " A(const A&){}\n" " const A& operator=(const A&){return *this;}\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:12:5]: (warning) Member variable 'A::m_SemVar' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:13:5]: (warning) Member variable 'A::m_SemVar' is not initialized in the copy constructor. [uninitMemberVar]\n" "[test.cpp:14:14]: (warning) Member variable 'A::m_SemVar' is not assigned a value in 'A::operator='. [operatorEqVarError]\n", errout_str()); @@ -1972,14 +1972,14 @@ class TestConstructors : public TestFixture { " B b;\n" " A() {}\n" " A(const A& rhs) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" " B b;\n" " A() {}\n" " A(const A& rhs) {}\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:4:5]: (warning, inconclusive) Member variable 'A::b' is not assigned in the copy constructor. Should it be copied? [missingMemberCopy]\n", errout_str()); } @@ -1995,7 +1995,7 @@ class TestConstructors : public TestFixture { "}\n" "void S::Set(const T& val) {\n" " t = val;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -2004,7 +2004,7 @@ class TestConstructors : public TestFixture { " Foo(int m) { this->setMember(m); }\n" " void setMember(int m) { member = m; }\n" " int member;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2016,7 +2016,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred() : var(0) {}\n" " ~Fred() {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2024,7 +2024,7 @@ class TestConstructors : public TestFixture { check("class something {\n" " int * ( something :: * process()) () { return 0; }\n" " something() { process(); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2035,7 +2035,7 @@ class TestConstructors : public TestFixture { " int& pa = a;\n" " pa = 4;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -2044,7 +2044,7 @@ class TestConstructors : public TestFixture { " int* pa = &a;\n" " *pa = 4;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -2054,7 +2054,7 @@ class TestConstructors : public TestFixture { " for (int i = 0; i < 2; i++)\n" " *pa++ = i;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -2063,7 +2063,7 @@ class TestConstructors : public TestFixture { " int* pa = a[1];\n" " *pa = 0;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'S::a' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct S {\n" @@ -2072,7 +2072,7 @@ class TestConstructors : public TestFixture { " int pa = a;\n" " pa = 4;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'S::a' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2091,7 +2091,7 @@ class TestConstructors : public TestFixture { " A() {\n" " Wrapper::foo(x);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2109,7 +2109,7 @@ class TestConstructors : public TestFixture { " d = rhs.get();\n" " }\n" " double d;\n" - "};", s); + "};\n", s); ASSERT_EQUALS("", errout_str()); check("struct S {\n" // #8485 @@ -2136,7 +2136,7 @@ class TestConstructors : public TestFixture { "{ }\n" "\n" "void Fred::operator=(const Fred &f)\n" - "{ }", dinit(CheckOptions, $.inconclusive = true)); + "{ }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:13:12]: (warning, inconclusive) Member variable 'Fred::ints' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); const Settings s = settingsBuilder().certainty(Certainty::inconclusive).severity(Severity::style).severity(Severity::warning).library("std.cfg").build(); @@ -2161,7 +2161,7 @@ class TestConstructors : public TestFixture { "\n" "private:\n" " ECODES _code;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:10:5]: (warning) Member variable 'Fred::_code' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -2174,7 +2174,7 @@ class TestConstructors : public TestFixture { " B() {}\n" "private:\n" " float f;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:3]: (warning) Member variable 'B::f' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("class C\n" @@ -2187,7 +2187,7 @@ class TestConstructors : public TestFixture { "\n" "C::C(FILE *fp) {\n" " C::fp = fp;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2198,7 +2198,7 @@ class TestConstructors : public TestFixture { " John() { (*this).i = 0; }\n" "private:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2213,7 +2213,7 @@ class TestConstructors : public TestFixture { " Bar();\n" " };\n" " Bar bars[2];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // Using struct that doesn't have constructor @@ -2226,7 +2226,7 @@ class TestConstructors : public TestFixture { " int x;\n" " };\n" " Bar bars[2];\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Foo::bars' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2240,7 +2240,7 @@ class TestConstructors : public TestFixture { " int x;\n" " };\n" " struct Bar bar;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2252,7 +2252,7 @@ class TestConstructors : public TestFixture { " Foo &operator=(const Foo &)\n" " { return *this; }\n" " static int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2263,7 +2263,7 @@ class TestConstructors : public TestFixture { " explicit Foo(int i) : Bar(mi=i) { }\n" "private:\n" " int mi;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Foo : public Bar\n" @@ -2272,7 +2272,7 @@ class TestConstructors : public TestFixture { " explicit Foo(int i) : Bar{mi=i} { }\n" "private:\n" " int mi;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2293,7 +2293,7 @@ class TestConstructors : public TestFixture { " Foo copy(rhs);\n" " copy.Swap(*this);\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2310,7 +2310,7 @@ class TestConstructors : public TestFixture { " {\n" " }\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:11]: (warning) Member variable 'Foo::a' is not assigned a value in 'Foo::operator='. [operatorEqVarError]\n", errout_str()); } @@ -2324,7 +2324,7 @@ class TestConstructors : public TestFixture { "Prefs::Prefs(wxSize size)\n" "{\n" " SetMinSize( wxSize( 48,48 ) );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:8]: (warning) Member variable 'Prefs::xasd' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2336,7 +2336,7 @@ class TestConstructors : public TestFixture { " int var1;\n" " int var2;\n" "};\n" - "A::A() : var1(0) { }"); + "A::A() : var1(0) { }\n"); ASSERT_EQUALS("[test.cpp:8:4]: (warning) Member variable 'A::var2' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2347,7 +2347,7 @@ class TestConstructors : public TestFixture { "private:\n" " int var;\n" "};\n" - "A::A(int a) { }"); + "A::A(int a) { }\n"); ASSERT_EQUALS("[test.cpp:7:4]: (warning) Member variable 'A::var' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2363,7 +2363,7 @@ class TestConstructors : public TestFixture { " : x(x), y(y)\n" " {}\n" " int x, y;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Point::x' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:4:5]: (warning) Member variable 'Point::y' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2375,7 +2375,7 @@ class TestConstructors : public TestFixture { "public:\n" " A()\n" " {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:5]: (warning) Member variable 'A::ints' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2390,7 +2390,7 @@ class TestConstructors : public TestFixture { "};\n" "Foo::Foo()\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:6]: (warning) Member variable 'Foo::mMember' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // single namespace @@ -2406,7 +2406,7 @@ class TestConstructors : public TestFixture { " Foo::Foo()\n" " {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:10]: (warning) Member variable 'Foo::mMember' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // constructor outside namespace @@ -2422,7 +2422,7 @@ class TestConstructors : public TestFixture { "}\n" "Foo::Foo()\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // constructor outside namespace @@ -2438,7 +2438,7 @@ class TestConstructors : public TestFixture { "}\n" "Output::Foo::Foo()\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:11:14]: (warning) Member variable 'Foo::mMember' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // constructor outside namespace with using, #4792 @@ -2455,7 +2455,7 @@ class TestConstructors : public TestFixture { "using namespace Output;" "Foo::Foo()\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:11:29]: (warning) Member variable 'Foo::mMember' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // constructor in separate namespace @@ -2474,7 +2474,7 @@ class TestConstructors : public TestFixture { " Foo::Foo()\n" " {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:13:10]: (warning) Member variable 'Foo::mMember' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // constructor in different separate namespace @@ -2493,7 +2493,7 @@ class TestConstructors : public TestFixture { " Foo::Foo()\n" " {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // constructor in different separate namespace (won't compile) @@ -2512,7 +2512,7 @@ class TestConstructors : public TestFixture { " Output::Foo::Foo()\n" " {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // constructor in nested separate namespace @@ -2534,7 +2534,7 @@ class TestConstructors : public TestFixture { " {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:15:14]: (warning) Member variable 'Foo::mMember' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // constructor in nested different separate namespace @@ -2556,7 +2556,7 @@ class TestConstructors : public TestFixture { " {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // constructor in nested different separate namespace @@ -2578,7 +2578,7 @@ class TestConstructors : public TestFixture { " {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2592,7 +2592,7 @@ class TestConstructors : public TestFixture { "};\n" "Fred::~Fred()\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2610,7 +2610,7 @@ class TestConstructors : public TestFixture { " {\n" " foo.set(0);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct Foo\n" @@ -2625,7 +2625,7 @@ class TestConstructors : public TestFixture { " Bar()\n" " {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:10:5]: (warning) Member variable 'Bar::foo' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2642,7 +2642,7 @@ class TestConstructors : public TestFixture { " {\n" " foo[0].a = 0;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct Foo\n" @@ -2656,7 +2656,7 @@ class TestConstructors : public TestFixture { " Bar()\n" " {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:9:5]: (warning) Member variable 'Bar::foo' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2672,7 +2672,7 @@ class TestConstructors : public TestFixture { " A() { }\n" "private:\n" " Altren value;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2696,7 +2696,7 @@ class TestConstructors : public TestFixture { " {\n" " free(m_str);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2708,7 +2708,7 @@ class TestConstructors : public TestFixture { " std::streamsize dataLength_;\n" " double bitsInData_;\n" " } obj;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:9]: (warning) Member variable 'LocalClass::bitsInData_' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct copy_protected;\n" @@ -2719,7 +2719,7 @@ class TestConstructors : public TestFixture { " std::streamsize dataLength_;\n" " double bitsInData_;\n" " } obj;\n" - "};"); + "};\n"); ASSERT_EQUALS( "[test.cpp:5:9]: (warning) Member variable 'LocalClass::bitsInData_' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -2732,7 +2732,7 @@ class TestConstructors : public TestFixture { " std::streamsize dataLength_;\n" " double bitsInData_;\n" " } obj;\n" - "};"); + "};\n"); ASSERT_EQUALS( "[test.cpp:5:9]: (warning) Member variable 'LocalClass::bitsInData_' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -2747,7 +2747,7 @@ class TestConstructors : public TestFixture { "};\n" "Fred::Fred() {\n" " a[x::y] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2764,7 +2764,7 @@ class TestConstructors : public TestFixture { "Fred & Fred::clone(const Fred & other) {\n" " x = 0;\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class Fred {\n" @@ -2778,7 +2778,7 @@ class TestConstructors : public TestFixture { "}\n" "Fred & Fred::clone(const Fred & other) {\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:14]: (warning) Member variable 'Fred::x' is not assigned a value in 'Fred::operator='. [operatorEqVarError]\n", errout_str()); } @@ -2796,7 +2796,7 @@ class TestConstructors : public TestFixture { "Fred::Fred(struct C c, D d) { }\n" "Fred::Fred(E e, struct F f) { }\n" "Fred::Fred(G g, H h) { }\n" - "Fred::Fred(struct I i, struct J j) { }"); + "Fred::Fred(struct I i, struct J j) { }\n"); ASSERT_EQUALS("[test.cpp:10:7]: (warning) Member variable 'Fred::x' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:11:7]: (warning) Member variable 'Fred::x' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:12:7]: (warning) Member variable 'Fred::x' is not initialized in the constructor. [uninitMemberVar]\n" @@ -2905,7 +2905,7 @@ class TestConstructors : public TestFixture { " A(int s) {\n" " v = new int [sz = s];\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2916,7 +2916,7 @@ class TestConstructors : public TestFixture { " A() {\n" " rtl::math::setNan(&d);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A {\n" " double d;\n" @@ -2924,7 +2924,7 @@ class TestConstructors : public TestFixture { " A() {\n" " ::rtl::math::setNan(&d);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2939,7 +2939,7 @@ class TestConstructors : public TestFixture { " }\n" " void foo(int a) { i = a; }\n" " void foo(float a) { f = a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2971,7 +2971,7 @@ class TestConstructors : public TestFixture { " D() { foo(); }\n" " void foo() { }\n" " void foo() const { i = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:18:5]: (warning) Member variable 'C::i' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:25:5]: (warning) Member variable 'D::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -2988,7 +2988,7 @@ class TestConstructors : public TestFixture { "}\n" "using namespace NS;\n" "MyClass::~MyClass() { }\n" - "MyClass::MyClass() : SomeVar(false) { }"); + "MyClass::MyClass() : SomeVar(false) { }\n"); ASSERT_EQUALS("", errout_str()); } @@ -3006,7 +3006,7 @@ class TestConstructors : public TestFixture { "}\n" "void MyClass::Restart() {\n" " m_retCode = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3019,7 +3019,7 @@ class TestConstructors : public TestFixture { " {\n" " if (1) {}\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:4]: (warning) Member variable 'Foo::member' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("class Foo {\n" " friend class Bar;\n" @@ -3029,7 +3029,7 @@ class TestConstructors : public TestFixture { " {\n" " while (1) {}\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:4]: (warning) Member variable 'Foo::member' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("class Foo {\n" " friend class Bar;\n" @@ -3039,7 +3039,7 @@ class TestConstructors : public TestFixture { " {\n" " for (;;) {}\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:4]: (warning) Member variable 'Foo::member' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3051,7 +3051,7 @@ class TestConstructors : public TestFixture { " int x;\n" " };\n" "};\n" - "app::B::B(void){}"); + "app::B::B(void){}\n"); ASSERT_EQUALS("[test.cpp:8:9]: (warning) Member variable 'B::x' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3103,7 +3103,7 @@ class TestConstructors : public TestFixture { "\n" "private:\n" " char name[255];\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'John::name' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("class John\n" @@ -3113,7 +3113,7 @@ class TestConstructors : public TestFixture { "\n" "private:\n" " char name[255];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class John\n" @@ -3123,7 +3123,7 @@ class TestConstructors : public TestFixture { "\n" "private:\n" " char name[255];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class John\n" @@ -3132,7 +3132,7 @@ class TestConstructors : public TestFixture { " John() { }\n" "\n" " double operator[](const unsigned long i);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A;\n" @@ -3141,7 +3141,7 @@ class TestConstructors : public TestFixture { "public:\n" " John() { }\n" " A a[5];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A;\n" @@ -3150,7 +3150,7 @@ class TestConstructors : public TestFixture { "public:\n" " John() { }\n" " A (*a)[5];\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:5]: (warning) Member variable 'John::a' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3162,7 +3162,7 @@ class TestConstructors : public TestFixture { "\n" "private:\n" " char name[255];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #5754 @@ -3173,7 +3173,7 @@ class TestConstructors : public TestFixture { "\n" "private:\n" " char name[255];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3190,7 +3190,7 @@ class TestConstructors : public TestFixture { " memset(a,0,sizeof(a));\n" " memset(b,0,sizeof(b));\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3207,7 +3207,7 @@ class TestConstructors : public TestFixture { " if (snprintf(a,10,\"a\")) { }\n" " if (snprintf(b,10,\"b\")) { }\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3219,7 +3219,7 @@ class TestConstructors : public TestFixture { "public:\n" " Foo()\n" " { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3231,7 +3231,7 @@ class TestConstructors : public TestFixture { " static const char STR[];\n" "};\n" "const char Foo::STR[] = \"abc\";\n" - "Foo::Foo() { }"); + "Foo::Foo() { }\n"); ASSERT_EQUALS("", errout_str()); } @@ -3241,7 +3241,7 @@ class TestConstructors : public TestFixture { " int array[10];\n" "public:\n" " Foo() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:5]: (warning) Member variable 'Foo::array' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("class Foo\n" @@ -3249,7 +3249,7 @@ class TestConstructors : public TestFixture { " int array[10];\n" "public:\n" " Foo() { memset(array, 0, sizeof(array)); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Foo\n" @@ -3257,7 +3257,7 @@ class TestConstructors : public TestFixture { " int array[10];\n" "public:\n" " Foo() { ::memset(array, 0, sizeof(array)); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3266,7 +3266,7 @@ class TestConstructors : public TestFixture { " char a[10];\n" "public:\n" " Foo() { ::ZeroMemory(a); }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3277,7 +3277,7 @@ class TestConstructors : public TestFixture { " BaseGDL* eArr[3];\n" "public:\n" " IxExprListT() {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:5]: (warning) Member variable 'IxExprListT::eArr' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct sRAIUnitDefBL {\n" " sRAIUnitDefBL();\n" @@ -3286,7 +3286,7 @@ class TestConstructors : public TestFixture { "struct sRAIUnitDef {\n" " sRAIUnitDef() {}\n" " sRAIUnitDefBL *List[35];\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:3]: (warning) Member variable 'sRAIUnitDef::List' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3333,7 +3333,7 @@ class TestConstructors : public TestFixture { "\n" "private:\n" " char a[2][2];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3344,7 +3344,7 @@ class TestConstructors : public TestFixture { " char a[2][2][2];\n" "public:\n" " John() { a[0][0][0] = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3355,7 +3355,7 @@ class TestConstructors : public TestFixture { " Foo()\n" " : bar({\"a\", \"b\"})\n" " {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3371,7 +3371,7 @@ class TestConstructors : public TestFixture { " Fred() : f{0, true} { }\n" " float get() const;\n" "};\n" - "float Fred::get() const { return g; }"); + "float Fred::get() const { return g; }\n"); ASSERT_EQUALS("[test.cpp:9:5]: (warning) Member variable 'Fred::g' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3387,7 +3387,7 @@ class TestConstructors : public TestFixture { "public:\n" " A() {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A\n" @@ -3401,7 +3401,7 @@ class TestConstructors : public TestFixture { "public:\n" " A() {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:10:5]: (warning) Member variable 'A::b' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("class A\n" @@ -3416,7 +3416,7 @@ class TestConstructors : public TestFixture { "public:\n" " A() {\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3433,7 +3433,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred()\n" " { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:11:5]: (warning) Member variable 'Fred::p' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct POINT\n" @@ -3449,7 +3449,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred()\n" " { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct POINT\n" @@ -3465,7 +3465,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred()\n" " { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // non static data-member initialization @@ -3481,7 +3481,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred()\n" " { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3493,13 +3493,13 @@ class TestConstructors : public TestFixture { "public:\n" " Fred()\n" " { a = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred {\n" "private:\n" " union { int a{}; int b; };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3513,7 +3513,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred() : data_type(0)\n" " { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:5]: (warning) Member variable 'Fred::data' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3526,7 +3526,7 @@ class TestConstructors : public TestFixture { "private:\n" " void Init();" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // Unknown non-member function (friend class) @@ -3537,7 +3537,7 @@ class TestConstructors : public TestFixture { "private:\n" " friend ABC;\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // Unknown non-member function (is Init a virtual function?) @@ -3547,7 +3547,7 @@ class TestConstructors : public TestFixture { " Fred() { Init(); }\n" "private:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Fred::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // Unknown non-member function @@ -3557,7 +3557,7 @@ class TestConstructors : public TestFixture { " Fred() { Init(); }\n" "private:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Fred::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // Unknown non-member function @@ -3568,7 +3568,7 @@ class TestConstructors : public TestFixture { " Fred() { Init(); }\n" "private:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:5]: (warning) Member variable 'Fred::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // Unknown member functions and unknown static functions @@ -3588,7 +3588,7 @@ class TestConstructors : public TestFixture { " static void static_f();\n" "private:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:5]: (warning) Member variable 'Fred::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // Unknown overloaded member functions @@ -3601,7 +3601,7 @@ class TestConstructors : public TestFixture { " void func();\n" "private:\n" " int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3613,7 +3613,7 @@ class TestConstructors : public TestFixture { " Fred() {}\n" "private:\n" " unsigned int i;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:5]: (warning) Member variable 'Fred::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3624,7 +3624,7 @@ class TestConstructors : public TestFixture { "struct Y {\n" " Y() {}\n" " X x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3640,7 +3640,7 @@ class TestConstructors : public TestFixture { " if(!(in >> foo))\n" " throw 0;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3652,7 +3652,7 @@ class TestConstructors : public TestFixture { " typedef int * pointer;\n" " Foo() : a(0) {}\n" " pointer a;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3663,7 +3663,7 @@ class TestConstructors : public TestFixture { "public:\n" " int * pointer;\n" " Foo() { memset(this, 0, sizeof(*this)); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -3672,7 +3672,7 @@ class TestConstructors : public TestFixture { "public:\n" " int * pointer;\n" " Foo() { ::memset(this, 0, sizeof(*this)); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -3681,13 +3681,13 @@ class TestConstructors : public TestFixture { " int * p;\n" " char c;\n" " Foo() { memset(p, 0, sizeof(int)); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Foo::c' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct Foo {\n" " int i;\n" " char c;\n" " Foo() { memset(&i, 0, sizeof(int)); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Foo::c' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct Foo { int f; };\n" "struct Bar { int b; };\n" @@ -3701,7 +3701,7 @@ class TestConstructors : public TestFixture { "int main() {\n" " FooBar foobar;\n" " return foobar.foo.f + foobar.bar.b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:3]: (warning) Member variable 'FooBar::bar' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct Foo { int f; };\n" "struct Bar { int b; };\n" @@ -3715,7 +3715,7 @@ class TestConstructors : public TestFixture { "int main() {\n" " FooBar foobar;\n" " return foobar.foo.f + foobar.bar.b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:3]: (warning) Member variable 'FooBar::bar' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); // #7755 @@ -3724,7 +3724,7 @@ class TestConstructors : public TestFixture { " memset(this->data, 0, 42);\n" " }\n" " char data[42];\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3734,7 +3734,7 @@ class TestConstructors : public TestFixture { check("class Foo {\n" " int foo;\n" " Foo() { }\n" - "};", s); + "};\n", s); ASSERT_EQUALS("", errout_str()); } @@ -3743,7 +3743,7 @@ class TestConstructors : public TestFixture { check("class Foo {\n" " int foo;\n" " Foo() { }\n" - "};", s); + "};\n", s); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'Foo::foo' is not initialized in the constructor. [uninitMemberVarPrivate]\n", errout_str()); } } @@ -3756,7 +3756,7 @@ class TestConstructors : public TestFixture { " Foo() { }\n" "public:\n" " explicit Foo(int _i) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:14]: (warning) Member variable 'Foo::foo' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3777,7 +3777,7 @@ class TestConstructors : public TestFixture { "int* A::f(int* p)\n" "{\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3791,7 +3791,7 @@ class TestConstructors : public TestFixture { " int *i;\n" "public:\n" " Fred() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3805,7 +3805,7 @@ class TestConstructors : public TestFixture { " Fred() { }\n" "private:\n" " int x;\n" - "};", s); + "};\n", s); ASSERT_EQUALS("", errout_str()); } @@ -3815,7 +3815,7 @@ class TestConstructors : public TestFixture { "public:\n" " Fred() { }\n" " int *operator [] (int index) { return 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -3829,7 +3829,7 @@ class TestConstructors : public TestFixture { " { f.d = 0; }\n" "\n" " double d;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -3841,7 +3841,7 @@ class TestConstructors : public TestFixture { " { }\n" "\n" " double d;\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Fred::d' is not initialized in the constructor. [uninitMemberVar]\n", "", errout_str()); } @@ -3855,7 +3855,7 @@ class TestConstructors : public TestFixture { " { f.d = 0; return true; }\n" "\n" " double d;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -3867,7 +3867,7 @@ class TestConstructors : public TestFixture { " { return true; }\n" "\n" " double d;\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Fred::d' is not initialized in the constructor. [uninitMemberVar]\n", "", errout_str()); } @@ -3881,7 +3881,7 @@ class TestConstructors : public TestFixture { " { d = 0; return true; }\n" "\n" " double d;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -3893,7 +3893,7 @@ class TestConstructors : public TestFixture { " { return true; }\n" "\n" " double d;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Fred::d' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3907,7 +3907,7 @@ class TestConstructors : public TestFixture { " { f.d = 0; }\n" "\n" " double d;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -3919,7 +3919,7 @@ class TestConstructors : public TestFixture { " { }\n" "\n" " double d;\n" - "};"); + "};\n"); TODO_ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'Fred::d' is not initialized in the constructor. [uninitMemberVar]\n", "", errout_str()); } @@ -3933,7 +3933,7 @@ class TestConstructors : public TestFixture { "public:\n" " A() { Init( B ); };\n" " void Init( Structure& S ) { S.C = 0; };\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct Structure {\n" @@ -3945,7 +3945,7 @@ class TestConstructors : public TestFixture { "public:\n" " A() { Init( B ); };\n" " void Init(const Structure& S) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:5]: (warning) Member variable 'A::B' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3970,7 +3970,7 @@ class TestConstructors : public TestFixture { "A::B::B()\n" "{\n" " i = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class B\n" @@ -3996,7 +3996,7 @@ class TestConstructors : public TestFixture { "\n" "A::B::B()\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:18:4]: (warning) Member variable 'B::j' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:22:7]: (warning) Member variable 'B::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -4017,7 +4017,7 @@ class TestConstructors : public TestFixture { "public:\n" " Foo() { }\n" "};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("namespace n1\n" @@ -4039,7 +4039,7 @@ class TestConstructors : public TestFixture { "public:\n" " Foo() { }\n" "};\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:11:10]: (warning) Member variable 'Foo::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("namespace n1\n" @@ -4061,7 +4061,7 @@ class TestConstructors : public TestFixture { "public:\n" " Foo() { }\n" "};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4082,7 +4082,7 @@ class TestConstructors : public TestFixture { "\n" " void init(int value)\n" " { i = value; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A\n" @@ -4100,7 +4100,7 @@ class TestConstructors : public TestFixture { "\n" " void init(int value)\n" " { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:5]: (warning) Member variable 'A::i' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("class bar {\n" // #9887 @@ -4121,7 +4121,7 @@ class TestConstructors : public TestFixture { " int a;\n" " A() { a=0; }\n" " A(A const &a) { operator=(a); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -4132,7 +4132,7 @@ class TestConstructors : public TestFixture { " a = rhs.a;\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -4142,7 +4142,7 @@ class TestConstructors : public TestFixture { " A & operator = (const A & rhs) {\n" " return *this;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'A::a' is not initialized in the copy constructor. [uninitMemberVar]\n" "[test.cpp:5:9]: (warning) Member variable 'A::a' is not assigned a value in 'A::operator='. [operatorEqVarError]\n", errout_str()); } @@ -4154,28 +4154,28 @@ class TestConstructors : public TestFixture { "struct B {\n" " A* a;\n" " B() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:5]: (warning) Member variable 'B::a' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct A;\n" "struct B {\n" " A* a;\n" " B() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'B::a' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct A;\n" "struct B {\n" " const A* a;\n" " B() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'B::a' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("struct A;\n" "struct B {\n" " A* const a;\n" " B() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'B::a' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); check("class Test {\n" // #8498 @@ -4226,7 +4226,7 @@ class TestConstructors : public TestFixture { " A* const a;\n" " B() { }\n" " B(B& b) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Member variable 'B::a' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:5:5]: (warning) Member variable 'B::a' is not initialized in the copy constructor. [uninitMemberVar]\n", errout_str()); @@ -4234,21 +4234,21 @@ class TestConstructors : public TestFixture { "struct B {\n" " A* const a;\n" " B& operator=(const B& r) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #3804 check("struct B {\n" " const int a;\n" " B() { }\n" " B(B& b) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'B::a' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:4:5]: (warning) Member variable 'B::a' is not initialized in the copy constructor. [uninitMemberVar]\n", errout_str()); check("struct B {\n" " const int a;\n" " B& operator=(const B& r) { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4258,7 +4258,7 @@ class TestConstructors : public TestFixture { "public:\n" " C() _STLP_NOTHROW {}\n" " C(const C&) _STLP_NOTHROW {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4267,7 +4267,7 @@ class TestConstructors : public TestFixture { " int mValue;\n" "public:\n" " operatorX() : mValue(0) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4277,7 +4277,7 @@ class TestConstructors : public TestFixture { " T* mElements;\n" "};\n" "template Container::Container() : mElements(nullptr) {}\n" - "Container intContainer;"); + "Container intContainer;\n"); ASSERT_EQUALS("", errout_str()); } @@ -4287,7 +4287,7 @@ class TestConstructors : public TestFixture { "public:\n" " SelectionPosition() {}\n" " const rvec &x() const;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4302,7 +4302,7 @@ class TestConstructors : public TestFixture { " x = 1;\n" " return true;\n" " }\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Member variable 'C::x' is not initialized in the constructor.\n", "[test.cpp:3:5]: (warning) Member variable 'C::x' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -4316,7 +4316,7 @@ class TestConstructors : public TestFixture { " x = 1;\n" " return true;\n" " }\n" - "};", dinit(CheckOptions, $.inconclusive = true)); + "};\n", dinit(CheckOptions, $.inconclusive = true)); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Member variable 'C::x' is not initialized in the constructor.\n", "[test.cpp:3:5]: (warning) Member variable 'C::x' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); @@ -4330,7 +4330,7 @@ class TestConstructors : public TestFixture { " x = 1;\n" " return true;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4343,7 +4343,7 @@ class TestConstructors : public TestFixture { " x = 1;\n" " return true;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4353,7 +4353,7 @@ class TestConstructors : public TestFixture { " i = i * SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4363,7 +4363,7 @@ class TestConstructors : public TestFixture { " i = i / SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4373,7 +4373,7 @@ class TestConstructors : public TestFixture { " i = i % SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4383,7 +4383,7 @@ class TestConstructors : public TestFixture { " i = i + SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4393,7 +4393,7 @@ class TestConstructors : public TestFixture { " i = i - SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4403,7 +4403,7 @@ class TestConstructors : public TestFixture { " i = i << SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4413,7 +4413,7 @@ class TestConstructors : public TestFixture { " i = i >> SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4423,7 +4423,7 @@ class TestConstructors : public TestFixture { " i = i ^ SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4438,7 +4438,7 @@ class TestConstructors : public TestFixture { " x = 1;\n" " return true;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4451,7 +4451,7 @@ class TestConstructors : public TestFixture { " x = 1;\n" " return true;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4461,7 +4461,7 @@ class TestConstructors : public TestFixture { " i *= SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4471,7 +4471,7 @@ class TestConstructors : public TestFixture { " i /= SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4481,7 +4481,7 @@ class TestConstructors : public TestFixture { " i %= SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4491,7 +4491,7 @@ class TestConstructors : public TestFixture { " i += SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4501,7 +4501,7 @@ class TestConstructors : public TestFixture { " i -= SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4511,7 +4511,7 @@ class TestConstructors : public TestFixture { " i <<= SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4521,7 +4521,7 @@ class TestConstructors : public TestFixture { " i >>= SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4531,7 +4531,7 @@ class TestConstructors : public TestFixture { " i ^= SetValue();\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4546,7 +4546,7 @@ class TestConstructors : public TestFixture { " x = 1;\n" " return true;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4559,7 +4559,7 @@ class TestConstructors : public TestFixture { " x = 1;\n" " return true;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4568,7 +4568,7 @@ class TestConstructors : public TestFixture { " bool b = (0 < SetValue());\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4577,7 +4577,7 @@ class TestConstructors : public TestFixture { " bool b = (0 <= SetValue());\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4586,7 +4586,7 @@ class TestConstructors : public TestFixture { " bool b = (0 > SetValue());\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct C {\n" @@ -4595,7 +4595,7 @@ class TestConstructors : public TestFixture { " bool b = (0 >= SetValue());\n" " }\n" " int SetValue() { return x = 1; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -4613,7 +4613,7 @@ class TestConstructors : public TestFixture { "class C {\n" " private:\n" " A* b;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("template class A{};\n" @@ -4625,7 +4625,7 @@ class TestConstructors : public TestFixture { " bool m_value;\n" "};\n" "template\n" - "A>::A() : m_value(false) {}"); + "A>::A() : m_value(false) {}\n"); ASSERT_EQUALS("", errout_str()); check("template struct S;\n" // #11177 @@ -4644,7 +4644,7 @@ class TestConstructors : public TestFixture { "public:\n" " A& operator=() { return *this; }\n" "};\n" - "A a;"); + "A a;\n"); ASSERT_EQUALS("", errout_str()); } diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 17c5b8eff3c..ffd4d387cfc 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -175,7 +175,7 @@ class TestCppcheck : public TestFixture { "void f()\n" "{\n" " (void)(*((int*)0));\n" - "}"); + "}\n"); int called = 0; std::unordered_set addons; @@ -259,7 +259,7 @@ class TestCppcheck : public TestFixture { "void f()\n" "{\n" " (void)(*((int*)0));\n" - "}"); + "}\n"); int called = 0; std::unordered_set addons; @@ -342,7 +342,7 @@ class TestCppcheck : public TestFixture { "void f()\n" "{\n" " (void)(*((int*)0));\n" - "}"); + "}\n"); const char xmldata[] = R"()"; const Settings s = settingsBuilder().libraryxml(xmldata).build(); @@ -364,11 +364,11 @@ class TestCppcheck : public TestFixture { "inline void f()\n" "{\n" " (void)(*((int*)0));\n" - "}"); + "}\n"); ScopedFile test_file_a("a.c", - "#include \"inc.h\""); + "#include \"inc.h\"\n"); ScopedFile test_file_b("b.c", - "#include \"inc.h\""); + "#include \"inc.h\"\n"); // this is the "simple" format const auto s = dinit(Settings, $.templateFormat = templateFormat); // TODO: remove when we only longer rely on toString() in unique message handling @@ -400,7 +400,7 @@ class TestCppcheck : public TestFixture { "long a=m[9], b=m[9];\n" "(void)a;\n" "(void)b;\n" - "}"); + "}\n"); // this is the "simple" format const auto s = dinit(Settings, $.templateFormat = templateFormat); // TODO: remove when we only longer rely on toString() in unique message handling? @@ -490,7 +490,7 @@ class TestCppcheck : public TestFixture { ";\n"; simplecpp::OutputList outputList; - const simplecpp::TokenList tokens2(code, files, "", &outputList); + const simplecpp::TokenList tokens2(code, files, "", {}, &outputList); const std::string expected2 = " \n" " \n" " \n" diff --git a/test/testerrorlogger.cpp b/test/testerrorlogger.cpp index 014ac3a0a8f..c849d3a0c61 100644 --- a/test/testerrorlogger.cpp +++ b/test/testerrorlogger.cpp @@ -140,7 +140,7 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS("info", loc.getinfo()); } { - const SimpleTokenList tokenlist("a", "dir/a.cpp"); + const SimpleTokenList tokenlist("a\n", "dir/a.cpp"); { const ErrorMessage::FileLocation loc(tokenlist.front(), &tokenlist.get()); ASSERT_EQUALS("dir/a.cpp", loc.getOrigFile(false)); @@ -173,7 +173,7 @@ class TestErrorLogger : public TestFixture { } } { - const SimpleTokenList tokenlist("a", "dir\\a.cpp"); + const SimpleTokenList tokenlist("a\n", "dir\\a.cpp"); { const ErrorMessage::FileLocation loc(tokenlist.front(), &tokenlist.get()); ASSERT_EQUALS("dir\\a.cpp", loc.getOrigFile(false)); @@ -213,12 +213,12 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS("dir/a.cpp", ErrorMessage::FileLocation("dir/a.cpp", "info", 1, 1).getfile(false)); ASSERT_EQUALS("dir/a.cpp", ErrorMessage::FileLocation("dir\\a.cpp", "info", 1, 1).getfile(false)); { - const SimpleTokenList tokenlist("a", "dir/a.cpp"); + const SimpleTokenList tokenlist("a\n", "dir/a.cpp"); ASSERT_EQUALS("dir/a.cpp", ErrorMessage::FileLocation(tokenlist.front(), &tokenlist.get()).getfile(false)); ASSERT_EQUALS("dir/a.cpp", ErrorMessage::FileLocation(tokenlist.front(), "info", &tokenlist.get()).getfile(false)); } { - const SimpleTokenList tokenlist("a", "dir\\a.cpp"); + const SimpleTokenList tokenlist("a\n", "dir\\a.cpp"); ASSERT_EQUALS("dir/a.cpp", ErrorMessage::FileLocation(tokenlist.front(), &tokenlist.get()).getfile(false)); ASSERT_EQUALS("dir/a.cpp", ErrorMessage::FileLocation(tokenlist.front(), "info", &tokenlist.get()).getfile(false)); } diff --git a/test/testexceptionsafety.cpp b/test/testexceptionsafety.cpp index 1be46fbf282..7e3de4405b0 100644 --- a/test/testexceptionsafety.cpp +++ b/test/testexceptionsafety.cpp @@ -84,7 +84,7 @@ class TestExceptionSafety : public TestFixture { " ~x() {\n" " throw e;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (warning) Class x is not safe, destructor throws exception [exceptThrowInDestructor]\n" "[test.cpp:3:9]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n", errout_str()); @@ -93,7 +93,7 @@ class TestExceptionSafety : public TestFixture { "};\n" "x::~x() {\n" " throw e;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (warning) Class x is not safe, destructor throws exception [exceptThrowInDestructor]\n" "[test.cpp:5:5]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n", errout_str()); @@ -105,7 +105,7 @@ class TestExceptionSafety : public TestFixture { " } catch (...) {\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class x {\n" @@ -114,7 +114,7 @@ class TestExceptionSafety : public TestFixture { " throw e;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n", errout_str()); // #11031 should not warn when noexcept false @@ -123,7 +123,7 @@ class TestExceptionSafety : public TestFixture { " ~A() noexcept(false) {\n" " throw 30;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -134,7 +134,7 @@ class TestExceptionSafety : public TestFixture { " if (x)\n" " throw 123;\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9]: (warning) Exception thrown in invalid state, 'p' points at deallocated memory. [exceptDeallocThrow]\n", errout_str()); check("void f() {\n" @@ -143,7 +143,7 @@ class TestExceptionSafety : public TestFixture { " if (foo)\n" " throw 1;\n" " p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9]: (warning) Exception thrown in invalid state, 'p' points at deallocated memory. [exceptDeallocThrow]\n", errout_str()); } @@ -154,7 +154,7 @@ class TestExceptionSafety : public TestFixture { " if (foo)\n" " throw 1;\n" " p = new int;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -162,7 +162,7 @@ class TestExceptionSafety : public TestFixture { " delete p;\n" " reset(p);\n" " throw 1;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -171,14 +171,14 @@ class TestExceptionSafety : public TestFixture { " static int* p = 0;\n" " delete p;\n" " throw 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " static int* p = 0;\n" " delete p;\n" " throw 1;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Exception thrown in invalid state, 'p' points at deallocated memory. [exceptDeallocThrow]\n", errout_str()); } @@ -192,7 +192,7 @@ class TestExceptionSafety : public TestFixture { " {\n" " throw err;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:9]: (style) Throwing a copy of the caught exception instead of rethrowing the original exception. [exceptRethrowCopy]\n", errout_str()); } @@ -206,7 +206,7 @@ class TestExceptionSafety : public TestFixture { " {\n" " throw err;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:9]: (style) Throwing a copy of the caught exception instead of rethrowing the original exception. [exceptRethrowCopy]\n", errout_str()); } @@ -218,7 +218,7 @@ class TestExceptionSafety : public TestFixture { " catch(std::runtime_error& err) {\n" " throw err;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:9]: (style) Throwing a copy of the caught exception instead of rethrowing the original exception. [exceptRethrowCopy]\n", errout_str()); } @@ -233,7 +233,7 @@ class TestExceptionSafety : public TestFixture { " exception err2;\n" " throw err2;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -250,7 +250,7 @@ class TestExceptionSafety : public TestFixture { " throw inner;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:13]: (style) Throwing a copy of the caught exception instead of rethrowing the original exception. [exceptRethrowCopy]\n", errout_str()); check("void f() {\n" @@ -265,7 +265,7 @@ class TestExceptionSafety : public TestFixture { " throw outer;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -277,7 +277,7 @@ class TestExceptionSafety : public TestFixture { " catch( ::std::exception err) {\n" " foo(err);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (style) Exception should be caught by reference. [catchExceptionByValue]\n", errout_str()); check("void f() {\n" @@ -287,7 +287,7 @@ class TestExceptionSafety : public TestFixture { " catch(const exception err) {\n" " foo(err);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (style) Exception should be caught by reference. [catchExceptionByValue]\n", errout_str()); check("void f() {\n" @@ -297,7 +297,7 @@ class TestExceptionSafety : public TestFixture { " catch( ::std::exception& err) {\n" " foo(err);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -307,7 +307,7 @@ class TestExceptionSafety : public TestFixture { " catch(exception* err) {\n" " foo(err);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -317,7 +317,7 @@ class TestExceptionSafety : public TestFixture { " catch(const exception& err) {\n" " foo(err);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -327,7 +327,7 @@ class TestExceptionSafety : public TestFixture { " catch(int err) {\n" " foo(err);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -337,7 +337,7 @@ class TestExceptionSafety : public TestFixture { " catch(exception* const err) {\n" " foo(err);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -347,14 +347,14 @@ class TestExceptionSafety : public TestFixture { "void func3() noexcept(true) { throw 1; }\n" "void func4() noexcept(false) { throw 1; }\n" "void func5() noexcept(true) { func1(); }\n" - "void func6() noexcept(false) { func1(); }"); + "void func6() noexcept(false) { func1(); }\n"); ASSERT_EQUALS("[test.cpp:2:25]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n" "[test.cpp:3:31]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n" "[test.cpp:5:31]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n", errout_str()); // avoid false positives check("const char *func() noexcept { return 0; }\n" - "const char *func1() noexcept { try { throw 1; } catch(...) {} return 0; }"); + "const char *func1() noexcept { try { throw 1; } catch(...) {} return 0; }\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" // #14526 @@ -378,12 +378,12 @@ class TestExceptionSafety : public TestFixture { "void func2() throw() { throw 1; }\n" "void func3() throw(int) { throw 1; }\n" "void func4() throw() { func1(); }\n" - "void func5() throw(int) { func1(); }"); + "void func5() throw(int) { func1(); }\n"); ASSERT_EQUALS("[test.cpp:2:24]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n" "[test.cpp:4:24]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n", errout_str()); // avoid false positives - check("const char *func() throw() { return 0; }"); + check("const char *func() throw() { return 0; }\n"); ASSERT_EQUALS("", errout_str()); @@ -451,12 +451,12 @@ class TestExceptionSafety : public TestFixture { void nothrowAttributeThrow() { check("void func1() throw(int) { throw 1; }\n" "void func2() __attribute((nothrow)); void func2() { throw 1; }\n" - "void func3() __attribute((nothrow)); void func3() { func1(); }"); + "void func3() __attribute((nothrow)); void func3() { func1(); }\n"); ASSERT_EQUALS("[test.cpp:2:53]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n" "[test.cpp:3:53]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n", errout_str()); // avoid false positives - check("const char *func() __attribute((nothrow)); void func1() { return 0; }"); + check("const char *func() __attribute((nothrow)); void func1() { return 0; }\n"); ASSERT_EQUALS("", errout_str()); } @@ -465,30 +465,30 @@ class TestExceptionSafety : public TestFixture { " void copyMemberValues() throw () {\n" " copyMemberValues();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } void nothrowDeclspecThrow() { check("void func1() throw(int) { throw 1; }\n" "void __declspec(nothrow) func2() { throw 1; }\n" - "void __declspec(nothrow) func3() { func1(); }"); + "void __declspec(nothrow) func3() { func1(); }\n"); ASSERT_EQUALS("[test.cpp:2:36]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n" "[test.cpp:3:36]: (error) Unhandled exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]\n", errout_str()); // avoid false positives - check("const char *func() __attribute((nothrow)); void func1() { return 0; }"); + check("const char *func() __attribute((nothrow)); void func1() { return 0; }\n"); ASSERT_EQUALS("", errout_str()); } void rethrowNoCurrentException1() { - check("void func1(const bool flag) { try{ if(!flag) throw; } catch (int&) { ; } }"); + check("void func1(const bool flag) { try{ if(!flag) throw; } catch (int&) { ; } }\n"); ASSERT_EQUALS("[test.cpp:1:46]: (error) Rethrowing current exception with 'throw;', it seems there is no current exception to rethrow." " If there is no current exception this calls std::terminate(). More: https://isocpp.org/wiki/faq/exceptions#throw-without-an-object [rethrowNoCurrentException]\n", errout_str()); } void rethrowNoCurrentException2() { - check("void func1() { try{ ; } catch (...) { ; } throw; }"); + check("void func1() { try{ ; } catch (...) { ; } throw; }\n"); ASSERT_EQUALS("[test.cpp:1:43]: (error) Rethrowing current exception with 'throw;', it seems there is no current exception to rethrow." " If there is no current exception this calls std::terminate(). More: https://isocpp.org/wiki/faq/exceptions#throw-without-an-object [rethrowNoCurrentException]\n", errout_str()); } @@ -496,7 +496,7 @@ class TestExceptionSafety : public TestFixture { void rethrowNoCurrentException3() { check("void on_error() { try { throw; } catch (const int &) { ; } catch (...) { ; } }\n" // exception dispatcher idiom "void func2() { try{ ; } catch (const int&) { throw; } ; }\n" - "void func3() { throw 0; }"); + "void func3() { throw 0; }\n"); ASSERT_EQUALS("", errout_str()); } diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index d5a18f7d916..4ebe3360aba 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -142,14 +142,14 @@ class TestFunctions : public TestFixture { check("void f()\n" "{\n" " bsd_signal(SIGABRT, SIG_IGN);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (style) Obsolescent function 'bsd_signal' called. It is recommended to use 'sigaction' instead. [bsd_signalCalled]\n", errout_str()); check("int f()\n" "{\n" " int bsd_signal(0);\n" " return bsd_signal;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -158,7 +158,7 @@ class TestFunctions : public TestFixture { " if(!hp = gethostbyname(\"127.0.0.1\")) {\n" " exit(1);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:14]: (style) Obsolescent function 'gethostbyname' called. It is recommended to use 'getaddrinfo' instead. [gethostbynameCalled]\n", errout_str()); check("void f()\n" @@ -168,13 +168,13 @@ class TestFunctions : public TestFixture { " if(!hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET)) {\n" " exit(1);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:14]: (style) Obsolescent function 'gethostbyaddr' called. It is recommended to use 'getnameinfo' instead. [gethostbyaddrCalled]\n", errout_str()); check("void f()\n" "{\n" " usleep( 1000 );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (style) Obsolescent function 'usleep' called. It is recommended to use 'nanosleep' or 'setitimer' instead. [usleepCalled]\n", errout_str()); } @@ -186,7 +186,7 @@ class TestFunctions : public TestFixture { "{\n" " n1::index();\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::size_t f()\n" @@ -194,19 +194,19 @@ class TestFunctions : public TestFixture { " std::size_t index(0);\n" " index++;\n" " return index;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f()\n" "{\n" " return this->index();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " int index( 0 );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const char f()\n" @@ -214,7 +214,7 @@ class TestFunctions : public TestFixture { " const char var[6] = \"index\";\n" " const char i = index(var, 0);\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:20]: (style) Obsolescent function 'index' called. It is recommended to use 'strchr' instead. [indexCalled]\n", errout_str()); } @@ -222,7 +222,7 @@ class TestFunctions : public TestFixture { void prohibitedFunctions_qt_index() { check("void TDataModel::forceRowRefresh(int row) {\n" " emit dataChanged(index(row, 0), index(row, columnCount() - 1));\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:22]: (style) Obsolescent function 'index' called. It is recommended to use 'strchr' instead. [indexCalled]\n" "[test.cpp:2:37]: (style) Obsolescent function 'index' called. It is recommended to use 'strchr' instead. [indexCalled]\n", @@ -233,14 +233,14 @@ class TestFunctions : public TestFixture { check("void f()\n" "{\n" " int rindex( 0 );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " const char var[7] = \"rindex\";\n" " print(rindex(var, 0));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (style) Obsolescent function 'rindex' called. It is recommended to use 'strrchr' instead. [rindexCalled]\n", errout_str()); } @@ -250,7 +250,7 @@ class TestFunctions : public TestFixture { "public:\n" " Fred() : index(0) { }\n" " int index;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -258,13 +258,13 @@ class TestFunctions : public TestFixture { check("void f()\n" "{\n" " char *x = gets(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:15]: (warning) Obsolete function 'gets' called. It is recommended to use 'fgets' or 'gets_s' instead. [getsCalled]\n", errout_str()); check("void f()\n" "{\n" " foo(x, gets(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (warning) Obsolete function 'gets' called. It is recommended to use 'fgets' or 'gets_s' instead. [getsCalled]\n", errout_str()); } @@ -272,32 +272,32 @@ class TestFunctions : public TestFixture { check("void f()\n" "{\n" " char *x = alloca(10);\n" - "}"); // #4382 - there are no VLAs in C++ + "}\n"); // #4382 - there are no VLAs in C++ ASSERT_EQUALS("[test.cpp:3:15]: (warning) Obsolete function 'alloca' called. [allocaCalled]\n", errout_str()); check("void f()\n" "{\n" " char *x = alloca(10);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:3:15]: (warning) Obsolete function 'alloca' called. In C99 and later it is recommended to use a variable length array instead. [allocaCalled]\n", errout_str()); const Settings s = settingsBuilder(settings).c(Standards::C89).cpp(Standards::CPP03).build(); check("void f()\n" "{\n" " char *x = alloca(10);\n" - "}", s); // #4382 - there are no VLAs in C++ + "}\n", s); // #4382 - there are no VLAs in C++ ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " char *x = alloca(10);\n" - "}", s, false); // #7558 - no alternative to alloca in C89 + "}\n", s, false); // #7558 - no alternative to alloca in C89 ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " char *x = alloca(10);\n" - "}", s, false); + "}\n", s, false); ASSERT_EQUALS("", errout_str()); } @@ -311,7 +311,7 @@ class TestFunctions : public TestFixture { "{\n" " int b ; b = ftime ( 1 ) ;\n" " return 0 ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -321,7 +321,7 @@ class TestFunctions : public TestFixture { "{\n" " char *x = std::gets(str);\n" " char *y = gets(str);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:20]: (warning) Obsolete function 'gets' called. It is recommended to use 'fgets' or 'gets_s' instead. [getsCalled]\n" "[test.cpp:4:15]: (warning) Obsolete function 'gets' called. It is recommended to use 'fgets' or 'gets_s' instead. [getsCalled]\n", errout_str()); } @@ -332,7 +332,7 @@ class TestFunctions : public TestFixture { "{\n" " char *x = std::gets(str);\n" " usleep( 1000 );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:20]: (warning) Obsolete function 'gets' called. It is recommended to use 'fgets' or 'gets_s' instead. [getsCalled]\n" "[test.cpp:4:5]: (style) Obsolescent function 'usleep' called. It is recommended to use 'nanosleep' or 'setitimer' instead. [usleepCalled]\n", errout_str()); } @@ -344,14 +344,14 @@ class TestFunctions : public TestFixture { " char s [ 10 ] ;\n" " gets ( s ) ;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (warning) Obsolete function 'gets' called. It is recommended to use 'fgets' or 'gets_s' instead. [getsCalled]\n", errout_str()); check("int getcontext(ucontext_t *ucp);\n" "void f (ucontext_t *ucp)\n" "{\n" " getcontext ( ucp ) ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (portability) Obsolescent function 'getcontext' called. Applications are recommended to be rewritten to use POSIX threads. [getcontextCalled]\n", errout_str()); } @@ -362,7 +362,7 @@ class TestFunctions : public TestFixture { " char s [ 10 ] ;\n" " gets ( s ) ;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -371,7 +371,7 @@ class TestFunctions : public TestFixture { "{\n" " char *cpwd;" " crypt(pwd, cpwd);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:20]: (warning) Return value of function crypt() is not used. [ignoredReturnValue]\n" "[test.cpp:3:20]: (portability) Non reentrant function 'crypt' called. For threadsafe applications it is recommended to use the reentrant replacement function 'crypt_r'. [cryptCalled]\n", errout_str()); @@ -380,7 +380,7 @@ class TestFunctions : public TestFixture { " char *pwd = getpass(\"Password:\");" " char *cpwd;" " crypt(pwd, cpwd);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:57]: (warning) Return value of function crypt() is not used. [ignoredReturnValue]\n" "[test.cpp:3:57]: (portability) Non reentrant function 'crypt' called. For threadsafe applications it is recommended to use the reentrant replacement function 'crypt_r'. [cryptCalled]\n", errout_str()); @@ -388,7 +388,7 @@ class TestFunctions : public TestFixture { "{\n" " int crypt = 0;" " return crypt;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -397,14 +397,14 @@ class TestFunctions : public TestFixture { "{\n" " time_t t = 0;" " auto lt = std::localtime(&t);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:37]: (portability) Non reentrant function 'localtime' called. For threadsafe applications it is recommended to use the reentrant replacement function 'localtime_r'. [localtimeCalled]\n", errout_str()); // Passed as function argument check("void f()\n" "{\n" " printf(\"Magic guess: %d\", getpwent());\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:31]: (portability) Non reentrant function 'getpwent' called. For threadsafe applications it is recommended to use the reentrant replacement function 'getpwent_r'. [getpwentCalled]\n", errout_str()); // Pass return value @@ -412,14 +412,14 @@ class TestFunctions : public TestFixture { "{\n" " time_t t = 0;" " struct tm *foo = localtime(&t);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:39]: (portability) Non reentrant function 'localtime' called. For threadsafe applications it is recommended to use the reentrant replacement function 'localtime_r'. [localtimeCalled]\n", errout_str()); // Access via global namespace check("void f()\n" "{\n" " ::getpwent();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:7]: (warning) Return value of function ::getpwent() is not used. [ignoredReturnValue]\n" "[test.cpp:3:7]: (portability) Non reentrant function 'getpwent' called. For threadsafe applications it is recommended to use the reentrant replacement function 'getpwent_r'. [getpwentCalled]\n", errout_str()); @@ -427,68 +427,68 @@ class TestFunctions : public TestFixture { check("int getpwent()\n" "{\n" " return 123;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Be quiet on other namespaces check("void f()\n" "{\n" " foobar::getpwent();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Be quiet on class member functions check("void f()\n" "{\n" " foobar.getpwent();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void invalidFunctionUsage1() { - check("void f() { memset(a,b,sizeof(a)!=12); }"); + check("void f() { memset(a,b,sizeof(a)!=12); }\n"); ASSERT_EQUALS("[test.cpp:1:32]: (error) Invalid memset() argument nr 3. A non-boolean value is required. [invalidFunctionArgBool]\n", errout_str()); - check("void f() { memset(a,b,sizeof(a)!=0); }"); + check("void f() { memset(a,b,sizeof(a)!=0); }\n"); ASSERT_EQUALS("[test.cpp:1:32]: (error) Invalid memset() argument nr 3. A non-boolean value is required. [invalidFunctionArgBool]\n", errout_str()); - check("void f() { memset(a,b,!c); }"); + check("void f() { memset(a,b,!c); }\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Invalid memset() argument nr 3. A non-boolean value is required. [invalidFunctionArgBool]\n", errout_str()); // Ticket #6990 - check("void f(bool c) { memset(a,b,c); }"); + check("void f(bool c) { memset(a,b,c); }\n"); ASSERT_EQUALS("[test.cpp:1:29]: (error) Invalid memset() argument nr 3. A non-boolean value is required. [invalidFunctionArgBool]\n", errout_str()); - check("void f() { memset(a,b,true); }"); + check("void f() { memset(a,b,true); }\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Invalid memset() argument nr 3. A non-boolean value is required. [invalidFunctionArgBool]\n", errout_str()); // Ticket #6588 (c mode) check("void record(char* buf, int n) {\n" " memset(buf, 0, n < 255);\n" /* KO */ " memset(buf, 0, n < 255 ? n : 255);\n" /* OK */ - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:2:20]: (error) Invalid memset() argument nr 3. A non-boolean value is required. [invalidFunctionArgBool]\n", errout_str()); // Ticket #6588 (c++ mode) check("void record(char* buf, int n) {\n" " memset(buf, 0, n < 255);\n" /* KO */ " memset(buf, 0, n < 255 ? n : 255);\n" /* OK */ - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (error) Invalid memset() argument nr 3. A non-boolean value is required. [invalidFunctionArgBool]\n", errout_str()); check("int boolArgZeroIsInvalidButOneIsValid(int a, int param) {\n" " return div(a, param > 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:23]: (error) Invalid div() argument nr 2. The value is 0 or 1 (boolean) but the valid values are ':-1,1:'. [invalidFunctionArg]\n", errout_str()); check("void boolArgZeroIsValidButOneIsInvalid(int param) {\n" " strtol(a, b, param > 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (error) Invalid strtol() argument nr 3. The value is 0 or 1 (boolean) but the valid values are '0,2:36'. [invalidFunctionArg]\n", errout_str()); - check("void f() { strtol(a,b,1); }"); + check("void f() { strtol(a,b,1); }\n"); ASSERT_EQUALS("[test.cpp:1:23]: (error) Invalid strtol() argument nr 3. The value is 1 but the valid values are '0,2:36'. [invalidFunctionArg]\n", errout_str()); - check("void f() { strtol(a,b,10); }"); + check("void f() { strtol(a,b,10); }\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::vector& v) {\n" // #10754 @@ -531,16 +531,16 @@ class TestFunctions : public TestFixture { } void invalidFunctionUsageStrings() { - check("size_t f() { char x = 'x'; return strlen(&x); }"); + check("size_t f() { char x = 'x'; return strlen(&x); }\n"); ASSERT_EQUALS("[test.cpp:1:42]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); - check("size_t f() { return strlen(&x); }"); + check("size_t f() { return strlen(&x); }\n"); ASSERT_EQUALS("", errout_str()); - check("size_t f(char x) { return strlen(&x); }"); + check("size_t f(char x) { return strlen(&x); }\n"); ASSERT_EQUALS("[test.cpp:1:34]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); - check("size_t f() { char x = '\\0'; return strlen(&x); }"); + check("size_t f() { char x = '\\0'; return strlen(&x); }\n"); ASSERT_EQUALS("", errout_str()); check("size_t f() {\n" @@ -550,41 +550,41 @@ class TestFunctions : public TestFixture { " else\n" " x = 'a';\n" " return strlen(&x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:17]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); - check("int f() { char x = '\\0'; return strcmp(\"Hello world\", &x); }"); + check("int f() { char x = '\\0'; return strcmp(\"Hello world\", &x); }\n"); ASSERT_EQUALS("", errout_str()); - check("int f() { char x = 'x'; return strcmp(\"Hello world\", &x); }"); + check("int f() { char x = 'x'; return strcmp(\"Hello world\", &x); }\n"); ASSERT_EQUALS("[test.cpp:1:54]: (error) Invalid strcmp() argument nr 2. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); - check("size_t f(char x) { char * y = &x; return strlen(y); }"); + check("size_t f(char x) { char * y = &x; return strlen(y); }\n"); TODO_ASSERT_EQUALS("[test.cpp:1:42]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", "", errout_str()); - check("size_t f(char x) { char * y = &x; char *z = y; return strlen(z); }"); + check("size_t f(char x) { char * y = &x; char *z = y; return strlen(z); }\n"); TODO_ASSERT_EQUALS("[test.cpp:1:42]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", "", errout_str()); - check("size_t f() { char x = 'x'; char * y = &x; char *z = y; return strlen(z); }"); + check("size_t f() { char x = 'x'; char * y = &x; char *z = y; return strlen(z); }\n"); TODO_ASSERT_EQUALS("[test.cpp:1:42]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", "", errout_str()); - check("size_t f() { char x = '\\0'; char * y = &x; char *z = y; return strlen(z); }"); + check("size_t f() { char x = '\\0'; char * y = &x; char *z = y; return strlen(z); }\n"); ASSERT_EQUALS("", errout_str()); - check("size_t f() { char x[] = \"Hello world\"; return strlen(x); }"); + check("size_t f() { char x[] = \"Hello world\"; return strlen(x); }\n"); ASSERT_EQUALS("", errout_str()); - check("size_t f(char x[]) { return strlen(x); }"); + check("size_t f(char x[]) { return strlen(x); }\n"); ASSERT_EQUALS("", errout_str()); - check("int f(char x, char y) { return strcmp(&x, &y); }"); + check("int f(char x, char y) { return strcmp(&x, &y); }\n"); ASSERT_EQUALS("[test.cpp:1:39]: (error) Invalid strcmp() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n" "[test.cpp:1:43]: (error) Invalid strcmp() argument nr 2. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); - check("size_t f() { char x[] = \"Hello world\"; return strlen(&x[0]); }"); + check("size_t f() { char x[] = \"Hello world\"; return strlen(&x[0]); }\n"); ASSERT_EQUALS("", errout_str()); - check("size_t f() { char* x = \"Hello world\"; return strlen(&x[0]); }"); + check("size_t f() { char* x = \"Hello world\"; return strlen(&x[0]); }\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -597,11 +597,11 @@ class TestFunctions : public TestFixture { " size_t l1 = strlen(&s1.x);\n" " size_t l2 = strlen(&s2.x);\n" " return l1 + l2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:22]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n" "[test.cpp:9:22]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); - check("const char x = 'x'; size_t f() { return strlen(&x); }"); + check("const char x = 'x'; size_t f() { return strlen(&x); }\n"); ASSERT_EQUALS("[test.cpp:1:48]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); check("struct someStruct {\n" @@ -616,7 +616,7 @@ class TestFunctions : public TestFixture { "int f(struct someStruct * const tp, const int k)\n" "{\n" " return strcmp(&tp->x.buf[k], \"needle\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct someStruct {\n" @@ -625,29 +625,29 @@ class TestFunctions : public TestFixture { "int f(struct someStruct * const tp, const int k)\n" "{\n" " return strcmp(&tp->buf[k], \"needle\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("const char x = 'x'; size_t f() { char y = x; return strlen(&y); }"); + check("const char x = 'x'; size_t f() { char y = x; return strlen(&y); }\n"); ASSERT_EQUALS("[test.cpp:1:60]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); - check("const char x = '\\0'; size_t f() { return strlen(&x); }"); + check("const char x = '\\0'; size_t f() { return strlen(&x); }\n"); ASSERT_EQUALS("", errout_str()); - check("const char x = '\\0'; size_t f() { char y = x; return strlen(&y); }"); + check("const char x = '\\0'; size_t f() { char y = x; return strlen(&y); }\n"); ASSERT_EQUALS("", errout_str()); check("size_t f() {\n" " char * a = \"Hello world\";\n" " char ** b = &a;\n" " return strlen(&b[0][0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("size_t f() {\n" " char ca[] = \"asdf\";\n" " return strlen((char*) &ca);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5225 @@ -658,67 +658,67 @@ class TestFunctions : public TestFixture { " strcat(str, &d);\n" " puts(str);\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:15]: (error) Invalid strcat() argument nr 2. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); check("FILE* f(void) {\n" " const char fileName[1] = { \'x\' };\n" " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (error) Invalid fopen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); check("FILE* f(void) {\n" " const char fileName[2] = { \'x\', \'y\' };\n" " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (error) Invalid fopen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); check("FILE* f(void) {\n" " const char fileName[3] = { \'x\', \'y\' ,\'\\0\' };\n" " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("FILE* f(void) {\n" " const char fileName[3] = { \'x\', \'\\0\' ,\'y\' };\n" " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("FILE* f(void) {\n" " const char fileName[3] = { \'x\', \'y\' };\n" // implicit '\0' added at the end " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("FILE* f(void) {\n" " const char fileName[] = { \'\\0\' };\n" " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("FILE* f(void) {\n" " const char fileName[] = { \'0\' + 42 };\n" // no size is explicitly defined, no implicit '\0' is added " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (error) Invalid fopen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); check("FILE* f(void) {\n" " const char fileName[] = { \'0\' + 42, \'x\' };\n" // no size is explicitly defined, no implicit '\0' is added " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (error) Invalid fopen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); check("FILE* f(void) {\n" " const char fileName[2] = { \'0\' + 42 };\n" // implicitly '\0' added at the end because size is set to 2 " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("FILE* f(void) {\n" " const char fileName[] = { };\n" " return fopen(fileName, \"r\"); \n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void scanMetaTypes()\n" // don't crash @@ -729,7 +729,7 @@ class TestFunctions : public TestFixture { " if (strstr(name, \"GammaRay::\") != name)\n" " metaTypes.push_back(mtId);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" @@ -771,10 +771,10 @@ class TestFunctions : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); - check("size_t f() { wchar_t x = L'x'; return wcslen(&x); }"); + check("size_t f() { wchar_t x = L'x'; return wcslen(&x); }\n"); ASSERT_EQUALS("[test.cpp:1:46]: (error) Invalid wcslen() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); - check("void f() { char a[10] = \"1234567890\"; puts(a); }", dinit(CheckOptions, $.cpp = false)); // #1770 + check("void f() { char a[10] = \"1234567890\"; puts(a); }\n", dinit(CheckOptions, $.cpp = false)); // #1770 ASSERT_EQUALS("[test.c:1:44]: (error) Invalid puts() argument nr 1. A nul-terminated string is required. [invalidFunctionArgStr]\n", errout_str()); } @@ -800,7 +800,7 @@ class TestFunctions : public TestFixture { " std::cout << sqrt(-1) << std::endl;\n" " std::cout << sqrtf(-1) << std::endl;\n" " std::cout << sqrtl(-1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25]: (error) Invalid sqrt() argument nr 1. The value is -1 but the valid values are '0.0:'. [invalidFunctionArg]\n" "[test.cpp:4:26]: (error) Invalid sqrtf() argument nr 1. The value is -1 but the valid values are '0.0:'. [invalidFunctionArg]\n" "[test.cpp:5:26]: (error) Invalid sqrtl() argument nr 1. The value is -1 but the valid values are '0.0:'. [invalidFunctionArg]\n", errout_str()); @@ -811,7 +811,7 @@ class TestFunctions : public TestFixture { " std::cout << sqrt(-0.) << std::endl;\n" " std::cout << sqrtf(-0.) << std::endl;\n" " std::cout << sqrtl(-0.) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -819,7 +819,7 @@ class TestFunctions : public TestFixture { " std::cout << sqrt(1) << std::endl;\n" " std::cout << sqrtf(1) << std::endl;\n" " std::cout << sqrtl(1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -839,7 +839,7 @@ class TestFunctions : public TestFixture { " std::cout << log1p(-3) << std::endl;\n" " std::cout << log1pf(-3) << std::endl;\n" " std::cout << log1pl(-3) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:24]: (error) Invalid log() argument nr 1. The value is -2 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" "[test.cpp:4:25]: (error) Invalid logf() argument nr 1. The value is -2 but the valid values are '1.4013e-45:'. [invalidFunctionArg]\n" "[test.cpp:5:25]: (error) Invalid logl() argument nr 1. The value is -2 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" @@ -876,7 +876,7 @@ class TestFunctions : public TestFixture { " std::cout << log1p(-2) << std::endl;\n" " std::cout << log1pf(-2) << std::endl;\n" " std::cout << log1pl(-2) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:24]: (error) Invalid log() argument nr 1. The value is -1 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" "[test.cpp:4:25]: (error) Invalid logf() argument nr 1. The value is -1 but the valid values are '1.4013e-45:'. [invalidFunctionArg]\n" "[test.cpp:5:25]: (error) Invalid logl() argument nr 1. The value is -1 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" @@ -913,7 +913,7 @@ class TestFunctions : public TestFixture { " std::cout << log1p(-2.0) << std::endl;\n" " std::cout << log1pf(-2.0) << std::endl;\n" " std::cout << log1pl(-2.0) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25]: (error) Invalid log() argument nr 1. The value is -1 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" "[test.cpp:4:26]: (error) Invalid logf() argument nr 1. The value is -1 but the valid values are '1.4013e-45:'. [invalidFunctionArg]\n" "[test.cpp:5:26]: (error) Invalid logl() argument nr 1. The value is -1 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" @@ -950,7 +950,7 @@ class TestFunctions : public TestFixture { " std::cout << log1p(-1.1) << std::endl;\n" " std::cout << log1pf(-1.1) << std::endl;\n" " std::cout << log1pl(-1.1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25]: (error) Invalid log() argument nr 1. The value is -0.1 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" "[test.cpp:4:26]: (error) Invalid logf() argument nr 1. The value is -0.1 but the valid values are '1.4013e-45:'. [invalidFunctionArg]\n" "[test.cpp:5:26]: (error) Invalid logl() argument nr 1. The value is -0.1 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" @@ -987,7 +987,7 @@ class TestFunctions : public TestFixture { " std::cout << log1p(-1.) << std::endl;\n" " std::cout << log1pf(-1.0) << std::endl;\n" " std::cout << log1pl(-1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:23]: (error) Invalid log() argument nr 1. The value is 0 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" "[test.cpp:4:25]: (error) Invalid logf() argument nr 1. The value is 0 but the valid values are '1.4013e-45:'. [invalidFunctionArg]\n" "[test.cpp:5:25]: (error) Invalid logl() argument nr 1. The value is 0 but the valid values are '4.94066e-324:'. [invalidFunctionArg]\n" @@ -1060,21 +1060,21 @@ class TestFunctions : public TestFixture { " std::cout << log1p(2.0) << std::endl;\n" " std::cout << log1pf(2.0) << std::endl;\n" " std::cout << log1pf(2.0f) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" " std::string *log(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3473 - no warning if "log" is a variable - check("Fred::Fred() : log(0) { }"); + check("Fred::Fred() : log(0) { }\n"); ASSERT_EQUALS("", errout_str()); // #5748 - check("void f() { foo.log(0); }"); + check("void f() { foo.log(0); }\n"); ASSERT_EQUALS("", errout_str()); } @@ -1112,7 +1112,7 @@ class TestFunctions : public TestFixture { " + acosl(0.1E-1) \n" " + acosl(+0.1E-1) \n" " + acosl(-0.1E-1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -1120,7 +1120,7 @@ class TestFunctions : public TestFixture { " std::cout << acos(1.1) << std::endl;\n" " std::cout << acosf(1.1) << std::endl;\n" " std::cout << acosl(1.1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25]: (error) Invalid acos() argument nr 1. The value is 1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n" "[test.cpp:4:26]: (error) Invalid acosf() argument nr 1. The value is 1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n" "[test.cpp:5:26]: (error) Invalid acosl() argument nr 1. The value is 1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n", errout_str()); @@ -1130,7 +1130,7 @@ class TestFunctions : public TestFixture { " std::cout << acos(-1.1) << std::endl;\n" " std::cout << acosf(-1.1) << std::endl;\n" " std::cout << acosl(-1.1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:26]: (error) Invalid acos() argument nr 1. The value is -1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n" "[test.cpp:4:27]: (error) Invalid acosf() argument nr 1. The value is -1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n" "[test.cpp:5:27]: (error) Invalid acosl() argument nr 1. The value is -1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n", errout_str()); @@ -1173,7 +1173,7 @@ class TestFunctions : public TestFixture { " + asinl(0.1E-1) \n" " + asinl(+0.1E-1) \n" " + asinl(-0.1E-1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -1181,7 +1181,7 @@ class TestFunctions : public TestFixture { " std::cout << asin(1.1) << std::endl;\n" " std::cout << asinf(1.1) << std::endl;\n" " std::cout << asinl(1.1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25]: (error) Invalid asin() argument nr 1. The value is 1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n" "[test.cpp:4:26]: (error) Invalid asinf() argument nr 1. The value is 1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n" "[test.cpp:5:26]: (error) Invalid asinl() argument nr 1. The value is 1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n", errout_str()); @@ -1191,7 +1191,7 @@ class TestFunctions : public TestFixture { " std::cout << asin(-1.1) << std::endl;\n" " std::cout << asinf(-1.1) << std::endl;\n" " std::cout << asinl(-1.1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:26]: (error) Invalid asin() argument nr 1. The value is -1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n" "[test.cpp:4:27]: (error) Invalid asinf() argument nr 1. The value is -1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n" "[test.cpp:5:27]: (error) Invalid asinl() argument nr 1. The value is -1.1 but the valid values are '-1.0:1.0'. [invalidFunctionArg]\n", errout_str()); @@ -1204,7 +1204,7 @@ class TestFunctions : public TestFixture { " std::cout << pow(0,-10) << std::endl;\n" " std::cout << powf(0,-10) << std::endl;\n" " std::cout << powl(0,-10) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19]: (warning) Passing values 0 and -10 to pow() leads to implementation-defined result. [wrongmathcall]\n" "[test.cpp:4:19]: (warning) Passing values 0 and -10 to powf() leads to implementation-defined result. [wrongmathcall]\n" "[test.cpp:5:19]: (warning) Passing values 0 and -10 to powl() leads to implementation-defined result. [wrongmathcall]\n", errout_str()); @@ -1214,7 +1214,7 @@ class TestFunctions : public TestFixture { " std::cout << pow(0,10) << std::endl;\n" " std::cout << powf(0,10) << std::endl;\n" " std::cout << powl(0,10) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1255,7 +1255,7 @@ class TestFunctions : public TestFixture { " std::cout << atan2l(0.1E-1,3) ;\n" " std::cout << atan2l(+0.1E-1,1) ;\n" " std::cout << atan2l(-0.1E-1,8) ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -1263,7 +1263,7 @@ class TestFunctions : public TestFixture { " std::cout << atan2(0,0) << std::endl;\n" " std::cout << atan2f(0,0) << std::endl;\n" " std::cout << atan2l(0,0) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19]: (warning) Passing values 0 and 0 to atan2() leads to implementation-defined result. [wrongmathcall]\n" "[test.cpp:4:19]: (warning) Passing values 0 and 0 to atan2f() leads to implementation-defined result. [wrongmathcall]\n" "[test.cpp:5:19]: (warning) Passing values 0 and 0 to atan2l() leads to implementation-defined result. [wrongmathcall]\n", errout_str()); @@ -1276,7 +1276,7 @@ class TestFunctions : public TestFixture { " std::cout << fmod(1.0,0) << std::endl;\n" " std::cout << fmodf(1.0,0) << std::endl;\n" " std::cout << fmodl(1.0,0) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:28]: (error) Invalid fmod() argument nr 2. The value is 0 but the valid values are '!0.0'. [invalidFunctionArg]\n" "[test.cpp:4:29]: (error) Invalid fmodf() argument nr 2. The value is 0 but the valid values are '!0.0'. [invalidFunctionArg]\n" "[test.cpp:5:29]: (error) Invalid fmodl() argument nr 2. The value is 0 but the valid values are '!0.0'. [invalidFunctionArg]\n" @@ -1289,7 +1289,7 @@ class TestFunctions : public TestFixture { " std::cout << fmod(1.0,1) << std::endl;\n" " std::cout << fmodf(1.0,1) << std::endl;\n" " std::cout << fmodl(1.0,1) << std::endl;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1298,7 +1298,7 @@ class TestFunctions : public TestFixture { " print(exp(x) - 1);\n" " print(log(1 + x));\n" " print(1 - erf(x));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Expression 'exp(x) - 1' can be replaced by 'expm1(x)' to avoid loss of precision. [unpreciseMathCall]\n" "[test.cpp:3:11]: (style) Expression 'log(1 + x)' can be replaced by 'log1p(x)' to avoid loss of precision. [unpreciseMathCall]\n" "[test.cpp:4:11]: (style) Expression '1 - erf(x)' can be replaced by 'erfc(x)' to avoid loss of precision. [unpreciseMathCall]\n", errout_str()); @@ -1307,7 +1307,7 @@ class TestFunctions : public TestFixture { " print(exp(x) - 1.0);\n" " print(log(1.0 + x));\n" " print(1.0 - erf(x));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Expression 'exp(x) - 1' can be replaced by 'expm1(x)' to avoid loss of precision. [unpreciseMathCall]\n" "[test.cpp:3:11]: (style) Expression 'log(1 + x)' can be replaced by 'log1p(x)' to avoid loss of precision. [unpreciseMathCall]\n" "[test.cpp:4:12]: (style) Expression '1 - erf(x)' can be replaced by 'erfc(x)' to avoid loss of precision. [unpreciseMathCall]\n", errout_str()); @@ -1316,7 +1316,7 @@ class TestFunctions : public TestFixture { " print(exp(3 + x*f(a)) - 1);\n" " print(log(x*4 + 1));\n" " print(1 - erf(34*x + f(x) - c));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Expression 'exp(x) - 1' can be replaced by 'expm1(x)' to avoid loss of precision. [unpreciseMathCall]\n" "[test.cpp:3:11]: (style) Expression 'log(1 + x)' can be replaced by 'log1p(x)' to avoid loss of precision. [unpreciseMathCall]\n" "[test.cpp:4:11]: (style) Expression '1 - erf(x)' can be replaced by 'erfc(x)' to avoid loss of precision. [unpreciseMathCall]\n", errout_str()); @@ -1324,7 +1324,7 @@ class TestFunctions : public TestFixture { check("void foo() {\n" " print(2*exp(x) - 1);\n" " print(1 - erf(x)/2.0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1341,67 +1341,67 @@ class TestFunctions : public TestFixture { check("void foo() {\n" " mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("[test.cpp:2:3]: (warning) Return value of function mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("void foo() {\n" " foo::mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("[test.cpp:2:8]: (warning) Return value of function foo::mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("void f() {\n" " foo x;\n" " x.mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Return value of function x.mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("bool mystrcmp(char* a, char* b);\n" // cppcheck sees a custom strcmp definition, but it returns a value. Assume it is the one specified in the library. "void foo() {\n" " mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Return value of function mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("void mystrcmp(char* a, char* b);\n" // cppcheck sees a custom strcmp definition which returns void! "void foo() {\n" " mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " class mystrcmp { mystrcmp() {} };\n" // strcmp is a constructor definition here - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " return mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " return foo::mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " if(mystrcmp(a, b));\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " bool b = mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); // #6194 check("void foo() {\n" " MyStrCmp mystrcmp(x, y);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); // #6197 check("void foo() {\n" " abc::def.mystrcmp(a,b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); // #6233 @@ -1412,30 +1412,30 @@ class TestFunctions : public TestFixture { " };\n" " lambda(13.3);\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // TODO: use settings2? // #6669 check("void foo(size_t size) {\n" " void * res{malloc(size)};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // TODO: use settings2? // #7447 check("void foo() {\n" " int x{mystrcmp(a,b)};\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); // #7905 check("void foo() {\n" " int x({mystrcmp(a,b)});\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" // don't crash " DEBUG(123)(mystrcmp(a,b))(fd);\n" - "}", settings2); + "}\n", settings2); check("struct teststruct {\n" " int testfunc1() __attribute__ ((warn_unused_result)) { return 1; }\n" " [[nodiscard]] int testfunc2() { return 1; }\n" @@ -1446,7 +1446,7 @@ class TestFunctions : public TestFixture { " TestStruct1.testfunc1();\n" " TestStruct1.testfunc2();\n" " return 0;\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("[test.cpp:4:18]: (warning) Return value of function testfunc1() is not used. [ignoredReturnValue]\n" "[test.cpp:4:31]: (warning) Return value of function testfunc2() is not used. [ignoredReturnValue]\n" "[test.cpp:8:17]: (warning) Return value of function TestStruct1.testfunc1() is not used. [ignoredReturnValue]\n" @@ -1456,7 +1456,7 @@ class TestFunctions : public TestFixture { check("template uint8_t b(std::tuple d) {\n" " std::tuple c{std::move(d)};\n" " return std::get<0>(c);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // TODO: use settings2? check("struct A { int x; };\n" @@ -1464,13 +1464,13 @@ class TestFunctions : public TestFixture { "A f(int x, Ts... xs) {\n" " return {std::move(x), static_cast(xs)...};\n" "}\n" - "A g() { return f(1); }"); + "A g() { return f(1); }\n"); ASSERT_EQUALS("", errout_str()); // TODO: use settings2? // #8412 - unused operator result check("void foo() {\n" " !mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("[test.cpp:2:4]: (warning) Return value of function mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("void f(std::vector v) {\n" @@ -1502,24 +1502,24 @@ class TestFunctions : public TestFixture { check("void foo() {\n" " mystrcmp(a, b);\n" - "}", settings2); + "}\n", settings2); ASSERT_EQUALS("[test.cpp:2:3]: (style) Error code from the return value of function mystrcmp() is not used. [ignoredReturnErrorCode]\n", errout_str()); } void memsetZeroBytes() { check("void f() {\n" " memset(p, 10, 0x0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) memset() called to fill 0 bytes. [memsetZeroBytes]\n", errout_str()); check("void f() {\n" " memset(p, sizeof(p), 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) memset() called to fill 0 bytes. [memsetZeroBytes]\n", errout_str()); check("void f() {\n" " memset(p, sizeof(p), i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6269 false positives in case of overloaded standard library functions @@ -1528,13 +1528,13 @@ class TestFunctions : public TestFixture { " void f( void ) {\n" " memset( 0 );\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #7285 check("void f() {\n" " memset(&tm, sizeof(tm), 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) memset() called to fill 0 bytes. [memsetZeroBytes]\n", errout_str()); } @@ -1545,7 +1545,7 @@ class TestFunctions : public TestFixture { " memset(is, 1.0f, 40);\n" " int* is2 = new int[10];\n" " memset(is2, 0.1f, 40);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (portability) The 2nd memset() argument '1.0f' is a float, its representation is implementation defined. [memsetFloat]\n" "[test.cpp:5:18]: (portability) The 2nd memset() argument '0.1f' is a float, its representation is implementation defined. [memsetFloat]\n", errout_str()); @@ -1553,19 +1553,19 @@ class TestFunctions : public TestFixture { " int* is = new int[10];\n" " float g = computeG();\n" " memset(is, g, 40);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (portability) The 2nd memset() argument 'g' is a float, its representation is implementation defined. [memsetFloat]\n", errout_str()); check("void f() {\n" " int* is = new int[10];\n" " memset(is, 0.0f, 40);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // FP " float x = 2.3f;\n" " memset(a, (x?64:0), 40);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -1573,7 +1573,7 @@ class TestFunctions : public TestFixture { " memset(ss, 256, 4);\n" " short ss2[2];\n" " memset(ss2, -129, 4);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (warning) The 2nd memset() argument '256' doesn't fit into an 'unsigned char'. [memsetValueOutOfRange]\n" "[test.cpp:5:18]: (warning) The 2nd memset() argument '-129' doesn't fit into an 'unsigned char'. [memsetValueOutOfRange]\n", errout_str()); @@ -1588,23 +1588,23 @@ class TestFunctions : public TestFixture { " memset(cs2, 255, 30);\n" " char cs3[30];\n" " memset(cs3, 0, 30);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int is[10];\n" " const int i = g();\n" " memset(is, 1.0f + i, 40);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:21]: (portability) The 2nd memset() argument '1.0f+i' is a float, its representation is implementation defined. [memsetFloat]\n", errout_str()); } void checkMissingReturn1() { - check("int f() {}"); + check("int f() {}\n"); ASSERT_EQUALS("[test.cpp:1:10]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); { - const char code[] = "int main(void) {}"; + const char code[] = "int main(void) {}\n"; { const Settings s = settingsBuilder().c(Standards::C89).build(); @@ -1622,16 +1622,16 @@ class TestFunctions : public TestFixture { } } - check("F(A,B) { x=1; }"); + check("F(A,B) { x=1; }\n"); ASSERT_EQUALS("", errout_str()); - check("auto foo4() -> void {}"); + check("auto foo4() -> void {}\n"); ASSERT_EQUALS("", errout_str()); - check("void STDCALL foo() {}"); + check("void STDCALL foo() {}\n"); ASSERT_EQUALS("", errout_str()); - check("void operator=(int y) { x=y; }"); + check("void operator=(int y) { x=y; }\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" @@ -1647,14 +1647,14 @@ class TestFunctions : public TestFixture { check("int foo(int x) {\n" " return 1;\n" " (void)x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo(int x) {\n" " if (x) goto out;\n" " return 1;\n" "out:\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); // switch @@ -1663,7 +1663,7 @@ class TestFunctions : public TestFixture { " case 1: break;\n" // <- error " case 2: return 1;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); check("int f() {\n" @@ -1671,7 +1671,7 @@ class TestFunctions : public TestFixture { " case 1: return 2; break;\n" " default: return 1;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool test(unsigned char v1, int v2) {\n" @@ -1685,7 +1685,7 @@ class TestFunctions : public TestFixture { " default:\n" " return true;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // if/else @@ -1693,7 +1693,7 @@ class TestFunctions : public TestFixture { " if (x) {\n" " return 1;\n" " }\n" // <- error (missing else) - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); check("int f(int x) {\n" @@ -1702,19 +1702,19 @@ class TestFunctions : public TestFixture { " } else {\n" " return 1;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); check("int f() {\n" " if (!0) {\n" " return 1;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" " if (!0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); // loop @@ -1722,7 +1722,7 @@ class TestFunctions : public TestFixture { " while (1) {\n" " dostuff();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // return {..} @@ -1731,20 +1731,20 @@ class TestFunctions : public TestFixture { " return {};\n" " else\n" " return {1, 2};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // noreturn function - check("int f(int x) { exit(0); }"); + check("int f(int x) { exit(0); }\n"); ASSERT_EQUALS("", errout_str()); - check("int f(int x) { assert(0); }"); + check("int f(int x) { assert(0); }\n"); ASSERT_EQUALS("", errout_str()); - check("int f(int x) { if (x) return 1; else return bar({1}, {}); }"); + check("int f(int x) { if (x) return 1; else return bar({1}, {}); }\n"); ASSERT_EQUALS("", errout_str()); - check("auto f() -> void {}"); // #10342 + check("auto f() -> void {}\n"); // #10342 ASSERT_EQUALS("", errout_str()); check("struct S1 {\n" // #7433 @@ -1764,36 +1764,36 @@ class TestFunctions : public TestFixture { errout_str()); // #11171 - check("std::enable_if_t f() {}"); + check("std::enable_if_t f() {}\n"); ASSERT_EQUALS("", errout_str()); - check("std::enable_if_t f() {}"); + check("std::enable_if_t f() {}\n"); ASSERT_EQUALS( "[test.cpp:1:51]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); - check("template std::enable_if_t{}, int> f(T) {}"); + check("template std::enable_if_t{}, int> f(T) {}\n"); ASSERT_EQUALS( "[test.cpp:1:71]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); - check("template std::enable_if_t{}> f(T) {}"); + check("template std::enable_if_t{}> f(T) {}\n"); ASSERT_EQUALS("", errout_str()); - check("typename std::enable_if::type f() {}"); + check("typename std::enable_if::type f() {}\n"); ASSERT_EQUALS("", errout_str()); - check("typename std::enable_if::type f() {}"); + check("typename std::enable_if::type f() {}\n"); ASSERT_EQUALS( "[test.cpp:1:64]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); - check("template typename std::enable_if{}, int>::type f(T) {}"); + check("template typename std::enable_if{}, int>::type f(T) {}\n"); ASSERT_EQUALS( "[test.cpp:1:84]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); - check("template typename std::enable_if{}>::type f(T) {}"); + check("template typename std::enable_if{}>::type f(T) {}\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -1954,35 +1954,35 @@ class TestFunctions : public TestFixture { // NRVO check void returnLocalStdMove1() { - check("struct A{}; A f() { A var; return std::move(var); }"); + check("struct A{}; A f() { A var; return std::move(var); }\n"); ASSERT_EQUALS("[test.cpp:1:45]: (performance) Using std::move for returning object by-value from function will affect copy elision optimization." " More: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-return-move-local [returnStdMoveLocal]\n", errout_str()); } // RVO, C++03 ctor style void returnLocalStdMove2() { - check("struct A{}; A f() { return std::move( A() ); }"); + check("struct A{}; A f() { return std::move( A() ); }\n"); ASSERT_EQUALS("[test.cpp:1:40]: (performance) Using std::move for returning object by-value from function will affect copy elision optimization." " More: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-return-move-local [returnStdMoveLocal]\n", errout_str()); } // RVO, new ctor style void returnLocalStdMove3() { - check("struct A{}; A f() { return std::move(A{}); }"); + check("struct A{}; A f() { return std::move(A{}); }\n"); ASSERT_EQUALS("[test.cpp:1:39]: (performance) Using std::move for returning object by-value from function will affect copy elision optimization." " More: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-return-move-local [returnStdMoveLocal]\n", errout_str()); } // Function argument void returnLocalStdMove4() { - check("struct A{}; A f(A a) { return std::move(A{}); }"); + check("struct A{}; A f(A a) { return std::move(A{}); }\n"); ASSERT_EQUALS("[test.cpp:1:42]: (performance) Using std::move for returning object by-value from function will affect copy elision optimization." " More: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-return-move-local [returnStdMoveLocal]\n", errout_str()); } void returnLocalStdMove5() { check("struct A{} a; A f1() { return std::move(a); }\n" - "A f2() { volatile A var; return std::move(var); }"); + "A f2() { volatile A var; return std::move(var); }\n"); ASSERT_EQUALS("", errout_str()); check("struct S { std::string msg{ \"abc\" }; };\n" @@ -2009,14 +2009,14 @@ class TestFunctions : public TestFixture { " int *a;\n" " a = malloc( -10 );\n" " free(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (error) Invalid malloc() argument nr 1. The value is -10 but the valid values are '0:'. [invalidFunctionArg]\n", errout_str()); check("void f() {\n" " int *a;\n" " a = alloca( -10 );\n" " free(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8]: (warning) Obsolete function 'alloca' called. [allocaCalled]\n" "[test.cpp:3:17]: (error) Invalid alloca() argument nr 1. The value is -10 but the valid values are '0:'. [invalidFunctionArg]\n", errout_str()); } @@ -2027,12 +2027,12 @@ class TestFunctions : public TestFixture { check("void f() {\n" " lib_func();" - "}", s); + "}\n", s); ASSERT_EQUALS("[test.cpp:2:5]: (information) --check-library: There is no matching configuration for function lib_func() [checkLibraryFunction]\n", errout_str()); check("void f(void* v) {\n" " lib_func(v);" - "}", s); + "}\n", s); ASSERT_EQUALS("[test.cpp:2:5]: (information) --check-library: There is no matching configuration for function lib_func() [checkLibraryFunction]\n", errout_str()); // #10105 @@ -2048,7 +2048,7 @@ class TestFunctions : public TestFixture { "\n" " void testFunctionReturnType() {\n" " }\n" - "};", s); + "};\n", s); ASSERT_EQUALS("", errout_str()); // #11183 @@ -2058,7 +2058,7 @@ class TestFunctions : public TestFixture { "\n" "void f() {\n" " cb(std::string(\"\"));\n" - "}", s); + "}\n", s); TODO_ASSERT_EQUALS("", "[test.cpp:6:5]: (information) --check-library: There is no matching configuration for function cb() [checkLibraryFunction]\n", errout_str()); // #7375 diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 7d91a013940..c798950b8e3 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -321,7 +321,7 @@ class TestGarbage : public TestFixture { void final_class_x() { - const char code[] = "class __declspec(dllexport) x final { };"; + const char code[] = "class __declspec(dllexport) x final { };\n"; SimpleTokenizer tokenizer(settings, *this); ASSERT(tokenizer.tokenize(code)); ASSERT_EQUALS("", errout_str()); @@ -329,18 +329,18 @@ class TestGarbage : public TestFixture { void wrong_syntax1() { { - const char code[] ="TR(kvmpio, PROTO(int rw), ARGS(rw), TP_(aa->rw;))"; + const char code[] ="TR(kvmpio, PROTO(int rw), ARGS(rw), TP_(aa->rw;))\n"; ASSERT_THROW_INTERNAL(checkCode(code), UNKNOWN_MACRO); ASSERT_EQUALS("", errout_str()); } { - const char code[] ="struct A { template struct { }; };"; + const char code[] ="struct A { template struct { }; };\n"; ASSERT_THROW_INTERNAL(checkCode(code), SYNTAX); } { - const char code[] ="enum ABC { A,B, typedef enum { C } };"; + const char code[] ="enum ABC { A,B, typedef enum { C } };\n"; ASSERT_THROW_INTERNAL(checkCode(code), SYNTAX); } } @@ -351,7 +351,7 @@ class TestGarbage : public TestFixture { " Y y;\n" "}\n" "\n" - "void G( template class (j) ) {}"; + "void G( template class (j) ) {}\n"; // don't segfault.. ASSERT_THROW_INTERNAL(checkCode(code), SYNTAX); @@ -366,7 +366,7 @@ class TestGarbage : public TestFixture { " for( #endif typedef typedef cb[N] )\n" " ca[N]; = cb[i]\n" " )\n" - "}"; + "}\n"; SimpleTokenizer tokenizer(settings, *this); try { @@ -380,25 +380,25 @@ class TestGarbage : public TestFixture { } void wrong_syntax4() { // #3618 - const char code[] = "typedef void (x) (int); return x&"; + const char code[] = "typedef void (x) (int); return x&\n"; ASSERT_THROW_INTERNAL(checkCode(code), SYNTAX); } void wrong_syntax_if_macro() { // #2518 #4171 - ASSERT_THROW_INTERNAL(checkCode("void f() { if MACRO(); }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() { if MACRO(); }\n"), SYNTAX); // #4668 - note there is no semicolon after MACRO() - ASSERT_THROW_INTERNAL(checkCode("void f() { if (x) MACRO() {} }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() { if (x) MACRO() {} }\n"), SYNTAX); // #4810 - note there is no semicolon after MACRO() - ASSERT_THROW_INTERNAL(checkCode("void f() { if (x) MACRO() else ; }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() { if (x) MACRO() else ; }\n"), SYNTAX); } void wrong_syntax_class_x_y() { // #3585 - const char code[] = "class x y { };"; + const char code[] = "class x y { };\n"; { SimpleTokenizer tokenizer(settings, *this, false); @@ -413,65 +413,65 @@ class TestGarbage : public TestFixture { } void wrong_syntax_anonymous_struct() { - ASSERT_THROW_INTERNAL(checkCode("struct { int x; } = {0};"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("struct { int x; } * = {0};"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("struct { int x; } = {0};\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("struct { int x; } * = {0};\n"), SYNTAX); } void syntax_case_default() { - ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case: z(); break;}}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case: z(); break;}}\n"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case;: z(); break;}}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case;: z(); break;}}\n"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case {}: z(); break;}}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case {}: z(); break;}}\n"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case 0?{1}:{2} : z(); break;}}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case 0?{1}:{2} : z(); break;}}\n"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case 0?1;:{2} : z(); break;}}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case 0?1;:{2} : z(); break;}}\n"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case 0?(1?{3:4}):2 : z(); break;}}"), AST); + ASSERT_THROW_INTERNAL(checkCode("void f() {switch (n) { case 0?(1?{3:4}):2 : z(); break;}}\n"), AST); //ticket #4234 - ASSERT_THROW_INTERNAL(checkCode("( ) { switch break ; { switch ( x ) { case } y break ; : } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( ) { switch break ; { switch ( x ) { case } y break ; : } }\n"), SYNTAX); //ticket #4267 - ASSERT_THROW_INTERNAL(checkCode("f ( ) { switch break; { switch ( x ) { case } case break; -6: ( ) ; } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("f ( ) { switch break; { switch ( x ) { case } case break; -6: ( ) ; } }\n"), SYNTAX); // Missing semicolon - ASSERT_THROW_INTERNAL(checkCode("void foo () { switch(0) case 0 : default : }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void foo () { switch(0) case 0 : default : }\n"), SYNTAX); } void garbageCode1() { - (void)checkCode("struct x foo_t; foo_t typedef y;"); + (void)checkCode("struct x foo_t; foo_t typedef y;\n"); } void garbageCode2() { //#4300 (segmentation fault) - TODO_ASSERT_THROW(checkCode("enum { D = 1 struct { } ; } s.b = D;"), InternalError); + TODO_ASSERT_THROW(checkCode("enum { D = 1 struct { } ; } s.b = D;\n"), InternalError); } void garbageCode3() { //#4849 (segmentation fault in Tokenizer::simplifyStructDecl (invalid code)) - TODO_ASSERT_THROW(checkCode("enum { D = 2 s ; struct y { x } ; } { s.a = C ; s.b = D ; }"), InternalError); + TODO_ASSERT_THROW(checkCode("enum { D = 2 s ; struct y { x } ; } { s.a = C ; s.b = D ; }\n"), InternalError); } void garbageCode4() { // #4887 - ASSERT_THROW_INTERNAL(checkCode("void f ( ) { = a ; if ( 1 ) if = ( 0 ) ; }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f ( ) { = a ; if ( 1 ) if = ( 0 ) ; }\n"), SYNTAX); } void garbageCode5() { // #5168 (segmentation fault) - ASSERT_THROW_INTERNAL(checkCode("( asm : ; void : );"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( asm : ; void : );\n"), SYNTAX); } void garbageCode6() { // #5214 - ASSERT_THROW_INTERNAL(checkCode("int b = ( 0 ? ? ) 1 : 0 ;"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("int a = int b = ( 0 ? ? ) 1 : 0 ;"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("int b = ( 0 ? ? ) 1 : 0 ;\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("int a = int b = ( 0 ? ? ) 1 : 0 ;\n"), SYNTAX); } void garbageCode7() { - ASSERT_THROW_INTERNAL(checkCode("1 (int j) { return return (c) * sizeof } y[1];"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("foo(Args&&...) fn void = { } auto template { { e = T::error }; };\n" "ScopedEnum1 se1; { enum class E : T { e = 0 = e ScopedEnum2 struct UnscopedEnum3 { T{ e = 4 }; };\n" "arr[(int) E::e]; }; UnscopedEnum3 e2 = f()\n" @@ -479,48 +479,48 @@ class TestGarbage : public TestFixture { "namespace UnscopedEnum { template struct UnscopedEnum1 { E{ e = T::error }; }; UnscopedEnum1 { enum E : { e = 0 }; };\n" "UnscopedEnum2 ue3; template struct UnscopedEnum3 { enum { }; }; int arr[E::e]; };\n" "UnscopedEnum3 namespace template int f() { enum E { e }; T::error }; return (int) E(); } int test1 int g() { enum E { e = E };\n" - "E::e; } int test2 = g(); }"), InternalError); + "E::e; } int test2 = g(); }\n"), InternalError); } void garbageCode9() { - TODO_ASSERT_THROW(checkCode("enum { e = { } } ( ) { { enum { } } } { e } "), InternalError); + TODO_ASSERT_THROW(checkCode("enum { e = { } } ( ) { { enum { } } } { e } \n"), InternalError); } void garbageCode10() { // #6127 - ASSERT_THROW_INTERNAL(checkCode("for( rl=reslist; rl!=NULL; rl=rl->next )"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("for( rl=reslist; rl!=NULL; rl=rl->next )\n"), SYNTAX); } void garbageCode12() { // do not crash - (void)checkCode("{ g; S (void) { struct } { } int &g; }"); + (void)checkCode("{ g; S (void) { struct } { } int &g; }\n"); ignore_errout(); // we do not care about the output } void garbageCode13() { // Ticket #2607 - crash - (void)checkCode("struct C {} {} x"); + (void)checkCode("struct C {} {} x\n"); } void garbageCode15() { // Ticket #5203 - ASSERT_THROW_INTERNAL(checkCode("int f ( int* r ) { { int s[2] ; f ( s ) ; if ( ) } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("int f ( int* r ) { { int s[2] ; f ( s ) ; if ( ) } }\n"), SYNTAX); } void garbageCode16() { // #6080 (segmentation fault) - (void)checkCode("{ } A() { delete }"); // #6080 + (void)checkCode("{ } A() { delete }\n"); // #6080 ignore_errout(); // we do not care about the output } void garbageCode17() { ASSERT_THROW_INTERNAL(checkCode("void h(int l) {\n" " while\n" // Don't crash (#3870) - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode18() { - ASSERT_THROW_INTERNAL(checkCode("switch(){case}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("switch(){case}\n"), SYNTAX); } void garbageCode20() { // #3953 (valgrind errors on garbage code) - ASSERT_EQUALS("void f ( 0 * ) ;", checkCode("void f ( 0 * ) ;")); + ASSERT_EQUALS("void f ( 0 * ) ;", checkCode("void f ( 0 * ) ;\n")); } void garbageCode21() { @@ -531,7 +531,7 @@ class TestGarbage : public TestFixture { " x;\n" " int a, a2, a2*x; if () ;\n" " )\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode22() { @@ -539,7 +539,7 @@ class TestGarbage : public TestFixture { ASSERT_THROW_INTERNAL(checkCode("int f()\n" "{\n" " return if\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode23() { @@ -547,7 +547,7 @@ class TestGarbage : public TestFixture { ASSERT_THROW_INTERNAL_EQUALS(checkCode("{\n" " if (1) = x\n" " else abort s[2]\n" - "}"), + "}\n"), SYNTAX, "syntax error"); } @@ -570,7 +570,7 @@ class TestGarbage : public TestFixture { " switch ( x ) {\n" " case struct Tree : break;\n" " }\n" - "}"), SYNTAX); + "}\n"), SYNTAX); ignore_errout(); // we do not care about the output } @@ -582,13 +582,13 @@ class TestGarbage : public TestFixture { " case 0:\n" " return;\n" " }\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode27() { ASSERT_THROW_INTERNAL(checkCode("int f() {\n" " return if\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode28() { // #5702 (segmentation fault) @@ -596,7 +596,7 @@ class TestGarbage : public TestFixture { (void)checkCode("struct R1 {\n" " int a;\n" " R1 () : a { }\n" - "};"); + "};\n"); ignore_errout(); // we do not care about the output } @@ -604,16 +604,16 @@ class TestGarbage : public TestFixture { // simply survive - a syntax error would be even better (#5867) (void)checkCode("void f(int x) {\n" " x = 42\n" - "}"); + "}\n"); ignore_errout(); // we do not care about the output } void garbageCode31() { - ASSERT_THROW_INTERNAL(checkCode("typedef struct{}x[([],)]typedef e y;(y,x 0){}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("typedef struct{}x[([],)]typedef e y;(y,x 0){}\n"), SYNTAX); } void garbageCode33() { // #6613 (segmentation fault) - (void)checkCode("main(()B{});"); + (void)checkCode("main(()B{});\n"); } // Bug #6626 crash: Token::astOperand2() const ( do while ) @@ -621,13 +621,13 @@ class TestGarbage : public TestFixture { const char code[] = "void foo(void) {\n" " do\n" " while (0);\n" - "}"; + "}\n"; ASSERT_THROW_INTERNAL(checkCode(code), SYNTAX); } void garbageCode35() { // ticket #2604 segmentation fault - ASSERT_THROW_INTERNAL(checkCode("sizeof <= A"), AST); + ASSERT_THROW_INTERNAL(checkCode("sizeof <= A\n"), AST); } void garbageCode36() { // #6334 @@ -641,311 +641,311 @@ class TestGarbage : public TestFixture { void garbageCode37() { // #5166 segmentation fault (invalid code) in lib/checkother.cpp:329 ( void * f { } void b ( ) { * f } ) - (void)checkCode("void * f { } void b ( ) { * f }"); + (void)checkCode("void * f { } void b ( ) { * f }\n"); ignore_errout(); // we do not care about the output } void garbageCode38() { // Ticket #6666 (segmentation fault) - (void)checkCode("{ f2 { } } void f3 () { delete[] } { }"); + (void)checkCode("{ f2 { } } void f3 () { delete[] } { }\n"); ignore_errout(); // we do not care about the output } void garbageCode40() { // #6620 (segmentation fault) - (void)checkCode("{ ( ) () { virtual } ; { } E } A { : { } ( ) } * const ( ) const { }"); + (void)checkCode("{ ( ) () { virtual } ; { } E } A { : { } ( ) } * const ( ) const { }\n"); // test doesn't seem to work on any platform: ASSERT_THROW(checkCode("{ ( ) () { virtual } ; { } E } A { : { } ( ) } * const ( ) const { }", "test.c"), InternalError); } void garbageCode41() { // #6685 (segmentation fault) - (void)checkCode(" { } { return } *malloc(__SIZE_TYPE__ size); *memcpy(void n); static * const () { memcpy (*slot, 3); } { (); } { }"); + (void)checkCode(" { } { return } *malloc(__SIZE_TYPE__ size); *memcpy(void n); static * const () { memcpy (*slot, 3); } { (); } { }\n"); } void garbageCode42() { // #5760 (segmentation fault) - (void)checkCode("{ } * const ( ) { }"); + (void)checkCode("{ } * const ( ) { }\n"); } void garbageCode43() { // #6703 (segmentation fault) - (void)checkCode("int { }; struct A a = { }"); + (void)checkCode("int { }; struct A a = { }\n"); } void garbageCode44() { // #6704 - ASSERT_THROW_INTERNAL(checkCode("{ { }; }; { class A : }; public typedef b;"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ { }; }; { class A : }; public typedef b;\n"), SYNTAX); } void garbageCode45() { // #6608 - ASSERT_THROW_INTERNAL(checkCode("struct true template < > { = } > struct Types \"s\" ; static_assert < int > ;"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("struct true template < > { = } > struct Types \"s\" ; static_assert < int > ;\n"), SYNTAX); } void garbageCode46() { // #6705 (segmentation fault) - (void)checkCode(" { bar(char *x); void foo (int ...) { struct } va_list ap; va_start(ap, size); va_arg(ap, (d)); }"); + (void)checkCode(" { bar(char *x); void foo (int ...) { struct } va_list ap; va_start(ap, size); va_arg(ap, (d)); }\n"); ignore_errout(); // we do not care about the output } void garbageCode47() { // #6706 (segmentation fault) - (void)checkCode(" { { }; }; * new private: B: B;"); + (void)checkCode(" { { }; }; * new private: B: B;\n"); } void garbageCode48() { // #6712 (segmentation fault) - ASSERT_THROW_INTERNAL(checkCode(" { d\" ) d ...\" } int main ( ) { ( ) catch ( A a ) { { } catch ( ) \"\" } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode(" { d\" ) d ...\" } int main ( ) { ( ) catch ( A a ) { { } catch ( ) \"\" } }\n"), SYNTAX); } void garbageCode49() { // #6715 - ASSERT_THROW_INTERNAL(checkCode(" ( ( ) ) { } ( { ( __builtin_va_arg_pack ( ) ) ; } ) { ( int { ( ) ( ( ) ) } ( ) { } ( ) ) += ( ) }"), AST); + ASSERT_THROW_INTERNAL(checkCode(" ( ( ) ) { } ( { ( __builtin_va_arg_pack ( ) ) ; } ) { ( int { ( ) ( ( ) ) } ( ) { } ( ) ) += ( ) }\n"), AST); } void garbageCode51() { // #6719 - ASSERT_THROW_INTERNAL(checkCode(" (const \"C\" ...); struct base { int f2; base (int arg1, int arg2); }; global_base(0x55, 0xff); { ((global_base.f1 0x55) (global_base.f2 0xff)) { } } base::base(int arg1, int arg2) { f2 = }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode(" (const \"C\" ...); struct base { int f2; base (int arg1, int arg2); }; global_base(0x55, 0xff); { ((global_base.f1 0x55) (global_base.f2 0xff)) { } } base::base(int arg1, int arg2) { f2 = }\n"), SYNTAX); } void garbageCode53() { // #6721 - ASSERT_THROW_INTERNAL(checkCode("{ { } }; void foo (struct int i) { x->b[i] = = }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ { } }; void foo (struct int i) { x->b[i] = = }\n"), SYNTAX); } void garbageCode54() { // #6722 - ASSERT_THROW_INTERNAL(checkCode("{ typedef long ((pf) p) (); }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ typedef long ((pf) p) (); }\n"), SYNTAX); } void garbageCode55() { // #6724 - ASSERT_THROW_INTERNAL(checkCode("() __attribute__((constructor)); { } { }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("() __attribute__((constructor)); { } { }\n"), SYNTAX); } void garbageCode56() { // #6713 - ASSERT_THROW_INTERNAL(checkCode("void foo() { int a = 0; int b = ???; }"), AST); + ASSERT_THROW_INTERNAL(checkCode("void foo() { int a = 0; int b = ???; }\n"), AST); } void garbageCode57() { // #6731 - ASSERT_THROW_INTERNAL(checkCode("{ } if () try { } catch (...) B::~B { }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ } if () try { } catch (...) B::~B { }\n"), SYNTAX); } void garbageCode58() { // #6732, #6762 - ASSERT_THROW_INTERNAL(checkCode("{ }> {= ~A()^{} }P { }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("{= ~A()^{} }P { } { }> is"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ }> {= ~A()^{} }P { }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{= ~A()^{} }P { } { }> is\n"), SYNTAX); } void garbageCode59() { // #6735 - ASSERT_THROW_INTERNAL(checkCode("{ { } }; char font8x8[256][8]"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ { } }; char font8x8[256][8]\n"), SYNTAX); } void garbageCode60() { // #6736 - ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef int int_array[]; int_array &right ="), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef int int_array[]; int_array &right =\n"), SYNTAX); } void garbageCode61() { // #6737 - ASSERT_THROW_INTERNAL(checkCode("{ (const U&) }; { }; { }; struct U : virtual public"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ (const U&) }; { }; { }; struct U : virtual public\n"), SYNTAX); } void garbageCode63() { // #6739 - ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef int u_array[]; typedef u_array &u_array_ref; (u_array_ref arg) { } u_array_ref u_array_ref_gbl_obj0"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef int u_array[]; typedef u_array &u_array_ref; (u_array_ref arg) { } u_array_ref u_array_ref_gbl_obj0\n"), SYNTAX); } void garbageCode64() { // #6740 - ASSERT_THROW_INTERNAL(checkCode("{ } foo(void (*bar)(void))"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ } foo(void (*bar)(void))\n"), SYNTAX); } void garbageCode65() { // #6741 (segmentation fault) // TODO write some syntax error - (void)checkCode("{ } { } typedef int u_array[]; typedef u_array &u_array_ref; (u_array_ref arg) { } u_array_ref"); + (void)checkCode("{ } { } typedef int u_array[]; typedef u_array &u_array_ref; (u_array_ref arg) { } u_array_ref\n"); } void garbageCode66() { // #6742 - ASSERT_THROW_INTERNAL(checkCode("{ { } }; { { } }; { }; class bar : public virtual"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ { } }; { { } }; { }; class bar : public virtual\n"), SYNTAX); } void garbageCode68() { // #6745 (segmentation fault) - (void)checkCode("(int a[3]); typedef void (*fp) (void); fp"); + (void)checkCode("(int a[3]); typedef void (*fp) (void); fp\n"); } void garbageCode69() { // #6746 - ASSERT_THROW_INTERNAL(checkCode("{ (make_mess, aux); } typedef void F(void); aux(void (*x)()) { } (void (*y)()) { } F*"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ (make_mess, aux); } typedef void F(void); aux(void (*x)()) { } (void (*y)()) { } F*\n"), SYNTAX); } void garbageCode70() { // #6747 - ASSERT_THROW_INTERNAL(checkCode("{ } __attribute__((constructor)) void"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ } __attribute__((constructor)) void\n"), SYNTAX); } void garbageCode71() { // #6748 - ASSERT_THROW_INTERNAL(checkCode("( ) { } typedef void noattr_t ( ) ; noattr_t __attribute__ ( )"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( ) { } typedef void noattr_t ( ) ; noattr_t __attribute__ ( )\n"), SYNTAX); } void garbageCode72() { // #6749 - ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef void voidfn(void); = } } unsigned *d = (b b--) --*d"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void foo (int **p) { { { };>= } } unsigned *d = (b b--) --*d\n"), SYNTAX); } void garbageCode78() { // #6756 - ASSERT_THROW_INTERNAL(checkCode("( ) { [ ] } ( ) { } const_array_of_int ( ) { } typedef int A [ ] [ ] ; A a = { { } { } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( ) { [ ] } ( ) { } const_array_of_int ( ) { } typedef int A [ ] [ ] ; A a = { { } { } }\n"), SYNTAX); ignore_errout(); // we do not care about the output } void garbageCode79() { // #6757 - ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef void ( func_type ) ( ) ; func_type & ( )"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef void ( func_type ) ( ) ; func_type & ( )\n"), SYNTAX); } void garbageCode80() { // #6759 - ASSERT_THROW_INTERNAL(checkCode("( ) { ; ( ) ; ( * ) [ ] ; [ ] = ( ( ) ( ) h ) ! ( ( ) ) } { ; } { } head heads [ ] = ; = & heads [ 2 ]"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( ) { ; ( ) ; ( * ) [ ] ; [ ] = ( ( ) ( ) h ) ! ( ( ) ) } { ; } { } head heads [ ] = ; = & heads [ 2 ]\n"), SYNTAX); } void garbageCode81() { // #6760 - ASSERT_THROW_INTERNAL(checkCode("{ } [ ] { ( ) } { } typedef void ( *fptr1 ) ( ) const"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ } [ ] { ( ) } { } typedef void ( *fptr1 ) ( ) const\n"), SYNTAX); } void garbageCode82() { // #6761 - ASSERT_THROW_INTERNAL(checkCode("p(\"Hello \" 14) _yn(const size_t) typedef bool pfunk (*pfunk)(const size_t)"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("p(\"Hello \" 14) _yn(const size_t) typedef bool pfunk (*pfunk)(const size_t)\n"), SYNTAX); } void garbageCode83() { // #6771 - ASSERT_THROW_INTERNAL(checkCode("namespace A { class } class A { friend C ; } { } ;"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("namespace A { class } class A { friend C ; } { } ;\n"), SYNTAX); } void garbageCode84() { // #6780 - ASSERT_THROW_INTERNAL(checkCode("int main ( [ ] ) { " " [ ] ; int i = 0 ; do { } ; } ( [ ] ) { }"), SYNTAX); // do not crash + ASSERT_THROW_INTERNAL(checkCode("int main ( [ ] ) { " " [ ] ; int i = 0 ; do { } ; } ( [ ] ) { }\n"), SYNTAX); // do not crash } void garbageCode85() { // #6784 (segmentation fault) - (void)checkCode("{ } { } typedef void ( *VoidFunc() ) ( ) ; VoidFunc"); // do not crash + (void)checkCode("{ } { } typedef void ( *VoidFunc() ) ( ) ; VoidFunc\n"); // do not crash } void garbageCode86() { // #6785 - ASSERT_THROW_INTERNAL(checkCode("{ } typedef char ( *( X ) ( void) , char ) ;"), SYNTAX); // do not crash + ASSERT_THROW_INTERNAL(checkCode("{ } typedef char ( *( X ) ( void) , char ) ;\n"), SYNTAX); // do not crash } void garbageCode87() { // #6788 - ASSERT_THROW_INTERNAL(checkCode("((X (128))) (int a) { v[ = {} (x 42) a] += }"), SYNTAX); // do not crash + ASSERT_THROW_INTERNAL(checkCode("((X (128))) (int a) { v[ = {} (x 42) a] += }\n"), SYNTAX); // do not crash } void garbageCode88() { // #6786 - ASSERT_THROW_INTERNAL(checkCode("( ) { ( 0 ) { ( ) } } g ( ) { i( ( false ?) ( ) : 1 ) ; } ;"), SYNTAX); // do not crash + ASSERT_THROW_INTERNAL(checkCode("( ) { ( 0 ) { ( ) } } g ( ) { i( ( false ?) ( ) : 1 ) ; } ;\n"), SYNTAX); // do not crash } void garbageCode90() { // #6790 - ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef int u_array [[ ] ; typedef u_array & u_array_ref] ( ) { } u_array_ref_gbl_obj0"), SYNTAX); // do not crash + ASSERT_THROW_INTERNAL(checkCode("{ } { } typedef int u_array [[ ] ; typedef u_array & u_array_ref] ( ) { } u_array_ref_gbl_obj0\n"), SYNTAX); // do not crash } void garbageCode91() { // #6791 - ASSERT_THROW_INTERNAL(checkCode("typedef __attribute__((vector_size (16))) { return[ (v2df){ } ;] }"), SYNTAX); // throw syntax error + ASSERT_THROW_INTERNAL(checkCode("typedef __attribute__((vector_size (16))) { return[ (v2df){ } ;] }\n"), SYNTAX); // throw syntax error } void garbageCode92() { // #6792 - ASSERT_THROW_INTERNAL(checkCode("template < typename _Tp ( ( ) ; _Tp ) , decltype > { } { ( ) ( ) }"), SYNTAX); // do not crash + ASSERT_THROW_INTERNAL(checkCode("template < typename _Tp ( ( ) ; _Tp ) , decltype > { } { ( ) ( ) }\n"), SYNTAX); // do not crash } void garbageCode94() { // #6803 //checkCode("typedef long __m256i __attribute__ ( ( ( ) ) )[ ; ( ) { } typedef __m256i __attribute__ ( ( ( ) ) ) < ] ( ) { ; }"); - ASSERT_THROW_INTERNAL(checkCode("typedef long __m256i __attribute__ ( ( ( ) ) )[ ; ( ) { } typedef __m256i __attribute__ ( ( ( ) ) ) < ] ( ) { ; }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("typedef long __m256i __attribute__ ( ( ( ) ) )[ ; ( ) { } typedef __m256i __attribute__ ( ( ( ) ) ) < ] ( ) { ; }\n"), SYNTAX); } void garbageCode95() { // #6804 - ASSERT_THROW_INTERNAL(checkCode("{ } x x ; { } h h [ ] ( ) ( ) { struct x ( x ) ; int __attribute__ ( ) f ( ) { h - > first = & x ; struct x * n = h - > first ; ( ) n > } }"), SYNTAX); // do not crash + ASSERT_THROW_INTERNAL(checkCode("{ } x x ; { } h h [ ] ( ) ( ) { struct x ( x ) ; int __attribute__ ( ) f ( ) { h - > first = & x ; struct x * n = h - > first ; ( ) n > } }\n"), SYNTAX); // do not crash } void garbageCode96() { // #6807 - ASSERT_THROW_INTERNAL(checkCode("typedef J J[ ; typedef ( ) ( ) { ; } typedef J J ;] ( ) ( J cx ) { n } ;"), SYNTAX); // throw syntax error + ASSERT_THROW_INTERNAL(checkCode("typedef J J[ ; typedef ( ) ( ) { ; } typedef J J ;] ( ) ( J cx ) { n } ;\n"), SYNTAX); // throw syntax error } void garbageCode97() { // #6808 - ASSERT_THROW_INTERNAL(checkCode("namespace A {> } class A{ { }} class A : T< ;"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("namespace A {> } class A{ { }} class A : T< ;\n"), SYNTAX); } void garbageCode98() { // #6838 ASSERT_THROW_INTERNAL(checkCode("for (cocon To::ta@Taaaaaforconst oken aaaaaaaaaaaa5Dl()\n" "const unsigned in;\n" - "fon *tok = f);.s(Token i = d-)L;"), SYNTAX); + "fon *tok = f);.s(Token i = d-)L;\n"), SYNTAX); } void garbageCode99() { // #6726 ASSERT_THROW_INTERNAL_EQUALS(checkCode("{ xs :: i(:) ! ! x/5 ! !\n" "i, :: a :: b integer, } foo2(x) :: j(:)\n" "b type(*), d(:), a x :: end d(..), foo end\n" - "foo4 b d(..), a a x type(*), b foo2 b"), SYNTAX, "syntax error"); + "foo4 b d(..), a a x type(*), b foo2 b\n"), SYNTAX, "syntax error"); } void garbageCode100() { // #6840 - ASSERT_THROW_INTERNAL(checkCode("( ) { ( i< ) } int foo ( ) { int i ; ( for ( i => 1 ) ; ) }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( ) { ( i< ) } int foo ( ) { int i ; ( for ( i => 1 ) ; ) }\n"), SYNTAX); } void garbageCode101() { // #6835 // Reported case - ASSERT_THROW_INTERNAL(checkCode("template < class , =( , int) X = 1 > struct A { } ( ) { = } [ { } ] ( ) { A < void > 0 }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("template < class , =( , int) X = 1 > struct A { } ( ) { = } [ { } ] ( ) { A < void > 0 }\n"), SYNTAX); // Reduced case - ASSERT_THROW_INTERNAL(checkCode("template < class =( , ) X = 1> struct A {}; A a;"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("template < class =( , ) X = 1> struct A {}; A a;\n"), SYNTAX); } void garbageCode102() { // #6846 (segmentation fault) - ASSERT_THROW_INTERNAL(checkCode("struct Object { ( ) ; Object & operator= ( Object ) { ( ) { } if ( this != & b ) } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("struct Object { ( ) ; Object & operator= ( Object ) { ( ) { } if ( this != & b ) } }\n"), SYNTAX); } void garbageCode103() { // #6824 - ASSERT_THROW_INTERNAL(checkCode("a f(r) int * r; { { int s[2]; [f(s); if () ] } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("a f(r) int * r; { { int s[2]; [f(s); if () ] } }\n"), SYNTAX); } void garbageCode104() { // #6847 - ASSERT_THROW_INTERNAL(checkCode("template < Types > struct S {> ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) } { ( )> >} { ( ) { } } ( ) { ( ) }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("template < Types > struct S {> ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) } { ( )> >} { ( ) { } } ( ) { ( ) }\n"), SYNTAX); } void garbageCode105() { // #6859 - ASSERT_THROW_INTERNAL(checkCode("void foo (int i) { int a , for (a 1; a( < 4; a++) if (a) (b b++) (b);) n++; }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void foo (int i) { int a , for (a 1; a( < 4; a++) if (a) (b b++) (b);) n++; }\n"), SYNTAX); } void garbageCode106() { // #6880 - ASSERT_THROW_INTERNAL(checkCode("[ ] typedef typedef b_array b_array_ref [ ; ] ( ) b_array_ref b_array_ref_gbl_obj0 { ; { b_array_ref b_array_ref_gbl_obj0 } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("[ ] typedef typedef b_array b_array_ref [ ; ] ( ) b_array_ref b_array_ref_gbl_obj0 { ; { b_array_ref b_array_ref_gbl_obj0 } }\n"), SYNTAX); } void garbageCode107() { // #6881 - TODO_ASSERT_THROW(checkCode("enum { val = 1{ }; { const} }; { } Bar { const int A = val const } ;"), InternalError); + TODO_ASSERT_THROW(checkCode("enum { val = 1{ }; { const} }; { } Bar { const int A = val const } ;\n"), InternalError); } void garbageCode108() { // #6895 "segmentation fault (invalid code) in CheckCondition::isOppositeCond" - ASSERT_THROW_INTERNAL(checkCode("A( ) { } bool f( ) { ( ) F; ( ) { ( == ) if ( !=< || ( !A( ) && r[2] ) ) ( !A( ) ) ( ) } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("A( ) { } bool f( ) { ( ) F; ( ) { ( == ) if ( !=< || ( !A( ) && r[2] ) ) ( !A( ) ) ( ) } }\n"), SYNTAX); } void garbageCode109() { // #6900 "segmentation fault (invalid code) in CheckStl::runSimplifiedChecks" - (void)checkCode("( *const<> (( ) ) { } ( *const ( ) ( ) ) { } ( * const<> ( size_t )) ) { } ( * const ( ) ( ) ) { }"); + (void)checkCode("( *const<> (( ) ) { } ( *const ( ) ( ) ) { } ( * const<> ( size_t )) ) { } ( * const ( ) ( ) ) { }\n"); } void garbageCode110() { // #6902 "segmentation fault (invalid code) in CheckStl::string_c_str" - ASSERT_THROW_INTERNAL(checkCode("( *const<> ( size_t ) ; foo ) { } * ( *const ( size_t ) ( ) ;> foo )< { }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( *const<> ( size_t ) ; foo ) { } * ( *const ( size_t ) ( ) ;> foo )< { }\n"), SYNTAX); } void garbageCode111() { // #6907 - TODO_ASSERT_THROW(checkCode("enum { FOO = 1( ,) } {{ FOO }} ;"), InternalError); + TODO_ASSERT_THROW(checkCode("enum { FOO = 1( ,) } {{ FOO }} ;\n"), InternalError); } void garbageCode112() { // #6909 - TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ) } {{ }}>> enum { FOO< = ( ) } { { } } ;"), InternalError); + TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ) } {{ }}>> enum { FOO< = ( ) } { { } } ;\n"), InternalError); } void garbageCode114() { // #2118 ASSERT_NO_THROW(checkCode("Q_GLOBAL_STATIC_WITH_INITIALIZER(Qt4NodeStaticData, qt4NodeStaticData, {\n" " for (unsigned i = 0 ; i < count; i++) {\n" " }\n" - "});")); + "});\n")); } void garbageCode115() { // #5506 - ASSERT_THROW_INTERNAL(checkCode("A template < int { int = -1 ; } template < int N > struct B { int [ A < N > :: zero ] ; } ; B < 0 > b ;"), UNKNOWN_MACRO); + ASSERT_THROW_INTERNAL(checkCode("A template < int { int = -1 ; } template < int N > struct B { int [ A < N > :: zero ] ; } ; B < 0 > b ;\n"), UNKNOWN_MACRO); } void garbageCode116() { // #5356 - ASSERT_THROW_INTERNAL(checkCode("struct template struct B { }; B < 0 > b;"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("struct template struct B { }; B < 0 > b;\n"), SYNTAX); } void garbageCode117() { // #6121 TODO_ASSERT_THROW(checkCode("enum E { f = {} };\n" - "int a = f;"), InternalError); + "int a = f;\n"), InternalError); } void garbageCode118() { // #5600 - missing include causes invalid enum @@ -955,32 +955,32 @@ class TestGarbage : public TestFixture { "};\n" "struct bytecode {};\n" "jv jq_next() { opcode = ((opcode) +NUM_OPCODES);\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode119() { // #5598 (segmentation fault) - (void)checkCode("{ { void foo() { struct }; template struct S { Used x; void bar() } auto f = [this] { }; } };"); + (void)checkCode("{ { void foo() { struct }; template struct S { Used x; void bar() } auto f = [this] { }; } };\n"); ignore_errout(); // we do not care about the output } void garbageCode120() { // #4927 (segmentation fault) (void)checkCode("int main() {\n" " return 0\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void garbageCode121() { // #2585 ASSERT_THROW_INTERNAL(checkCode("abcdef?" "?<" "123456?" "?>" - "+?" "?="), SYNTAX); + "+?" "?=\n"), SYNTAX); } void garbageCode122() { // #6303 (segmentation fault) (void)checkCode("void foo() {\n" "char *a = malloc(10);\n" "a[0]\n" - "}"); + "}\n"); ignore_errout(); // we do not care about the output } @@ -989,18 +989,18 @@ class TestGarbage : public TestFixture { " class C {\n" " C tpl_mem(T *) { return }\n" " };\n" - "}"); + "}\n"); ignore_errout(); // we do not care about the output } void garbageCode125() { - ASSERT_THROW_INTERNAL(checkCode("{ T struct B : T valueA_AA ; } T : [ T > ( ) { B } template < T > struct A < > : ] { ( ) { return valueA_AC struct { : } } b A < int > AC ( ) a_aa.M ; ( ) ( ) }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("template < Types > struct S :{ ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) }"), + ASSERT_THROW_INTERNAL(checkCode("{ T struct B : T valueA_AA ; } T : [ T > ( ) { B } template < T > struct A < > : ] { ( ) { return valueA_AC struct { : } } b A < int > AC ( ) a_aa.M ; ( ) ( ) }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("template < Types > struct S :{ ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) }\n"), SYNTAX); } void garbageCode126() { - ASSERT_THROW_INTERNAL(checkCode("{ } float __ieee754_sinhf ( float x ) { float t , , do { gf_u ( jx ) { } ( 0 ) return ; ( ) { } t } ( 0x42b17180 ) { } }"), + ASSERT_THROW_INTERNAL(checkCode("{ } float __ieee754_sinhf ( float x ) { float t , , do { gf_u ( jx ) { } ( 0 ) return ; ( ) { } t } ( 0x42b17180 ) { } }\n"), SYNTAX); } @@ -1013,38 +1013,38 @@ class TestGarbage : public TestFixture { " ~A() { printf(\"A d'tor\\n\"); }\n" "};\n" " const A& foo(const A& arg) { return arg; }\n" - " foo(A(12)).Var"); + " foo(A(12)).Var\n"); ignore_errout(); // we do not care about the output } void garbageCode128() { - TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ) } {{ }} enum {{ FOO << = } ( ) } {{ }} ;"), + TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ) } {{ }} enum {{ FOO << = } ( ) } {{ }} ;\n"), InternalError); } void garbageCode129() { - ASSERT_THROW_INTERNAL(checkCode("operator - ( { } typedef typename x ; ( ) ) { ( { { ( ( ) ) } ( { } ) } ) }"), + ASSERT_THROW_INTERNAL(checkCode("operator - ( { } typedef typename x ; ( ) ) { ( { { ( ( ) ) } ( { } ) } ) }\n"), SYNTAX); } void garbageCode130() { - TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ){ } { { } } { { FOO} = } ( ) } { { } } enumL\" ( enumL\" { { FOO } ( ) } { { } } ;"), + TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ){ } { { } } { { FOO} = } ( ) } { { } } enumL\" ( enumL\" { { FOO } ( ) } { { } } ;\n"), InternalError); } void garbageCode131() { - ASSERT_THROW_INTERNAL(checkCode("( void ) { ( ) } ( ) / { ( ) }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( void ) { ( ) } ( ) / { ( ) }\n"), SYNTAX); // actually the invalid code should trigger an syntax error... } void garbageCode132() { // #7022 - ASSERT_THROW_INTERNAL(checkCode("() () { } { () () ({}) i() } void i(void(*ptr) ()) { ptr(!) () }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("() () { } { () () ({}) i() } void i(void(*ptr) ()) { ptr(!) () }\n"), SYNTAX); } void garbageCode133() { - ASSERT_THROW_INTERNAL(checkCode("void f() {{}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() {{}\n"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f()) {}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f()) {}\n"), SYNTAX); ASSERT_THROW_INTERNAL(checkCode("void f()\n" "{\n" @@ -1095,32 +1095,32 @@ class TestGarbage : public TestFixture { void garbageCode134() { // Ticket #5605, #5759, #5762, #5774, #5823, #6059 - ASSERT_THROW_INTERNAL(checkCode("foo() template struct tuple Args> tuple { } main() { foo(); }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("() template < T = typename = x > struct a {} { f () }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("template < T = typename = > struct a { f }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("foo() template struct tuple Args> tuple { } main() { foo(); }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("() template < T = typename = x > struct a {} { f () }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("template < T = typename = > struct a { f }\n"), SYNTAX); (void)checkCode("struct S { int i, j; }; " "template struct X {}; " "X<&S::i, int> x = X<&S::i, int>(); " - "X<&S::j, int> y = X<&S::j, int>();"); + "X<&S::j, int> y = X<&S::j, int>();\n"); ignore_errout(); // we are not interested in the output (void)checkCode("template struct A {}; " "template <> struct A {}; " - "void foo(const void* f = 0) {}"); + "void foo(const void* f = 0) {}\n"); (void)checkCode("template struct A { " " static const int s = 0; " "}; " - "A a;"); + "A a;\n"); (void)checkCode("template class A {}; " "template > class B {}; " "template > class C { " " C() : _a(0), _b(0) {} " " int _a, _b; " - "};"); + "};\n"); (void)checkCode("template struct A { " " static int i; " "}; " - "void f() { A::i = 0; }"); + "void f() { A::i = 0; }\n"); ignore_errout(); // we are not interested in the output } @@ -1129,17 +1129,17 @@ class TestGarbage : public TestFixture { " return a >> extern\n" "}\n" "long a = 1 ;\n" - "long b = 2 ;"); + "long b = 2 ;\n"); ignore_errout(); // we are not interested in the output } void garbageCode136() { // #7033 - ASSERT_THROW_INTERNAL(checkCode("{ } () { void f() { node_t * n; for (; -n) {} } } { }"), + ASSERT_THROW_INTERNAL(checkCode("{ } () { void f() { node_t * n; for (; -n) {} } } { }\n"), SYNTAX); } void garbageCode137() { // #7034 - ASSERT_THROW_INTERNAL(checkCode("\" \" typedef signed char f; \" \"; void a() { f * s = () &[]; (; ) (; ) }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("\" \" typedef signed char f; \" \"; void a() { f * s = () &[]; (; ) (; ) }\n"), SYNTAX); } void garbageCode138() { // #6660 (segmentation fault) @@ -1151,7 +1151,7 @@ class TestGarbage : public TestFixture { " {};\n" " } halo;\n" "}\n" - "CS_PLUGIN_NAMESPACE_END(csparser)"); + "CS_PLUGIN_NAMESPACE_END(csparser)\n"); ignore_errout(); // we are not interested in the output } @@ -1160,19 +1160,19 @@ class TestGarbage : public TestFixture { " de_ctrl = (nDirection == RIGHT_TO_LEFT) ?\n" " ( (0 & ~(((1 << (1 - (0 ? DE_CONTROL_DIRECTION))) - 1) << (0 ? DE_CONTROL_DIRECTION))) )\n" " : 42;\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode140() { // #7035 - ASSERT_THROW_INTERNAL(checkCode("int foo(int align) { int off(= 0 % align; return off) ? \\ align - off : 0; \\ }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("int foo(int align) { int off(= 0 % align; return off) ? \\ align - off : 0; \\ }\n"), SYNTAX); } void garbageCode141() { // #7043 - TODO_ASSERT_THROW(checkCode("enum { X = << { X } } enum { X = X } = X ;"), InternalError); + TODO_ASSERT_THROW(checkCode("enum { X = << { X } } enum { X = X } = X ;\n"), InternalError); } void garbageCode142() { // #7050 - ASSERT_THROW_INTERNAL(checkCode("{ } ( ) { void mapGraphs ( ) { node_t * n ; for (!oid n ) { } } } { }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ } ( ) { void mapGraphs ( ) { node_t * n ; for (!oid n ) { } } } { }\n"), SYNTAX); } void garbageCode143() { // #6922 @@ -1186,18 +1186,18 @@ class TestGarbage : public TestFixture { " VGAwCR(0x64,0x?? );\n" " }\n" " }\n" - "}"), AST); + "}\n"), AST); } void garbageCode144() { // #6865 - ASSERT_THROW_INTERNAL(checkCode("template < typename > struct A { } ; template < typename > struct A < INVALID > : A < int[ > { }] ;"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("template < typename > struct A { } ; template < typename > struct A < INVALID > : A < int[ > { }] ;\n"), SYNTAX); } void garbageCode146() { // #7081 ASSERT_THROW_INTERNAL(checkCode("void foo() {\n" " ? std::cout << pow((, 1) << std::endl;\n" " double ( ); }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() { x = , * [ | + 0xff | > 0xff]; }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() { x = , | 0xff , 0.1 < ; }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() { x = [ 1 || ] ; }"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f1() { x = name6 1 || ? name3 [ ( 1 || +) ] ; }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() { x= name2 & name3 name2 = | 0.1 , | 0.1 , | 0.1 name4 <= >( ); }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() { x = , * [ | + 0xff | > 0xff]; }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() { x = , | 0xff , 0.1 < ; }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() { x = [ 1 || ] ; }\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f1() { x = name6 1 || ? name3 [ ( 1 || +) ] ; }\n"), SYNTAX); } void garbageValueFlow() { @@ -1306,46 +1306,46 @@ class TestGarbage : public TestFixture { } { // 6122 survive garbage code - const char code[] = "; { int i ; for ( i = 0 ; = 123 ; ) - ; }"; + const char code[] = "; { int i ; for ( i = 0 ; = 123 ; ) - ; }\n"; ASSERT_THROW_INTERNAL(checkCode(code), SYNTAX); } { - const char code[] = "void f1() { for (int n = 0 n < 10 n++); }"; + const char code[] = "void f1() { for (int n = 0 n < 10 n++); }\n"; ASSERT_THROW_INTERNAL(checkCode(code), SYNTAX); } } void garbageSymbolDatabase() { - (void)checkCode("void f( { u = 1 ; } ) { }"); + (void)checkCode("void f( { u = 1 ; } ) { }\n"); - ASSERT_THROW_INTERNAL(checkCode("{ }; void namespace A::f; { g() { int } }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ }; void namespace A::f; { g() { int } }\n"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("class Foo {}; class Bar : public Foo"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("class Foo {}; class Bar : public Foo\n"), SYNTAX); // #5663 (segmentation fault) (void)checkCode("YY_DECL { switch (yy_act) {\n" " case 65: YY_BREAK\n" " case YY_STATE_EOF(block):\n" " yyterminate();\n" - "} }"); + "} }\n"); ignore_errout(); // we are not interested in the output } void garbageAST() { ASSERT_THROW_INTERNAL(checkCode("N 1024 float a[N], b[N + 3], c[N]; void N; (void) i;\n" "int #define for (i = avx_test i < c[i]; i++)\n" - "b[i + 3] = a[i] * {}"), SYNTAX); // Don't hang (#5787) + "b[i + 3] = a[i] * {}\n"), SYNTAX); // Don't hang (#5787) - (void)checkCode("START_SECTION([EXTRA](bool isValid(const String &filename)))"); // Don't crash (#5991) + (void)checkCode("START_SECTION([EXTRA](bool isValid(const String &filename)))\n"); // Don't crash (#5991) // #8352 ASSERT_THROW_INTERNAL(checkCode("else return % name5 name2 - =name1 return enum | { - name3 1 enum != >= 1 >= ++ { { || " - "{ return return { | { - name3 1 enum != >= 1 >= ++ { name6 | ; ++}}}}}}}"), UNKNOWN_MACRO); + "{ return return { | { - name3 1 enum != >= 1 >= ++ { name6 | ; ++}}}}}}}\n"), UNKNOWN_MACRO); ASSERT_THROW_INTERNAL(checkCode("else return % name5 name2 - =name1 return enum | { - name3 1 enum != >= 1 >= ++ { { || " - "{ return return { | { - name3 1 enum != >= 1 >= ++ { { || ; ++}}}}}}}}"), UNKNOWN_MACRO); + "{ return return { | { - name3 1 enum != >= 1 >= ++ { { || ; ++}}}}}}}}\n"), UNKNOWN_MACRO); - ASSERT_THROW_INTERNAL(checkCode("f(*p, requires(x));"), AST); // #14740 + ASSERT_THROW_INTERNAL(checkCode("f(*p, requires(x));\n"), AST); // #14740 } void templateSimplifierCrashes() { @@ -1369,7 +1369,7 @@ class TestGarbage : public TestFixture { " void f() {\n" " s.operator A >();\n" " }\n" - "}"); + "}\n"); ASSERT_NO_THROW(checkCode( // #6034 "template class T, typename... Args>\n" @@ -1383,7 +1383,7 @@ class TestGarbage : public TestFixture { "\n" "int main() {\n" " foo >::value;\n" - "}")); + "}\n")); (void)checkCode( // #6117 (segmentation fault) "template struct something_like_tuple\n" @@ -1401,7 +1401,7 @@ class TestGarbage : public TestFixture { "\n" "typedef something_like_tuple something_like_tuple_t;\n" "SA ((is_last::value == false));\n" - "SA ((is_last::value == false));"); + "SA ((is_last::value == false));\n"); ignore_errout(); // we are not interested in the output (void)checkCode( // #6225 (use-after-free) @@ -1412,7 +1412,7 @@ class TestGarbage : public TestFixture { " template \n" " struct A {};\n" " using AliasA = A;\n" - "}"); + "}\n"); // #3449 ASSERT_EQUALS("template < typename T > struct A ;\n" @@ -1420,72 +1420,72 @@ class TestGarbage : public TestFixture { "{ } ;", checkCode("template struct A;\n" "struct B { template struct C };\n" - "{};")); + "{};\n")); } void garbageCode161() { //7200 - ASSERT_THROW_INTERNAL(checkCode("{ }{ if () try { } catch (...)} B : : ~B { }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{ }{ if () try { } catch (...)} B : : ~B { }\n"), SYNTAX); } void garbageCode162() { //7208 - ASSERT_THROW_INTERNAL(checkCode("return << >> x return << >> x ", false), UNKNOWN_MACRO); + ASSERT_THROW_INTERNAL(checkCode("return << >> x return << >> x \n", false), UNKNOWN_MACRO); } void garbageCode163() { //7228 - ASSERT_THROW_INTERNAL(checkCode("typedef s f[](){typedef d h(;f)}", false), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("typedef s f[](){typedef d h(;f)}\n", false), SYNTAX); } void garbageCode164() { //7234 - ASSERT_THROW_INTERNAL(checkCode("class d{k p;}(){d::d():B<()}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("class d{k p;}(){d::d():B<()}\n"), SYNTAX); } void garbageCode165() { //7235 - ASSERT_THROW_INTERNAL(checkCode("for(;..)", false),SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("for(;..)\n", false),SYNTAX); } void garbageCode167() { //7237 - ASSERT_THROW_INTERNAL(checkCode("class D00i000{:D00i000::}i"),SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("class D00i000{:D00i000::}i\n"),SYNTAX); } void garbageCode168() { // #7246 (segmentation fault) - (void)checkCode("long foo(void) { return *bar; }", false); + (void)checkCode("long foo(void) { return *bar; }\n", false); ignore_errout(); // we do not care about the output } void garbageCode169() { // 6713 ASSERT_THROW_INTERNAL(checkCode("( ) { ( ) ; { return } switch ( ) i\n" - "set case break ; default: ( ) }", false), SYNTAX); + "set case break ; default: ( ) }\n", false), SYNTAX); } void garbageCode170() { // 7255 - ASSERT_THROW_INTERNAL(checkCode("d i(){{f*s=typeid(()0,)}}", false), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("d i(){{f*s=typeid(()0,)}}\n", false), SYNTAX); } void garbageCode171() { // 7270 - ASSERT_THROW_INTERNAL(checkCode("(){case()?():}:", false), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("(){case()?():}:\n", false), SYNTAX); } void garbageCode172() { // #7357 - ASSERT_THROW_INTERNAL(checkCode("p>,"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("p>,\n"), SYNTAX); } void garbageCode173() { // #6781 heap corruption ; TemplateSimplifier::simplifyTemplateInstantiations - ASSERT_THROW_INTERNAL(checkCode(" template < Types > struct S : >( S < ...Types... > S <) > { ( ) { } } ( ) { return S < void > ( ) }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode(" template < Types > struct S : >( S < ...Types... > S <) > { ( ) { } } ( ) { return S < void > ( ) }\n"), SYNTAX); } void garbageCode174() { // #7356 - ASSERT_THROW_INTERNAL(checkCode("{r e() { w*constD = (())D = cast< }}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{r e() { w*constD = (())D = cast< }}\n"), SYNTAX); } void garbageCode175() { // #7027 @@ -1494,32 +1494,32 @@ class TestGarbage : public TestFixture { " for ( i = t3 , i < t1 ; i++ )\n" " for ( j = 0 ; j < = j++ )\n" " return t1 ,\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode176() { // #7257 (segmentation fault) - (void)checkCode("class t { { struct } enum class f : unsigned { q } b ; operator= ( T ) { switch ( b ) { case f::q: } } { assert ( b ) ; } } { ; & ( t ) ( f::t ) ; } ;"); + (void)checkCode("class t { { struct } enum class f : unsigned { q } b ; operator= ( T ) { switch ( b ) { case f::q: } } { assert ( b ) ; } } { ; & ( t ) ( f::t ) ; } ;\n"); ignore_errout(); // we are not interested in the output } void garbageCode181() { - ASSERT_THROW_INTERNAL(checkCode("int test() { int +; }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("int test() { int +; }\n"), SYNTAX); } // #4195 - segfault for "enum { int f ( ) { return = } r = f ( ) ; }" void garbageCode182() { - ASSERT_THROW_INTERNAL(checkCode("enum { int f ( ) { return = } r = f ( ) ; }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("enum { int f ( ) { return = } r = f ( ) ; }\n"), SYNTAX); } // #7505 - segfault void garbageCode183() { - ASSERT_THROW_INTERNAL(checkCode("= { int } enum return { r = f() f(); }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("= { int } enum return { r = f() f(); }\n"), SYNTAX); } void garbageCode184() { // #7699 ASSERT_THROW_INTERNAL(checkCode("unsigned int AquaSalSystem::GetDisplayScreenCount() {\n" " NSArray* pScreens = [NSScreen screens];\n" " return pScreens ? [pScreens count] : 1;\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } void garbageCode185() { // #6011 crash in libreoffice failure to create proper AST @@ -1531,29 +1531,29 @@ class TestGarbage : public TestFixture { " pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? TRUE : FALSE ) );\n" " return bStatus;\n" " };\n" - "}"); + "}\n"); ignore_errout(); // we are not interested in the output } // #8151 - segfault due to incorrect template syntax void garbageCode186() { - ASSERT_THROW_INTERNAL(checkCode("A<>C"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("A<>C\n"), SYNTAX); } void garbageCode187() { // # 8152 - segfault in handling const char inp[] = "0|\0|0>;\n"; ASSERT_THROW_INTERNAL(checkCode(inp), SYNTAX); - (void)checkCode("template struct S : A< B || C > {};"); // No syntax error: #8390 - (void)checkCode("static_assert(A || B, ab);"); + (void)checkCode("template struct S : A< B || C > {};\n"); // No syntax error: #8390 + (void)checkCode("static_assert(A || B, ab);\n"); } void garbageCode188() { // #8255 - ASSERT_THROW_INTERNAL(checkCode("{z r(){(){for(;<(x);){if(0==0)}}}}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{z r(){(){for(;<(x);){if(0==0)}}}}\n"), SYNTAX); } void garbageCode189() { // #8317 (segmentation fault) - (void)checkCode("t&n(){()()[](){()}}$"); + (void)checkCode("t&n(){()()[](){()}}$\n"); } void garbageCode190() { // #8307 @@ -1561,31 +1561,31 @@ class TestGarbage : public TestFixture { " int i;\n" " i *= 0;\n" " !i <;\n" - "}"), + "}\n"), AST); } void garbageCode191() { // #8333 - ASSERT_THROW_INTERNAL(checkCode("struct A { int f(const); };"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("struct A { int f(int, const, char); };"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("struct A { int f(struct); };"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("struct A { int f(const); };\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("struct A { int f(int, const, char); };\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("struct A { int f(struct); };\n"), SYNTAX); // The following code is valid and should not trigger any error - ASSERT_NO_THROW(checkCode("struct A { int f ( char ) ; } ;")); + ASSERT_NO_THROW(checkCode("struct A { int f ( char ) ; } ;\n")); } void garbageCode192() { // #8386 (segmentation fault) - ASSERT_THROW_INTERNAL(checkCode("{(()[((0||0xf||))]0[])}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{(()[((0||0xf||))]0[])}\n"), SYNTAX); } // #8740 void garbageCode193() { - ASSERT_THROW_INTERNAL(checkCode("d f(){!=[]&&0()!=0}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("d f(){!=[]&&0()!=0}\n"), SYNTAX); } // #8384 void garbageCode194() { - ASSERT_THROW_INTERNAL(checkCode("{((()))(return 1||);}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{((()))(return 1||);}\n"), SYNTAX); } // #8709 - no garbage but to avoid stability regression (segmentation fault) @@ -1595,19 +1595,19 @@ class TestGarbage : public TestFixture { " switch (d) { case b:; }\n" " double e(b);\n" " if(e <= 0) {}\n" - "}"); + "}\n"); ignore_errout(); // we do not care about the output } // #8265 void garbageCode196() { - ASSERT_THROW_INTERNAL(checkCode("0|,0<= void { ( ()) } 1 name3 return >= >= ( ) >= name5 (\n" " name5 name6 :nam00 [ ()])}))})})})};\n" - "}"), SYNTAX); + "}\n"), SYNTAX); } // #8752 (segmentation fault) void garbageCode199() { - ASSERT_THROW_INTERNAL(checkCode("d f(){e n00e0[]n00e0&" "0+f=0}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("d f(){e n00e0[]n00e0&" "0+f=0}\n"), SYNTAX); } // #8757 void garbageCode200() { - ASSERT_THROW_INTERNAL(checkCode("(){e break,{(case)!{e:[]}}}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("(){e break,{(case)!{e:[]}}}\n"), SYNTAX); } // #8873 void garbageCode201() { - ASSERT_THROW_INTERNAL(checkCode("void f() { std::string s=\"abc\"; return s + }"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() { std::string s=\"abc\"; return s + }\n"), SYNTAX); } // #8907 void garbageCode202() { - ASSERT_THROW_INTERNAL(checkCode("void f() { UNKNOWN_MACRO(return); }"), UNKNOWN_MACRO); - ASSERT_THROW_INTERNAL(checkCode("void f() { UNKNOWN_MACRO(throw); }"), UNKNOWN_MACRO); + ASSERT_THROW_INTERNAL(checkCode("void f() { UNKNOWN_MACRO(return); }\n"), UNKNOWN_MACRO); + ASSERT_THROW_INTERNAL(checkCode("void f() { UNKNOWN_MACRO(throw); }\n"), UNKNOWN_MACRO); ignore_errout(); } void garbageCode203() { // #8972 (segmentation fault) - ASSERT_THROW_INTERNAL(checkCode("{ > () {} }"), SYNTAX); - (void)checkCode("template <> a > ::b();"); + ASSERT_THROW_INTERNAL(checkCode("{ > () {} }\n"), SYNTAX); + (void)checkCode("template <> a > ::b();\n"); } void garbageCode204() { - ASSERT_THROW_INTERNAL(checkCode("template ()> c; template a as() {} as>();"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("template ()> c; template a as() {} as>();\n"), SYNTAX); } void garbageCode205() { @@ -1667,55 +1667,55 @@ class TestGarbage : public TestFixture { "CodeSnippetsEvent :: CodeSnippetsEvent ( const CodeSnippetsEvent & Event )\n" ": wxCommandEvent ( Event )\n" ", m_SnippetID ( 0 ) {\n" - "}"), + "}\n"), INTERNAL); } void garbageCode206() { - ASSERT_EQUALS("[test.cpp:1] syntax error: operator", getSyntaxError("void foo() { for (auto operator new : int); }")); - ASSERT_EQUALS("[test.cpp:1] syntax error", getSyntaxError("void foo() { for (a operator== :) }")); + ASSERT_EQUALS("[test.cpp:1] syntax error: operator", getSyntaxError("void foo() { for (auto operator new : int); }\n")); + ASSERT_EQUALS("[test.cpp:1] syntax error", getSyntaxError("void foo() { for (a operator== :) }\n")); } void garbageCode207() { // #8750 - ASSERT_THROW_INTERNAL(checkCode("d f(){(.n00e0(return%n00e0''('')));}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("d f(){(.n00e0(return%n00e0''('')));}\n"), SYNTAX); } void garbageCode208() { // #8753 - ASSERT_THROW_INTERNAL(checkCode("d f(){(for(((((0{t b;((((((((()))))))))}))))))}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("d f(){(for(((((0{t b;((((((((()))))))))}))))))}\n"), SYNTAX); } void garbageCode209() { // #8756 - ASSERT_THROW_INTERNAL(checkCode("{(- -##0xf/-1 0)[]}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{(- -##0xf/-1 0)[]}\n"), SYNTAX); } void garbageCode210() { // #8762 - ASSERT_THROW_INTERNAL(checkCode("{typedef typedef c n00e0[]c000(;n00e0&c000)}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("{typedef typedef c n00e0[]c000(;n00e0&c000)}\n"), SYNTAX); } void garbageCode211() { // #8764 - ASSERT_THROW_INTERNAL(checkCode("{typedef f typedef[]({typedef e e,>;typedef(((typedef;typedef(((typedef struct A {};\n" "template struct A {}; \n" - "A a;"); + "A a;\n"); } void garbageCode217() { // #10011 @@ -1723,11 +1723,11 @@ class TestGarbage : public TestFixture { " auto p;\n" " if (g(p)) {}\n" " assert();\n" - "}"), AST); + "}\n"), AST); } void garbageCode218() { // #8763 - ASSERT_THROW_INTERNAL(checkCode("d f(){t n0000 const[]n0000+0!=n0000,(0)}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("d f(){t n0000 const[]n0000+0!=n0000,(0)}\n"), SYNTAX); } void garbageCode219() { // #10101 (void)checkCode("typedef void (*func) (addr) ;\n" @@ -1747,111 +1747,111 @@ class TestGarbage : public TestFixture { ASSERT_THROW_INTERNAL(checkCode("template\n"), SYNTAX); // don't crash } void garbageCode223() { // #11639 - ASSERT_THROW_INTERNAL(checkCode("struct{}*"), SYNTAX); // don't crash + ASSERT_THROW_INTERNAL(checkCode("struct{}*\n"), SYNTAX); // don't crash } void garbageCode224() { - ASSERT_THROW_INTERNAL(checkCode("void f(){ auto* b = dynamic_cast int { return 0; }() };")); + ASSERT_NO_THROW(checkCode("void f() { enum { A = [=]() mutable { return 0; }() }; }\n")); + ASSERT_NO_THROW(checkCode("enum { A = [=](void) mutable -> int { return 0; }() };\n")); } void garbageCode229() { // #14126 - ASSERT_THROW_INTERNAL(checkCode("void f() {} [[maybe_unused]]"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("void f() {} [[unused]]"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() {} [[maybe_unused]]\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("void f() {} [[unused]]\n"), SYNTAX); } void garbageCode230() { // #14432 - ASSERT_THROW_INTERNAL(checkCode("e U U,i"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("e U U,i\n"), SYNTAX); } void garbageCode231() { - ASSERT_THROW_INTERNAL(checkCode("char char* [] = {\"a\" \"b\"}"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("char char* [] = {\"a\" \"b\"}\n"), SYNTAX); } void syntaxErrorFirstToken() { - ASSERT_THROW_INTERNAL(checkCode("&operator(){[]};"), SYNTAX); // #7818 - ASSERT_THROW_INTERNAL(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"), SYNTAX); // #6858 - ASSERT_THROW_INTERNAL(checkCode(">{ x while (y) z int = }"), SYNTAX); // #4175 - ASSERT_THROW_INTERNAL(checkCode("&p(!{}e x){({(0?:?){({})}()})}"), SYNTAX); // #7118 - ASSERT_THROW_INTERNAL(checkCode(" { struct { typename D4:typename Base }; };"), SYNTAX); // #3533 + ASSERT_THROW_INTERNAL(checkCode("&operator(){[]};\n"), SYNTAX); // #7818 + ASSERT_THROW_INTERNAL(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }\n"), SYNTAX); // #6858 + ASSERT_THROW_INTERNAL(checkCode(">{ x while (y) z int = }\n"), SYNTAX); // #4175 + ASSERT_THROW_INTERNAL(checkCode("&p(!{}e x){({(0?:?){({})}()})}\n"), SYNTAX); // #7118 + ASSERT_THROW_INTERNAL(checkCode(" { struct { typename D4:typename Base }; };\n"), SYNTAX); // #3533 ASSERT_THROW_INTERNAL(checkCode(" > template < . > struct Y < T > { = } ;\n"), SYNTAX); // #6108 } void syntaxErrorLastToken() { - ASSERT_THROW_INTERNAL(checkCode("int *"), SYNTAX); // #7821 - ASSERT_THROW_INTERNAL(checkCode("x[y]"), SYNTAX); // #2986 - ASSERT_THROW_INTERNAL(checkCode("( ) &"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("|| #if #define <="), SYNTAX); // #2601 - ASSERT_THROW_INTERNAL(checkCode("f::y:y : \n"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("++4++ + + E++++++++++ + ch " "tp.oed5[.]"), SYNTAX); // #7074 - ASSERT_THROW_INTERNAL(checkCode("d a(){f s=0()8[]s?():0}*()?:0", false), SYNTAX); // #7236 - ASSERT_THROW_INTERNAL(checkCode("!2 : #h2 ?:", false), SYNTAX); // #7769 - ASSERT_THROW_INTERNAL(checkCode("--"), SYNTAX); - ASSERT_THROW_INTERNAL(checkCode("volatile true , test < test < #ifdef __ppc__ true ,"), SYNTAX); // #4169 + ASSERT_THROW_INTERNAL(checkCode("++4++ + + E++++++++++ + ch " "tp.oed5[.]\n"), SYNTAX); // #7074 + ASSERT_THROW_INTERNAL(checkCode("d a(){f s=0()8[]s?():0}*()?:0\n", false), SYNTAX); // #7236 + ASSERT_THROW_INTERNAL(checkCode("!2 : #h2 ?:\n", false), SYNTAX); // #7769 + ASSERT_THROW_INTERNAL(checkCode("--\n"), SYNTAX); + ASSERT_THROW_INTERNAL(checkCode("volatile true , test < test < #ifdef __ppc__ true ,\n"), SYNTAX); // #4169 ASSERT_THROW_INTERNAL(checkCode("a,b--\n"), SYNTAX); // #2847 - ASSERT_THROW_INTERNAL(checkCode("x a[0] ="), SYNTAX); // #2682 + ASSERT_THROW_INTERNAL(checkCode("x a[0] =\n"), SYNTAX); // #2682 ASSERT_THROW_INTERNAL(checkCode("auto_ptr\n"), SYNTAX); // #2967 ASSERT_THROW_INTERNAL(checkCode("char a[1]\n"), SYNTAX); // #2865 - ASSERT_THROW_INTERNAL(checkCode("<><<"), SYNTAX); // #2612 - ASSERT_THROW_INTERNAL(checkCode("z"), SYNTAX); // #2831 - ASSERT_THROW_INTERNAL(checkCode("><,f<<\n"), SYNTAX); // #2612 + ASSERT_THROW_INTERNAL(checkCode("z\n"), SYNTAX); // #2831 + ASSERT_THROW_INTERNAL(checkCode("><,f typedef name5 | ( , ;){ } (); }"), SYNTAX); // #9067 - ASSERT_THROW_INTERNAL(checkCode("void f() { x= {}( ) ( 'x')[ ] (); }"), SYNTAX); // #9068 - ASSERT_THROW_INTERNAL(checkCode("void f() { x= y{ } name5 y[ ] + y ^ name5 ^ name5 for ( ( y y y && y y y && name5 ++ int )); }"), SYNTAX); // #9069 + ASSERT_THROW_INTERNAL(checkCode("void f() { x= 'x' > typedef name5 | ( , ;){ } (); }\n"), SYNTAX); // #9067 + ASSERT_THROW_INTERNAL(checkCode("void f() { x= {}( ) ( 'x')[ ] (); }\n"), SYNTAX); // #9068 + ASSERT_THROW_INTERNAL(checkCode("void f() { x= y{ } name5 y[ ] + y ^ name5 ^ name5 for ( ( y y y && y y y && name5 ++ int )); }\n"), SYNTAX); // #9069 } void cliCode() { @@ -1862,12 +1862,12 @@ class TestGarbage : public TestFixture { "bool GetDeviceInformation(String ^ port, LibCECConfiguration ^configuration, uint32_t timeoutMs) {\n" "bool bReturn(false);\n" "}\n" - "};")); + "};\n")); ignore_errout(); // we are not interested in the output } void enumTrailingComma() { - ASSERT_THROW_INTERNAL(checkCode("enum ssl_shutdown_t {ssl_shutdown_none = 0,ssl_shutdown_close_notify = , } ;"), SYNTAX); // #8079 + ASSERT_THROW_INTERNAL(checkCode("enum ssl_shutdown_t {ssl_shutdown_none = 0,ssl_shutdown_close_notify = , } ;\n"), SYNTAX); // #8079 } void nonGarbageCode1() { @@ -1880,25 +1880,25 @@ class TestGarbage : public TestFixture { "template< class T >\n" "template< class Predicate > int\n" "List::DeleteIf( const Predicate &pred )\n" - "{}")); + "{}\n")); ignore_errout(); // we are not interested in the output // #8749 ASSERT_NO_THROW(checkCode( "struct A {\n" " void operator+=(A&) && = delete;\n" - "};")); + "};\n")); // #8788 ASSERT_NO_THROW(checkCode( "struct foo;\n" "void f() {\n" " auto fn = []() -> foo* { return new foo(); };\n" - "}")); + "}\n")); ignore_errout(); // we do not care about the output // #13892 - ASSERT_NO_THROW(checkCode("void foovm(int x[const *]);")); + ASSERT_NO_THROW(checkCode("void foovm(int x[const *]);\n")); // #14676 ASSERT_NO_THROW(checkCode("int main() {\n" diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 72a13ee6c42..8e523e3d06e 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -93,7 +93,7 @@ class TestIncompleteStatement : public TestFixture { "{\n" " const char def[] =\n" " \"abc\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -102,7 +102,7 @@ class TestIncompleteStatement : public TestFixture { check("void foo()\n" "{\n" " \"abc\";\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Redundant code: Found a statement that begins with string constant. [constStatement]\n", errout_str()); } @@ -111,7 +111,7 @@ class TestIncompleteStatement : public TestFixture { check("void foo()\n" "{\n" " const char *str[] = { \"abc\" };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -125,7 +125,7 @@ class TestIncompleteStatement : public TestFixture { "\"more \"\n" "\"world\"\n" "};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -134,7 +134,7 @@ class TestIncompleteStatement : public TestFixture { check("void foo()\n" "{\n" " 50;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n", errout_str()); } @@ -145,7 +145,7 @@ class TestIncompleteStatement : public TestFixture { " 1 == (two + three);\n" " 2 != (two + three);\n" " (one + two) != (two + three);\n" - "}"); + "}\n"); } void test7() { // #9335 @@ -160,7 +160,7 @@ class TestIncompleteStatement : public TestFixture { " for (C c(S); ; ) {\n" " (void)c;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -174,7 +174,7 @@ class TestIncompleteStatement : public TestFixture { " {\n" " { 346.1,114.1 }, { 347.1,111.1 }\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -186,7 +186,7 @@ class TestIncompleteStatement : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { (void*)0; }"); + check("void f() { (void*)0; }\n"); ASSERT_EQUALS("[test.cpp:1:12]: (warning) Redundant code: Found unused cast in expression '(void*)0'. [constStatement]\n", errout_str()); check("void f() {\n" // #13148 @@ -200,12 +200,12 @@ class TestIncompleteStatement : public TestFixture { errout_str()); check("#define X 0\n" - "void f() { X; }"); + "void f() { X; }\n"); ASSERT_EQUALS("", errout_str()); } void intarray() { - check("int arr[] = { 100/2, 1*100 };"); + check("int arr[] = { 100/2, 1*100 };\n"); ASSERT_EQUALS("", errout_str()); } @@ -213,7 +213,7 @@ class TestIncompleteStatement : public TestFixture { check("struct st arr[] = {\n" " { 100/2, 1*100 }\n" " { 90, 70 }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -221,14 +221,14 @@ class TestIncompleteStatement : public TestFixture { check("struct st arr[] = {\n" " { 100/2, 1*100 }\n" " { 90, 70 }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } void conditionalcall() { check("void f() {\n" " 0==x ? X() : Y();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -236,7 +236,7 @@ class TestIncompleteStatement : public TestFixture { // #2462 - C++11 struct initialization check("void f() {\n" " ABC abc{1,2,3};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6260 - C++11 array initialization @@ -244,30 +244,30 @@ class TestIncompleteStatement : public TestFixture { " static const char* a[][2] {\n" " {\"b\", \"\"},\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #2482 - false positive for empty struct - check("struct A {};"); + check("struct A {};\n"); ASSERT_EQUALS("", errout_str()); // #4387 - C++11 initializer list - check("A::A() : abc{0} {}"); + check("A::A() : abc{0} {}\n"); ASSERT_EQUALS("", errout_str()); // #5042 - C++11 initializer list - check("A::A() : abc::def{0} {}"); + check("A::A() : abc::def{0} {}\n"); ASSERT_EQUALS("", errout_str()); // #4503 - vector init - check("void f() { vector v{1}; }"); + check("void f() { vector v{1}; }\n"); ASSERT_EQUALS("", errout_str()); } void returnstruct() { check("struct s foo() {\n" " return (struct s){0,0};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4754 @@ -276,19 +276,19 @@ class TestIncompleteStatement : public TestFixture { " {\"hi\", \"there\"},\n" " {\"happy\", \"sad\"}\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct s foo() {\n" " return (struct s){0};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void cast() { check("void f() {\n" " ((struct foo *)(0x1234))->xy = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(const std::exception& e) {\n" // #10918 @@ -307,14 +307,14 @@ class TestIncompleteStatement : public TestFixture { check("void f() {\n" " int x = 1;\n" " x++, x++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void cpp11init() { check("void f() {\n" " int x{1};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector f(int* p) {\n" @@ -326,7 +326,7 @@ class TestIncompleteStatement : public TestFixture { void cpp11init2() { check("x handlers{\n" " { \"mode2\", []() { return 2; } },\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -334,33 +334,33 @@ class TestIncompleteStatement : public TestFixture { check("struct A { void operator()(int); };\n" "void f() {\n" "A{}(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("template struct A { void operator()(int); };\n" "void f() {\n" "A{}(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void block() { check("void f() {\n" " ({ do_something(); 0; });\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" "out:\n" " ({ do_something(); 0; });\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void mapindex() { check("void f() {\n" " map[{\"1\",\"2\"}]=0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -368,7 +368,7 @@ class TestIncompleteStatement : public TestFixture { check("void foo(int,const char*,int);\n" // #8827 "void f(int value) {\n" " foo(42,\"test\",42),(value&42);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:22]: (warning) Found suspicious operator ',', result is not used. [constStatement]\n", errout_str()); check("int f() {\n" // #11257 @@ -456,13 +456,13 @@ class TestIncompleteStatement : public TestFixture { "[test.cpp:9:5]: (warning, inconclusive) Found suspicious operator '~', result is not used. [constStatement]\n", errout_str()); - check("void f1(int x) { x; }", dinit(CheckOptions, $.inconclusive = true)); + check("void f1(int x) { x; }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:1:18]: (warning) Unused variable value 'x' [constStatement]\n", errout_str()); - check("void f() { if (Type t; g(t)) {} }"); // #9776 + check("void f() { if (Type t; g(t)) {} }\n"); // #9776 ASSERT_EQUALS("", errout_str()); - check("void f(int x) { static_cast(x); }"); + check("void f(int x) { static_cast(x); }\n"); ASSERT_EQUALS("[test.cpp:1:38]: (warning) Redundant code: Found unused cast in expression 'static_cast(x)'. [constStatement]\n", errout_str()); check("void f(int x, int* p) {\n" @@ -473,7 +473,7 @@ class TestIncompleteStatement : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { false; }"); // #10856 + check("void f() { false; }\n"); // #10856 ASSERT_EQUALS("[test.cpp:1:12]: (warning) Redundant code: Found a statement that begins with bool constant. [constStatement]\n", errout_str()); check("void f(int i) {\n" @@ -783,55 +783,55 @@ class TestIncompleteStatement : public TestFixture { void vardecl() { // #8984 - check("void f() { a::b *c = d(); }", dinit(CheckOptions, $.inconclusive = true)); + check("void f() { a::b *c = d(); }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); - check("void f() { std::vector *c; }", dinit(CheckOptions, $.inconclusive = true)); + check("void f() { std::vector *c; }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); - check("void f() { a::b &c = d(); }", dinit(CheckOptions, $.inconclusive = true)); + check("void f() { a::b &c = d(); }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); - check("void f() { std::vector &c; }", dinit(CheckOptions, $.inconclusive = true)); + check("void f() { std::vector &c; }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); - check("void f() { a::b &&c = d(); }", dinit(CheckOptions, $.inconclusive = true)); + check("void f() { a::b &&c = d(); }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); - check("void f() { std::vector &&c; }", dinit(CheckOptions, $.inconclusive = true)); + check("void f() { std::vector &&c; }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); - check("void f() { char * const * a, * const * b; }", dinit(CheckOptions, $.inconclusive = true)); + check("void f() { char * const * a, * const * b; }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); - check("void f() { char * const * a = 0, * volatile restrict * b; }", dinit(CheckOptions, $.inconclusive = true, $.cpp = false)); + check("void f() { char * const * a = 0, * volatile restrict * b; }\n", dinit(CheckOptions, $.inconclusive = true, $.cpp = false)); ASSERT_EQUALS("", errout_str()); - check("void f() { char * const * a = 0, * volatile const * b; }", dinit(CheckOptions, $.inconclusive = true)); + check("void f() { char * const * a = 0, * volatile const * b; }\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } void archive() { check("void f(Archive &ar) {\n" " ar & x;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f(int ar) {\n" " ar & x;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2:6]: (warning, inconclusive) Found suspicious operator '&', result is not used. [constStatement]\n", errout_str()); } void ast() { - check("struct c { void a() const { for (int x=0; x;); } };", dinit(CheckOptions, $.inconclusive = true)); + check("struct c { void a() const { for (int x=0; x;); } };\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } void oror() { check("void foo() {\n" " params_given (params, \"overrides\") || (overrides = \"1\");\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f(std::ifstream& file) {\n" // #10930 diff --git a/test/testio.cpp b/test/testio.cpp index 16d770bb0bd..ad95345e1fd 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -124,50 +124,50 @@ class TestIO : public TestFixture { check( "void foo() {\n" " std::cout << std::cout;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (error) Invalid usage of output stream: '<< std::cout'. [coutCerrMisusage]\n", errout_str()); check( "void foo() {\n" " std::cout << (std::cout);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (error) Invalid usage of output stream: '<< std::cout'. [coutCerrMisusage]\n", errout_str()); check( "void foo() {\n" " std::cout << \"xyz\" << std::cout;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (error) Invalid usage of output stream: '<< std::cout'. [coutCerrMisusage]\n", errout_str()); check( "void foo(int i) {\n" " std::cout << i << std::cerr;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (error) Invalid usage of output stream: '<< std::cerr'. [coutCerrMisusage]\n", errout_str()); check( "void foo() {\n" " std::cout << \"xyz\";\n" " std::cout << \"xyz\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( "void foo() {\n" " std::cout << std::cout.good();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( "void foo() {\n" " unknownObject << std::cout;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( "void foo() {\n" " MACRO(std::cout <<, << std::cout)\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -180,7 +180,7 @@ class TestIO : public TestFixture { " fread(buffer, 5, 6, f);\n" " rewind(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" @@ -188,7 +188,7 @@ class TestIO : public TestFixture { " fread(buffer, 5, 6, f);\n" " rewind(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("[test.cpp:5:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" @@ -196,7 +196,7 @@ class TestIO : public TestFixture { " fread(buffer, 5, 6, f);\n" " rewind(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:5:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" @@ -204,7 +204,7 @@ class TestIO : public TestFixture { " fread(buffer, 5, 6, f);\n" " rewind(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("[test.cpp:5:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" @@ -212,7 +212,7 @@ class TestIO : public TestFixture { " fread(buffer, 5, 6, f);\n" " rewind(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("[test.cpp:5:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" @@ -220,7 +220,7 @@ class TestIO : public TestFixture { " fread(buffer, 5, 6, f);\n" " rewind(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:5:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" @@ -228,55 +228,55 @@ class TestIO : public TestFixture { " fread(buffer, 5, 6, f);\n" " rewind(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("[test.cpp:5:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = fopen(name, \"r+\");\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " f = _wfopen(name, L\"r+\");\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " f = _tfopen(name, _T(\"r+\"));\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " f = _tfopen(name, _T(\"r+\"));\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " _wfopen_s(&f, name, L\"r+\");\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " _tfopen_s(&f, name, _T(\"r+\"));\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " _tfopen_s(&f, name, _T(\"r+\"));\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " f = tmpfile();\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("", errout_str()); // Write mode @@ -285,19 +285,19 @@ class TestIO : public TestFixture { " fwrite(buffer, 5, 6, f);\n" " rewind(f);\n" " fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (error) Read operation on a file that was opened only for writing. [readWriteOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = fopen(name, \"w+\");\n" " fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " f = tmpfile();\n" " fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Append mode @@ -306,14 +306,14 @@ class TestIO : public TestFixture { " fwrite(buffer, 5, 6, f);\n" " rewind(f);\n" " fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) Repositioning operation performed on a file opened in append mode has no effect. [seekOnAppendedFile]\n" "[test.cpp:5:5]: (error) Read operation on a file that was opened only for writing. [readWriteOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = fopen(name, \"a+\");\n" " fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Variable declared locally @@ -321,7 +321,7 @@ class TestIO : public TestFixture { " FILE* f = fopen(name, \"r\");\n" " fwrite(buffer, 5, 6, f);\n" " fclose(f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); // Call unknown function @@ -330,60 +330,60 @@ class TestIO : public TestFixture { " fwrite(buffer, 5, 6, f);\n" " bar(f);\n" " fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // freopen and tmpfile check("void foo(FILE*& f) {\n" " f = freopen(name, \"r\", f);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = _wfreopen(name, L\"r\", f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = _tfreopen(name, _T(\"r\"), f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = _tfreopen(name, _T(\"r\"), f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = _wfreopen_s(&f, name, L\"r\", f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = _tfreopen_s(&f, name, _T(\"r\"), f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = _tfreopen_s(&f, name, _T(\"r\"), f);\n" " fwrite(buffer, 5, 6, f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32W)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Write operation on a file that was opened only for reading. [writeReadOnlyFile]\n", errout_str()); // Crash tests check("void foo(FILE*& f) {\n" " f = fopen(name, mode);\n" // No assertion failure (#3830) " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("void fopen(std::string const &filepath, std::string const &mode);"); // #3832 + check("void fopen(std::string const &filepath, std::string const &mode);\n"); // #3832 } void wrongMode_complex() { @@ -392,7 +392,7 @@ class TestIO : public TestFixture { " else f = fopen(name, \"r\");\n" " if(a) fwrite(buffer, 5, 6, f);\n" " else fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -401,14 +401,14 @@ class TestIO : public TestFixture { " else f = fopen(name, \"r\");\n" " if(a) fwrite(buffer, 5, 6, f);\n" " else fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " FILE* f = fopen(name, \"w\");\n" " if(a) fwrite(buffer, 5, 6, f);\n" " else fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Read operation on a file that was opened only for writing. [readWriteOnlyFile]\n", errout_str()); } @@ -421,7 +421,7 @@ class TestIO : public TestFixture { " ungetc('a', f);\n" " ungetwc(L'a', f);\n" " rewind(f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Used file that is not opened. [useClosedFile]\n" "[test.cpp:4:5]: (error) Used file that is not opened. [useClosedFile]\n" "[test.cpp:5:5]: (error) Used file that is not opened. [useClosedFile]\n" @@ -435,40 +435,40 @@ class TestIO : public TestFixture { " return;" " }\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " fclose(f);\n" " f = fopen(name, \"r\");\n" " fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " f = fopen(name, \"r\");\n" " f = g;\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " FILE* f;\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Used file that is not opened. [useClosedFile]\n", errout_str()); check("void foo() {\n" " FILE* f(stdout);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" // #3965 " FILE* f[3];\n" " f[0] = fopen(name, mode);\n" " fclose(f[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4368: multiple functions @@ -491,7 +491,7 @@ class TestIO : public TestFixture { " dump();\n" " close();\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("static FILE *fp = NULL;\n" @@ -505,7 +505,7 @@ class TestIO : public TestFixture { "{\n" " fclose(fp);\n" " fprintf(fp, \"Here's the output.\\n\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:11:3]: (error) Used file that is not opened. [useClosedFile]\n", errout_str()); // #4466 @@ -518,7 +518,7 @@ class TestIO : public TestFixture { " fclose(infile);\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void chdcd_parse_nero(FILE *infile) {\n" @@ -530,7 +530,7 @@ class TestIO : public TestFixture { " fclose(infile);\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4649 @@ -540,14 +540,14 @@ class TestIO : public TestFixture { " a.f2 = fopen(name,mode);\n" " fclose(a.f1);\n" " fclose(a.f2);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #1473 check("void foo() {\n" " FILE *a = fopen(\"aa\", \"r\");\n" " while (fclose(a)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (warning) fclose() used as loop condition may skip loop body or double-close file handle. [fcloseInLoopCondition]\n", errout_str()); check("void foo() {\n" @@ -555,7 +555,7 @@ class TestIO : public TestFixture { " while (fclose(a)) {\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -563,13 +563,13 @@ class TestIO : public TestFixture { " while (fclose(a)) {\n" " a = fopen(\"aa\", \"r\");\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " FILE *a = fopen(\"aa\", \"r\");\n" " do {} while (fclose(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:18]: (warning) fclose() used as loop condition may skip loop body or double-close file handle. [fcloseInLoopCondition]\n", errout_str()); // #6823 @@ -579,7 +579,7 @@ class TestIO : public TestFixture { " f[1] = fopen(\"2\", \"w\");\n" " fclose(f[0]);\n" " fclose(f[1]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #12236 @@ -595,13 +595,13 @@ class TestIO : public TestFixture { check("void foo(FILE* f) {\n" " fwrite(buffer, 5, 6, f);\n" " fread(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour. [IOWithoutPositioning]\n", errout_str()); check("void foo(FILE* f) {\n" " fread(buffer, 5, 6, f);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour. [IOWithoutPositioning]\n", errout_str()); check("void foo(FILE* f, bool read) {\n" @@ -609,42 +609,42 @@ class TestIO : public TestFixture { " fread(buffer, 5, 6, f);\n" " else\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE* f) {\n" " fread(buffer, 5, 6, f);\n" " fflush(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE* f) {\n" " fread(buffer, 5, 6, f);\n" " rewind(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE* f) {\n" " fread(buffer, 5, 6, f);\n" " fsetpos(f, pos);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE* f) {\n" " fread(buffer, 5, 6, f);\n" " fseek(f, 0, SEEK_SET);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE* f) {\n" " fread(buffer, 5, 6, f);\n" " long pos = ftell(f);\n" " fwrite(buffer, 5, 6, f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error) Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour. [IOWithoutPositioning]\n", errout_str()); // #6452 - member functions @@ -657,7 +657,7 @@ class TestIO : public TestFixture { " int bytesRead = fread(aboutToOverwrite.data(), 1, bufferLength, d->file);\n" " seek(writePosition);\n" " fwrite(buffer.data(), sizeof(char), buffer.size(), d->file);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class FileStream {\n" @@ -668,7 +668,7 @@ class TestIO : public TestFixture { " int bytesRead = fread(aboutToOverwrite.data(), 1, bufferLength, d->file);\n" " unknown(writePosition);\n" " fwrite(buffer.data(), sizeof(char), buffer.size(), d->file);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class FileStream {\n" @@ -680,7 +680,7 @@ class TestIO : public TestFixture { " int bytesRead = fread(aboutToOverwrite.data(), 1, bufferLength, d->file);\n" " known(writePosition);\n" " fwrite(buffer.data(), sizeof(char), buffer.size(), d->file);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:5]: (error) Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour. [IOWithoutPositioning]\n", errout_str()); check("class FileStream {\n" @@ -692,7 +692,7 @@ class TestIO : public TestFixture { " int bytesRead = fread(X::data(), 1, bufferLength, d->file);\n" " known(writePosition);\n" " fwrite(X::data(), sizeof(char), buffer.size(), d->file);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:5]: (error) Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour. [IOWithoutPositioning]\n", errout_str()); check("struct MemStream {\n" @@ -717,25 +717,25 @@ class TestIO : public TestFixture { check("void foo() {\n" " FILE* f = fopen(\"\", \"a+\");\n" " fseek(f, 0, SEEK_SET);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " FILE* f = fopen(\"\", \"w\");\n" " fseek(f, 0, SEEK_SET);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " FILE* f = fopen(\"\", \"a\");\n" " fseek(f, 0, SEEK_SET);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Repositioning operation performed on a file opened in append mode has no effect. [seekOnAppendedFile]\n", errout_str()); check("void foo() {\n" " FILE* f = fopen(\"\", \"a\");\n" " fflush(f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5578 check("void foo() {\n" @@ -743,7 +743,7 @@ class TestIO : public TestFixture { " fclose(f);\n" " f = fopen(\"\", \"r\");\n" " fseek(f, 0, SEEK_SET);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6566 } @@ -767,30 +767,30 @@ class TestIO : public TestFixture { check("void foo()\n" "{\n" " fflush(stdin);\n" - "}", dinit(CheckOptions, $.portability = true)); + "}\n", dinit(CheckOptions, $.portability = true)); ASSERT_EQUALS("[test.cpp:3:5]: (portability) fflush() called on input stream 'stdin' may result in undefined behaviour on non-linux systems. [fflushOnInputStream]\n", errout_str()); check("void foo()\n" "{\n" " fflush(stdout);\n" - "}", dinit(CheckOptions, $.portability = true)); + "}\n", dinit(CheckOptions, $.portability = true)); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " f = fopen(path, \"r\");\n" " fflush(f);\n" - "}", dinit(CheckOptions, $.portability = true)); + "}\n", dinit(CheckOptions, $.portability = true)); ASSERT_EQUALS("[test.cpp:3:5]: (portability) fflush() called on input stream 'f' may result in undefined behaviour on non-linux systems. [fflushOnInputStream]\n", errout_str()); check("void foo(FILE*& f) {\n" " f = fopen(path, \"w\");\n" " fflush(f);\n" - "}", dinit(CheckOptions, $.portability = true)); + "}\n", dinit(CheckOptions, $.portability = true)); ASSERT_EQUALS("", errout_str()); check("void foo(FILE*& f) {\n" " fflush(f);\n" - "}", dinit(CheckOptions, $.portability = true)); + "}\n", dinit(CheckOptions, $.portability = true)); ASSERT_EQUALS("", errout_str()); } @@ -798,7 +798,7 @@ class TestIO : public TestFixture { check("void foo() {\n" " FILE *f1 = fopen(\"tmp\", \"wt\");\n" " FILE *f2 = fopen(\"tmp\", \"rt\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (warning) The file '\"tmp\"' is opened for read and write access at the same time on different streams [incompatibleFileOpen]\n", errout_str()); } @@ -810,7 +810,7 @@ class TestIO : public TestFixture { " fgets(line, sizeof(line), fp);\n" " dostuff(line);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (warning) Using feof() as a loop condition causes the last line to be processed twice. [wrongfeofUsage]\n", errout_str()); check("int foo(FILE *fp) {\n" @@ -819,7 +819,7 @@ class TestIO : public TestFixture { " if (!feof(fp))\n" " return 1;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE *fp){\n" @@ -829,7 +829,7 @@ class TestIO : public TestFixture { " dostuff(line);\n" " fgets(line, sizeof(line), fp);" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(FILE *fp) {\n" @@ -838,7 +838,7 @@ class TestIO : public TestFixture { " fgets(line, sizeof(line), fp);\n" " dostuff(line);\n" " } while (!feof(fp));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:12]: (warning) Using feof() as a loop condition causes the last line to be processed twice. [wrongfeofUsage]\n", errout_str()); check("void foo(FILE *fp) {\n" @@ -847,7 +847,7 @@ class TestIO : public TestFixture { " dostuff(line);\n" " fgets(line, sizeof(line), fp);\n" " } while (!feof(fp));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -862,7 +862,7 @@ class TestIO : public TestFixture { " sscanf(foo, \"%[^~]\", bar);\n" " scanf(\"%dx%s\", &b, bar);\n" " fclose(file);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (warning) fscanf() without field width limits can crash with huge input data. [invalidscanf]\n" "[test.cpp:5:9]: (warning) scanf() without field width limits can crash with huge input data. [invalidscanf]\n" "[test.cpp:6:9]: (warning) scanf() without field width limits can crash with huge input data. [invalidscanf]\n" @@ -878,7 +878,7 @@ class TestIO : public TestFixture { " scanf(\"aa%d\", &a);\n" // No %s " scanf(\"aa%ld\", &a);\n" // No %s " scanf(\"%*[^~]\");\n" // Ignore input - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) scanf format string requires 0 parameters but 1 is given. [wrongPrintfScanfArgNum]\n", errout_str()); } @@ -888,7 +888,7 @@ class TestIO : public TestFixture { " scanf(\"%7c\", str);\n" " scanf(\"%8c\", str);\n" " scanf(\"%9c\", str);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:3]: (error) Width 9 given in format string (no. 1) is larger than destination buffer 'str[8]', use %8c to prevent overflowing it. [invalidScanfFormatWidth]\n", errout_str()); } @@ -897,7 +897,7 @@ class TestIO : public TestFixture { "{\n" " char str [8];\n" " scanf (\"%70s\",str);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:3]: (error) Width 70 given in format string (no. 1) is larger than destination buffer 'str[8]', use %7s to prevent overflowing it. [invalidScanfFormatWidth]\n", errout_str()); } @@ -905,7 +905,7 @@ class TestIO : public TestFixture { check("char s1[42], s2[42];\n" "void test() {\n" " scanf(\"%42s%42[a-z]\", s1, s2);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Width 42 given in format string (no. 1) is larger than destination buffer 's1[42]', use %41s to prevent overflowing it. [invalidScanfFormatWidth]\n" "[test.cpp:3:5]: (error) Width 42 given in format string (no. 2) is larger than destination buffer 's2[42]', use %41[a-z] to prevent overflowing it. [invalidScanfFormatWidth]\n", errout_str()); } @@ -920,7 +920,7 @@ class TestIO : public TestFixture { #define TEST_SCANF_CODE(format, type) \ - "void f(){" type " x; scanf(\"" format "\", &x);}" + "void f(){" type " x; scanf(\"" format "\", &x);}\n" #define TEST_SCANF_ERR(format, formatStr, type) \ "[test.c:1]: (warning) " format " in format string (no. 1) requires '" formatStr " *' but the argument type is '" type " *'.\n" @@ -935,7 +935,7 @@ class TestIO : public TestFixture { TEST_SCANF_ERR_AKA_("test.cpp", format, formatStr, type, akaType) #define TEST_PRINTF_CODE(format, type) \ - "void f(" type " x){printf(\"" format "\", x);}" + "void f(" type " x){printf(\"" format "\", x);}\n" #define TEST_PRINTF_ERR(format, requiredType, actualType) \ "[test.c:1]: (warning) " format " in format string (no. 1) requires '" requiredType "' but the argument type is '" actualType "'.\n" @@ -1074,7 +1074,7 @@ class TestIO : public TestFixture { " scanf(\"%*1x %1x %29s\", &count, KeyName);\n" // #3373 " fscanf(f, \"%7ms\", &ref);\n" // #3461 " sscanf(ip_port, \"%*[^:]:%4d\", &port);\n" // #3468 - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -1082,7 +1082,7 @@ class TestIO : public TestFixture { " scanf(\"%1d\", &foo, &bar);\n" " fscanf(bar, \"%1d\", &foo, &bar);\n" " scanf(\"%*1x %1x %29s\", &count, KeyName, foo);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) scanf format string requires 0 parameters but 1 is given.\n" "[test.cpp:3]: (warning) scanf format string requires 1 parameter but 2 are given.\n" "[test.cpp:4]: (warning) fscanf format string requires 1 parameter but 2 are given.\n" @@ -1093,7 +1093,7 @@ class TestIO : public TestFixture { " scanf(\"%1u%1u\", bar());\n" " sscanf(bar, \"%1d%1d\", &foo);\n" " scanf(\"%*1x %1x %29s\", &count);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (error) scanf format string requires 1 parameter but only 0 are given.\n" "[test.cpp:3]: (error) scanf format string requires 2 parameters but only 1 is given.\n" "[test.cpp:4]: (error) sscanf format string requires 2 parameters but only 1 is given.\n" @@ -1105,7 +1105,7 @@ class TestIO : public TestFixture { " sscanf(input, \"%3s\", output);\n" " sscanf(input, \"%4s\", output);\n" " sscanf(input, \"%5s\", output);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6]: (error) Width 5 given in format string (no. 1) is larger than destination buffer 'output[5]', use %4s to prevent overflowing it.\n", errout_str()); check("void foo() {\n" @@ -1115,7 +1115,7 @@ class TestIO : public TestFixture { " sscanf(input, \"%3s\", output);\n" " sscanf(input, \"%4s\", output);\n" " sscanf(input, \"%5s\", output);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:5]: (warning, inconclusive) Width 3 given in format string (no. 1) is smaller than destination buffer 'output[5]'.\n" "[test.cpp:7]: (error) Width 5 given in format string (no. 1) is larger than destination buffer 'output[5]', use %4s to prevent overflowing it.\n" "[test.cpp:4]: (warning) sscanf() without field width limits can crash with huge input data.\n", errout_str()); @@ -1127,7 +1127,7 @@ class TestIO : public TestFixture { " bufT projectId= {0};\n" " const int scanrc=sscanf(line, \"Project(\\\"{%36s}\\\")\", projectId);\n" " sscanf(input, \"%5s\", output);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:6]: (warning, inconclusive) Width 36 given in format string (no. 1) is smaller than destination buffer 'projectId[2048]'.\n", errout_str()); check("void foo(unsigned int i) {\n" @@ -1140,7 +1140,7 @@ class TestIO : public TestFixture { " scanf(\"%t\", &i);\n" " scanf(\"%L\", &i);\n" " scanf(\"%I\", &i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) 'h' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n" "[test.cpp:3]: (warning) 'hh' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n" "[test.cpp:4]: (warning) 'l' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n" @@ -1196,13 +1196,13 @@ class TestIO : public TestFixture { check("void foo() {\n" " scanf(\"%u\", \"s3\");\n" " scanf(\"%u\", L\"s5W\");\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 1) requires 'unsigned int *' but the argument type is 'const char *'.\n" "[test.cpp:3]: (warning) %u in format string (no. 1) requires 'unsigned int *' but the argument type is 'const wchar_t *'.\n", errout_str()); check("void foo(long l) {\n" " scanf(\"%u\", l);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 1) requires 'unsigned int *' but the argument type is 'signed long'.\n", errout_str()); TEST_SCANF_WARN("%lu","unsigned long","bool"); @@ -1584,13 +1584,13 @@ class TestIO : public TestFixture { check("void foo() {\n" " scanf(\"%Ld\", \"s3\");\n" " scanf(\"%Ld\", L\"s5W\");\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %Ld in format string (no. 1) requires 'long long *' but the argument type is 'const char *'.\n" "[test.cpp:3]: (warning) %Ld in format string (no. 1) requires 'long long *' but the argument type is 'const wchar_t *'.\n", errout_str()); check("void foo(int i) {\n" " scanf(\"%Ld\", i);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %Ld in format string (no. 1) requires 'long long *' but the argument type is 'signed int'.\n", errout_str()); TEST_SCANF_WARN("%ju", "uintmax_t", "bool"); @@ -2061,13 +2061,13 @@ class TestIO : public TestFixture { check("void foo() {\n" " scanf(\"%d\", \"s3\");\n" " scanf(\"%d\", L\"s5W\");\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 1) requires 'int *' but the argument type is 'const char *'.\n" "[test.cpp:3]: (warning) %d in format string (no. 1) requires 'int *' but the argument type is 'const wchar_t *'.\n", errout_str()); check("void foo(long l) {\n" " scanf(\"%d\", l);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 1) requires 'int *' but the argument type is 'signed long'.\n", errout_str()); TEST_SCANF_WARN("%x", "unsigned int", "bool"); @@ -2105,13 +2105,13 @@ class TestIO : public TestFixture { check("void foo() {\n" " scanf(\"%x\", \"s3\");\n" " scanf(\"%x\", L\"s5W\");\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'const char *'.\n" "[test.cpp:3]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'const wchar_t *'.\n", errout_str()); check("void foo(long l) {\n" " scanf(\"%x\", l);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'signed long'.\n", errout_str()); TEST_SCANF_WARN("%f", "float", "bool"); @@ -2145,13 +2145,13 @@ class TestIO : public TestFixture { check("void foo() {\n" " scanf(\"%f\", \"s3\");\n" " scanf(\"%f\", L\"s5W\");\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %f in format string (no. 1) requires 'float *' but the argument type is 'const char *'.\n" "[test.cpp:3]: (warning) %f in format string (no. 1) requires 'float *' but the argument type is 'const wchar_t *'.\n", errout_str()); check("void foo(float f) {\n" " scanf(\"%f\", f);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %f in format string (no. 1) requires 'float *' but the argument type is 'float'.\n", errout_str()); TEST_SCANF_WARN("%lf", "double", "bool"); @@ -2241,13 +2241,13 @@ class TestIO : public TestFixture { check("void foo() {\n" " scanf(\"%n\", \"s3\");\n" " scanf(\"%n\", L\"s5W\");\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'const char *'.\n" "[test.cpp:3]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'const wchar_t *'.\n", errout_str()); check("void foo(long l) {\n" " scanf(\"%n\", l);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'signed long'.\n", errout_str()); check("void g() {\n" // #5104 @@ -2261,7 +2261,7 @@ class TestIO : public TestFixture { " scanf(\"%lf\",&v4[0]);\n" " myvector v5(1);\n" " scanf(\"%10s\",v5[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); { @@ -2293,7 +2293,7 @@ class TestIO : public TestFixture { check("void g() {\n" " const char c[]=\"42\";\n" " scanf(\"%s\", c);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %s in format string (no. 1) requires a 'char *' but the argument type is 'const char *'.\n" "[test.cpp:3]: (warning) scanf() without field width limits can crash with huge input data.\n", errout_str()); } @@ -2303,7 +2303,7 @@ class TestIO : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %i in format string (no. 1) requires 'int *' but the argument type is 'const char *'.\n", errout_str()); - check("struct S { unsigned char a[1]; };" // #14302 + check("struct S { unsigned char a[1]; };\n" // #14302 "void f(S s) {\n" " scanf(\"%hhu\", s.a);\n" "}\n"); @@ -2321,7 +2321,7 @@ class TestIO : public TestFixture { " snprintf(str,10,\"%u%s\");\n" " sprintf(string1, \"%-*.*s\", 32, string2);\n" // #3364 " snprintf(a, 9, \"%s%d\", \"11223344\");\n" // #3655 - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (error) printf format string requires 1 parameter but only 0 are given.\n" "[test.cpp:3]: (error) printf format string requires 2 parameters but only 1 is given.\n" "[test.cpp:4]: (error) printf format string requires 3 parameters but only 2 are given.\n" @@ -2336,7 +2336,7 @@ class TestIO : public TestFixture { " printf(\"\", 0);\n" " printf(\"%i\", 123, bar());\n" " printf(\"%i%s\", 0, bar(), 43123);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) printf format string requires 0 parameters but 1 is given.\n" "[test.cpp:3]: (warning) printf format string requires 1 parameter but 2 are given.\n" "[test.cpp:4]: (warning) printf format string requires 2 parameters but 3 are given.\n", errout_str()); @@ -2346,7 +2346,7 @@ class TestIO : public TestFixture { " swprintf(string1, L\"%s%s\", L\"a\", string2);\n" // MSVC implementation " swprintf(string1, 6, L\"%i\", 32, string2);\n" // Standard implementation " swprintf(string1, 6, L\"%i%s\", 32, string2);\n" // Standard implementation - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) swprintf format string requires 1 parameter but 2 are given.\n" "[test.cpp:4]: (warning) swprintf format string requires 1 parameter but 2 are given.\n", errout_str()); @@ -2363,7 +2363,7 @@ class TestIO : public TestFixture { " printf(\"string: %.*s\", len, string);\n" // #3311 " fprintf(stderr, \"%*cText.\", indent, ' ');\n" // #3313 " sprintf(string1, \"%*\", 32);\n" // #3364 - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char* s, const char* s2, std::string s3, int i) {\n" @@ -2373,7 +2373,7 @@ class TestIO : public TestFixture { " printf(\"%s\", s3);\n" " printf(\"%s\", \"s4\");\n" " printf(\"%u\", s);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %s in format string (no. 1) requires 'char *' but the argument type is 'signed int'.\n" "[test.cpp:4]: (warning) %s in format string (no. 2) requires 'char *' but the argument type is 'signed int'.\n" "[test.cpp:5]: (warning) %s in format string (no. 1) requires 'char *' but the argument type is 'std::string'.\n" @@ -2386,7 +2386,7 @@ class TestIO : public TestFixture { " printf(\"%jo\", s3);\n" " printf(\"%jx\", i);\n" " printf(\"%jX\", i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %jd in format string (no. 1) requires 'intmax_t' but the argument type is 'char *'.\n" "[test.cpp:3]: (warning) %ji in format string (no. 1) requires 'intmax_t' but the argument type is 'char *'.\n" "[test.cpp:4]: (warning) %ju in format string (no. 1) requires 'uintmax_t' but the argument type is 'const char *'.\n" @@ -2400,7 +2400,7 @@ class TestIO : public TestFixture { " printf(\"%jd\", ui);\n" " printf(\"%jd\", s3);\n" " printf(\"%jd\", i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %ju in format string (no. 1) requires 'uintmax_t' but the argument type is 'unsigned int'.\n" "[test.cpp:4]: (warning) %jd in format string (no. 1) requires 'intmax_t' but the argument type is 'unsigned int'.\n" "[test.cpp:5]: (warning) %jd in format string (no. 1) requires 'intmax_t' but the argument type is 'std::string'.\n" @@ -2413,7 +2413,7 @@ class TestIO : public TestFixture { " printf(\"%n\", pi);\n" " printf(\"%n\", s);\n" " printf(\"%n\", \"s4\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'signed int'.\n" "[test.cpp:4]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'signed int'.\n" "[test.cpp:6]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'std::string'.\n" @@ -2421,7 +2421,7 @@ class TestIO : public TestFixture { check("void foo() {\n" " printf(\"%n\", L\"s5W\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'const wchar_t *'.\n", errout_str()); check("class foo {};\n" @@ -2434,7 +2434,7 @@ class TestIO : public TestFixture { " printf(\"%X\", bp);\n" " printf(\"%X\", u);\n" " printf(\"%X\", i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %X in format string (no. 1) requires 'unsigned int' but the argument type is 'foo'.\n" "[test.cpp:4]: (warning) %c in format string (no. 1) requires 'unsigned int' but the argument type is 'const char *'.\n" "[test.cpp:5]: (warning) %o in format string (no. 1) requires 'unsigned int' but the argument type is 'double'.\n" @@ -2445,7 +2445,7 @@ class TestIO : public TestFixture { "void foo(const char* cpc, char* pc) {\n" " printf(\"%x\", cpc);\n" " printf(\"%x\", pc);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %x in format string (no. 1) requires 'unsigned int' but the argument type is 'const char *'.\n" "[test.cpp:4]: (warning) %x in format string (no. 1) requires 'unsigned int' but the argument type is 'char *'.\n", errout_str()); @@ -2455,7 +2455,7 @@ class TestIO : public TestFixture { " printf(\"%X\", L\"s5W\");\n" " printf(\"%c\", L\"s5W\");\n" " printf(\"%o\", L\"s5W\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %x in format string (no. 1) requires 'unsigned int' but the argument type is 'const wchar_t *'.\n" "[test.cpp:4]: (warning) %X in format string (no. 1) requires 'unsigned int' but the argument type is 'const wchar_t *'.\n" "[test.cpp:5]: (warning) %c in format string (no. 1) requires 'unsigned int' but the argument type is 'const wchar_t *'.\n" @@ -2471,7 +2471,7 @@ class TestIO : public TestFixture { " printf(\"%i\", b);\n" " printf(\"%i\", bp);\n" " printf(\"%i\", uc);\n" // char is smaller than int, so there shouldn't be a problem - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %i in format string (no. 1) requires 'int' but the argument type is 'foo'.\n" "[test.cpp:4]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'const char *'.\n" "[test.cpp:5]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'double'.\n" @@ -2483,7 +2483,7 @@ class TestIO : public TestFixture { "void foo() {\n" " printf(\"%i\", L\"s5W\");\n" " printf(\"%d\", L\"s5W\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %i in format string (no. 1) requires 'int' but the argument type is 'const wchar_t *'.\n" "[test.cpp:4]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'const wchar_t *'.\n", errout_str()); @@ -2497,7 +2497,7 @@ class TestIO : public TestFixture { " printf(\"%u\", b);\n" " printf(\"%u\", bp);\n" " printf(\"%u\", bo);\n" // bool shouldn't have a negative sign - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'foo'.\n" "[test.cpp:4]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'const char *'.\n" "[test.cpp:5]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'double'.\n" @@ -2508,7 +2508,7 @@ class TestIO : public TestFixture { check("class foo {};\n" "void foo(const int* cpi, foo f, bar b, bar* bp, double d, int i, bool bo) {\n" " printf(\"%u\", L\"s5W\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'const wchar_t *'.\n", errout_str()); check("class foo {};\n" @@ -2518,7 +2518,7 @@ class TestIO : public TestFixture { " printf(\"%p\", bp);\n" " printf(\"%p\", cpi);\n" " printf(\"%p\", b);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %p in format string (no. 1) requires an address but the argument type is 'foo'.\n" "[test.cpp:4]: (warning) %p in format string (no. 1) requires an address but the argument type is 'char'.\n", errout_str()); @@ -2530,7 +2530,7 @@ class TestIO : public TestFixture { " printf(\"%p\", cpwc);\n" " printf(\"%p\", \"s4\");\n" " printf(\"%p\", L\"s5W\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class foo {};\n" @@ -2542,7 +2542,7 @@ class TestIO : public TestFixture { " printf(\"%f\", d);\n" " printf(\"%f\", b);\n" " printf(\"%f\", (float)cpi);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires 'double' but the argument type is 'foo'.\n" "[test.cpp:4]: (warning) %E in format string (no. 1) requires 'double' but the argument type is 'const char *'.\n" "[test.cpp:5]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'const signed int *'.\n" @@ -2555,7 +2555,7 @@ class TestIO : public TestFixture { " printf(\"%f\", cpc);\n" " printf(\"%G\", pc);\n" " printf(\"%f\", pc);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires 'double' but the argument type is 'const char *'.\n" "[test.cpp:4]: (warning) %E in format string (no. 1) requires 'double' but the argument type is 'char *'.\n" "[test.cpp:5]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'const char *'.\n" @@ -2568,7 +2568,7 @@ class TestIO : public TestFixture { " printf(\"%E\", L\"s5W\");\n" " printf(\"%f\", L\"s5W\");\n" " printf(\"%G\", L\"s5W\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires 'double' but the argument type is 'const wchar_t *'.\n" "[test.cpp:4]: (warning) %E in format string (no. 1) requires 'double' but the argument type is 'const wchar_t *'.\n" "[test.cpp:5]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'const wchar_t *'.\n" @@ -2579,7 +2579,7 @@ class TestIO : public TestFixture { " printf(\"%u\", f);\n" " printf(\"%f\", f);\n" " printf(\"%p\", f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'foo'.\n" "[test.cpp:4]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'foo'.\n" "[test.cpp:5]: (warning) %p in format string (no. 1) requires an address but the argument type is 'foo'.\n", errout_str()); @@ -2589,14 +2589,14 @@ class TestIO : public TestFixture { check("void foo(signed char sc, unsigned char uc, short int si, unsigned short int usi) {\n" " printf(\"%hhx %hhd\", sc, uc);\n" " printf(\"%hd %hu\", si, usi);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %hhx in format string (no. 1) requires 'unsigned char' but the argument type is 'signed char'.\n" "[test.cpp:2]: (warning) %hhd in format string (no. 2) requires 'char' but the argument type is 'unsigned char'.\n", errout_str()); check("void foo(long long int lli, unsigned long long int ulli, long int li, unsigned long int uli) {\n" " printf(\"%llo %llx\", lli, ulli);\n" " printf(\"%ld %lu\", li, uli);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(intmax_t im, uintmax_t uim, size_t s, ptrdiff_t p, long double ld, std::size_t ss, std::ptrdiff_t sp) {\n" @@ -2606,7 +2606,7 @@ class TestIO : public TestFixture { " printf(\"%Lf\", ld);\n" " printf(\"%zx\", ss);\n" " printf(\"%ti\", sp);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Unrecognized (and non-existent in standard library) specifiers. @@ -2618,31 +2618,31 @@ class TestIO : public TestFixture { " printf(\"%La\", ld);\n" " printf(\"%zv\", ss);\n" " printf(\"%tp\", sp);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(long long l, ptrdiff_t p, std::ptrdiff_t sp) {\n" " printf(\"%td\", p);\n" " printf(\"%td\", sp);\n" " printf(\"%td\", l);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4]: (warning) %td in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'signed long long'.\n", errout_str()); check("void foo(int i, long double ld) {\n" " printf(\"%zx %zu\", i, ld);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %zx in format string (no. 1) requires 'size_t' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %zu in format string (no. 2) requires 'size_t' but the argument type is 'long double'.\n", errout_str()); check("void foo(unsigned int ui, long double ld) {\n" " printf(\"%zu %zx\", ui, ld);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %zu in format string (no. 1) requires 'size_t' but the argument type is 'unsigned int'.\n" "[test.cpp:2]: (warning) %zx in format string (no. 2) requires 'size_t' but the argument type is 'long double'.\n", errout_str()); check("void foo(int i, long double ld) {\n" " printf(\"%tx %tu\", i, ld);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %tx in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %tu in format string (no. 2) requires 'unsigned ptrdiff_t' but the argument type is 'long double'.\n", errout_str()); @@ -2657,7 +2657,7 @@ class TestIO : public TestFixture { " printf(\"%t\", i);\n" " printf(\"%L\", i);\n" " printf(\"%I\", i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) 'h' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n" "[test.cpp:3]: (warning) 'hh' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n" "[test.cpp:4]: (warning) 'l' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n" @@ -2673,7 +2673,7 @@ class TestIO : public TestFixture { " printf(\"%hhd\", i);\n" " printf(\"%ld\", i);\n" " printf(\"%lld\", i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %hd in format string (no. 1) requires 'short' but the argument type is 'unsigned int'.\n" "[test.cpp:3]: (warning) %hhd in format string (no. 1) requires 'char' but the argument type is 'unsigned int'.\n" "[test.cpp:4]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'unsigned int'.\n" @@ -2682,56 +2682,56 @@ class TestIO : public TestFixture { check("void foo(size_t s, ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix32)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix32)); ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka signed long}'.\n", errout_str()); check("void foo(std::size_t s, std::ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix32)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix32)); ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n" "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka signed long}'.\n", errout_str()); check("void foo(size_t s, ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix64)); ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka signed long}'.\n", errout_str()); check("void foo(std::size_t s, std::ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix64)); ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n" "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka signed long}'.\n", errout_str()); check("void foo(size_t s, ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka signed long}'.\n", errout_str()); check("void foo(std::size_t s, std::ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n" "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka signed long}'.\n", errout_str()); check("void foo(size_t s, ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long long}'.\n" "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka signed long long}'.\n", errout_str()); check("void foo(std::size_t s, std::ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long long}'.\n" "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka signed long long}'.\n", errout_str()); @@ -2740,7 +2740,7 @@ class TestIO : public TestFixture { " printf(\"%lu\", um);\n" " printf(\"%llu\", s);\n" " printf(\"%llu\", um);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:2]: (portability) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'size_t {aka unsigned long long}'.\n" "[test.cpp:3]: (portability) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'uintmax_t {aka unsigned long long}'.\n" "[test.cpp:4]: (portability) %llu in format string (no. 1) requires 'unsigned long long' but the argument type is 'size_t {aka unsigned long long}'.\n" @@ -2753,7 +2753,7 @@ class TestIO : public TestFixture { " printf(\"%llu\", i);\n" " printf(\"%lx\", i);\n" " printf(\"%llx\", i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'unsigned int'.\n" "[test.cpp:3]: (warning) %lld in format string (no. 1) requires 'long long' but the argument type is 'unsigned int'.\n" "[test.cpp:4]: (warning) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'unsigned int'.\n" @@ -2765,13 +2765,13 @@ class TestIO : public TestFixture { " printf(\"%lld\", i);\n" " printf(\"%lld\", im);\n" " printf(\"%lld\", p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %lld in format string (no. 1) requires 'long long' but the argument type is 'signed int'.\n", errout_str()); check("void foo(intmax_t im, ptrdiff_t p) {\n" " printf(\"%lld\", im);\n" " printf(\"%lld\", p);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:2]: (portability) %lld in format string (no. 1) requires 'long long' but the argument type is 'intmax_t {aka signed long long}'.\n" "[test.cpp:3]: (portability) %lld in format string (no. 1) requires 'long long' but the argument type is 'ptrdiff_t {aka signed long long}'.\n", errout_str()); @@ -2790,7 +2790,7 @@ class TestIO : public TestFixture { " printf(\"%d %f %f %d %f %f\",\n" " foo->d, foo->bar[0].i, a[0],\n" " f[0].d, f[0].baz.i, f[0].bar[0].i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:13]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'double'.\n" "[test.cpp:13]: (warning) %f in format string (no. 2) requires 'double' but the argument type is 'signed int'.\n" "[test.cpp:13]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'int'.\n" @@ -2799,7 +2799,7 @@ class TestIO : public TestFixture { "[test.cpp:13]: (warning) %f in format string (no. 6) requires 'double' but the argument type is 'int'.\n", errout_str()); check("short f() { return 0; }\n" - "void foo() { printf(\"%d %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%d %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed short'.\n" "[test.cpp:2]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed short'.\n" "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires 'unsigned __int64' but the argument type is 'signed short'.\n" @@ -2809,7 +2809,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'signed short'.\n", errout_str()); check("unsigned short f() { return 0; }\n" - "void foo() { printf(\"%u %d %ld %I64d %I64u %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%u %d %ld %I64d %I64u %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'unsigned short'.\n" "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires '__int64' but the argument type is 'unsigned short'.\n" "[test.cpp:2]: (warning) %I64u in format string (no. 5) requires 'unsigned __int64' but the argument type is 'unsigned short'.\n" @@ -2818,7 +2818,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'unsigned short'.\n", errout_str()); check("int f() { return 0; }\n" - "void foo() { printf(\"%d %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%d %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires 'unsigned __int64' but the argument type is 'signed int'.\n" @@ -2828,7 +2828,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'signed int'.\n", errout_str()); check("unsigned int f() { return 0; }\n" - "void foo() { printf(\"%u %d %ld %I64d %I64u %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%u %d %ld %I64d %I64u %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'unsigned int'.\n" "[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'unsigned int'.\n" "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires '__int64' but the argument type is 'unsigned int'.\n" @@ -2838,7 +2838,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'unsigned int'.\n", errout_str()); check("long f() { return 0; }\n" - "void foo() { printf(\"%ld %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%ld %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed long'.\n" "[test.cpp:2]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed long'.\n" "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires 'unsigned __int64' but the argument type is 'signed long'.\n" @@ -2848,7 +2848,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'signed long'.\n", errout_str()); check("unsigned long f() { return 0; }\n" - "void foo() { printf(\"%lu %d %ld %I64d %I64u %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%lu %d %ld %I64d %I64u %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'unsigned long'.\n" "[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'unsigned long'.\n" "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires '__int64' but the argument type is 'unsigned long'.\n" @@ -2858,7 +2858,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'unsigned long'.\n", errout_str()); check("long long f() { return 0; }\n" - "void foo() { printf(\"%lld %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%lld %u %lu %I64u %I64d %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed long long'.\n" "[test.cpp:2]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed long long'.\n" "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires 'unsigned __int64' but the argument type is 'signed long long'.\n" @@ -2867,7 +2867,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'signed long long'.\n", errout_str()); check("unsigned long long f() { return 0; }\n" - "void foo() { printf(\"%llu %d %ld %I64d %I64u %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%llu %d %ld %I64d %I64u %f %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'unsigned long long'.\n" "[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'unsigned long long'.\n" "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires '__int64' but the argument type is 'unsigned long long'.\n" @@ -2876,7 +2876,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'unsigned long long'.\n", errout_str()); check("float f() { return 0; }\n" - "void foo() { printf(\"%f %d %ld %u %lu %I64d %I64u %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%f %d %ld %u %lu %I64d %I64u %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'float'.\n" "[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'float'.\n" "[test.cpp:2]: (warning) %u in format string (no. 4) requires 'unsigned int' but the argument type is 'float'.\n" @@ -2887,7 +2887,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address but the argument type is 'float'.\n", errout_str()); check("double f() { return 0; }\n" - "void foo() { printf(\"%f %d %ld %u %lu %I64d %I64u %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%f %d %ld %u %lu %I64d %I64u %Lf %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'double'.\n" "[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'double'.\n" "[test.cpp:2]: (warning) %u in format string (no. 4) requires 'unsigned int' but the argument type is 'double'.\n" @@ -2898,7 +2898,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address but the argument type is 'double'.\n", errout_str()); check("long double f() { return 0; }\n" - "void foo() { printf(\"%Lf %d %ld %u %lu %I64d %I64u %f %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }"); + "void foo() { printf(\"%Lf %d %ld %u %lu %I64d %I64u %f %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'long double'.\n" "[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'long double'.\n" "[test.cpp:2]: (warning) %u in format string (no. 4) requires 'unsigned int' but the argument type is 'long double'.\n" @@ -2909,37 +2909,37 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address but the argument type is 'long double'.\n", errout_str()); check("int f() { return 0; }\n" - "void foo() { printf(\"%I64d %I64u %I64x %d\", f(), f(), f(), f()); }"); + "void foo() { printf(\"%I64d %I64u %I64x %d\", f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %I64d in format string (no. 1) requires '__int64' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %I64u in format string (no. 2) requires 'unsigned __int64' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %I64x in format string (no. 3) requires 'unsigned __int64' but the argument type is 'signed int'.\n", errout_str()); check("long long f() { return 0; }\n" - "void foo() { printf(\"%I32d %I32u %I32x %lld\", f(), f(), f(), f()); }"); + "void foo() { printf(\"%I32d %I32u %I32x %lld\", f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'signed long long'.\n" "[test.cpp:2]: (warning) %I32u in format string (no. 2) requires 'unsigned __int32' but the argument type is 'signed long long'.\n" "[test.cpp:2]: (warning) %I32x in format string (no. 3) requires 'unsigned __int32' but the argument type is 'signed long long'.\n", errout_str()); check("unsigned long long f() { return 0; }\n" - "void foo() { printf(\"%I32d %I32u %I32x %llx\", f(), f(), f(), f()); }"); + "void foo() { printf(\"%I32d %I32u %I32x %llx\", f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned long long'.\n" "[test.cpp:2]: (warning) %I32u in format string (no. 2) requires 'unsigned __int32' but the argument type is 'unsigned long long'.\n" "[test.cpp:2]: (warning) %I32x in format string (no. 3) requires 'unsigned __int32' but the argument type is 'unsigned long long'.\n", errout_str()); check("signed char f() { return 0; }\n" - "void foo() { printf(\"%Id %Iu %Ix %hhi\", f(), f(), f(), f()); }"); + "void foo() { printf(\"%Id %Iu %Ix %hhi\", f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %Id in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'signed char'.\n" "[test.cpp:2]: (warning) %Iu in format string (no. 2) requires 'size_t' but the argument type is 'signed char'.\n" "[test.cpp:2]: (warning) %Ix in format string (no. 3) requires 'size_t' but the argument type is 'signed char'.\n", errout_str()); check("unsigned char f() { return 0; }\n" - "void foo() { printf(\"%Id %Iu %Ix %hho\", f(), f(), f(), f()); }"); + "void foo() { printf(\"%Id %Iu %Ix %hho\", f(), f(), f(), f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %Id in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'unsigned char'.\n" "[test.cpp:2]: (warning) %Iu in format string (no. 2) requires 'size_t' but the argument type is 'unsigned char'.\n" "[test.cpp:2]: (warning) %Ix in format string (no. 3) requires 'size_t' but the argument type is 'unsigned char'.\n", errout_str()); check("namespace bar { int f() { return 0; } }\n" - "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar::f(), bar::f(), bar::f(), bar::f(), bar::f(), bar::f()); }"); + "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar::f(), bar::f(), bar::f(), bar::f(), bar::f(), bar::f()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'signed int'.\n" @@ -2947,7 +2947,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address but the argument type is 'signed int'.\n", errout_str()); check("struct Fred { int i; } f;\n" - "void foo() { printf(\"%d %u %lu %f %Lf %p\", f.i, f.i, f.i, f.i, f.i, f.i); }"); + "void foo() { printf(\"%d %u %lu %f %Lf %p\", f.i, f.i, f.i, f.i, f.i, f.i); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'signed int'.\n" @@ -2955,7 +2955,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address but the argument type is 'signed int'.\n", errout_str()); check("struct Fred { unsigned int u; } f;\n" - "void foo() { printf(\"%u %d %ld %f %Lf %p\", f.u, f.u, f.u, f.u, f.u, f.u); }"); + "void foo() { printf(\"%u %d %ld %f %Lf %p\", f.u, f.u, f.u, f.u, f.u, f.u); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'unsigned int'.\n" "[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'unsigned int'.\n" "[test.cpp:2]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'unsigned int'.\n" @@ -2963,7 +2963,7 @@ class TestIO : public TestFixture { "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address but the argument type is 'unsigned int'.\n", errout_str()); check("struct Fred { unsigned int ui() { return 0; } } f;\n" - "void foo() { printf(\"%u %d %ld %f %Lf %p\", f.ui(), f.ui(), f.ui(), f.ui(), f.ui(), f.ui()); }"); + "void foo() { printf(\"%u %d %ld %f %Lf %p\", f.ui(), f.ui(), f.ui(), f.ui(), f.ui(), f.ui()); }\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'unsigned int'.\n" "[test.cpp:2]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'unsigned int'.\n" "[test.cpp:2]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'unsigned int'.\n" @@ -2974,12 +2974,12 @@ class TestIO : public TestFixture { check("void f(int len, int newline) {\n" " printf(\"%s\", newline ? a : str + len);\n" " printf(\"%s\", newline + newline);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %s in format string (no. 1) requires 'char *' but the argument type is 'signed int'.\n", errout_str()); check("struct Fred { int i; } f;\n" "struct Fred & bar() { };\n" - "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }"); + "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'signed int'.\n" @@ -2988,7 +2988,7 @@ class TestIO : public TestFixture { check("struct Fred { int i; } f;\n" "const struct Fred & bar() { };\n" - "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }"); + "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'signed int'.\n" @@ -2997,7 +2997,7 @@ class TestIO : public TestFixture { check("struct Fred { int i; } f;\n" "static const struct Fred & bar() { };\n" - "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }"); + "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'signed int'.\n" @@ -3006,7 +3006,7 @@ class TestIO : public TestFixture { check("struct Fred { int i; } f[2];\n" "struct Fred * bar() { return f; };\n" - "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }"); + "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'signed int'.\n" @@ -3015,7 +3015,7 @@ class TestIO : public TestFixture { check("struct Fred { int i; } f[2];\n" "const struct Fred * bar() { return f; };\n" - "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }"); + "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'signed int'.\n" @@ -3024,7 +3024,7 @@ class TestIO : public TestFixture { check("struct Fred { int i; } f[2];\n" "static const struct Fred * bar() { return f; };\n" - "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }"); + "void foo() { printf(\"%d %u %lu %f %Lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %lu in format string (no. 3) requires 'unsigned long' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'signed int'.\n" @@ -3033,7 +3033,7 @@ class TestIO : public TestFixture { check("struct Fred { int32_t i; } f;\n" "struct Fred & bar() { };\n" - "void foo() { printf(\"%d %ld %u %lu %f %Lf\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }"); + "void foo() { printf(\"%d %ld %u %lu %f %Lf\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %ld in format string (no. 2) requires 'long' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %u in format string (no. 3) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %lu in format string (no. 4) requires 'unsigned long' but the argument type is 'signed int'.\n" @@ -3044,27 +3044,27 @@ class TestIO : public TestFixture { // #4984 check("void f(double *x) {\n" " printf(\"%f\", x[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int array[10];\n" "int * foo() { return array; }\n" "void f() {\n" " printf(\"%f\", foo()[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'.\n", errout_str()); check("struct Base { int length() { } };\n" "struct Derived : public Base { };\n" "void foo(Derived * d) {\n" " printf(\"%f\", d.length());\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'.\n", errout_str()); check("std::vector v;\n" "void foo() {\n" " printf(\"%d %u %f\", v[0], v[0], v[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:3]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'signed int'.\n", errout_str()); @@ -3072,7 +3072,7 @@ class TestIO : public TestFixture { check("int bar(int a);\n" "void foo() {\n" " printf(\"%d\", bar(0));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector v;\n" @@ -3318,20 +3318,20 @@ class TestIO : public TestFixture { check("void foo() {\n" " printf(\"%f %d\", static_cast(1.0f), reinterpret_cast(0));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const void *'.\n", errout_str()); check("void foo() {\n" " UNKNOWN * u;\n" " printf(\"%d %x %u %f\", u[i], u[i], u[i], u[i]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " long * l;\n" " printf(\"%d %x %u %f\", l[i], l[i], l[i], l[i]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'signed long'.\n" "[test.cpp:3]: (warning) %x in format string (no. 2) requires 'unsigned int' but the argument type is 'signed long'.\n" "[test.cpp:3]: (warning) %u in format string (no. 3) requires 'unsigned int' but the argument type is 'signed long'.\n" @@ -3352,27 +3352,27 @@ class TestIO : public TestFixture { " printf(\"%u\",v6[0]);\n" " myvector v7(1,0);\n" " printf(\"%s\",v7[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::vector v;\n" // #5151 "void foo() {\n" " printf(\"%c %u %f\", v.at(32), v.at(32), v.at(32));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'char'.\n" "[test.cpp:3]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'char'.\n", errout_str()); // #5195 (segmentation fault) check("void T::a(const std::vector& vx) {\n" " printf(\"%f\", vx.at(0));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5486 check("void foo() {\n" " ssize_t test = 0;\n" " printf(\"%zd\", test);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6009 @@ -3380,7 +3380,7 @@ class TestIO : public TestFixture { "extern int IntByReturnValue();\n" "void MyFunction() {\n" " printf( \"%s - %s\", StringByReturnValue(), IntByReturnValue() );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4]: (warning) %s in format string (no. 1) requires 'char *' but the argument type is 'std::string'.\n" "[test.cpp:4]: (warning) %s in format string (no. 2) requires 'char *' but the argument type is 'signed int'.\n", errout_str()); @@ -3393,7 +3393,7 @@ class TestIO : public TestFixture { " Array array1;\n" " Array array2;\n" " printf(\"%u %u\", array1[0], array2[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'int'.\n" "[test.cpp:9]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'float'.\n", errout_str()); @@ -3401,19 +3401,19 @@ class TestIO : public TestFixture { check("struct S { unsigned short x; } s = {0};\n" "void foo() {\n" " printf(\"%d\", s.x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Ticket #7601 check("void foo(int i, unsigned int ui, long long ll, unsigned long long ull) {\n" " printf(\"%Ld %Lu %Ld %Lu\", i, ui, ll, ull);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %Ld in format string (no. 1) requires 'long long' but the argument type is 'signed int'.\n" "[test.cpp:2]: (warning) %Lu in format string (no. 2) requires 'unsigned long long' but the argument type is 'unsigned int'.\n", errout_str()); check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n" " printf(\"%hhd %hhd %hhd %hhd %hhd %hhd %hhd %hhd\", c, uc, s, us, i, ui, l, ul);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %hhd in format string (no. 2) requires 'char' but the argument type is 'unsigned char'.\n" "[test.cpp:2]: (warning) %hhd in format string (no. 3) requires 'char' but the argument type is 'signed short'.\n" "[test.cpp:2]: (warning) %hhd in format string (no. 4) requires 'char' but the argument type is 'unsigned short'.\n" @@ -3424,7 +3424,7 @@ class TestIO : public TestFixture { check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n" " printf(\"%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu\", c, uc, s, us, i, ui, l, ul);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %hhu in format string (no. 1) requires 'unsigned char' but the argument type is 'char'.\n" "[test.cpp:2]: (warning) %hhu in format string (no. 3) requires 'unsigned char' but the argument type is 'signed short'.\n" "[test.cpp:2]: (warning) %hhu in format string (no. 4) requires 'unsigned char' but the argument type is 'unsigned short'.\n" @@ -3435,7 +3435,7 @@ class TestIO : public TestFixture { check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n" " printf(\"%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\", c, uc, s, us, i, ui, l, ul);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %hhx in format string (no. 1) requires 'unsigned char' but the argument type is 'char'.\n" "[test.cpp:2]: (warning) %hhx in format string (no. 3) requires 'unsigned char' but the argument type is 'signed short'.\n" "[test.cpp:2]: (warning) %hhx in format string (no. 4) requires 'unsigned char' but the argument type is 'unsigned short'.\n" @@ -3446,7 +3446,7 @@ class TestIO : public TestFixture { check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n" " printf(\"%hd %hd %hd %hd %hd %hd %hd %hd\", c, uc, s, us, i, ui, l, ul);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %hd in format string (no. 1) requires 'short' but the argument type is 'char'.\n" "[test.cpp:2]: (warning) %hd in format string (no. 2) requires 'short' but the argument type is 'unsigned char'.\n" "[test.cpp:2]: (warning) %hd in format string (no. 4) requires 'short' but the argument type is 'unsigned short'.\n" @@ -3457,7 +3457,7 @@ class TestIO : public TestFixture { check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n" " printf(\"%hu %hu %hu %hu %hu %hu %hu %hu\", c, uc, s, us, i, ui, l, ul);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %hu in format string (no. 1) requires 'unsigned short' but the argument type is 'char'.\n" "[test.cpp:2]: (warning) %hu in format string (no. 2) requires 'unsigned short' but the argument type is 'unsigned char'.\n" "[test.cpp:2]: (warning) %hu in format string (no. 3) requires 'unsigned short' but the argument type is 'signed short'.\n" @@ -3468,7 +3468,7 @@ class TestIO : public TestFixture { check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n" " printf(\"%hx %hx %hx %hx %hx %hx %hx %hx\", c, uc, s, us, i, ui, l, ul);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2]: (warning) %hx in format string (no. 1) requires 'unsigned short' but the argument type is 'char'.\n" "[test.cpp:2]: (warning) %hx in format string (no. 2) requires 'unsigned short' but the argument type is 'unsigned char'.\n" "[test.cpp:2]: (warning) %hx in format string (no. 3) requires 'unsigned short' but the argument type is 'signed short'.\n" @@ -3484,19 +3484,19 @@ class TestIO : public TestFixture { "\n" "void foo(struct S x) {\n" " printf(\"%f\", x.f(4.0));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("enum E : uint8_t { E0 }; \n" // #7959 "void f(E e) {\n" " printf(\"%hhu\", e);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("enum E : uint8_t { E0 }; \n" "void f(E e) {\n" " printf(\"%lu\", e);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'uint8_t'.\n", "", errout_str()); @@ -4259,7 +4259,7 @@ class TestIO : public TestFixture { " printf(\"%1$d\", 1);" " printf(\"%1$d, %d, %1$d\", 1, 2);" " scanf(\"%1$d\", &bar);" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -4268,7 +4268,7 @@ class TestIO : public TestFixture { " printf(\"%1$d, %d, %4$d\", 1, 2, 3);\n" " scanf(\"%2$d\", &bar);\n" " printf(\"%0$f\", 0.0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error) printf format string requires 1 parameter but only 0 are given. [wrongPrintfScanfArgNum]\n" "[test.cpp:4:3]: (warning) printf: referencing parameter 4 while 3 arguments given [wrongPrintfScanfParameterPositionError]\n" "[test.cpp:5:3]: (warning) scanf: referencing parameter 2 while 1 arguments given [wrongPrintfScanfParameterPositionError]\n" @@ -4291,7 +4291,7 @@ class TestIO : public TestFixture { " printf(\"%I32d %I32u %I32x\", u32, u32, u32);\n" " printf(\"%I64d %I64u %I64x\", i64, i64, i64);\n" " printf(\"%I64d %I64u %I64x\", u64, u64, u64);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:8:5]: (portability) %Id in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'size_t {aka unsigned long}'. [invalidPrintfArgType_sint]\n" "[test.cpp:9:5]: (portability) %Iu in format string (no. 2) requires 'size_t' but the argument type is 'ptrdiff_t {aka signed long}'. [invalidPrintfArgType_uint]\n" "[test.cpp:9:5]: (portability) %Ix in format string (no. 3) requires 'size_t' but the argument type is 'ptrdiff_t {aka signed long}'. [invalidPrintfArgType_uint]\n" @@ -4313,7 +4313,7 @@ class TestIO : public TestFixture { " printf(\"%I32d %I32u %I32x\", u32, u32, u32);\n" " printf(\"%I64d %I64u %I64x\", i64, i64, i64);\n" " printf(\"%I64d %I64u %I64x\", u64, u64, u64);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:8:5]: (portability) %Id in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'size_t {aka unsigned long long}'. [invalidPrintfArgType_sint]\n" "[test.cpp:9:5]: (portability) %Iu in format string (no. 2) requires 'size_t' but the argument type is 'ptrdiff_t {aka signed long long}'. [invalidPrintfArgType_uint]\n" "[test.cpp:9:5]: (portability) %Ix in format string (no. 3) requires 'size_t' but the argument type is 'ptrdiff_t {aka signed long long}'. [invalidPrintfArgType_uint]\n" @@ -4339,7 +4339,7 @@ class TestIO : public TestFixture { " printf(\"%I16x%i\", s, i);\n" " printf(\"%I32%i\", s, i);\n" " printf(\"%I64%i\", s, i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) 'I' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier. [invalidLengthModifierError]\n" "[test.cpp:5:5]: (warning) 'I' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier. [invalidLengthModifierError]\n" "[test.cpp:6:5]: (warning) 'I' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier. [invalidLengthModifierError]\n" @@ -4384,7 +4384,7 @@ class TestIO : public TestFixture { " printf(\"%zd\", s);\n" " printf(\"%zd%i\", s, i);\n" " printf(\"%zu\", s);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:6:5]: (portability) %zu in format string (no. 1) requires 'size_t' but the argument type is 'SSIZE_T {aka signed long}'. [invalidPrintfArgType_uint]\n", errout_str()); check("void foo() {\n" @@ -4393,7 +4393,7 @@ class TestIO : public TestFixture { " printf(\"%zd\", s);\n" " printf(\"%zd%i\", s, i);\n" " printf(\"%zu\", s);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:6:5]: (portability) %zu in format string (no. 1) requires 'size_t' but the argument type is 'SSIZE_T {aka signed long long}'. [invalidPrintfArgType_uint]\n", errout_str()); check("void foo() {\n" @@ -4402,7 +4402,7 @@ class TestIO : public TestFixture { " printf(\"%zd\", s);\n" " printf(\"%zd%i\", s, i);\n" " printf(\"%zu\", s);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix64)); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -4412,7 +4412,7 @@ class TestIO : public TestFixture { " printf(\"%zd\", s);\n" " printf(\"%zd%i\", s, i);\n" " printf(\"%zu\", s);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:7:5]: (portability) %zu in format string (no. 1) requires 'size_t' but the argument type is 'SSIZE_T {aka signed long long}'. [invalidPrintfArgType_uint]\n", errout_str()); } @@ -4431,7 +4431,7 @@ class TestIO : public TestFixture { " scanf(\"%I32d %I32u %I32x\", &u32, &u32, &u32);\n" " scanf(\"%I64d %I64u %I64x\", &i64, &i64, &i64);\n" " scanf(\"%I64d %I64u %I64x\", &u64, &u64, &u64);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:8:5]: (portability) %Id in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long *}'. [invalidScanfArgType_int]\n" "[test.cpp:9:5]: (portability) %Iu in format string (no. 2) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka signed long *}'. [invalidScanfArgType_int]\n" "[test.cpp:9:5]: (portability) %Ix in format string (no. 3) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka signed long *}'. [invalidScanfArgType_int]\n" @@ -4455,7 +4455,7 @@ class TestIO : public TestFixture { " scanf(\"%I32d %I32u %I32x\", &u32, &u32, &u32);\n" " scanf(\"%I64d %I64u %I64x\", &i64, &i64, &i64);\n" " scanf(\"%I64d %I64u %I64x\", &u64, &u64, &u64);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:8:5]: (portability) %Id in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long long *}'. [invalidScanfArgType_int]\n" "[test.cpp:9:5]: (portability) %Iu in format string (no. 2) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka signed long long *}'. [invalidScanfArgType_int]\n" "[test.cpp:9:5]: (portability) %Ix in format string (no. 3) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka signed long long *}'. [invalidScanfArgType_int]\n" @@ -4483,7 +4483,7 @@ class TestIO : public TestFixture { " scanf(\"%I16x%i\", &s, &i);\n" " scanf(\"%I32%i\", &s, &i);\n" " scanf(\"%I64%i\", &s, &i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning) 'I' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier. [invalidLengthModifierError]\n" "[test.cpp:5:5]: (warning) 'I' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier. [invalidLengthModifierError]\n" "[test.cpp:6:5]: (warning) 'I' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier. [invalidLengthModifierError]\n" @@ -4505,7 +4505,7 @@ class TestIO : public TestFixture { " scanf(\"%zd\", &s);\n" " scanf(\"%zd%i\", &s, &i);\n" " scanf(\"%zu\", &s);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:6:5]: (portability) %zu in format string (no. 1) requires 'size_t *' but the argument type is 'SSIZE_T * {aka signed long *}'. [invalidScanfArgType_int]\n", errout_str()); check("void foo() {\n" @@ -4514,7 +4514,7 @@ class TestIO : public TestFixture { " scanf(\"%zd\", &s);\n" " scanf(\"%zd%i\", &s, &i);\n" " scanf(\"%zu\", &s);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:6:5]: (portability) %zu in format string (no. 1) requires 'size_t *' but the argument type is 'SSIZE_T * {aka signed long long *}'. [invalidScanfArgType_int]\n", errout_str()); check("void foo() {\n" @@ -4523,7 +4523,7 @@ class TestIO : public TestFixture { " scanf(\"%zd\", &s);\n" " scanf(\"%zd%i\", &s, &i);\n" " scanf(\"%zu\", &s);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix64)); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -4533,7 +4533,7 @@ class TestIO : public TestFixture { " scanf(\"%zd\", &s);\n" " scanf(\"%zd%i\", &s, &i);\n" " scanf(\"%zu\", &s);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win64)); ASSERT_EQUALS("[test.cpp:7:5]: (portability) %zu in format string (no. 1) requires 'size_t *' but the argument type is 'SSIZE_T * {aka signed long long *}'. [invalidScanfArgType_int]\n", errout_str()); } @@ -4544,7 +4544,7 @@ class TestIO : public TestFixture { " String string;\n" " string.Format(\"%I32d\", u32);\n" " string.AppendFormat(\"%I32d\", u32);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -4552,7 +4552,7 @@ class TestIO : public TestFixture { " CString string;\n" " string.Format(\"%I32d\", u32);\n" " string.AppendFormat(\"%I32d\", u32);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix32)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Unix32)); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -4561,7 +4561,7 @@ class TestIO : public TestFixture { " string.Format(\"%I32d\", u32);\n" " string.AppendFormat(\"%I32d\", u32);\n" " CString::Format(\"%I32d\", u32);\n" - "}", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.portability = true, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:4:12]: (portability) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'. [invalidPrintfArgType_sint]\n" "[test.cpp:5:12]: (portability) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'. [invalidPrintfArgType_sint]\n" "[test.cpp:6:14]: (portability) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'. [invalidPrintfArgType_sint]\n", errout_str()); @@ -4955,20 +4955,20 @@ class TestIO : public TestFixture { check("void foo(float f) {\n" " QString string;\n" " string.sprintf(\"%d\", f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:3:12]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'float'. [invalidPrintfArgType_sint]\n", errout_str()); check("void foo(float f) {\n" " QString string;\n" " string = QString::asprintf(\"%d\", f);\n" - "}", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); + "}\n", dinit(CheckOptions, $.platform = Platform::Type::Win32A)); ASSERT_EQUALS("[test.cpp:3:23]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'float'. [invalidPrintfArgType_sint]\n", errout_str()); } void testTernary() { // ticket #6182 check("void test(const std::string &val) {\n" " printf(\"%s\", val.empty() ? \"I like to eat bananas\" : val.c_str());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4976,30 +4976,30 @@ class TestIO : public TestFixture { check("void test() {\n" " unsigned const x = 5;\n" " printf(\"%u\", x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void testAstType() { // ticket #7014 check("void test() {\n" " printf(\"%c\", \"hello\"[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test() {\n" " printf(\"%lld\", (long long)1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test() {\n" " printf(\"%i\", (short *)x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) %i in format string (no. 1) requires 'int' but the argument type is 'signed short *'. [invalidPrintfArgType_sint]\n", errout_str()); check("int (*fp)();\n" // #7178 - function pointer call "void test() {\n" " printf(\"%i\", fp());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5007,7 +5007,7 @@ class TestIO : public TestFixture { check("void foo() {\n" " printf(\"%u %lu %llu\", 0U, 0UL, 0ULL);\n" " printf(\"%u %lu %llu\", 0u, 0ul, 0ull);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5015,7 +5015,7 @@ class TestIO : public TestFixture { check("void f() {\n" " const char *s = \"0\";\n" " printf(\"%ld%lld\", atol(s), atoll(s));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // 8141 @@ -5034,7 +5034,7 @@ class TestIO : public TestFixture { "PCINT pci;" "void foo() {\n" " printf(\"%d %p %p\", i, pi, pci);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("using INT = int;\n\n" @@ -5045,7 +5045,7 @@ class TestIO : public TestFixture { "PCINT pci;" "void foo() {\n" " printf(\"%f %f %f\", i, pi, pci);\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:8:5]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'. [invalidPrintfArgType_float]\n" "[test.cpp:8:5]: (warning) %f in format string (no. 2) requires 'double' but the argument type is 'signed int *'. [invalidPrintfArgType_float]\n" "[test.cpp:8:5]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'const signed int *'. [invalidPrintfArgType_float]\n", errout_str()); @@ -5063,17 +5063,17 @@ class TestIO : public TestFixture { void testPrintfParenthesis() { // #8489 check("void f(int a) {\n" " printf(\"%f\", (a >> 24) & 0xff);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'. [invalidPrintfArgType_float]\n", errout_str()); check("void f(int a) {\n" " printf(\"%f\", 0xff & (a >> 24));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'. [invalidPrintfArgType_float]\n", errout_str()); check("void f(int a) {\n" " printf(\"%f\", ((a >> 24) + 1) & 0xff);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'signed int'. [invalidPrintfArgType_float]\n", errout_str()); } @@ -5081,7 +5081,7 @@ class TestIO : public TestFixture { check("void foo(const std::vector& IO, const int* pio) {\n" "const auto Idx = std::distance(&IO.front(), pio);\n" "printf(\"Idx = %td\", Idx);\n" - "}", dinit(CheckOptions, $.portability = true)); + "}\n", dinit(CheckOptions, $.portability = true)); ASSERT_EQUALS("", errout_str()); } diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 6b6397851fb..cb5f9d53c8a 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -245,7 +245,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " p = NULL;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:5]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -254,7 +254,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " char *q = p;\n" " free(q);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -263,7 +263,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " char *q = p + 1;\n" " free(q - 1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -272,7 +272,7 @@ class TestLeakAutoVar : public TestFixture { " char *a = malloc(10);\n" " a += 10;\n" " free(a - 10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -281,7 +281,7 @@ class TestLeakAutoVar : public TestFixture { "{\n" " char *p = new char[100];\n" " list += p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -290,7 +290,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " p = strcpy(p,q);\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -298,7 +298,7 @@ class TestLeakAutoVar : public TestFixture { check("void foo(struct str *d) {\n" " struct str *p = malloc(10);\n" " d->p = p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -306,7 +306,7 @@ class TestLeakAutoVar : public TestFixture { check("void foo(struct str *d) {\n" " struct str *p = malloc(10);\n" " d->p = &p->x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -315,7 +315,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = x();\n" " free(p);\n" " p = NULL;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -325,7 +325,7 @@ class TestLeakAutoVar : public TestFixture { " if (x) { p = malloc(10); }\n" " if (!x) { p = NULL; }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -333,7 +333,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " char *p = malloc(10);\n" " x = a(b(p));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:4:1]: (information) --check-library: Function b() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); } @@ -343,7 +343,7 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " bar(&p);\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -353,22 +353,22 @@ class TestLeakAutoVar : public TestFixture { " char * &ref = p;\n" " p = malloc(10);\n" " free(ref);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); TODO_ASSERT_EQUALS("", "[test.cpp:6:1]: (error) Memory leak: p [memleak]\n", errout_str()); } void assign14() { check("void f(int x) {\n" " char *p;\n" - " if (x && (p = malloc(10))) { }" - "}"); - ASSERT_EQUALS("[test.c:3:35]: (error) Memory leak: p [memleak]\n", errout_str()); + " if (x && (p = malloc(10))) { }\n" + "}\n"); + ASSERT_EQUALS("[test.c:4:1]: (error) Memory leak: p [memleak]\n", errout_str()); check("void f(int x) {\n" " char *p;\n" - " if (x && (p = new char[10])) { }" - "}", dinit(CheckOptions, $.cpp = true)); - ASSERT_EQUALS("[test.cpp:3:37]: (error) Memory leak: p [memleak]\n", errout_str()); + " if (x && (p = new char[10])) { }\n" + "}\n", dinit(CheckOptions, $.cpp = true)); + ASSERT_EQUALS("[test.cpp:4:1]: (error) Memory leak: p [memleak]\n", errout_str()); } void assign15() { @@ -379,7 +379,7 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " p = malloc(sizeof *p);\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -388,48 +388,48 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " free(p);\n" " if (p=dostuff()) *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void assign17() { // #9047 check("void f() {\n" " char *p = (char*)malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:1]: (error) Memory leak: p [memleak]\n", errout_str()); check("void f() {\n" " char *p = (char*)(int*)malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:1]: (error) Memory leak: p [memleak]\n", errout_str()); } void assign18() { check("void f(int x) {\n" " char *p;\n" - " if (x && (p = (char*)malloc(10))) { }" - "}"); - ASSERT_EQUALS("[test.c:3:42]: (error) Memory leak: p [memleak]\n", errout_str()); + " if (x && (p = (char*)malloc(10))) { }\n" + "}\n"); + ASSERT_EQUALS("[test.c:4:1]: (error) Memory leak: p [memleak]\n", errout_str()); check("void f(int x) {\n" " char *p;\n" - " if (x && (p = (char*)(int*)malloc(10))) { }" - "}"); - ASSERT_EQUALS("[test.c:3:48]: (error) Memory leak: p [memleak]\n", errout_str()); + " if (x && (p = (char*)(int*)malloc(10))) { }\n" + "}\n"); + ASSERT_EQUALS("[test.c:4:1]: (error) Memory leak: p [memleak]\n", errout_str()); } void assign19() { check("void f() {\n" " char *p = malloc(10);\n" " free((void*)p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void assign20() { // #9187 check("void f() {\n" " char *p = static_cast(malloc(10));\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:3:1]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -437,14 +437,14 @@ class TestLeakAutoVar : public TestFixture { check("void f(int **x) {\n" // #10186 " void *p = malloc(10);\n" " *x = (int*)p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("struct S { int i; };\n" // #10996 "void f() {\n" " S* s = new S();\n" " (void)s;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:5:1]: (error) Memory leak: s [memleak]\n", errout_str()); } @@ -452,12 +452,12 @@ class TestLeakAutoVar : public TestFixture { const Settings s = settingsBuilder().library("posix.cfg").checkLibrary().build(); check("void f(char tempFileName[256]) {\n" " const int fd = socket(AF_INET, SOCK_PACKET, 0 );\n" - "}", dinit(CheckOptions, $.cpp = true, $.s = &s)); + "}\n", dinit(CheckOptions, $.cpp = true, $.s = &s)); ASSERT_EQUALS("[test.cpp:3:1]: (error) Resource leak: fd [resourceLeak]\n", errout_str()); check("void f() {\n" " const void * const p = malloc(10);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:3:1]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -565,7 +565,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" // #11796 " int* p{ new int };\n" " int* q(new int);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:4:1]: (error) Memory leak: p [memleak]\n" "[test.cpp:4:1]: (error) Memory leak: q [memleak]\n", errout_str()); @@ -629,13 +629,13 @@ class TestLeakAutoVar : public TestFixture { check("void f(int*& x) {\n" // #8235 " int* p = (int*)malloc(10);\n" " x = p ? p : nullptr;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f(int*& x) {\n" " int* p = (int*)malloc(10);\n" " x = p != nullptr ? p : nullptr;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f(const char* n) {\n" // #12724 @@ -666,17 +666,17 @@ class TestLeakAutoVar : public TestFixture { void isAutoDealloc() { check("void f() {\n" " char *p = new char[100];" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:29]: (error) Memory leak: p [memleak]\n", errout_str()); check("void f() {\n" " Fred *fred = new Fred;" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " std::string *str = new std::string;" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:40]: (error) Memory leak: str [memleak]\n", errout_str()); check("class TestType {\n" // #9028 @@ -685,13 +685,13 @@ class TestLeakAutoVar : public TestFixture { "};\n" "void f() {\n" " TestType *tt = new TestType();\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:7:1]: (error) Memory leak: tt [memleak]\n", errout_str()); check("void f(Bar& b) {\n" // #7622 " char* data = new char[10];\n" " b = Bar(*new Foo(data));\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:4:1]: (information) --check-library: Function Foo() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); check("class B {};\n" @@ -699,7 +699,7 @@ class TestLeakAutoVar : public TestFixture { " void g() {\n" " auto d = new D();\n" " if (d) {}\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:6:1]: (error) Memory leak: d [memleak]\n", errout_str()); check("struct S {\n" // #12354 @@ -710,7 +710,7 @@ class TestLeakAutoVar : public TestFixture { " if (b)\n" " p = new S();\n" " p->f();\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:9:1]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -719,7 +719,7 @@ class TestLeakAutoVar : public TestFixture { " void *p = malloc(10);\n" " void *q = realloc(p, 20);\n" " free(q)\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -727,7 +727,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " void *p = malloc(10);\n" " void *q = realloc(p, 20);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:4:1]: (error) Memory leak: q [memleak]\n", errout_str()); } @@ -735,7 +735,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " char *p = malloc(10);\n" " char *q = (char*) realloc(p, 20);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:4:1]: (error) Memory leak: q [memleak]\n", errout_str()); } @@ -744,7 +744,7 @@ class TestLeakAutoVar : public TestFixture { " void * q = realloc(p, 10);\n" " if (q == NULL)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:5:1]: (error) Memory leak: q [memleak]\n", errout_str()); } @@ -755,7 +755,7 @@ class TestLeakAutoVar : public TestFixture { " if (size && !datap)\n" " free(ptr);\n" " return datap;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9990 @@ -769,7 +769,7 @@ class TestLeakAutoVar : public TestFixture { " return;\n" " }\n" " free(p2);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -778,7 +778,7 @@ class TestLeakAutoVar : public TestFixture { " void *p = fopen(name,a);\n" " void *q = freopen(name, b, p);\n" " fclose(q)\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -786,7 +786,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " void *p = fopen(name,a);\n" " void *q = freopen(name, b, p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:4:1]: (error) Resource leak: q [resourceLeak]\n", errout_str()); } @@ -794,13 +794,13 @@ class TestLeakAutoVar : public TestFixture { check("void f(char *p) {\n" " free(p);\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:6]: (error) Dereferencing 'p' after it is deallocated / released [deallocuse]\n", errout_str()); check("void f(char *p) {\n" " free(p);\n" " char c = *p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:15]: (error) Dereferencing 'p' after it is deallocated / released [deallocuse]\n", errout_str()); } @@ -808,7 +808,7 @@ class TestLeakAutoVar : public TestFixture { check("void f(struct str *p) {\n" " free(p);\n" " p = p->next;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:9]: (error) Dereferencing 'p' after it is deallocated / released [deallocuse]\n", errout_str()); } @@ -816,25 +816,25 @@ class TestLeakAutoVar : public TestFixture { check("void f(char *p) {\n" " free(p);\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:5] -> [test.c:3:5]: (error) Returning/dereferencing 'p' after it is deallocated / released [deallocret]\n", errout_str()); check("void f(char *p) {\n" " if (!p) free(p);\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char *p) {\n" " if (!p) delete p;\n" " return p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f(char *p) {\n" " if (!p) delete [] p;\n" " return p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f(void* p) {\n" @@ -844,7 +844,7 @@ class TestLeakAutoVar : public TestFixture { " }\n" " g(p);\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -852,7 +852,7 @@ class TestLeakAutoVar : public TestFixture { check("void f(char *p) {\n" " free(p), p = 0;\n" " *p = 0;\n" // <- Make sure pointer info is reset. It is NOT a freed pointer dereference - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -860,7 +860,7 @@ class TestLeakAutoVar : public TestFixture { check("void f(char *p) {\n" " free(p);\n" " x = p = foo();\n" // <- p is not dereferenced - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -869,14 +869,14 @@ class TestLeakAutoVar : public TestFixture { "void f(Foo* foo) {\n" " delete foo->ptr;\n" " foo->ptr = new Foo;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("struct Foo { int* ptr; };\n" "void f(Foo* foo) {\n" " delete foo->ptr;\n" " x = *foo->ptr;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); TODO_ASSERT_EQUALS("[test.cpp:4:6]: (error) Dereferencing 'ptr' after it is deallocated / released [deallocuse]\n", "", errout_str()); check("void parse() {\n" @@ -885,7 +885,7 @@ class TestLeakAutoVar : public TestFixture { " ~Buf() { delete[]m_buf; }\n" " uint8_t *m_buf;\n" " };\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("struct Foo {\n" @@ -897,14 +897,14 @@ class TestLeakAutoVar : public TestFixture { " delete foo->ptr;\n" " foo->ptr = new Foo;\n" " foo->ptr->func();\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void foo(void (*conv)(char**)) {\n" " char * ptr=(char*)malloc(42);\n" " free(ptr);\n" " (*conv)(&ptr);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -913,7 +913,7 @@ class TestLeakAutoVar : public TestFixture { " int *ptr = new int;\n" " delete(ptr);\n" " *ptr = 0;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:4:6]: (error) Dereferencing 'ptr' after it is deallocated / released [deallocuse]\n", errout_str()); } @@ -964,14 +964,14 @@ class TestLeakAutoVar : public TestFixture { " int *array = new int[42];\n" " delete [] array;\n" " return array[1];" // << - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:3:3] -> [test.cpp:4:3]: (error) Returning/dereferencing 'array' after it is deallocated / released [deallocret]\n", errout_str()); check("int f() {\n" " int *array = (int*)malloc(40);\n" " free(array);\n" " return array[1];" // << - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:3] -> [test.c:4:3]: (error) Returning/dereferencing 'array' after it is deallocated / released [deallocret]\n", errout_str()); } @@ -982,7 +982,7 @@ class TestLeakAutoVar : public TestFixture { "}\n" "void f2(struct foo *f, int *out) {\n" " *out = f->x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1120,35 +1120,35 @@ class TestLeakAutoVar : public TestFixture { " else\n" " p = 0;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:9] -> [test.c:6:5]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( "void foo(char *p) {\n" " free(p);\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:3] -> [test.c:3:3]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( "void foo(char *p, char *r) {\n" " free(p);\n" " free(r);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( "void foo() {\n" " free(p);\n" " free(r);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( "void foo(char *p) {\n" " if (x < 3) free(p);\n" " else { if (x > 9) free(p); }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( @@ -1156,7 +1156,7 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " getNext(&p);\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( @@ -1164,7 +1164,7 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " bar();\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:3] -> [test.c:4:3]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( @@ -1172,7 +1172,7 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " printf(\"Freed memory at location %x\", p);\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:41]: (error) Dereferencing 'p' after it is deallocated / released [deallocuse]\n" "[test.c:2:3] -> [test.c:4:3]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); @@ -1181,21 +1181,21 @@ class TestLeakAutoVar : public TestFixture { "void foo(FILE *p) {\n" " fclose(p);\n" " fclose(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:3] -> [test.c:3:3]: (error) Resource handle 'p' freed twice. [doubleFree]\n", errout_str()); check( "void foo(FILE *p, FILE *r) {\n" " fclose(p);\n" " fclose(r);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( "void foo(FILE *p) {\n" " if (x < 3) fclose(p);\n" " else { if (x > 9) fclose(p); }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( @@ -1203,7 +1203,7 @@ class TestLeakAutoVar : public TestFixture { " fclose(p);\n" " gethandle(&p);\n" " fclose(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( @@ -1211,14 +1211,14 @@ class TestLeakAutoVar : public TestFixture { " fclose(p);\n" " gethandle();\n" " fclose(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:3] -> [test.c:4:3]: (error) Resource handle 'p' freed twice. [doubleFree]\n", errout_str()); check( "void foo(Data* p) {\n" " free(p->a);\n" " free(p->b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( @@ -1229,7 +1229,7 @@ class TestLeakAutoVar : public TestFixture { " exit();\n" " }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( @@ -1240,7 +1240,7 @@ class TestLeakAutoVar : public TestFixture { " x = 0;\n" " }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:4:9] -> [test.c:7:5]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( @@ -1249,35 +1249,35 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " p = do_something();\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check( "void foo(char *p) {\n" " delete p;\n" " delete p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:10] -> [test.cpp:3:10]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( "void foo(char *p, char *r) {\n" " delete p;\n" " delete r;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( "void foo(P p) {\n" " delete p.x;\n" " delete p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( "void foo(char **p) {\n" " delete p[0];\n" " delete p[1];\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1285,7 +1285,7 @@ class TestLeakAutoVar : public TestFixture { " delete p;\n" " getNext(&p);\n" " delete p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1293,21 +1293,21 @@ class TestLeakAutoVar : public TestFixture { " delete p;\n" " bar();\n" " delete p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:10] -> [test.cpp:4:10]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( "void foo(char *p) {\n" " delete[] p;\n" " delete[] p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:3:12]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( "void foo(char *p, char *r) {\n" " delete[] p;\n" " delete[] r;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1315,7 +1315,7 @@ class TestLeakAutoVar : public TestFixture { " delete[] p;\n" " getNext(&p);\n" " delete[] p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1323,7 +1323,7 @@ class TestLeakAutoVar : public TestFixture { " delete[] p;\n" " bar();\n" " delete[] p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:4:12]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( @@ -1334,7 +1334,7 @@ class TestLeakAutoVar : public TestFixture { " delete pxpm;\n" " pxpm = NULL;\n" " return *this;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1351,7 +1351,7 @@ class TestLeakAutoVar : public TestFixture { " throw;\n" " }\n" " delete ptr;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1367,7 +1367,7 @@ class TestLeakAutoVar : public TestFixture { " if(doDelete)\n" " delete a;\n" " return 0;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); TODO_ASSERT_EQUALS("", "[test.cpp:8:8] -> [test.cpp:11:15]: (error) Memory pointed to by 'a' is freed twice. [doubleFree]\n", errout_str()); check( @@ -1381,7 +1381,7 @@ class TestLeakAutoVar : public TestFixture { " delete[] x;\n" " }\n" " delete[] x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1393,7 +1393,7 @@ class TestLeakAutoVar : public TestFixture { " delete[] x;\n" " }\n" " delete[] x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Memory pointed to by 'x' is freed twice.\n", "", errout_str()); check( @@ -1405,7 +1405,7 @@ class TestLeakAutoVar : public TestFixture { " delete[] x;\n" " }\n" " delete[] x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Memory pointed to by 'x' is freed twice.\n", "", errout_str()); check( @@ -1417,7 +1417,7 @@ class TestLeakAutoVar : public TestFixture { " free(x);\n" " }\n" " free(x);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.c:8]: (error) Memory pointed to by 'x' is freed twice.\n", "", errout_str()); check( @@ -1431,7 +1431,7 @@ class TestLeakAutoVar : public TestFixture { " delete[] x;\n" " }\n" " delete[] x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1445,7 +1445,7 @@ class TestLeakAutoVar : public TestFixture { " delete[] x;\n" " } while (true);\n" " delete[] x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1457,7 +1457,7 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:6:9] -> [test.c:8:5]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); check( @@ -1478,7 +1478,7 @@ class TestLeakAutoVar : public TestFixture { "void MyThrow(err)\n" "{\n" " throw(err);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( @@ -1499,7 +1499,7 @@ class TestLeakAutoVar : public TestFixture { "void MyExit(err)\n" "{\n" " exit(err);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check( // #6252 @@ -1514,14 +1514,14 @@ class TestLeakAutoVar : public TestFixture { " delete m_thing;\n" " m_thing = new Thing;\n" " }\n" - "};", dinit(CheckOptions, $.cpp = true)); + "};\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); // #7401 check("void pCodeLabelDestruct(pCode *pc) {\n" " free(PCL(pc)->label);\n" " free(pc);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1531,7 +1531,7 @@ class TestLeakAutoVar : public TestFixture { " if (a == 2) { free(p); return ((void*)1); }\n" " free(p);\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1548,7 +1548,7 @@ class TestLeakAutoVar : public TestFixture { " free(bar)\n" " } while(!done);\n" " return;" - "}" + "}\n" ); ASSERT_EQUALS("", errout_str()); } @@ -1560,7 +1560,7 @@ class TestLeakAutoVar : public TestFixture { " exit(1);\n" " }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(void* p, int i) {\n" // #11391 @@ -1580,7 +1580,7 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " x = (q == p);\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:3] -> [test.c:4:3]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); } @@ -1588,7 +1588,7 @@ class TestLeakAutoVar : public TestFixture { check("void do_wordexp(FILE *f) {\n" " free(getword(f));\n" " fclose(f);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1597,14 +1597,14 @@ class TestLeakAutoVar : public TestFixture { " free(p);\n" " if (x && (p = malloc(10)))\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char *p, int x) {\n" " delete[] p;\n" " if (x && (p = new char[10]))\n" " delete[] p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -1717,7 +1717,7 @@ class TestLeakAutoVar : public TestFixture { " if (q == NULL)\n" " return;\n" " free(q);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:16] -> [test.c:8:5]: (error) Memory pointed to by 'p' is freed twice. [doubleFree]\n", errout_str()); } @@ -1753,7 +1753,7 @@ class TestLeakAutoVar : public TestFixture { " int *i = new int;\n" " unique_ptr x(i);\n" " delete i;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:6:5] -> [test.cpp:7:12]: (error) Memory pointed to by 'i' is freed twice. [doubleFree]\n", errout_str()); check("using namespace std;\n" @@ -1762,14 +1762,14 @@ class TestLeakAutoVar : public TestFixture { "{\n" " int *i = new int;\n" " unique_ptr x(i);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } void doublefree15() { // #11966 check("void f(FILE* fp) {\n" " static_cast(fclose(fp));\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -1831,7 +1831,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " char *p = malloc(10);\n" " exit(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1839,7 +1839,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " char *p = malloc(10);\n" " fatal_error();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:18]: (information) --check-library: Function fatal_error() should have configuration [checkLibraryNoReturn]\n", errout_str()); } @@ -1850,9 +1850,9 @@ class TestLeakAutoVar : public TestFixture { " if (x) {\n" " free(p);\n" " ::exit(0);\n" - " }" + " }\n" " free(p);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -1860,9 +1860,9 @@ class TestLeakAutoVar : public TestFixture { " if (x) {\n" " free(p);\n" " std::exit(0);\n" - " }" + " }\n" " free(p);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -1875,7 +1875,7 @@ class TestLeakAutoVar : public TestFixture { " func_notret();\n" " }\n" " free(ptr);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1884,7 +1884,7 @@ class TestLeakAutoVar : public TestFixture { " p->x = malloc(10);\n" " free(p->x);\n" " p->x = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(s_t s) {\n" // #11061 @@ -1906,7 +1906,7 @@ class TestLeakAutoVar : public TestFixture { check("void g(size_t len) {\n" // #12365 " char* b = new char[len + 1]{};\n" " std::string str = std::string(b);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:4:1]: (error) Memory leak: b [memleak]\n", errout_str()); } @@ -1917,7 +1917,7 @@ class TestLeakAutoVar : public TestFixture { " if (err) {\n" " free(reg);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1930,7 +1930,7 @@ class TestLeakAutoVar : public TestFixture { " goto x;\n" " }\n" " return p;\n" // no error since there is a goto - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1955,7 +1955,7 @@ class TestLeakAutoVar : public TestFixture { " if (x) { p = malloc(10); }\n" " else { return 0; }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1964,7 +1964,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = NULL;\n" " if (x) { p = malloc(10); }\n" " else { return 0; }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:5:1]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -1973,7 +1973,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " if (!p) { return; }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("char * f(size_t size) {" @@ -1981,14 +1981,14 @@ class TestLeakAutoVar : public TestFixture { " if (!p && size != 0)" " return NULL;" " return p;" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char *p = malloc(10);\n" " if (p) { } else { return; }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3866 - UNLIKELY @@ -1996,7 +1996,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " if (UNLIKELY(!p)) { return; }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2005,7 +2005,7 @@ class TestLeakAutoVar : public TestFixture { " char *p;\n" " if (x) { p = malloc(10); }\n" " if (x) { free(p); }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" @@ -2013,7 +2013,7 @@ class TestLeakAutoVar : public TestFixture { " if (x) { p = malloc(10); }\n" " if (!x) { return; }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2022,7 +2022,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " if (!p && x) { p = malloc(10); }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2033,7 +2033,7 @@ class TestLeakAutoVar : public TestFixture { " free(a);\n" " else\n" " a = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:6:9]: (error) Memory leak: a [memleak]\n", errout_str()); } @@ -2043,7 +2043,7 @@ class TestLeakAutoVar : public TestFixture { " if (x < 0)\n" // assume negative value indicates its unallocated " return;\n" " free(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2053,7 +2053,7 @@ class TestLeakAutoVar : public TestFixture { " if (fd == -1)\n" " return -1;\n" " return fd;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" @@ -2061,7 +2061,7 @@ class TestLeakAutoVar : public TestFixture { " if (fd != -1)\n" " return fd;\n" " return -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2071,7 +2071,7 @@ class TestLeakAutoVar : public TestFixture { " if (dostuff(p==NULL,0))\n" " return;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2081,7 +2081,7 @@ class TestLeakAutoVar : public TestFixture { " if (!(x != NULL))\n" " return;\n" " free(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2091,7 +2091,7 @@ class TestLeakAutoVar : public TestFixture { " if (NULL == (p = malloc(4)))\n" " return;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2099,7 +2099,7 @@ class TestLeakAutoVar : public TestFixture { check("void f(char **p) {\n" " if ((*p = malloc(4)) == NULL)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2110,7 +2110,7 @@ class TestLeakAutoVar : public TestFixture { " return 1;\n" " free(path);\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int fd, const char *mode) {\n" @@ -2119,7 +2119,7 @@ class TestLeakAutoVar : public TestFixture { " return 1;\n" // <- memory leak " free(path);\n" " return 0;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4] memory leak", "", errout_str()); } @@ -2129,7 +2129,7 @@ class TestLeakAutoVar : public TestFixture { " if (buf == (char*)NULL)\n" " return NULL;\n" " return buf;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2139,14 +2139,14 @@ class TestLeakAutoVar : public TestFixture { "void test_alloc() {\n" " if ( global_ptr = new SSS()) {}\n" " return;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("FILE* hFile;\n" "int openFile( void ) {\n" " if ((hFile = fopen(\"1.txt\", \"wb\" )) == NULL) return 0;\n" " return 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2157,7 +2157,7 @@ class TestLeakAutoVar : public TestFixture { " return;\n" " free(p);\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(void) {\n" @@ -2166,7 +2166,7 @@ class TestLeakAutoVar : public TestFixture { " return;\n" " free(p);\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2176,7 +2176,7 @@ class TestLeakAutoVar : public TestFixture { " if (!p)\n" " return NULL;\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int *f() {\n" @@ -2184,7 +2184,7 @@ class TestLeakAutoVar : public TestFixture { " if (!!(!p))\n" " return NULL;\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2195,7 +2195,7 @@ class TestLeakAutoVar : public TestFixture { " if (q == 0)\n" " return;\n" " free(q);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:5:9]: (error) Memory leak: p [memleak]\n", errout_str()); check("void f() {\n" @@ -2206,7 +2206,7 @@ class TestLeakAutoVar : public TestFixture { " return;\n" " } else\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:8:9]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -2217,7 +2217,7 @@ class TestLeakAutoVar : public TestFixture { " if (!b)\n" " return;\n" " a = b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2228,7 +2228,7 @@ class TestLeakAutoVar : public TestFixture { " else\n" " void * p2 = malloc(2);\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:30]: (error) Memory leak: p1 [memleak]\n" "[test.c:5:30]: (error) Memory leak: p2 [memleak]\n", errout_str()); @@ -2237,7 +2237,7 @@ class TestLeakAutoVar : public TestFixture { " void * p1 = malloc(5);\n" " else\n" " void * p2 = malloc(2);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:30]: (error) Memory leak: p1 [memleak]\n" "[test.c:5:30]: (error) Memory leak: p2 [memleak]\n", errout_str()); } @@ -2250,7 +2250,7 @@ class TestLeakAutoVar : public TestFixture { " p = malloc(5);\n" " }\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:6:5]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -2260,7 +2260,7 @@ class TestLeakAutoVar : public TestFixture { " if (fd >= 0)\n" " return fd;\n" " return -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(const char * pathname, int flags) {\n" @@ -2268,7 +2268,7 @@ class TestLeakAutoVar : public TestFixture { " if (fd <= -1)\n" " return -1;\n" " return fd;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2410,7 +2410,7 @@ class TestLeakAutoVar : public TestFixture { " default: return;\n" " }\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2421,7 +2421,7 @@ class TestLeakAutoVar : public TestFixture { " for (i=0;i<5;i++) { }\n" " if (x) { free(p) }\n" " else { a = p; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2456,13 +2456,13 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " FILE*f=fopen(fname,a);\n" " free(f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:12] -> [test.c:3:5]: (error) Mismatching allocation and deallocation: f [mismatchAllocDealloc]\n", errout_str()); check("void f() {\n" " FILE*f=fopen(fname,a);\n" " free((void*)f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:12] -> [test.c:3:5]: (error) Mismatching allocation and deallocation: f [mismatchAllocDealloc]\n", errout_str()); check("void f() {\n" @@ -2472,18 +2472,18 @@ class TestLeakAutoVar : public TestFixture { " delete[] cPtr;\n" " cPtr = new char[100];\n" " delete cPtr;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:6:12] -> [test.cpp:7:12]: (error) Mismatching allocation and deallocation: cPtr [mismatchAllocDealloc]\n", errout_str()); check("void f() {\n" " char *cPtr = new char[100];\n" " free(cPtr);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:18] -> [test.cpp:3:5]: (error) Mismatching allocation and deallocation: cPtr [mismatchAllocDealloc]\n", errout_str()); check("void f() {\n" " char *cPtr = new (buf) char[100];\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -2502,7 +2502,7 @@ class TestLeakAutoVar : public TestFixture { " void* a = malloc(1);\n" " void* b = freopen(f, p, a);\n" " free(b);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:2:14] -> [test.c:3:14]: (error) Mismatching allocation and deallocation: a [mismatchAllocDealloc]\n" "[test.c:3:14] -> [test.c:4:4]: (error) Mismatching allocation and deallocation: b [mismatchAllocDealloc]\n", errout_str()); @@ -2510,14 +2510,14 @@ class TestLeakAutoVar : public TestFixture { " void* a;\n" " void* b = realloc(a, 10);\n" " free(b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int * i = new int;\n" " int * j = realloc(i, 2 * sizeof(int));\n" " delete[] j;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:14] -> [test.cpp:3:14]: (error) Mismatching allocation and deallocation: i [mismatchAllocDealloc]\n" "[test.cpp:3:14] -> [test.cpp:4:13]: (error) Mismatching allocation and deallocation: j [mismatchAllocDealloc]\n", errout_str()); @@ -2547,26 +2547,26 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " FILE*f=fopen(fname,a);\n" " std::unique_ptr fp{f};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:3:30]: (error) Mismatching allocation and deallocation: f [mismatchAllocDealloc]\n", errout_str()); check("void f() {\n" " FILE*f=fopen(fname,a);\n" " std::unique_ptr fp{f, &fclose};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " FILE*f=fopen(fname,a);\n" " std::shared_ptr fp{f, &fclose};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("struct deleter { void operator()(FILE* f) { fclose(f); }};\n" "void f() {\n" " FILE*f=fopen(fname,a);\n" " std::unique_ptr fp{f};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("int * create();\n" @@ -2588,39 +2588,39 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " FILE*f=fopen(fname,a);\n" " std::shared_ptr fp{f, [](FILE* x) { fclose(x); }};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " FILE*f=fopen(fname,a);\n" " std::shared_ptr fp{f, +[](FILE* x) { fclose(x); }};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " FILE*f=fopen(fname,a);\n" " std::shared_ptr fp{f, [](FILE* x) { free(f); }};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:3:30]: (error) Mismatching allocation and deallocation: f [mismatchAllocDealloc]\n", errout_str()); check("void f() {\n" " FILE*f=fopen(fname,a);\n" " std::shared_ptr fp{f, [](FILE* x) {}};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:3:30]: (error) Mismatching allocation and deallocation: f [mismatchAllocDealloc]\n", errout_str()); check("class C;\n" "void f() {\n" " C* c = new C{};\n" " std::shared_ptr a{c, [](C*) {}};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("class C;\n" "void f() {\n" " C* c = new C{};\n" " std::shared_ptr a{c, [](C* x) { delete x; }};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("struct DirDeleter {\n" // #12544 @@ -2652,7 +2652,7 @@ class TestLeakAutoVar : public TestFixture { check("int f() {\n" " char *p = malloc(100);\n" " return 123;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:5]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -2660,7 +2660,7 @@ class TestLeakAutoVar : public TestFixture { check("char *f() {\n" " char *p = malloc(100);\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2668,7 +2668,7 @@ class TestLeakAutoVar : public TestFixture { check("struct dev * f() {\n" " struct ABC *abc = malloc(100);\n" " return &abc->dev;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2680,7 +2680,7 @@ class TestLeakAutoVar : public TestFixture { " throw 1;\n" " }\n" " free(p);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f(char *p, int x) {\n" @@ -2689,7 +2689,7 @@ class TestLeakAutoVar : public TestFixture { " throw 1;\n" " }\n" " delete p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f(char *p, int x) {\n" @@ -2698,7 +2698,7 @@ class TestLeakAutoVar : public TestFixture { " throw 1;\n" " }\n" " delete [] p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2712,7 +2712,7 @@ class TestLeakAutoVar : public TestFixture { " return;\n" " }\n" " *p = 0;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2720,7 +2720,7 @@ class TestLeakAutoVar : public TestFixture { check("std::pair f(size_t n) {\n" " char* p = (char* )malloc(n);\n" " return {p, p};\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2728,43 +2728,43 @@ class TestLeakAutoVar : public TestFixture { check("uint8_t *f() {\n" " void *x = malloc(1);\n" " return (uint8_t *)x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("uint8_t f() {\n" " void *x = malloc(1);\n" " return (uint8_t)x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Memory leak: x [memleak]\n", errout_str()); check("void** f() {\n" " void *x = malloc(1);\n" " return (void**)x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void* f() {\n" " void *x = malloc(1);\n" " return (long long)x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void* f() {\n" " void *x = malloc(1);\n" " return (void*)(short)x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Memory leak: x [memleak]\n", errout_str()); check("void* f() {\n" " void *x = malloc(1);\n" " return (mytype)x;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void* f() {\n" // Do not crash " void *x = malloc(1);\n" " return (mytype)y;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Memory leak: x [memleak]\n", errout_str()); } @@ -2772,25 +2772,25 @@ class TestLeakAutoVar : public TestFixture { check("void* f() {\n" " void *x = malloc(1);\n" " return (x);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void* f() {\n" " void *x = malloc(1);\n" " return ((x));\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void* f() {\n" " void *x = malloc(1);\n" " return ((((x))));\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("char* f() {\n" " void *x = malloc(1);\n" " return (char*)(x);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2798,7 +2798,7 @@ class TestLeakAutoVar : public TestFixture { check("void* f() {\n" " void *x = malloc (sizeof (struct alloc));\n" " return x + sizeof (struct alloc);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2807,7 +2807,7 @@ class TestLeakAutoVar : public TestFixture { " char* p = (char*)malloc(1);\n" " p[0] = 'x';\n" " return p[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:4:5]: (error) Memory leak: p [memleak]\n", errout_str()); check("struct S { int f(); };\n" // #11746 @@ -2815,14 +2815,14 @@ class TestLeakAutoVar : public TestFixture { " S* s = new S;\n" " delete s;\n" " return s->f();\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:4:5] -> [test.cpp:5:5]: (error) Returning/dereferencing 's' after it is deallocated / released [deallocret]\n", errout_str()); check("int f() {\n" " int* p = new int(3);\n" " delete p;\n" " return *p;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:3:5] -> [test.cpp:4:5]: (error) Returning/dereferencing 'p' after it is deallocated / released [deallocret]\n", errout_str()); } @@ -2878,7 +2878,7 @@ class TestLeakAutoVar : public TestFixture { void test1() { check("void f(double*&p) {\n" // 3809 " p = malloc(0x100);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); check("void f(int*& p) {\n" // #4400 @@ -2907,7 +2907,7 @@ class TestLeakAutoVar : public TestFixture { check("struct Fred {\n" " char *p;\n" " void f1() { free(p); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -2915,7 +2915,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " char *&p = x();\n" " p = malloc(10);\n" - "};", dinit(CheckOptions, $.cpp = true)); + "};\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2924,21 +2924,21 @@ class TestLeakAutoVar : public TestFixture { " static char *p;\n" " if (!p) p = malloc(10);\n" " if (x) { free(p); p = 0; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } void test5() { // unknown type - check("void f() { Fred *p = malloc(10); }", dinit(CheckOptions, $.cpp = true)); + check("void f() { Fred *p = malloc(10); }\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:1:34]: (error) Memory leak: p [memleak]\n", errout_str()); - check("void f() { Fred *p = malloc(10); }"); + check("void f() { Fred *p = malloc(10); }\n"); ASSERT_EQUALS("[test.c:1:34]: (error) Memory leak: p [memleak]\n", errout_str()); - check("void f() { Fred *p = new Fred; }", dinit(CheckOptions, $.cpp = true)); + check("void f() { Fred *p = new Fred; }\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); - check("void f() { Fred fred = malloc(10); }", dinit(CheckOptions, $.cpp = true)); + check("void f() { Fred fred = malloc(10); }\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2946,7 +2946,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " char *p = malloc(10);\n" " throw 123;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:3:5]: (error) Memory leak: p [memleak]\n", errout_str()); check("void f() {\n" @@ -2956,7 +2956,7 @@ class TestLeakAutoVar : public TestFixture { " throw 123;\n" " } catch (...) { }\n" " free(p);\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2973,7 +2973,7 @@ class TestLeakAutoVar : public TestFixture { " throw ::NS::Except();\n" " }\n" " delete pi;\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("", errout_str()); } @@ -2986,7 +2986,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " char *p = malloc(10);\n" " x(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:9]: (information) --check-library: Function x() should have configuration [checkLibraryNoReturn]\n" "[test.c:4:1]: (information) --check-library: Function x() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); @@ -3004,7 +3004,7 @@ class TestLeakAutoVar : public TestFixture { check("void f() {\n" " char *p = malloc(10);\n" " x(&p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:10]: (information) --check-library: Function x() should have configuration [checkLibraryNoReturn]\n" "[test.c:4:1]: (information) --check-library: Function x() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); @@ -3015,7 +3015,7 @@ class TestLeakAutoVar : public TestFixture { const char code[] = "void f() {\n" " char *p = malloc(10);\n" " if (set_data(p)) { }\n" - "}"; + "}\n"; check(code); ASSERT_EQUALS("[test.c:4:1]: (information) --check-library: Function set_data() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); check(code, dinit(CheckOptions, $.cpp = true)); @@ -3026,7 +3026,7 @@ class TestLeakAutoVar : public TestFixture { const char code[] = "void f() {\n" " char *p = malloc(10);\n" " if (set_data(p)) { return; }\n" - "}"; + "}\n"; check(code); ASSERT_EQUALS("[test.c:3:24]: (information) --check-library: Function set_data() should have / configuration [checkLibraryUseIgnore]\n" "[test.c:4:1]: (information) --check-library: Function set_data() should have / configuration [checkLibraryUseIgnore]\n" @@ -3043,7 +3043,7 @@ class TestLeakAutoVar : public TestFixture { " char *p = malloc(10);\n" " int ret = set_data(p);\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:4:5]: (information) --check-library: Function set_data() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); } @@ -3121,7 +3121,7 @@ class TestLeakAutoVar : public TestFixture { void ptrptr() { check("void f() {\n" " char **p = malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.c:3:1]: (error) Memory leak: p [memleak]\n", errout_str()); } @@ -3129,19 +3129,19 @@ class TestLeakAutoVar : public TestFixture { check("void QueueDSMCCPacket(unsigned char *data, int length) {\n" " unsigned char *dataCopy = malloc(length * sizeof(unsigned char));\n" " m_dsmccQueue.enqueue(new DSMCCPacket(dataCopy));\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:4:1]: (information) --check-library: Function DSMCCPacket() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); check("void QueueDSMCCPacket(unsigned char *data, int length) {\n" " unsigned char *dataCopy = malloc(length * sizeof(unsigned char));\n" " m_dsmccQueue.enqueue(new DSMCCPacket(somethingunrelated));\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:4:1]: (error) Memory leak: dataCopy [memleak]\n", errout_str()); check("void f() {\n" " char *buf = new char[1000];\n" " clist.push_back(new (std::nothrow) C(buf));\n" - "}", dinit(CheckOptions, $.cpp = true)); + "}\n", dinit(CheckOptions, $.cpp = true)); ASSERT_EQUALS("[test.cpp:4:1]: (information) --check-library: Function C() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); } @@ -3150,7 +3150,7 @@ class TestLeakAutoVar : public TestFixture { " double *new = malloc(1*sizeof(double));\n" " free(new);\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3163,7 +3163,7 @@ class TestLeakAutoVar : public TestFixture { " }\n" " c = malloc(128);\n" " return ret();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3226,7 +3226,7 @@ class TestLeakAutoVar : public TestFixture { "{\n" " char * buf = malloc(4);\n" " free_func((void *)(1), buf);\n" - "}", settingsFunctionCall); + "}\n", settingsFunctionCall); ASSERT_EQUALS("[test.cpp:5:1]: (information) --check-library: Function free_func() should have / configuration [checkLibraryUseIgnore]\n", errout_str()); check("void g(void*);\n" @@ -3312,7 +3312,7 @@ class TestLeakAutoVarRecursiveCountLimit : public TestFixture { "void foo() {\n" " if (0) { }\n" " THOU THOU\n" - "}"), LIMIT, "Internal limit: CheckLeakAutoVar::checkScope() Maximum recursive count of 1000 reached."); + "}\n"), LIMIT, "Internal limit: CheckLeakAutoVar::checkScope() Maximum recursive count of 1000 reached."); ASSERT_NO_THROW(checkP("#define ONE if (0) { }\n" "#define TEN ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE\n" "#define HUN TEN TEN TEN TEN TEN TEN TEN TEN TEN TEN\n" @@ -3320,7 +3320,7 @@ class TestLeakAutoVarRecursiveCountLimit : public TestFixture { "void foo() {\n" " if (0) { }\n" " THOU THOU\n" - "}")); + "}\n")); } }; @@ -3362,7 +3362,7 @@ class TestLeakAutoVarStrcpy : public TestFixture { "{\n" " char* ptr = new char[strlen(str)+1];\n" " m = strcpy(ptr, str);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3370,7 +3370,7 @@ class TestLeakAutoVarStrcpy : public TestFixture { check("void f(char *p) {\n" " free(p);\n" " strcpy(a, p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:15]: (error) Dereferencing 'p' after it is deallocated / released [deallocuse]\n", errout_str()); check("void f(char *p, const char *q) {\n" // #11665 @@ -3383,12 +3383,12 @@ class TestLeakAutoVarStrcpy : public TestFixture { check("void f(char *p) {\n" // #3041 - assigning pointer when it's used " free(p);\n" " strcpy(a, p=b());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void fclose_false_positive() { // #9575 - check("int f(FILE *fp) { return fclose(fp); }"); + check("int f(FILE *fp) { return fclose(fp); }\n"); ASSERT_EQUALS("", errout_str()); } @@ -3418,7 +3418,7 @@ class TestLeakAutoVarStrcpy : public TestFixture { " if (b)\n" " p = new S();\n" " p->f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:1]: (error) Memory leak: p [memleak]\n", errout_str()); check("class B { std::string s; };\n" // #12062 diff --git a/test/testlibrary.cpp b/test/testlibrary.cpp index a531ac4cba9..28264a02a53 100644 --- a/test/testlibrary.cpp +++ b/test/testlibrary.cpp @@ -109,7 +109,7 @@ class TestLibrary : public TestFixture { "
\n" ""; - const char code[] = "foo();"; + const char code[] = "foo();\n"; SimpleTokenList tokenList(code); tokenList.front()->next()->astOperand1(tokenList.front()); @@ -131,13 +131,13 @@ class TestLibrary : public TestFixture { Library library; ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); { - const char code[] = "fred.foo(123);"; // <- wrong scope, not library function + const char code[] = "fred.foo(123);\n"; // <- wrong scope, not library function const SimpleTokenList tokenList(code); ASSERT(library.isNotLibraryFunction(tokenList.front()->tokAt(2))); } { - const char code[] = "Fred::foo(123);"; // <- wrong scope, not library function + const char code[] = "Fred::foo(123);\n"; // <- wrong scope, not library function const SimpleTokenList tokenList(code); ASSERT(library.isNotLibraryFunction(tokenList.front()->tokAt(2))); @@ -153,7 +153,7 @@ class TestLibrary : public TestFixture { ""; TokenList tokenList(settingsDefault, Standards::Language::CPP); - const char code[] = "foo();"; // <- too few arguments, not library function + const char code[] = "foo();\n"; // <- too few arguments, not library function ASSERT(tokenList.createTokensFromString(code)); Token::createMutualLinks(tokenList.front()->next(), tokenList.back()->previous()); tokenList.createAst(); @@ -177,7 +177,7 @@ class TestLibrary : public TestFixture { { TokenList tokenList(settingsDefault, Standards::Language::CPP); - const char code[] = "foo();"; // <- too few arguments, not library function + const char code[] = "foo();\n"; // <- too few arguments, not library function ASSERT(tokenList.createTokensFromString(code)); Token::createMutualLinks(tokenList.front()->next(), tokenList.back()->previous()); tokenList.createAst(); @@ -186,7 +186,7 @@ class TestLibrary : public TestFixture { } { TokenList tokenList(settingsDefault, Standards::Language::CPP); - const char code[] = "foo(a);"; // <- library function + const char code[] = "foo(a);\n"; // <- library function ASSERT(tokenList.createTokensFromString(code)); Token::createMutualLinks(tokenList.front()->next(), tokenList.back()->previous()); tokenList.createAst(); @@ -197,7 +197,7 @@ class TestLibrary : public TestFixture { } { TokenList tokenList(settingsDefault, Standards::Language::CPP); - const char code[] = "foo(a, b);"; // <- library function + const char code[] = "foo(a, b);\n"; // <- library function ASSERT(tokenList.createTokensFromString(code)); Token::createMutualLinks(tokenList.front()->next(), tokenList.back()->previous()); tokenList.createAst(); @@ -208,7 +208,7 @@ class TestLibrary : public TestFixture { } { TokenList tokenList(settingsDefault, Standards::Language::CPP); - const char code[] = "foo(a, b, c);"; // <- too much arguments, not library function + const char code[] = "foo(a, b, c);\n"; // <- too much arguments, not library function ASSERT(tokenList.createTokensFromString(code)); Token::createMutualLinks(tokenList.front()->next(), tokenList.back()->previous()); tokenList.createAst(); @@ -225,7 +225,7 @@ class TestLibrary : public TestFixture { " \n" ""; - const char code[] = "Fred foo(123);"; // <- Variable declaration, not library function + const char code[] = "Fred foo(123);\n"; // <- Variable declaration, not library function SimpleTokenList tokenList(code); tokenList.front()->next()->astOperand1(tokenList.front()); tokenList.front()->next()->varId(1); @@ -285,7 +285,7 @@ class TestLibrary : public TestFixture { ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); ASSERT_EQUALS(0, library.functions().at("foo").argumentChecks.at(-1).notuninit); - const char code[] = "foo(a,b,c,d,e);"; + const char code[] = "foo(a,b,c,d,e);\n"; SimpleTokenList tokenList(code); tokenList.front()->next()->astOperand1(tokenList.front()); @@ -309,7 +309,7 @@ class TestLibrary : public TestFixture { Library library; ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); - const char code[] = "foo(a,b,c,d);"; + const char code[] = "foo(a,b,c,d);\n"; SimpleTokenList tokenList(code); tokenList.front()->next()->astOperand1(tokenList.front()); @@ -340,7 +340,7 @@ class TestLibrary : public TestFixture { Library library; ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); - const char code[] = "foo(a,b,c,d,e,f,g,h,i,j,k);"; + const char code[] = "foo(a,b,c,d,e,f,g,h,i,j,k);\n"; SimpleTokenList tokenList(code); tokenList.front()->next()->astOperand1(tokenList.front()); @@ -481,7 +481,7 @@ class TestLibrary : public TestFixture { Library library; ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); - const char code[] = "foo(a,b,c,d,e);"; + const char code[] = "foo(a,b,c,d,e);\n"; SimpleTokenList tokenList(code); tokenList.front()->next()->astOperand1(tokenList.front()); @@ -543,13 +543,13 @@ class TestLibrary : public TestFixture { ASSERT(library.functions().at("bar").argumentChecks.empty()); { - const char code[] = "Foo::foo();"; + const char code[] = "Foo::foo();\n"; const SimpleTokenList tokenList(code); ASSERT(library.isnotnoreturn(tokenList.front()->tokAt(2))); } { - const char code[] = "bar();"; + const char code[] = "bar();\n"; const SimpleTokenList tokenList(code); ASSERT(library.isnotnoreturn(tokenList.front())); } @@ -569,14 +569,14 @@ class TestLibrary : public TestFixture { { SimpleTokenizer tokenizer(settingsDefault, *this); - const char code[] = "CString str; str.Format();"; + const char code[] = "CString str; str.Format();\n"; ASSERT(tokenizer.tokenize(code)); ASSERT(library.isnotnoreturn(Token::findsimplematch(tokenizer.tokens(), "Format"))); } { SimpleTokenizer tokenizer(settingsDefault, *this); - const char code[] = "HardDrive hd; hd.Format();"; + const char code[] = "HardDrive hd; hd.Format();\n"; ASSERT(tokenizer.tokenize(code)); ASSERT(!library.isnotnoreturn(Token::findsimplematch(tokenizer.tokens(), "Format"))); } @@ -595,14 +595,14 @@ class TestLibrary : public TestFixture { { SimpleTokenizer tokenizer(settingsDefault, *this); - const char code[] = "struct X : public Base { void dostuff() { f(0); } };"; + const char code[] = "struct X : public Base { void dostuff() { f(0); } };\n"; ASSERT(tokenizer.tokenize(code)); ASSERT(library.isnullargbad(Token::findsimplematch(tokenizer.tokens(), "f"),1)); } { SimpleTokenizer tokenizer(settingsDefault, *this); - const char code[] = "struct X : public Base { void dostuff() { f(1,2); } };"; + const char code[] = "struct X : public Base { void dostuff() { f(1,2); } };\n"; ASSERT(tokenizer.tokenize(code)); ASSERT(!library.isnullargbad(Token::findsimplematch(tokenizer.tokens(), "f"),1)); } @@ -622,7 +622,7 @@ class TestLibrary : public TestFixture { Library library; ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); - const char code[] = "a(); b();"; + const char code[] = "a(); b();\n"; const SimpleTokenList tokenList(code); const Library::WarnInfo* a = library.getWarnInfo(tokenList.front()); @@ -872,7 +872,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::A a;")); + ASSERT(var.tokenize("std::A a;\n")); ASSERT_EQUALS(&A, library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); bool isIterator; @@ -882,7 +882,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::A::size_type a_s;")); + ASSERT(var.tokenize("std::A::size_type a_s;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); ASSERT(!library.detectContainerOrIterator(var.tokens())); @@ -890,7 +890,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::A::iterator a_it;")); + ASSERT(var.tokenize("std::A::iterator a_it;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT_EQUALS(&A, library.detectIterator(var.tokens())); bool isIterator; @@ -900,7 +900,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::B b;")); + ASSERT(var.tokenize("std::B b;\n")); ASSERT_EQUALS(&B, library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); bool isIterator; @@ -910,7 +910,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::B::size_type b_s;")); + ASSERT(var.tokenize("std::B::size_type b_s;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); ASSERT(!library.detectContainerOrIterator(var.tokens())); @@ -918,7 +918,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::B::iterator b_it;")); + ASSERT(var.tokenize("std::B::iterator b_it;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT_EQUALS(&B, library.detectIterator(var.tokens())); bool isIterator; @@ -928,7 +928,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("C c;")); + ASSERT(var.tokenize("C c;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); ASSERT(!library.detectContainerOrIterator(var.tokens())); @@ -936,7 +936,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("D d;")); + ASSERT(var.tokenize("D d;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); ASSERT(!library.detectContainerOrIterator(var.tokens())); @@ -944,7 +944,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::E e;")); + ASSERT(var.tokenize("std::E e;\n")); ASSERT(library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); bool isIterator; @@ -955,7 +955,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("E e;")); + ASSERT(var.tokenize("E e;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); ASSERT(!library.detectContainerOrIterator(var.tokens())); @@ -964,7 +964,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::E::iterator I;")); + ASSERT(var.tokenize("std::E::iterator I;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); ASSERT(!library.detectContainerOrIterator(var.tokens())); @@ -973,7 +973,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::E::size_type p;")); + ASSERT(var.tokenize("std::E::size_type p;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); ASSERT(!library.detectContainerOrIterator(var.tokens())); @@ -982,7 +982,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::F f;")); + ASSERT(var.tokenize("std::F f;\n")); ASSERT(library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); bool isIterator; @@ -992,7 +992,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("std::F::iterator I;")); + ASSERT(var.tokenize("std::F::iterator I;\n")); ASSERT(!library.detectContainer(var.tokens())); TODO_ASSERT(library.detectIterator(var.tokens())); bool isIterator = false; @@ -1002,7 +1002,7 @@ class TestLibrary : public TestFixture { { SimpleTokenizer var(*this); - ASSERT(var.tokenize("F::iterator I;")); + ASSERT(var.tokenize("F::iterator I;\n")); ASSERT(!library.detectContainer(var.tokens())); ASSERT(!library.detectIterator(var.tokens())); ASSERT(!library.detectContainerOrIterator(var.tokens())); diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 2999fd3f441..e05698ae23e 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -51,19 +51,19 @@ class TestMemleak : public TestFixture { void testFunctionReturnType() { { const char code[] = "const char *foo()\n" - "{ return 0; }"; + "{ return 0; }\n"; ASSERT_EQUALS(CheckMemoryLeakImpl::No, functionReturnType(code)); } { const char code[] = "Fred *newFred()\n" - "{ return new Fred; }"; + "{ return new Fred; }\n"; ASSERT_EQUALS(CheckMemoryLeakImpl::New, functionReturnType(code)); } { const char code[] = "char *foo()\n" - "{ return new char[100]; }"; + "{ return new char[100]; }\n"; ASSERT_EQUALS(CheckMemoryLeakImpl::NewArray, functionReturnType(code)); } @@ -72,7 +72,7 @@ class TestMemleak : public TestFixture { "{\n" " char *p = new char[100];\n" " return p;\n" - "}"; + "}\n"; ASSERT_EQUALS(CheckMemoryLeakImpl::NewArray, functionReturnType(code)); } } @@ -157,7 +157,7 @@ class TestMemleakInFunction : public TestFixture { "{\n" " char *a = (char *)malloc(10);\n" " a = realloc(a, 100);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); } @@ -167,7 +167,7 @@ class TestMemleakInFunction : public TestFixture { " char *a = (char *)malloc(10);\n" " a = (char *)realloc(a, 100);\n" " free(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); } @@ -179,7 +179,7 @@ class TestMemleakInFunction : public TestFixture { " if ((a = realloc(a, 100)) == NULL)\n" " return;\n" " free(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -191,7 +191,7 @@ class TestMemleakInFunction : public TestFixture { " if ((a = realloc(a, 100)) == NULL)\n" " return;\n" " free(a);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: a\n", "[test.cpp:4:10]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure [memleakOnRealloc]\n", @@ -209,7 +209,7 @@ class TestMemleakInFunction : public TestFixture { " free(buf);\n" " else\n" " free(new_buf);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -223,7 +223,7 @@ class TestMemleakInFunction : public TestFixture { " }\n" " free(pData);\n" " return true;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -235,7 +235,7 @@ class TestMemleakInFunction : public TestFixture { " if (!m_buf) {\n" " m_buf = origBuf;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -243,7 +243,7 @@ class TestMemleakInFunction : public TestFixture { check("void foo()\n" "{\n" " x = realloc(x,100);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -253,7 +253,7 @@ class TestMemleakInFunction : public TestFixture { " pa = pb = malloc(10);\n" " pa = realloc(pa, 20);" " exit();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -264,7 +264,7 @@ class TestMemleakInFunction : public TestFixture { " if (!p)\n" " error();\n" " usep(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -275,7 +275,7 @@ class TestMemleakInFunction : public TestFixture { " if ((a = realloc(a, x + 100)) == NULL)\n" " return;\n" " free(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -285,7 +285,7 @@ class TestMemleakInFunction : public TestFixture { " char **str;\n" " *str = realloc(*str,100);\n" " free (*str);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Common realloc mistake: \'str\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); } @@ -296,7 +296,7 @@ class TestMemleakInFunction : public TestFixture { " if (!p)\n" " error();\n" " usep(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -307,7 +307,7 @@ class TestMemleakInFunction : public TestFixture { " if( m_options == NULL )\n" " return false;\n" " return true;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Common realloc mistake: \'m_options\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); } @@ -317,7 +317,7 @@ class TestMemleakInFunction : public TestFixture { " if (zLine) {\n" " free(zLine);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -326,7 +326,7 @@ class TestMemleakInFunction : public TestFixture { "{\n" " void ***a = malloc(sizeof(a));\n" " ***a = realloc(***(a), sizeof(a) * 2);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:8]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); } @@ -335,7 +335,7 @@ class TestMemleakInFunction : public TestFixture { "{\n" " void *a = malloc(sizeof(a));\n" " a = realloc((void*)a, sizeof(a) * 2);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); } @@ -344,7 +344,7 @@ class TestMemleakInFunction : public TestFixture { "{\n" " void *a = malloc(sizeof(a));\n" " a = (realloc((void*)((a)), sizeof(a) * 2));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); } @@ -353,7 +353,7 @@ class TestMemleakInFunction : public TestFixture { "{\n" " void *a = malloc(sizeof(a));\n" " a = realloc((a) + 1, sizeof(a) * 2);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -364,7 +364,7 @@ class TestMemleakInFunction : public TestFixture { " bs = realloc(bs, 100);\n" " if (bs == NULL) return bs0;\n" " return bs;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -375,7 +375,7 @@ class TestMemleakInFunction : public TestFixture { " bs = realloc(bs, 100);\n" " if (bs == NULL) return;\n" " *bsp = bs;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -386,7 +386,7 @@ class TestMemleakInFunction : public TestFixture { " if (!(cigar = realloc(cigar, 100 * sizeof(*cigar))))\n" " return;\n" " s->cigar = cigar;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -394,28 +394,28 @@ class TestMemleakInFunction : public TestFixture { check("void f() {\n" "void *a = NULL;\n" "a = realloc(a, 20);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" "void *a = NULL;\n" "a = malloc(10);\n" "a = realloc(a, 20);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:1]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); check("void f() {\n" "void *a = nullptr;\n" "a = malloc(10);\n" "a = realloc(a, 20);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:1]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure [memleakOnRealloc]\n", errout_str()); check("void f(char *b) {\n" "void *a = NULL;\n" "a = b;\n" "a = realloc(a, 20);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -568,7 +568,7 @@ class TestMemleakInClass : public TestFixture { "Fred::~Fred()\n" "{\n" " delete [] str2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); check("class Fred\n" @@ -586,7 +586,7 @@ class TestMemleakInClass : public TestFixture { " {\n" " delete [] str2;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:11]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); } @@ -608,7 +608,7 @@ class TestMemleakInClass : public TestFixture { "Fred::~Fred()\n" "{\n" " free(str1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:17:5]: (error) Mismatching allocation and deallocation: Fred::str1 [mismatchAllocDealloc]\n", errout_str()); check("class Fred\n" @@ -624,7 +624,7 @@ class TestMemleakInClass : public TestFixture { " {\n" " free(str1);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:12:9]: (error) Mismatching allocation and deallocation: Fred::str1 [mismatchAllocDealloc]\n", errout_str()); } @@ -660,7 +660,7 @@ class TestMemleakInClass : public TestFixture { " delete tok;\n" " tok = next;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -689,7 +689,7 @@ class TestMemleakInClass : public TestFixture { " tok = next;\n" " }\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -713,7 +713,7 @@ class TestMemleakInClass : public TestFixture { "{\n" " ABC *p = new ABC;\n" " addAbc( p );\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct ABC;\n" @@ -730,7 +730,7 @@ class TestMemleakInClass : public TestFixture { " ABC *p = new ABC;\n" " addAbc( p );\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -746,7 +746,7 @@ class TestMemleakInClass : public TestFixture { " char *str = new char[100];\n" " delete [] str;\n" " hello();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -758,7 +758,7 @@ class TestMemleakInClass : public TestFixture { " delete [] str;\n" " hello();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -778,7 +778,7 @@ class TestMemleakInClass : public TestFixture { "Fred::~Fred()\n" "{\n" " delete this->i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class Fred\n" @@ -793,7 +793,7 @@ class TestMemleakInClass : public TestFixture { " {\n" " delete this->i;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -810,7 +810,7 @@ class TestMemleakInClass : public TestFixture { " int* c = new int(1);\n" " delete c;\n" " doNothing(c);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class A\n" @@ -823,7 +823,7 @@ class TestMemleakInClass : public TestFixture { " doNothing(c);\n" " }\n" " void doNothing() { }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -840,7 +840,7 @@ class TestMemleakInClass : public TestFixture { "{ p = new int; }\n" "\n" "A::~A()\n" - "{ delete (p); }"); + "{ delete (p); }\n"); ASSERT_EQUALS("", errout_str()); check("class A\n" @@ -851,7 +851,7 @@ class TestMemleakInClass : public TestFixture { " { p = new int; }\n" " ~A()\n" " { delete (p); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -863,7 +863,7 @@ class TestMemleakInClass : public TestFixture { " A();\n" "};\n" "A::A()\n" - "{ p = new int; }"); + "{ p = new int; }\n"); ASSERT_EQUALS("[test.cpp:4:11]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); check("class A\n" @@ -871,7 +871,7 @@ class TestMemleakInClass : public TestFixture { "public:\n" " int * p;\n" " A() { p = new int; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:11]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); } @@ -881,8 +881,8 @@ class TestMemleakInClass : public TestFixture { "public:\n" " int * p;\n" " A() : p(new int[10])\n" - " { }" - "};"); + " { }\n" + "};\n"); ASSERT_EQUALS("[test.cpp:4:11]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); check("class A\n" @@ -892,7 +892,7 @@ class TestMemleakInClass : public TestFixture { " A();\n" "};\n" "A::A() : p(new int[10])\n" - "{ }"); + "{ }\n"); ASSERT_EQUALS("[test.cpp:4:11]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); } @@ -914,7 +914,7 @@ class TestMemleakInClass : public TestFixture { "{ }\n" "\n" "void A::cleanup()\n" - "{ delete [] p; }"); + "{ delete [] p; }\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); check("class A\n" @@ -928,7 +928,7 @@ class TestMemleakInClass : public TestFixture { " { }\n" " void cleanup()\n" " { delete [] p; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); } @@ -950,7 +950,7 @@ class TestMemleakInClass : public TestFixture { "{ }\n" "\n" "void A::foo()\n" - "{ p = new int[10]; delete [] p; }"); + "{ p = new int[10]; delete [] p; }\n"); ASSERT_EQUALS("[test.cpp:17:3]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated. [publicAllocationError]\n", errout_str()); check("class A\n" @@ -964,7 +964,7 @@ class TestMemleakInClass : public TestFixture { " { }\n" " void foo()\n" " { p = new int[10]; delete [] p; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:11:7]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated. [publicAllocationError]\n", errout_str()); } @@ -977,7 +977,7 @@ class TestMemleakInClass : public TestFixture { "};\n" "\n" "void A::init()\n" - "{ p = new int[10]; }"); + "{ p = new int[10]; }\n"); ASSERT_EQUALS("[test.cpp:9:3]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated. [publicAllocationError]\n" "[test.cpp:3:10]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); @@ -987,7 +987,7 @@ class TestMemleakInClass : public TestFixture { "public:\n" " void init()\n" " { p = new int[10]; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:7]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated. [publicAllocationError]\n" "[test.cpp:3:10]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); @@ -1000,7 +1000,7 @@ class TestMemleakInClass : public TestFixture { "};\n" "\n" "void A::init()\n" - "{ p = new int; }"); + "{ p = new int; }\n"); ASSERT_EQUALS("[test.cpp:9:3]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated. [publicAllocationError]\n" "[test.cpp:3:10]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); @@ -1010,7 +1010,7 @@ class TestMemleakInClass : public TestFixture { "public:\n" " void init()\n" " { p = new int; }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:7]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated. [publicAllocationError]\n" "[test.cpp:3:10]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); @@ -1023,7 +1023,7 @@ class TestMemleakInClass : public TestFixture { "};\n" "\n" "void A::init()\n" - "{ p = malloc(sizeof(int)*10); }"); + "{ p = malloc(sizeof(int)*10); }\n"); ASSERT_EQUALS("[test.cpp:9:3]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated. [publicAllocationError]\n" "[test.cpp:3:10]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); @@ -1033,7 +1033,7 @@ class TestMemleakInClass : public TestFixture { "public:\n" " void init()\n" " { p = malloc(sizeof(int)*10); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:7]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated. [publicAllocationError]\n" "[test.cpp:3:10]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); } @@ -1047,7 +1047,7 @@ class TestMemleakInClass : public TestFixture { " ~A() { delete [] p; }\n" "};\n" "A::A()\n" - "{ p = new int[10]; }"); + "{ p = new int[10]; }\n"); ASSERT_EQUALS("", errout_str()); check("class A\n" @@ -1057,7 +1057,7 @@ class TestMemleakInClass : public TestFixture { " A()\n" " { p = new int[10]; }\n" " ~A() { delete [] p; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -1069,7 +1069,7 @@ class TestMemleakInClass : public TestFixture { " ~A() { delete p; }\n" "};\n" "A::A()\n" - "{ p = new int; }"); + "{ p = new int; }\n"); ASSERT_EQUALS("", errout_str()); check("class A\n" @@ -1079,7 +1079,7 @@ class TestMemleakInClass : public TestFixture { " A()\n" " { p = new int; }\n" " ~A() { delete p; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); @@ -1091,7 +1091,7 @@ class TestMemleakInClass : public TestFixture { " ~A() { free(p); }\n" "};\n" "A::A()\n" - "{ p = malloc(sizeof(int)*10); }"); + "{ p = malloc(sizeof(int)*10); }\n"); ASSERT_EQUALS("", errout_str()); check("class A\n" @@ -1101,7 +1101,7 @@ class TestMemleakInClass : public TestFixture { " A()\n" " { p = malloc(sizeof(int)*10); }\n" " ~A() { free(p); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1114,7 +1114,7 @@ class TestMemleakInClass : public TestFixture { "public:\n" " A() { a = b = new int[10]; }\n" " ~A() { delete [] a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1131,7 +1131,7 @@ class TestMemleakInClass : public TestFixture { "{\n" " A::pd = new char[12];\n" " delete [] A::pd;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:5]: (warning) Possible leak in public function. The pointer 'pd' is not deallocated before it is allocated. [publicAllocationError]\n", errout_str()); check("class A {\n" @@ -1143,7 +1143,7 @@ class TestMemleakInClass : public TestFixture { " pd = new char[12];\n" " delete [] pd;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:9]: (warning) Possible leak in public function. The pointer 'pd' is not deallocated before it is allocated. [publicAllocationError]\n", errout_str()); check("class A {\n" @@ -1157,7 +1157,7 @@ class TestMemleakInClass : public TestFixture { "{\n" " pd = new char[12];\n" " delete [] pd;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:5]: (warning) Possible leak in public function. The pointer 'pd' is not deallocated before it is allocated. [publicAllocationError]\n", errout_str()); } @@ -1173,7 +1173,7 @@ class TestMemleakInClass : public TestFixture { " }\n" "private:\n" " char *a;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class A : public x\n" @@ -1187,7 +1187,7 @@ class TestMemleakInClass : public TestFixture { "{\n" " a = new char[10];\n" " foo(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1205,7 +1205,7 @@ class TestMemleakInClass : public TestFixture { "{\n" " rp1 = new TRadioButton(this);\n" " rp2 = new TRadioButton(this);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class TRadioButton { };\n" @@ -1221,7 +1221,7 @@ class TestMemleakInClass : public TestFixture { "{\n" " rp1 = new TRadioButton;\n" " rp2 = new TRadioButton;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:19]: (style) Class 'Foo' is unsafe, 'Foo::rp1' can leak by wrong usage. [unsafeClassCanLeak]\n" "[test.cpp:6:19]: (style) Class 'Foo' is unsafe, 'Foo::rp2' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); @@ -1244,7 +1244,7 @@ class TestMemleakInClass : public TestFixture { "{\n" " delete rp1;\n" " delete rp2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1266,7 +1266,7 @@ class TestMemleakInClass : public TestFixture { " delete [] str2;\n" " }\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:15]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); check("namespace ns1 {\n" @@ -1290,7 +1290,7 @@ class TestMemleakInClass : public TestFixture { " {\n" " delete [] str2;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:15]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); check("namespace ns1 {\n" @@ -1313,7 +1313,7 @@ class TestMemleakInClass : public TestFixture { "ns1::Fred::~Fred()\n" "{\n" " delete [] str2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:15]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); check("namespace ns1 {\n" @@ -1338,7 +1338,7 @@ class TestMemleakInClass : public TestFixture { "ns1::ns2::Fred::~Fred()\n" "{\n" " delete [] str2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:19]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); check("namespace ns1 {\n" @@ -1365,7 +1365,7 @@ class TestMemleakInClass : public TestFixture { "ns1::ns2::ns3::Fred::~Fred()\n" "{\n" " delete [] str2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:23]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage. [unsafeClassCanLeak]\n", errout_str()); } @@ -1382,7 +1382,7 @@ class TestMemleakInClass : public TestFixture { " C *c;\n" "public:\n" " A() : b(new B()), c(new C(b)) { }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:9:8]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage. [unsafeClassCanLeak]\n" "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", "[test.cpp:9:8]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage. [unsafeClassCanLeak]\n", @@ -1404,7 +1404,7 @@ class TestMemleakInClass : public TestFixture { " b = new B();\n" " c = new C(b);\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:9:8]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage. [unsafeClassCanLeak]\n" "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", "[test.cpp:9:8]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage. [unsafeClassCanLeak]\n", @@ -1418,7 +1418,7 @@ class TestMemleakInClass : public TestFixture { "private:\n" " Fred() { a = new int; }\n" " ~Fred() { (delete(a), (a)=NULL); }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1437,7 +1437,7 @@ class TestMemleakInClass : public TestFixture { " ~CData() { if (m_impl) m_impl->Release(); }\n" "private:\n" " CDataImpl *m_impl;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1448,7 +1448,7 @@ class TestMemleakInClass : public TestFixture { "public:\n" " Fred(const Fred &fred) { a = new int; }\n" " ~Fred() { delete a; }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1459,7 +1459,7 @@ class TestMemleakInClass : public TestFixture { "public:\n" " Fred() { a = new int; }\n" " ~Fred();\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1505,7 +1505,7 @@ class TestMemleakInClass : public TestFixture { " if (!p)\n" " p = new int[100];\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -1537,7 +1537,7 @@ class TestMemleakInClass : public TestFixture { "void Tokenizer::deleteTokens(int *tok)\n" "{\n" " delete tok;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Global function @@ -1564,7 +1564,7 @@ class TestMemleakInClass : public TestFixture { "{\n" " deleteTokens(_tokens);\n" " _tokens = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1589,7 +1589,7 @@ class TestMemleakInClass : public TestFixture { "\n" "A::~A() {\n" " delete [] pkt_buffer;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:14:9]: (error) Mismatching allocation and deallocation: A::pkt_buffer [mismatchAllocDealloc]\n", errout_str()); check("struct S {\n" // 5678 @@ -1625,7 +1625,7 @@ class TestMemleakInClass : public TestFixture { " data_ = new char[42];\n" " delete data_;\n" " data_ = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:17:3]: (warning) Possible leak in public function. The pointer 'data_' is not deallocated before it is allocated. [publicAllocationError]\n" "[test.cpp:18:3]: (error) Mismatching allocation and deallocation: Foo::data_ [mismatchAllocDealloc]\n", errout_str()); @@ -1648,7 +1648,7 @@ class TestMemleakInClass : public TestFixture { " data_ = new char[42];\n" " delete data_;\n" " data_ = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:17:3]: (warning) Possible leak in public function. The pointer 'data_' is not deallocated before it is allocated. [publicAllocationError]\n" "[test.cpp:18:3]: (error) Mismatching allocation and deallocation: Foo::data_ [mismatchAllocDealloc]\n", errout_str()); } @@ -1663,7 +1663,7 @@ class TestMemleakInClass : public TestFixture { " ~Fred() { free(s); }\n" " void xy()\n" " { s = malloc(100); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:9:7]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated. [publicAllocationError]\n", errout_str()); check("class Fred\n" @@ -1675,7 +1675,7 @@ class TestMemleakInClass : public TestFixture { " { s = malloc(100); }\n" "private:\n" " char *s;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:7:7]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated. [publicAllocationError]\n", errout_str()); } @@ -1689,7 +1689,7 @@ class TestMemleakInClass : public TestFixture { " ~Fred() { free(s); }\n" " const Fred & operator = (const Fred &f)\n" " { s = malloc(100); }\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:9:7]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated. [publicAllocationError]\n", errout_str()); } }; @@ -1782,14 +1782,14 @@ class TestMemleakStructMember : public TestFixture { " struct ABC *abc = malloc(sizeof(struct ABC));\n" " abc->a = malloc(10);\n" " free(abc);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (error) Memory leak: abc.a [memleak]\n", errout_str()); check("static void foo()\n" "{\n" " struct ABC *abc = malloc(sizeof(struct ABC));\n" " abc->a = malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:1]: (error) Memory leak: abc.a [memleak]\n", errout_str()); check("static ABC * foo()\n" @@ -1802,7 +1802,7 @@ class TestMemleakStructMember : public TestFixture { " return 0;\n" " }\n" " return abc;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:9]: (error) Memory leak: abc.a [memleak]\n", errout_str()); check("static void foo(int a)\n" @@ -1814,7 +1814,7 @@ class TestMemleakStructMember : public TestFixture { " free(abc->a);\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:1]: (error) Memory leak: abc.a [memleak]\n", errout_str()); } @@ -1830,7 +1830,7 @@ class TestMemleakStructMember : public TestFixture { "out:\n" " free(abc->a);\n" " free(abc);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1840,13 +1840,13 @@ class TestMemleakStructMember : public TestFixture { " struct ABC *abc = malloc(sizeof(struct ABC));\n" " abc->a = malloc(10);\n" " return abc;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("static void foo(struct ABC *abc)\n" "{\n" " abc->a = malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #7302 @@ -1854,14 +1854,14 @@ class TestMemleakStructMember : public TestFixture { " struct ABC abc;\n" " abc.a = malloc(10);\n" " return abc.a;\n" - "}", false); + "}\n", false); ASSERT_EQUALS("", errout_str()); check("void* foo() {\n" " struct ABC abc;\n" " abc.a = malloc(10);\n" " return abc.b;\n" - "}", false); + "}\n", false); ASSERT_EQUALS("[test.c:4:5]: (error) Memory leak: abc.a [memleak]\n", errout_str()); } @@ -1871,7 +1871,7 @@ class TestMemleakStructMember : public TestFixture { " struct ABC *abc = malloc(sizeof(struct ABC));\n" " abc->a = malloc(10);\n" " return &abc->self;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1880,7 +1880,7 @@ class TestMemleakStructMember : public TestFixture { "{\n" " struct ABC *abc = abc1;\n" " abc->a = malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("static void foo()\n" @@ -1888,7 +1888,7 @@ class TestMemleakStructMember : public TestFixture { " struct ABC *abc;\n" " abc1 = abc = malloc(sizeof(ABC));\n" " abc->a = malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("static void foo()\n" @@ -1897,7 +1897,7 @@ class TestMemleakStructMember : public TestFixture { " ptr = malloc(sizeof(struct msn_entry));\n" " ptr->msn = malloc(100);\n" " back = ptr;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1906,7 +1906,7 @@ class TestMemleakStructMember : public TestFixture { check("static void foo() {\n" " struct ABC *abc = malloc(123);\n" " abc->a = abc->b = malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1915,7 +1915,7 @@ class TestMemleakStructMember : public TestFixture { " struct s f2;\n" " f2.a = malloc(100);\n" " *f1 = f2;\n" - "}", false); + "}\n", false); ASSERT_EQUALS("", errout_str()); } @@ -2041,7 +2041,7 @@ class TestMemleakStructMember : public TestFixture { " return 0;\n" " }\n" " return abc;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2052,7 +2052,7 @@ class TestMemleakStructMember : public TestFixture { " struct ABC *abc = malloc(sizeof(struct ABC));\n" " abc->a = malloc(10);\n" " func(abc);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("static void foo()\n" @@ -2060,7 +2060,7 @@ class TestMemleakStructMember : public TestFixture { " struct ABC *abc = malloc(sizeof(struct ABC));\n" " abclist.push_back(abc);\n" " abc->a = malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2070,7 +2070,7 @@ class TestMemleakStructMember : public TestFixture { " A a = { 0 };\n" " a.foo = (char *) malloc(10);\n" " assign(&a);\n" - "}", false); + "}\n", false); ASSERT_EQUALS("", errout_str()); } @@ -2080,7 +2080,7 @@ class TestMemleakStructMember : public TestFixture { " struct ABC *abc = malloc(100);\n" " abc.a = (char *) malloc(10);\n" " list_add_tail(&abc->list, head);\n" - "}", false); + "}\n", false); ASSERT_EQUALS("", errout_str()); } @@ -2091,7 +2091,7 @@ class TestMemleakStructMember : public TestFixture { " struct ABC abc;\n" " abc.a = (char *) malloc(10);\n" " a(abc.a);\n" - "}", false); + "}\n", false); ASSERT_EQUALS("", errout_str()); } @@ -2100,14 +2100,14 @@ class TestMemleakStructMember : public TestFixture { " struct s s1;\n" " s1->x = malloc(1);\n" " return (s1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct nc_rpc nc_rpc_getconfig() {\n" // #10382 " struct nc_rpc rpc;\n" " rpc->filter = malloc(1);\n" " return (nc_rpc)rpc;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("T* f(const char *str) {\n" // #10158 @@ -2154,7 +2154,7 @@ class TestMemleakStructMember : public TestFixture { " S* s = new S();\n" " s->p = new int();\n" " g((void*)s);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2173,7 +2173,7 @@ class TestMemleakStructMember : public TestFixture { " }\n" " free(abc->a);\n" " free(abc);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2189,7 +2189,7 @@ class TestMemleakStructMember : public TestFixture { " free(abc);\n" " abc = next;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2201,7 +2201,7 @@ class TestMemleakStructMember : public TestFixture { " abc = malloc(sizeof(struct ABC));\n" " abc->a = malloc(10);\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2219,7 +2219,7 @@ class TestMemleakStructMember : public TestFixture { " a.f = fopen(\"test\", \"r\");\n" " a.c = new char[12];\n" " a.m = malloc(12);\n" - "}"; + "}\n"; check(code1, true); ASSERT_EQUALS("[test.cpp:12:1]: (error) Resource leak: a.f [resourceLeak]\n" @@ -2244,7 +2244,7 @@ class TestMemleakStructMember : public TestFixture { " fclose(a.f);\n" " delete [] a.c;\n" " free(a.m);\n" - "}"; + "}\n"; check(code2, true); ASSERT_EQUALS("", errout_str()); @@ -2253,7 +2253,7 @@ class TestMemleakStructMember : public TestFixture { const char code3[] = "void func() {\n" " struct A a;\n" " a.f = fopen(\"test\", \"r\");\n" - "}"; + "}\n"; check(code3, true); ASSERT_EQUALS("", errout_str()); @@ -2268,7 +2268,7 @@ class TestMemleakStructMember : public TestFixture { "void func() {\n" " struct A a;\n" " a.f = fopen(\"test\", \"r\");\n" - "}"; + "}\n"; check(code4, true); ASSERT_EQUALS("", errout_str()); @@ -2284,7 +2284,7 @@ class TestMemleakStructMember : public TestFixture { "{\n" " Test& y = *x;\n" " y.data = malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2294,7 +2294,7 @@ class TestMemleakStructMember : public TestFixture { "unique_ptrotherbuffer{new char[otherbufsize+1]};\n" "char *const oldbuffer = otherbuffer.get();\n" "int const oldbufsize = otherbufsize;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2307,7 +2307,7 @@ class TestMemleakStructMember : public TestFixture { " (s).state_check_buff = (void* )malloc(1);\n" " if (s.state_check_buff == 0)\n" " return;\n" - "}", false); + "}\n", false); ASSERT_EQUALS("[test.c:9:1]: (error) Memory leak: s.state_check_buff [memleak]\n", errout_str()); } @@ -2317,7 +2317,7 @@ class TestMemleakStructMember : public TestFixture { " foo f;\n" " ((f)->realm) = strdup(realm);\n" " if(f->realm == NULL) {}\n" - "}", false); + "}\n", false); ASSERT_EQUALS("[test.c:6:1]: (error) Memory leak: f.realm [memleak]\n", errout_str()); } @@ -2328,7 +2328,7 @@ class TestMemleakStructMember : public TestFixture { "void func() {\n" " struct ABC abc;\n" " abc.a = myalloc();\n" - "}", false); + "}\n", false); ASSERT_EQUALS("[test.c:7:1]: (error) Memory leak: abc.a [memleak]\n", errout_str()); } @@ -2344,7 +2344,7 @@ class TestMemleakStructMember : public TestFixture { " }\n" " delete[] s.p;\n" " return 0;\n" - "}", true); + "}\n", true); ASSERT_EQUALS("", errout_str()); check( @@ -2425,23 +2425,23 @@ class TestMemleakNoVar : public TestFixture { // standard function.. check("void x() {\n" " strcpy(a, strdup(p));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (error) Allocation with strdup, strcpy doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); check("char *x() {\n" " char *ret = strcpy(malloc(10), \"abc\");\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("char *x() {\n" " return strcpy(malloc(10), \"abc\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void x() {\n" " free(malloc(10));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // user function.. @@ -2450,7 +2450,7 @@ class TestMemleakNoVar : public TestFixture { "\n" "void x() {\n" " set_error(strdup(p));\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:5:15]: (error) Allocation with strdup, set_error doesn't release it. [leakNoVarFunctionCall]\n", "", errout_str()); check("void f()\n" @@ -2458,68 +2458,68 @@ class TestMemleakNoVar : public TestFixture { " int fd;\n" " fd = mkstemp(strdup(\"/tmp/file.XXXXXXXX\"));\n" " close(fd);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Allocation with strdup, mkstemp doesn't release it.\n", "", errout_str()); check("void f()\n" "{\n" " if(TRUE || strcmp(strdup(a), b));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:23]: (error) Allocation with strdup, strcmp doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); check("void f()\n" "{\n" " if(!strcmp(strdup(a), b) == 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (error) Allocation with strdup, strcmp doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); check("void f()\n" "{\n" " 42, strcmp(strdup(a), b);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16]: (error) Allocation with strdup, strcmp doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); check("void f() {\n" " assert(freopen(\"/dev/null\", \"r\", stdin));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void x() {\n" " strcpy(a, (void*)strdup(p));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (error) Allocation with strdup, strcpy doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); check("void* malloc1() {\n" " return (malloc(1));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("char *x() {\n" " char *ret = (char*)strcpy(malloc(10), \"abc\");\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " free(malloc(1));\n" " strcpy(a, strdup(p));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:15]: (error) Allocation with strdup, strcpy doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); check("void f() {\n" " memcmp(calloc(10, 10), strdup(q), 100);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (error) Allocation with calloc, memcmp doesn't release it. [leakNoVarFunctionCall]\n" "[test.cpp:2:28]: (error) Allocation with strdup, memcmp doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); check("void* f(int size) {\n" " return (void*) malloc(size);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int* f(int size) {\n" " return static_cast(malloc(size));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() { if (new int[42]) {} }\n" // #10857 @@ -2644,25 +2644,25 @@ class TestMemleakNoVar : public TestFixture { check("void x()\n" "{\n" " malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Return value of allocation function 'malloc' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("void x()\n" "{\n" " calloc(10, 1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Return value of allocation function 'calloc' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("void x()\n" "{\n" " strdup(\"Test\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Return value of allocation function 'strdup' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("void x()\n" "{\n" " (char*) malloc(10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (error) Return value of allocation function 'malloc' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("void x()\n" @@ -2670,7 +2670,7 @@ class TestMemleakNoVar : public TestFixture { " char* ptr = malloc(10);\n" " foo(ptr);\n" " free(ptr);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f( void ) {\n" // FP: #11246 @@ -2679,19 +2679,19 @@ class TestMemleakNoVar : public TestFixture { " if ( ok )\n" " free( address ), address = 0;\n" " return 0;\n" - "} "); + "} \n"); ASSERT_EQUALS("", errout_str()); check("char** x(const char* str) {\n" " char* ptr[] = { malloc(10), malloc(5), strdup(str) };\n" " return ptr;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void x()\n" "{\n" " 42,malloc(42);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8]: (error) Return value of allocation function 'malloc' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("void *f()\n" @@ -2701,7 +2701,7 @@ class TestMemleakNoVar : public TestFixture { "void x()\n" "{\n" " f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Return value of allocation function 'f' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("void f()\n" // #8100 @@ -2711,7 +2711,7 @@ class TestMemleakNoVar : public TestFixture { "void x()\n" "{\n" " f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void *f() {\n" // #8848 @@ -2720,26 +2720,26 @@ class TestMemleakNoVar : public TestFixture { "void x()\n" "{\n" " f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void x()\n" "{\n" " if(!malloc(5)) fail();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (error) Return value of allocation function 'malloc' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("FOO* factory() {\n" " FOO* foo = new (std::nothrow) FOO;\n" " return foo;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Ticket #6536 check("struct S { S(int) {} };\n" "void foo(int i) {\n" " S socket(i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Ticket #6693 @@ -2749,12 +2749,12 @@ class TestMemleakNoVar : public TestFixture { "};\n" "void CTest::Initialise() {\n" " malloc();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" // #7348 - cast " p = (::X*)malloc(42);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #7182 "crash: CheckMemoryLeak::functionReturnType()" @@ -2762,7 +2762,7 @@ class TestMemleakNoVar : public TestFixture { "template auto binary_left_comma (T x, Ts... ts) { return (x , ... , ts); }\n" "int main() {\n" " unary_right_comma (a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -2778,7 +2778,7 @@ class TestMemleakNoVar : public TestFixture { " new int{};\n" " new int{ 1 };\n" " new uint8_t[4];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (error) Return value of allocation function 'new' is not stored. [leakReturnValNotUsed]\n" "[test.cpp:3:5]: (error) Return value of allocation function 'new' is not stored. [leakReturnValNotUsed]\n" "[test.cpp:4:5]: (error) Return value of allocation function 'new' is not stored. [leakReturnValNotUsed]\n" @@ -2796,7 +2796,7 @@ class TestMemleakNoVar : public TestFixture { check("void f(int* p) {\n" " new auto('c');\n" " new(p) int;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:1:29]: (error) Return value of allocation function 'new' is not stored. [leakReturnValNotUsed]\n" "[test.cpp:3]: (error) Return value of allocation function 'new' is not stored.\n", "", @@ -2833,7 +2833,7 @@ class TestMemleakNoVar : public TestFixture { " C{ new int(1), 1 };\n" " C{ new(p) int, 1 };\n" " C{ new QWidget, 1 };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b) { if (b && malloc(42)) {} }\n" // // #10858 @@ -2896,54 +2896,54 @@ class TestMemleakNoVar : public TestFixture { void smartPointerFunctionParam() { check("void x() {\n" " f(shared_ptr(new int(42)), g());\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_shared() instead. [leakUnsafeArgAlloc]\n", errout_str()); check("void x() {\n" " h(12, f(shared_ptr(new int(42)), g()));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_shared() instead. [leakUnsafeArgAlloc]\n", errout_str()); check("void x() {\n" " f(unique_ptr(new int(42)), g());\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_unique() instead. [leakUnsafeArgAlloc]\n", errout_str()); check("void x() {\n" " f(g(), shared_ptr(new int(42)));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_shared() instead. [leakUnsafeArgAlloc]\n", errout_str()); check("void x() {\n" " f(g(), unique_ptr(new int(42)));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_unique() instead. [leakUnsafeArgAlloc]\n", errout_str()); check("void x() {\n" " f(shared_ptr(new char), make_unique(32));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning, inconclusive) Unsafe allocation. If make_unique() throws, memory could be leaked. Use make_shared() instead. [leakUnsafeArgAlloc]\n", errout_str()); check("void x() {\n" " f(g(124), h(\"test\", 234), shared_ptr(new char));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning, inconclusive) Unsafe allocation. If h() throws, memory could be leaked. Use make_shared() instead. [leakUnsafeArgAlloc]\n", errout_str()); check("void x() {\n" " f(shared_ptr(new std::string(\"\")), g());\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_shared() instead. [leakUnsafeArgAlloc]\n", errout_str()); check("void g(int x) throw() { }\n" "void x() {\n" " f(g(124), shared_ptr(new char));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void __declspec(nothrow) g(int x) { }\n" "void x() {\n" " f(g(124), shared_ptr(new char));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void resourceLeak() { @@ -2954,23 +2954,23 @@ class TestMemleakNoVar : public TestFixture { " if (result) return !result;\n" " fclose(fp);\n" " return result;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " fopen(\"file.txt\", \"r\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (error) Return value of allocation function 'fopen' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("void foo() {\n" " FILE *f = fopen(\"file.txt\", \"r\");\n" " freopen(\"file.txt\", \"r\", f);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error) Return value of allocation function 'freopen' is not stored. [leakReturnValNotUsed]\n", errout_str()); check("void foo() {\n" " freopen(\"file.txt\", \"r\", stdin);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Holder {\n" @@ -2980,7 +2980,7 @@ class TestMemleakNoVar : public TestFixture { "};\n" "void foo() {\n" " Holder h ( fopen(\"file.txt\", \"r\"));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Holder {\n" @@ -2990,7 +2990,7 @@ class TestMemleakNoVar : public TestFixture { "};\n" "void foo() {\n" " Holder ( fopen(\"file.txt\", \"r\"));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Holder {\n" @@ -3000,7 +3000,7 @@ class TestMemleakNoVar : public TestFixture { "};\n" "void foo() {\n" " Holder h { fopen(\"file.txt\", \"r\")};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Holder {\n" @@ -3010,7 +3010,7 @@ class TestMemleakNoVar : public TestFixture { "};\n" "void foo() {\n" " Holder h = fopen(\"file.txt\", \"r\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Holder {\n" @@ -3020,7 +3020,7 @@ class TestMemleakNoVar : public TestFixture { "};\n" "void foo() {\n" " Holder { fopen(\"file.txt\", \"r\")};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Holder {\n" @@ -3030,7 +3030,7 @@ class TestMemleakNoVar : public TestFixture { "};\n" "void foo() {\n" " Holder { 0, fopen(\"file.txt\", \"r\")};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3041,7 +3041,7 @@ class TestMemleakNoVar : public TestFixture { "\n" "void f() {\n" " makeThing();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10631 @@ -3068,12 +3068,12 @@ class TestMemleakNoVar : public TestFixture { void crash1() { // #10729 check("void foo() {\n" " extern void *realloc (void *ptr, size_t size);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " extern void *malloc (size_t size);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index c1bf766b8bb..81c44d58811 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -228,7 +228,7 @@ class TestNullPointer : public TestFixture { "{\n" " while (tok);\n" " tok = tok->next();\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:3:12] -> [test.cpp:4:11]: (warning) Either the condition 'tok' is redundant or there is possible null pointer dereference: tok. [nullPointerRedundantCheck]\n", errout_str()); // #2681 @@ -253,7 +253,7 @@ class TestNullPointer : public TestFixture { " while (tok && tok->str() != \";\")\n" " tok = tok->next();\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:3]: (warning) Either the condition 'while' is redundant or there is possible null pointer dereference: tok.\n", "", errout_str()); check("void foo(Token &tok)\n" @@ -263,7 +263,7 @@ class TestNullPointer : public TestFixture { " while (!tok)\n" " char c = tok.read();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -274,7 +274,7 @@ class TestNullPointer : public TestFixture { " tok = tok->next();\n" " if( !tok ) break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -284,7 +284,7 @@ class TestNullPointer : public TestFixture { " while (tok && tok->str() != \";\")\n" " tok = tok->next();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(A*a)\n" @@ -299,7 +299,7 @@ class TestNullPointer : public TestFixture { " a->b();\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // dereference in outer scope.. @@ -308,7 +308,7 @@ class TestNullPointer : public TestFixture { " while (tok) tok = tok->next();\n" " }\n" " tok->str();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:16] -> [test.cpp:5:5]: (warning) Either the condition 'tok' is redundant or there is possible null pointer dereference: tok. [nullPointerRedundantCheck]\n", errout_str()); check("int foo(const Token *tok)\n" @@ -333,7 +333,7 @@ class TestNullPointer : public TestFixture { " while (d && d->i == 0)\n" " d = d->c;\n" " if (!d) throw;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct b {\n" @@ -358,7 +358,7 @@ class TestNullPointer : public TestFixture { " }\n" " else if (a->x == 2) { }\n" " if (a) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket #2134 - sizeof doesn't dereference @@ -368,7 +368,7 @@ class TestNullPointer : public TestFixture { " sizeof(*list);\n" " if (!list)\n" " ;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // ticket #2245 - sizeof doesn't dereference @@ -376,7 +376,7 @@ class TestNullPointer : public TestFixture { " if (!p) {\n" " int sz = sizeof(p->x);\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -388,7 +388,7 @@ class TestNullPointer : public TestFixture { " Fred fred;\n" " while (fred);\n" " fred.hello();\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -404,7 +404,7 @@ class TestNullPointer : public TestFixture { " int a = abc->a;\n" " if (!abc)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:13]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(struct ABC *abc) {\n" @@ -413,7 +413,7 @@ class TestNullPointer : public TestFixture { " bar(x, y, abc->a);\n" " if (!abc)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:2:9]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n" "[test.cpp:5:9] -> [test.cpp:3:12]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n" "[test.cpp:5:9] -> [test.cpp:4:15]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); @@ -423,7 +423,7 @@ class TestNullPointer : public TestFixture { " return;\n" " }\n" " if (abc) {}\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:9] -> [test.cpp:2:9]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); @@ -433,7 +433,7 @@ class TestNullPointer : public TestFixture { " return;\n" " }\n" " if (!abc);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:2:9]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); // TODO: False negative if member of member is dereferenced @@ -441,14 +441,14 @@ class TestNullPointer : public TestFixture { " abc->next->a = 0;\n" " if (abc->next)\n" " ;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null.\n", "", errout_str()); check("void foo(ABC *abc) {\n" " abc->a = 0;\n" " if (abc && abc->b == 0)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:9] -> [test.cpp:2:5]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); @@ -459,13 +459,13 @@ class TestNullPointer : public TestFixture { " if (abc && abc->a);\n" " if (!abc)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(struct ABC *abc) {\n" " int x = abc && a(abc->x);\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ok to use a linked list.. @@ -474,13 +474,13 @@ class TestNullPointer : public TestFixture { " abc = abc->next;\n" " if (!abc)\n" " ;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f(struct ABC *abc) {\n" " abc = (ABC *)(abc->_next);\n" - " if (abc) { }" - "}", dinit(CheckOptions, $.inconclusive = true)); + " if (abc) { }\n" + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // reassign struct.. @@ -490,7 +490,7 @@ class TestNullPointer : public TestFixture { " abc = abc->next;\n" " if (!abc)\n" " ;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void foo(struct ABC *abc)\n" @@ -499,7 +499,7 @@ class TestNullPointer : public TestFixture { " f(&abc);\n" " if (!abc)\n" " ;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // goto.. @@ -513,7 +513,7 @@ class TestNullPointer : public TestFixture { "out:\n" " if (!abc)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // loops.. @@ -527,7 +527,7 @@ class TestNullPointer : public TestFixture { " --a;\n" " }\n" " while (a > 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -539,7 +539,7 @@ class TestNullPointer : public TestFixture { " if (!tok)\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // dynamic_cast.. @@ -548,7 +548,7 @@ class TestNullPointer : public TestFixture { " int a = abc->a;\n" " if (!dynamic_cast(abc))\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #2641 - global pointer, function call @@ -557,14 +557,14 @@ class TestNullPointer : public TestFixture { " abc->a = 0;\n" " do_stuff();\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("",errout_str()); check("Fred *fred;\n" "void f() {\n" " fred->foo();\n" " if (fred) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("",errout_str()); // #2641 - local pointer, function call @@ -573,7 +573,7 @@ class TestNullPointer : public TestFixture { " abc->a = 0;\n" " do_stuff();\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:9] -> [test.cpp:3:5]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); @@ -583,7 +583,7 @@ class TestNullPointer : public TestFixture { " abc->a = 0;\n" " do_stuff();\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:2:5]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); @@ -598,32 +598,32 @@ class TestNullPointer : public TestFixture { " if ( abc ) {}\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3128 check("void f(ABC *abc) {\n" " x(!abc || y(abc->a));\n" " if (abc) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(ABC *abc) {\n" " x(def || !abc || y(def, abc->a));\n" " if (abc) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(ABC *abc) {\n" " x(abc && y(def, abc->a));\n" " if (abc) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(ABC *abc) {\n" " x(def && abc && y(def, abc->a));\n" " if (abc) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3228 - calling function with null object @@ -631,7 +631,7 @@ class TestNullPointer : public TestFixture { const char code[] = "void f(Fred *fred) {\n" " fred->x();\n" " if (fred) { }\n" - "}"; + "}\n"; check(code); ASSERT_EQUALS( "[test.cpp:3:9] -> [test.cpp:2:5]: (warning) Either the condition 'fred' is redundant or there is possible null pointer dereference: fred. [nullPointerRedundantCheck]\n", @@ -643,7 +643,7 @@ class TestNullPointer : public TestFixture { "void f(struct FRED *fred) {\n" " fred->x = 0;\n" " IF(!fred){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -651,7 +651,7 @@ class TestNullPointer : public TestFixture { " if (!buffer)\n" " uv_fatal_error();\n" " buffer->x = 11;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -665,14 +665,14 @@ class TestNullPointer : public TestFixture { " *p = 0;\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:6]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(int *p)\n" "{\n" " *p = 0;\n" " if (p) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:3:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -681,7 +681,7 @@ class TestNullPointer : public TestFixture { "{\n" " *p = 0;\n" " if (p || q) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:3:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -691,7 +691,7 @@ class TestNullPointer : public TestFixture { " bar(*p);\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:10]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(char *p)\n" @@ -699,14 +699,14 @@ class TestNullPointer : public TestFixture { " strcpy(p, \"abc\");\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:12]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(char *p)\n" "{\n" " if (*p == 0) { }\n" " if (!p) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:10]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); // no error @@ -716,7 +716,7 @@ class TestNullPointer : public TestFixture { " f(&p);\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -724,7 +724,7 @@ class TestNullPointer : public TestFixture { " int **p = f();\n" " if (!p)\n" " ;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void foo(int *p)\n" @@ -735,7 +735,7 @@ class TestNullPointer : public TestFixture { " *p = 0;\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int x)\n" @@ -743,7 +743,7 @@ class TestNullPointer : public TestFixture { " int a = 2 * x;" " if (x == 0)\n" " ;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void foo(int *p)\n" @@ -751,7 +751,7 @@ class TestNullPointer : public TestFixture { " int var1 = p ? *p : 0;\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int *p, bool x)\n" @@ -759,7 +759,7 @@ class TestNullPointer : public TestFixture { " int var1 = x ? *p : 5;\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:3:21]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -768,13 +768,13 @@ class TestNullPointer : public TestFixture { check("void f(int *p) {\n" " *p = 0;\n" " while (p) { p = 0; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p) {\n" " *p = 0;\n" " while (p) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:12] -> [test.cpp:2:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -785,7 +785,7 @@ class TestNullPointer : public TestFixture { " int var1 = p ? (p->a) : 0;\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(ABC *p)\n" @@ -793,7 +793,7 @@ class TestNullPointer : public TestFixture { " int var1 = p ? (1 + p->a) : 0;\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -825,7 +825,7 @@ class TestNullPointer : public TestFixture { " break;\n" " else\n" " p = p->next();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(Document *doc) {\n" @@ -833,27 +833,27 @@ class TestNullPointer : public TestFixture { " if (!doc) {\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3128 - false positive check("void f(int *p) {\n" " assert(!p || (*p<=6));\n" " if (p) { *p = 0; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p) {\n" " assert(p && (*p<=6));\n" " if (p) { *p = 0; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p) {\n" " *p = 12;\n" " assert(p && (*p<=6));\n" " if (p) { *p = 0; }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:12] -> [test.cpp:2:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -863,7 +863,7 @@ class TestNullPointer : public TestFixture { " p = p->next;\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(x *p)\n" @@ -871,7 +871,7 @@ class TestNullPointer : public TestFixture { " p = bar(p->next);\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(x *p)\n" @@ -879,7 +879,7 @@ class TestNullPointer : public TestFixture { " p = aa->bar(p->next);\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(x *p)\n" @@ -887,7 +887,7 @@ class TestNullPointer : public TestFixture { " p = *p2 = p->next;\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(struct ABC *abc)\n" @@ -895,32 +895,32 @@ class TestNullPointer : public TestFixture { " abc = abc ? abc->next : 0;\n" " if (!abc)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(struct ABC *abc) {\n" // #4523 " abc = (*abc).next;\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(struct ABC *abc) {\n" // #4523 " abc = (*abc->ptr);\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(Item *item) {\n" " x = item ? ab(item->x) : 0;\n" " if (item) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(Item *item) {\n" " item->x = 0;\n" " a = b ? c : d;\n" " if (item) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:2:5]: (warning) Either the condition 'item' is redundant or there is possible null pointer dereference: item. [nullPointerRedundantCheck]\n", errout_str()); @@ -934,7 +934,7 @@ class TestNullPointer : public TestFixture { "\n" " if( !pFrm )\n" " return FALSE;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Ticket #2463 @@ -954,7 +954,7 @@ class TestNullPointer : public TestFixture { " break;\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #2525 - sizeof @@ -963,26 +963,26 @@ class TestNullPointer : public TestFixture { " int c = sizeof(test[0]);\n" " if (!test)\n" " ;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f(type* p) {\n" // #4983 " x(sizeof p[0]);\n" " if (!p)\n" " ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3023 - checked deref check("void f(struct ABC *abc) {\n" " WARN_ON(!abc || abc->x == 0);\n" " if (!abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(struct ABC *abc) {\n" " WARN_ON(!abc || abc->x == 7);\n" " if (!abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3425 - false positives when there are macros @@ -990,14 +990,14 @@ class TestNullPointer : public TestFixture { "void f(int *p) {\n" " *p = 0;\n" " IF(!p){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #3914 - false positive " int *p;\n" " ((p=ret()) && (x=*p));\n" " if (p);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S { struct T { char c; } *p; };\n" // #6541 @@ -1021,7 +1021,7 @@ class TestNullPointer : public TestFixture { " char c = a.c();\n" " if (!a)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1036,18 +1036,18 @@ class TestNullPointer : public TestFixture { " } else { if (a == 2) {\n" " p = new FooCar; } }\n" " p->abcd();\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Possible null pointer dereference: p\n", "", errout_str()); check("static void foo() {\n" " int &r = *(int*)0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (error) Null pointer dereference: (int*)0 [nullPointer]\n", errout_str()); check("static void foo(int x) {\n" " int y = 5 + *(int*)0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (error) Null pointer dereference: (int*)0 [nullPointer]\n", errout_str()); { @@ -1062,7 +1062,7 @@ class TestNullPointer : public TestFixture { check("static void foo() {\n" " std::cout << *(int*)0;" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:19]: (error) Null pointer dereference: (int*)0 [nullPointer]\n", errout_str()); check("void f()\n" @@ -1072,12 +1072,12 @@ class TestNullPointer : public TestFixture { " delete c;\n" " }\n" " c[0] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (error) Null pointer dereference: c [nullPointer]\n", errout_str()); check("static void foo() {\n" " if (3 > *(int*)0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (error) Null pointer dereference: (int*)0 [nullPointer]\n", errout_str()); // no false positive.. @@ -1086,20 +1086,20 @@ class TestNullPointer : public TestFixture { " Foo *p = 0;\n" " p = new Foo;\n" " p->abcd();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" " int sz = sizeof((*(struct dummy *)0).x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void get_offset(long &offset)\n" "{\n" " mystruct * temp; temp = 0;\n" " offset = (long)(&(temp->z));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Ticket #1893 - try/catch inside else @@ -1118,7 +1118,7 @@ class TestNullPointer : public TestFixture { " }\n" " *Q=1;\n" " return Q;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int *test(int *Z)\n" @@ -1134,7 +1134,7 @@ class TestNullPointer : public TestFixture { " }\n" " *Q=1;\n" " return Q;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:12:6]: (warning) Possible null pointer dereference: Q [nullPointer]\n", errout_str()); // Ticket #2052 (false positive for 'else continue;') @@ -1145,7 +1145,7 @@ class TestNullPointer : public TestFixture { " else continue;\n" " *p = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // function pointer.. @@ -1154,7 +1154,7 @@ class TestNullPointer : public TestFixture { " void (*f)();\n" " f = 0;\n" " f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (error) Null pointer dereference: f [nullPointer]\n", errout_str()); check("int* g();\n" // #11007 @@ -1172,7 +1172,7 @@ class TestNullPointer : public TestFixture { " for (int i = 0; i < 10; ++i) {\n" " int x = *p + 1;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("void f(int a) {\n" @@ -1183,21 +1183,21 @@ class TestNullPointer : public TestFixture { " for (int i = 0; i < 3; i++) {\n" " if (a && (p[i] == '1'));\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // ticket #2251: taking the address of member check("void f() {\n" " Fred *fred = 0;\n" " int x = &fred->x;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // ticket #3220: dereferencing a null pointer is UB check("void f() {\n" " Fred *fred = NULL;\n" " fred->do_something();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Null pointer dereference: fred [nullPointer]\n", errout_str()); // ticket #3570 - parsing of conditions @@ -1207,21 +1207,21 @@ class TestNullPointer : public TestFixture { " if (x)\n" " p = q;\n" " if (p && *p) { }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int *p = NULL;\n" " if (x)\n" " p = q;\n" " if (!p || *p) { }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int *p = NULL;\n" " if (x)\n" " p = q;\n" " if (p || *p) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:15]: (warning) Possible null pointer dereference: p [nullPointer]\n", errout_str()); } @@ -1237,7 +1237,7 @@ class TestNullPointer : public TestFixture { "\n" "void g() {\n" " f(NULL, NULL);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -1262,7 +1262,7 @@ class TestNullPointer : public TestFixture { " for (int i = 0; i < n; i++) {\n" " argv32[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // No false negative: @@ -1277,7 +1277,7 @@ class TestNullPointer : public TestFixture { " for (int i = 0; i < n; i++) {\n" " argv32[i] = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:9]: (warning) Possible null pointer dereference: argv32 [nullPointer]\n", errout_str()); // #2231 - error if assignment in loop is not used @@ -1293,7 +1293,7 @@ class TestNullPointer : public TestFixture { " }\n" "\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:11:6]: (warning) Possible null pointer dereference: p [nullPointer]\n", errout_str()); } @@ -1302,7 +1302,7 @@ class TestNullPointer : public TestFixture { "{\n" " wxLongLong x = 0;\n" " int y = x.GetValue();\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -1311,7 +1311,7 @@ class TestNullPointer : public TestFixture { "{\n" " std::string * x = 0;\n" " *x = \"test\";\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:4]: (error) Null pointer dereference: x [nullPointer]\n", errout_str()); } @@ -1321,7 +1321,7 @@ class TestNullPointer : public TestFixture { "{\n" " struct my_type* p = 0;\n" " p->x = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:3]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); } @@ -1333,7 +1333,7 @@ class TestNullPointer : public TestFixture { " struct my_type* p;\n" " p = 0;\n" " return p->x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); } @@ -1360,7 +1360,7 @@ class TestNullPointer : public TestFixture { " char *p = 0;\n" " if (x) p = \"abcd\";\n" " return p ? f(*p) : f(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1369,7 +1369,7 @@ class TestNullPointer : public TestFixture { " int *p = 0;\n" " bar(&p);\n" " *p = 0;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -1378,14 +1378,14 @@ class TestNullPointer : public TestFixture { " int *p = 0;\n" " if (x) { return 0; }\n" " return !p || *p;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("int foo() {\n" " int *p = 0;\n" " if (x) { return 0; }\n" " return p && *p;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -1398,14 +1398,14 @@ class TestNullPointer : public TestFixture { " {\n" " i++;\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (error) Null pointer dereference: str [nullPointer]\n", errout_str()); } void nullpointer19() { // #3811 check("int foo() {\n" " perror(0);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -1414,14 +1414,14 @@ class TestNullPointer : public TestFixture { " struct xy *p = 0;\n" " if (x) p = q;\n" " if (p ? p->x || p->y : 0) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" // false negative " struct xy *p = 0;\n" " if (x) p = q;\n" " if (y ? p->x : p->y) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (warning) Possible null pointer dereference: p [nullPointer]\n" "[test.cpp:4:20]: (warning) Possible null pointer dereference: p [nullPointer]\n", errout_str()); @@ -1433,7 +1433,7 @@ class TestNullPointer : public TestFixture { " if (x) p = q;\n" " else return;\n" " *p = 0;\n" // <- p is not NULL - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1442,7 +1442,7 @@ class TestNullPointer : public TestFixture { " char *c = NULL;\n" " char cBuf[10];\n" " sprintf(cBuf, \"%s\", c ? c : \"0\" );\n" - "}"); + "}\n"); ASSERT_EQUALS("",errout_str()); } @@ -1451,7 +1451,7 @@ class TestNullPointer : public TestFixture { " char *c = NULL;\n" " x = c = new char[10];\n" " *c = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1461,7 +1461,7 @@ class TestNullPointer : public TestFixture { " int *array = NULL;\n" " if (data == 1 && array[i] == 0)\n" " std::cout << \"test\";\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:22]: (error) Null pointer dereference: array [nullPointer]\n", errout_str()); } @@ -1478,7 +1478,7 @@ class TestNullPointer : public TestFixture { " if (t2 && (!t1))\n" " return 0.0;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1492,7 +1492,7 @@ class TestNullPointer : public TestFixture { " pointer_=NULL;\n" " *pointer_=0;\n" " return *this;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:6]: (error) Null pointer dereference: pointer_ [nullPointer]\n", errout_str()); } @@ -1502,7 +1502,7 @@ class TestNullPointer : public TestFixture { " int i = s ? s->value + 1\n" " : s->value - 1; // <-- null ptr dereference\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:11] -> [test.cpp:4:15]: (warning) Either the condition 's' is redundant or there is possible null pointer dereference: s. [nullPointerRedundantCheck]\n", errout_str()); @@ -1553,7 +1553,7 @@ class TestNullPointer : public TestFixture { " }\n" "\n" " (void)f->x;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -1665,7 +1665,7 @@ class TestNullPointer : public TestFixture { "void f(struct A *a) {\n" " if (a->x == NULL) {}\n" " *(a->x);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:14] -> [test.cpp:4:8]: (warning) Either the condition 'a->x==NULL' is redundant or there is possible null pointer dereference: a->x. [nullPointerRedundantCheck]\n", errout_str()); @@ -1676,7 +1676,7 @@ class TestNullPointer : public TestFixture { "void f(struct A *a) {\n" " if (a->x == nullptr) {}\n" " *(a->x);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:14] -> [test.cpp:4:8]: (warning) Either the condition 'a->x==nullptr' is redundant or there is possible null pointer dereference: a->x. [nullPointerRedundantCheck]\n", errout_str()); @@ -1687,7 +1687,7 @@ class TestNullPointer : public TestFixture { "void f(struct A *a) {\n" " if (a->g() == nullptr) {}\n" " *(a->g());\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:16] -> [test.cpp:4:11]: (warning) Either the condition 'a->g()==nullptr' is redundant or there is possible null pointer dereference: a->g(). [nullPointerRedundantCheck]\n", errout_str()); @@ -1696,7 +1696,7 @@ class TestNullPointer : public TestFixture { "void f(struct A *a) {\n" " if (a->g() == nullptr) {}\n" " *(a->g());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1705,7 +1705,7 @@ class TestNullPointer : public TestFixture { "void f(struct A *a) {\n" " if (a->g() == nullptr) {}\n" " *(a->g());\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:16] -> [test.cpp:4:11]: (warning) Either the condition 'a->g()==nullptr' is redundant or there is possible null pointer dereference: a->g(). [nullPointerRedundantCheck]\n", errout_str()); @@ -1718,7 +1718,7 @@ class TestNullPointer : public TestFixture { " if (x) {\n" " (void)*a->x;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1730,7 +1730,7 @@ class TestNullPointer : public TestFixture { " if ( w == 0.0 )\n" " return 0;\n" " return b->get();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9423 check("extern F* GetF();\n" @@ -1747,7 +1747,7 @@ class TestNullPointer : public TestFixture { " if (!lPtrOk)\n" " return;\n" " lPtr->Clear();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1764,7 +1764,7 @@ class TestNullPointer : public TestFixture { " g();\n" " a d = *c->b();\n" " return d;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct a {\n" @@ -1780,7 +1780,7 @@ class TestNullPointer : public TestFixture { " e();\n" " a d = *c->b();\n" " return d;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1788,7 +1788,7 @@ class TestNullPointer : public TestFixture { check("void f() {\n" " char* p = new(std::nothrow) char[1];\n" " if( p ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1797,7 +1797,7 @@ class TestNullPointer : public TestFixture { " if(!p[0]) {}\n" " const int *const a = p;\n" " if(!a){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7] -> [test.cpp:2:8]: (warning) Either the condition '!a' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); } @@ -1806,7 +1806,7 @@ class TestNullPointer : public TestFixture { "auto f(T& x) -> decltype(x);\n" "int& g(int* x) {\n" " return f(*x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1816,7 +1816,7 @@ class TestNullPointer : public TestFixture { " if(n > 10) q = p;\n" " *p +=2;\n" " if(n < 120) *q+=12;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:18]: (warning) Possible null pointer dereference: q [nullPointer]\n", errout_str()); check("void f(int *p, int n) {\n" @@ -1824,7 +1824,7 @@ class TestNullPointer : public TestFixture { " if(n > 10) q = p;\n" " *p +=2;\n" " if(n > 10) *q+=12;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1838,7 +1838,7 @@ class TestNullPointer : public TestFixture { " }\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:8] -> [test.cpp:6:18]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -1854,7 +1854,7 @@ class TestNullPointer : public TestFixture { " if (c(e, \"\"))\n" " return nullptr;\n" " return e->b();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1864,7 +1864,7 @@ class TestNullPointer : public TestFixture { " if(b) c = b;\n" " if (!c) c = &a;\n" " return *c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int a, int* b) {\n" @@ -1873,7 +1873,7 @@ class TestNullPointer : public TestFixture { " bool d = !c;\n" " if (d) c = &a;\n" " return *c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int* x; };\n" @@ -1883,7 +1883,7 @@ class TestNullPointer : public TestFixture { " if(b) c.x = b;\n" " if (!c.x) c.x = &a;\n" " return *c.x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int* x; };\n" @@ -1894,7 +1894,7 @@ class TestNullPointer : public TestFixture { " bool d = !c.x;\n" " if (d) c.x = &a;\n" " return *c.x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int* x; };\n" @@ -1917,7 +1917,7 @@ class TestNullPointer : public TestFixture { "}\n" "void bar() {\n" " f(0, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Possible null pointer dereference: params [nullPointer]\n", errout_str()); } @@ -1933,7 +1933,7 @@ class TestNullPointer : public TestFixture { "int bar() {\n" " int **array = NULL;\n" " foo (array, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1943,7 +1943,7 @@ class TestNullPointer : public TestFixture { " while (tok3->astParent() && tok3->str() == \",\")\n" " tok3 = tok3->astParent();\n" " if (tok3 && tok3->str() == \"(\") {}\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:5:9] -> [test.cpp:3:12]: (warning) Either the condition 'tok3' is redundant or there is possible null pointer dereference: tok3. [nullPointerRedundantCheck]\n", errout_str()); @@ -1956,7 +1956,7 @@ class TestNullPointer : public TestFixture { " }\n" " if (!t1 || !t2)\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(int* i);\n" @@ -1964,7 +1964,7 @@ class TestNullPointer : public TestFixture { " while(f(i) && *i == 0)\n" " i++;\n" " if (!i) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1976,7 +1976,7 @@ class TestNullPointer : public TestFixture { " ListEntry *prev = NULL;\n" " for (ListEntry *cursor = listHead; cursor != NULL; prev = cursor, cursor = cursor->next) {}\n" " if (prev) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2499,7 +2499,7 @@ class TestNullPointer : public TestFixture { " int *p = 0;\n" " pp = &p;\n" " **pp = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:6]: (error) Null pointer dereference: *pp [nullPointer]\n", errout_str()); } @@ -2735,7 +2735,7 @@ class TestNullPointer : public TestFixture { " }\n" " }\n" " return \"unknown\";\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:7:12] -> [test.cpp:3:7]: (warning) Either the condition 'ctx' is redundant or there is possible null pointer dereference: ctx. [nullPointerRedundantCheck]\n", errout_str()); @@ -2777,7 +2777,7 @@ class TestNullPointer : public TestFixture { " int* myNull = GetThing();\n" " *myNull=42;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (error) Null pointer dereference: myNull [nullPointer]\n", errout_str()); check("struct foo {\n" @@ -2788,7 +2788,7 @@ class TestNullPointer : public TestFixture { " int* myNull = myFoo.GetThing();\n" " *myNull=42;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:10]: (error) Null pointer dereference: myNull [nullPointer]\n", errout_str()); check("struct T { bool g() const; };\n" @@ -2885,7 +2885,7 @@ class TestNullPointer : public TestFixture { " int * buf = foo(true);\n" " buf[2] = 0;" // << " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:14:9]: (error) Null pointer dereference: buf [nullPointer]\n", errout_str()); } @@ -3113,7 +3113,7 @@ class TestNullPointer : public TestFixture { " int *p{};\n" " int *&r{p};\n" " if (*r) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (error) Null pointer dereference: r [nullPointer]\n", errout_str()); } @@ -3142,7 +3142,7 @@ class TestNullPointer : public TestFixture { " if (!p)\n" " thunk().g(0);\n" " *p = 1;\n" - "}", + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -3151,13 +3151,13 @@ class TestNullPointer : public TestFixture { check("void f() {\n" " struct X *x = 0;\n" " if (addr == &x->y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " struct X *x = 0;\n" " if (addr == &x->y.z[0]) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkP("typedef int Count;\n" // #10018 @@ -3183,7 +3183,7 @@ class TestNullPointer : public TestFixture { " break;\n" " }\n" " return p;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:7:10]: (warning) Possible null pointer dereference: p [nullPointer]\n", errout_str()); } @@ -3193,7 +3193,7 @@ class TestNullPointer : public TestFixture { " while (*p && nasm_isspace(*p))\n" " p++;\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char* origin) {\n" // #11449 @@ -3208,7 +3208,7 @@ class TestNullPointer : public TestFixture { check("void f () {\n" " int *buf; buf = NULL;\n" " buf;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -3230,27 +3230,27 @@ class TestNullPointer : public TestFixture { " if (!p) {\n" " }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:6]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(char *p) {\n" " if (p && *p == 0) {\n" " }\n" " printf(\"%c\", *p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:19]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(char *p) {\n" " if (p && *p == 0) {\n" " } else { *p = 0; }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:15]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(char *p) {\n" " if (p) {\n" " }\n" " strcpy(p, \"abc\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:12]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(char *p) {\n" @@ -3258,7 +3258,7 @@ class TestNullPointer : public TestFixture { " }\n" " bar();\n" " strcpy(p, \"abc\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:5:12]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("void foo(abc *p) {\n" @@ -3266,7 +3266,7 @@ class TestNullPointer : public TestFixture { " }\n" " else { if (!p->x) {\n" " } }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); { @@ -3276,7 +3276,7 @@ class TestNullPointer : public TestFixture { " abort();\n" " }\n" " *p = 0;\n" - "}"; + "}\n"; check(code); ASSERT_EQUALS("", errout_str()); @@ -3289,7 +3289,7 @@ class TestNullPointer : public TestFixture { " (*bail)();\n" " }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char *p) {\n" @@ -3297,7 +3297,7 @@ class TestNullPointer : public TestFixture { " throw x;\n" " }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char *p) {\n" @@ -3305,21 +3305,21 @@ class TestNullPointer : public TestFixture { " ab.abort();\n" " }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char *p) {\n" " if (!p) {\n" " switch (x) { }\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void foo(char *p) {\n" " if (!p) {\n" " }\n" " return *x;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("int foo(int *p) {\n" @@ -3327,7 +3327,7 @@ class TestNullPointer : public TestFixture { " x = *p;\n" " return 5+*p;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:14]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n" "[test.cpp:2:9] -> [test.cpp:4:19]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -3337,7 +3337,7 @@ class TestNullPointer : public TestFixture { " if (!a) {\n" " a.x();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // This is why this check can't be used on the simplified token list @@ -3345,7 +3345,7 @@ class TestNullPointer : public TestFixture { " if (!dynamic_cast(foo)) {\n" " *foo = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket: #2300 - calling unknown function that may initialize the pointer @@ -3355,7 +3355,7 @@ class TestNullPointer : public TestFixture { " initfred();\n" " fred->x = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket #1219 @@ -3364,7 +3364,7 @@ class TestNullPointer : public TestFixture { " return;\n" " }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:5:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); // #2467 - unknown macro may terminate the application @@ -3373,7 +3373,7 @@ class TestNullPointer : public TestFixture { " MACRO;\n" " }\n" " fred->a();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #2493 - switch @@ -3386,7 +3386,7 @@ class TestNullPointer : public TestFixture { " fred->a();\n" " break;\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4118 - second if @@ -3394,7 +3394,7 @@ class TestNullPointer : public TestFixture { " int x = 1;\n" " if (!p) x = 0;\n" " if (x) *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #2674 - different functions @@ -3411,7 +3411,7 @@ class TestNullPointer : public TestFixture { "\n" "void Fred::b() {\n" " wilma->Reload();\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void test(int *i) {\n" @@ -3419,7 +3419,7 @@ class TestNullPointer : public TestFixture { " else {\n" " int b = *i;\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // #2696 - false positives nr 1 @@ -3432,7 +3432,7 @@ class TestNullPointer : public TestFixture { "\n" " if (pFoo)\n" " bar();\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // #2696 - false positives nr 2 @@ -3445,7 +3445,7 @@ class TestNullPointer : public TestFixture { " pFoo = pFoo->next;\n" "\n" " len = sizeof(pFoo->data);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // #2696 - false positives nr 3 @@ -3458,13 +3458,13 @@ class TestNullPointer : public TestFixture { " pFoo = pFoo->next;\n" "\n" " len = decltype(*pFoo);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("int foo(struct Fred *fred) {\n" " if (fred) { }\n" " return fred->a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:12]: (warning) Either the condition 'fred' is redundant or there is possible null pointer dereference: fred. [nullPointerRedundantCheck]\n", errout_str()); // #2789 - assign and check pointer @@ -3472,7 +3472,7 @@ class TestNullPointer : public TestFixture { " char *p; p = x();\n" " if (!p) { }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:4:6]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); // check, assign and use @@ -3481,7 +3481,7 @@ class TestNullPointer : public TestFixture { " if (p == 0 && (p = malloc(10)) != 0) {\n" " *p = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // check, assign and use @@ -3490,7 +3490,7 @@ class TestNullPointer : public TestFixture { " if (p == 0 && (p = malloc(10)) != a && (*p = a)) {\n" " *p = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // check, and use @@ -3499,7 +3499,7 @@ class TestNullPointer : public TestFixture { " if (p == 0 && (*p = 0)) {\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:3:21]: (warning) Either the condition 'p==0' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); // check, and use @@ -3508,7 +3508,7 @@ class TestNullPointer : public TestFixture { " if (p == 0 && p->x == 10) {\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:3:19]: (warning) Either the condition 'p==0' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); // check, and use @@ -3517,7 +3517,7 @@ class TestNullPointer : public TestFixture { " if (p == 0 || p->x == 10) {\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // check, and use @@ -3526,7 +3526,7 @@ class TestNullPointer : public TestFixture { " if (p == NULL && (*p = a)) {\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11] -> [test.cpp:3:24]: (warning) Either the condition 'p==NULL' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); // check, and use @@ -3534,14 +3534,14 @@ class TestNullPointer : public TestFixture { " if (!p && x==1 || p && p->x==0) {\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); { const char code[] = "void f(Fred *fred) {\n" " if (fred == NULL) { }\n" " fred->x();\n" - "}"; + "}\n"; check(code); // inconclusive ASSERT_EQUALS("[test.cpp:2:14] -> [test.cpp:3:5]: (warning) Either the condition 'fred==NULL' is redundant or there is possible null pointer dereference: fred. [nullPointerRedundantCheck]\n", errout_str()); @@ -3550,52 +3550,52 @@ class TestNullPointer : public TestFixture { check("void f(char *s) {\n" // #3358 " if (s==0);\n" " strcpy(a, s?b:c);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // sizeof check("void f(struct fred_t *fred) {\n" " if (!fred)\n" " int sz = sizeof(fred->x);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // check in macro check("void f(int *x) {\n" " $if (!x) {}\n" " *x = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // return ?: check("int f(ABC *p) {\n" // FP : return ?: " if (!p) {}\n" " return p ? p->x : 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(ABC *p) {\n" // no fn " if (!p) {}\n" " return q ? p->x : 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:3:16]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("int f(ABC *p) {\n" // FP : return && " if (!p) {}\n" " return p && p->x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x, int *p) {\n" " if (x || !p) {}\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14] -> [test.cpp:3:6]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); // sizeof check("void f() {\n" " int *pointer = NULL;\n" " pointer = func(sizeof pointer[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T {\n" // #14164 @@ -3618,12 +3618,12 @@ class TestNullPointer : public TestFixture { check("int f() {\n" " int* p = 0;\n" " return p[4];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("void f() {\n" " typeof(*NULL) y;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("int * f() {\n" @@ -3631,7 +3631,7 @@ class TestNullPointer : public TestFixture { "}\n" "int main() {\n" " return *f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:12]: (error) Null pointer dereference: f() [nullPointer]\n", errout_str()); } @@ -3639,7 +3639,7 @@ class TestNullPointer : public TestFixture { // Ticket #2621 check("void f(struct ABC *abc) {\n" " ({ if (abc) dbg(); })\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -3647,7 +3647,7 @@ class TestNullPointer : public TestFixture { // Ticket #2840 check("void f() {\n" " int bytes = snprintf(0, 0, \"%u\", 1);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -3655,25 +3655,25 @@ class TestNullPointer : public TestFixture { // Ticket #2840 check("void f() {\n" " int bytes = snprintf(0, 10, \"%u\", 1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:26]: (error) Null pointer dereference [nullPointer]\n", errout_str()); } void printf_with_invalid_va_argument() { check("void f() {\n" " printf(\"%s\", 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (error) Null pointer dereference [nullPointer]\n", errout_str()); check("void f(char* s) {\n" " printf(\"%s\", s);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char* s = 0;\n" " printf(\"%s\", s);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:18]: (error) Null pointer dereference: s [nullPointer]\n", errout_str()); @@ -3681,23 +3681,23 @@ class TestNullPointer : public TestFixture { check("void f() {\n" " char *s = 0;\n" " printf(\"%s\", s == 0 ? a : s);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " printf(\"%u%s\", 0, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:23]: (error) Null pointer dereference [nullPointer]\n", errout_str()); check("void f(char* s) {\n" " printf(\"%u%s\", 0, s);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char* s = 0;\n" " printf(\"%u%s\", 123, s);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:25]: (error) Null pointer dereference: s [nullPointer]\n", errout_str()); @@ -3705,51 +3705,51 @@ class TestNullPointer : public TestFixture { check("void f() {\n" " printf(\"%%%s%%\", 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (error) Null pointer dereference [nullPointer]\n", errout_str()); check("void f(char* s) {\n" " printf(\"text: %s, %s\", s, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:31]: (error) Null pointer dereference [nullPointer]\n", errout_str()); check("void f() {\n" " char* s = \"blabla\";\n" " printf(\"%s\", s);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char* s) {\n" " printf(\"text: %m%s, %s\", s, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:33]: (error) Null pointer dereference [nullPointer]\n", errout_str()); check("void f(char* s) {\n" " printf(\"text: %*s, %s\", s, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:32]: (error) Null pointer dereference [nullPointer]\n", errout_str()); // Ticket #3364 check("void f() {\n" " printf(\"%-*.*s\", s, 0);\n" " sprintf(\"%*\", s);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void scanf_with_invalid_va_argument() { check("void f(char* s) {\n" " sscanf(s, \"%s\", 0);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:21]: (error) Null pointer dereference [nullPointer]\n", errout_str()); check("void f() {\n" " scanf(\"%d\", 0);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:17]: (error) Null pointer dereference [nullPointer]\n", errout_str()); @@ -3758,19 +3758,19 @@ class TestNullPointer : public TestFixture { " char location[200];\n" " int width, height;\n" " sscanf(imgInfo, \"%s %d %d\", location, &width, &height);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket #3207 check("void f(char *dummy) {\n" " int iVal;\n" " sscanf(dummy, \"%d%c\", &iVal);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket #3211 check("void f(char *dummy) {\n" " int* iVal = 0;\n" " sscanf(dummy, \"%d\", iVal);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:25]: (error) Null pointer dereference: iVal [nullPointer]\n", errout_str()); @@ -3778,18 +3778,18 @@ class TestNullPointer : public TestFixture { check("void f(char *dummy) {\n" " int* iVal;\n" " sscanf(dummy, \"%d\", foo(iVal));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char *dummy) {\n" " int* iVal = 0;\n" " sscanf(dummy, \"%d%d\", foo(iVal), iVal);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char* dummy) {\n" " sscanf(dummy, \"%*d%u\", 0);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:28]: (error) Null pointer dereference [nullPointer]\n", errout_str()); @@ -3801,12 +3801,12 @@ class TestNullPointer : public TestFixture { " int* iVal = 0;\n" " if(maybe()) iVal = g();\n" " return iVal[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (warning) Possible null pointer dereference: iVal [nullPointer]\n", errout_str()); check("int foo(int* iVal) {\n" " return iVal[0];\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -3816,20 +3816,20 @@ class TestNullPointer : public TestFixture { "bool foo() {\n" " PolymorphicA* a = 0;\n" " return typeid(*a) == typeid(*a);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("struct NonPolymorphicA { ~A() {} };\n" "bool foo() {\n" " NonPolymorphicA* a = 0;\n" " return typeid(*a) == typeid(*a);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("bool foo() {\n" " char* c = 0;\n" " return typeid(*c) == typeid(*c);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -3838,40 +3838,40 @@ class TestNullPointer : public TestFixture { check("size_t foo() {\n" " char* c = 0;\n" " return alignof(*c);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("size_t foo() {\n" " return alignof(*0);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void foo(int *p) {\n" " f(alignof(*p));\n" " if (p) {}\n" " return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("size_t foo() {\n" " char* c = 0;\n" " return _Alignof(*c);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("size_t foo() {\n" " return _alignof(*0);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("size_t foo() {\n" " return __alignof(*0);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("size_t foo() {\n" " return __alignof__(*0);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); } @@ -3882,7 +3882,7 @@ class TestNullPointer : public TestFixture { " cnt = 0;\n" " for (int i = 0; i < cnt; ++i)\n" " *ptr++ = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #11635 @@ -3992,7 +3992,7 @@ class TestNullPointer : public TestFixture { "void f(int* x) {\n" " if (x)\n" " g(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T {\n" // #14308 @@ -4034,7 +4034,7 @@ class TestNullPointer : public TestFixture { " std::string s4 = p;\n" " std::string s5(p);\n" " foo(std::string(p));\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:9:10]: (error) Null pointer dereference: p [nullPointer]\n" "[test.cpp:10:22]: (error) Null pointer dereference: p [nullPointer]\n" "[test.cpp:11:20]: (error) Null pointer dereference: p [nullPointer]\n" @@ -4050,7 +4050,7 @@ class TestNullPointer : public TestFixture { " std::string s2 = nullptr;\n" " std::string s3(nullptr);\n" " foo(std::string(nullptr));\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2:10]: (error) Null pointer dereference [nullPointer]\n" "[test.cpp:3:22]: (error) Null pointer dereference [nullPointer]\n" "[test.cpp:4:17]: (error) Null pointer dereference [nullPointer]\n" @@ -4062,7 +4062,7 @@ class TestNullPointer : public TestFixture { " std::string s2 = NULL;\n" " std::string s3(NULL);\n" " foo(std::string(NULL));\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2:10]: (error) Null pointer dereference [nullPointer]\n" "[test.cpp:3:22]: (error) Null pointer dereference [nullPointer]\n" "[test.cpp:4:17]: (error) Null pointer dereference [nullPointer]\n" @@ -4078,7 +4078,7 @@ class TestNullPointer : public TestFixture { " foo(p == s1);\n" " foo(p == s2);\n" " foo(p == s3);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:4:15]: (error) Null pointer dereference: p [nullPointer]\n" "[test.cpp:5:15]: (error) Null pointer dereference: p [nullPointer]\n" "[test.cpp:7:9]: (error) Null pointer dereference: p [nullPointer]\n" @@ -4093,7 +4093,7 @@ class TestNullPointer : public TestFixture { " foo(s1.size() == 0);\n" " foo(s2.size() == 0);\n" " foo(s3->size() == 0);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f(std::string s1, const std::string& s2) {\n" @@ -4102,7 +4102,7 @@ class TestNullPointer : public TestFixture { " foo(0 == s2[0]);\n" " foo(s1[0] == 0);\n" " foo(s2[0] == 0);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f(std::string s1, const std::string& s2) {\n" @@ -4111,7 +4111,7 @@ class TestNullPointer : public TestFixture { " foo(s2 == '\\0');\n" " foo('\\0' == s1);\n" " foo('\\0' == s2);\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("class Bar {\n" @@ -4122,19 +4122,19 @@ class TestNullPointer : public TestFixture { " std::string s;\n" " Foo();\n" "};\n" - "Foo::Foo() : s(0) {}"); + "Foo::Foo() : s(0) {}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (error) Null pointer dereference [nullPointer]\n" "[test.cpp:9:14]: (error) Null pointer dereference [nullPointer]\n", errout_str()); check("void f() {\n" " std::string s = 0 == x ? \"a\" : \"b\";\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " const std::string s = g();\n" " ASSERT_MESSAGE(\"Error on s\", 0 == s.compare(\"Some text\"));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int i, std::string s);\n" @@ -4145,7 +4145,7 @@ class TestNullPointer : public TestFixture { " foo(var, NULL);\n" " foo(var, nullptr);\n" " foo(0, var);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (error) Null pointer dereference [nullPointer]\n" "[test.cpp:5:12]: (error) Null pointer dereference [nullPointer]\n" "[test.cpp:6:12]: (error) Null pointer dereference [nullPointer]\n" @@ -4190,7 +4190,7 @@ class TestNullPointer : public TestFixture { check("void f(std::ifstream& is) {\n" " char* p = 0;\n" " is >> p;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: p\n", "", errout_str()); check("void f(const std::ostringstream& oss, char* q) {\n" @@ -4199,7 +4199,7 @@ class TestNullPointer : public TestFixture { " oss << foo << p;\n" " if(q == 0)\n" " oss << foo << q;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:12]: (error) Null pointer dereference: p [nullPointer]\n" "[test.cpp:4:19]: (error) Null pointer dereference: p [nullPointer]\n" "[test.cpp:5:10] -> [test.cpp:6:23]: (warning) Either the condition 'q==0' is redundant or there is possible null pointer dereference: q. [nullPointerRedundantCheck]\n", errout_str()); @@ -4211,7 +4211,7 @@ class TestNullPointer : public TestFixture { " std::cin >> p;\n" " std::cout << abc << p;\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:2:10] -> [test.cpp:3:22]: (warning) Either the condition 'p==0' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n" "[test.cpp:2:10] -> [test.cpp:4:22]: (warning) Either the condition 'p==0' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n" "[test.cpp:2:10] -> [test.cpp:5]: (warning) Either the condition 'p==0' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n" @@ -4226,7 +4226,7 @@ class TestNullPointer : public TestFixture { " char* p2 = 0;\n" " std::cin >> (int)p;\n" // result casted " std::cout << (int)p;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f(const std::string& str) {\n" @@ -4234,13 +4234,13 @@ class TestNullPointer : public TestFixture { " std::istringstream istr(str);\n" " istr >> std::hex >> ret;\n" // Read integer " return ret;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); check("void f(int* i) {\n" " if(i) return;\n" " std::cout << i;\n" // Its no char* (#4240) - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // #5811 false positive: (error) Null pointer dereference @@ -4249,7 +4249,7 @@ class TestNullPointer : public TestFixture { " stringstream out;\n" " out << ((ip >> 0) & 0xFF);\n" " return out.str();\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // avoid regression from first fix attempt for #5811... check("void deserialize(const std::string &data) {\n" @@ -4269,42 +4269,42 @@ class TestNullPointer : public TestFixture { "void f(std::shared_ptr p) {\n" " if (p) {}\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:7] -> [test.cpp:4:11]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("struct Fred { int x; };\n" "void f(std::shared_ptr p) {\n" " p = nullptr;\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("struct Fred { int x; };\n" "void f(std::unique_ptr p) {\n" " if (p) {}\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:7] -> [test.cpp:4:11]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); check("struct Fred { int x; };\n" "void f(std::unique_ptr p) {\n" " p = nullptr;\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("struct Fred { int x; };\n" "void f() {\n" " std::shared_ptr p;\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("struct Fred { int x; };\n" "void f(std::shared_ptr p) {\n" " p.reset();\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("struct Fred { int x; };\n" @@ -4312,7 +4312,7 @@ class TestNullPointer : public TestFixture { " Fred * pp = nullptr;\n" " p.reset(pp);\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:11]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("struct Fred { int x; };\n" @@ -4320,28 +4320,28 @@ class TestNullPointer : public TestFixture { " std::shared_ptr p;\n" " p.reset(&f);\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Fred { int x; };\n" "void f(std::shared_ptr p) {\n" " p.reset();\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("struct Fred { int x; };\n" "void f() {\n" " std::shared_ptr p(nullptr);\n" " dostuff(p->x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); check("struct A {};\n" "void f(int n) {\n" " std::unique_ptr p;\n" " p.reset(new const A*[n]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9216 @@ -4352,7 +4352,7 @@ class TestNullPointer : public TestFixture { "void g(std::unique_ptr var) {\n" " var->reset();\n" " var->f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9439 @@ -4380,21 +4380,21 @@ class TestNullPointer : public TestFixture { " int *p = malloc(10);\n" " *p = 0;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (warning) If memory allocation fails, then there is a possible null pointer dereference: p [nullPointerOutOfMemory]\n", errout_str()); check("void f() {\n" " int *p = malloc(10);\n" " *(p+2) = 0;\n" " free(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8]: (error) If memory allocation fails: pointer addition with NULL pointer. [nullPointerArithmeticOutOfMemory]\n", errout_str()); check("void f() {\n" // #13676 " int* q = static_cast(std::malloc(4));\n" " *q = 0;\n" " std::free(q);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (warning) If memory allocation fails, then there is a possible null pointer dereference: q [nullPointerOutOfMemory]\n", errout_str()); } @@ -4406,7 +4406,7 @@ class TestNullPointer : public TestFixture { " *p = 0;\n" " foo(p);\n" " if (p) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // function seen (taking pointer parameter) @@ -4416,7 +4416,7 @@ class TestNullPointer : public TestFixture { " *p = 0;\n" " foo(p);\n" " if (p) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:6:9] -> [test.cpp:4:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -4428,7 +4428,7 @@ class TestNullPointer : public TestFixture { " *p = 0;\n" " foo(p);\n" " if (p) { }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); // function implementation not seen @@ -4438,7 +4438,7 @@ class TestNullPointer : public TestFixture { " *p = 0;\n" " foo(p);\n" " if (p) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:6:9] -> [test.cpp:4:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -4448,7 +4448,7 @@ class TestNullPointer : public TestFixture { " *p = 0;\n" " foo(p);\n" " if (p) { }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:2:6]: (warning, inconclusive) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str()); @@ -4461,7 +4461,7 @@ class TestNullPointer : public TestFixture { " abc->a = 0;\n" " foo(abc);\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // function seen (taking pointer parameter) @@ -4471,7 +4471,7 @@ class TestNullPointer : public TestFixture { " abc->a = 0;\n" " foo(abc);\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:6:9] -> [test.cpp:4:5]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); @@ -4483,7 +4483,7 @@ class TestNullPointer : public TestFixture { " abc->a = 0;\n" " foo(abc);\n" " if (abc) { }\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:6:9] -> [test.cpp:4:5]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); @@ -4493,7 +4493,7 @@ class TestNullPointer : public TestFixture { " abc->a = 0;\n" " foo(abc);\n" " if (abc) { }\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:2:5]: (warning, inconclusive) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str()); @@ -4567,7 +4567,7 @@ class TestNullPointer : public TestFixture { void functioncalllibrary() { SimpleTokenizer tokenizer(settingsDefault,*this,false); - const char code[] = "void f() { int a,b,c; x(a,b,c); }"; + const char code[] = "void f() { int a,b,c; x(a,b,c); }\n"; ASSERT_EQUALS(true, tokenizer.tokenize(code)); const Token *xtok = Token::findsimplematch(tokenizer.tokens(), "x"); @@ -4613,51 +4613,51 @@ class TestNullPointer : public TestFixture { check("void f(int *p = 0) {\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:6]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", errout_str()); check("void f(int *p = 0) {\n" " if (!p)\n" " return;\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char a, int *p = 0) {\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:6]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", errout_str()); check("void f(int *p = 0) {\n" " printf(\"p = %d\", *p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:23]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", errout_str()); check("void f(int *p = 0) {\n" " printf(\"p[1] = %d\", p[1]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:25]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", errout_str()); check("void f(int *p = 0) {\n" " buf[p] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" " if (p != 0 && bar())\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p) {\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" " if (p != 0)\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" @@ -4665,13 +4665,13 @@ class TestNullPointer : public TestFixture { " if (p == 0)\n" " p = &y;\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int a, int *p = 0) {\n" " if (a != 0)\n" " *p = 0;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS( "[test.cpp:3:8]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", errout_str()); @@ -4679,13 +4679,13 @@ class TestNullPointer : public TestFixture { check("void f(int *p = 0) {\n" " p = a;\n" " *p = 0;\n" // <- don't simplify and verify - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" " p += a;\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int *p = 0) {\n" @@ -4693,17 +4693,17 @@ class TestNullPointer : public TestFixture { " return 0;\n" " }\n" " return *p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" " std::cout << p ? *p : 0;\n" // Due to operator precedence, this is equivalent to: (std::cout << p) ? *p : 0; - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:23]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", errout_str()); // Check the first branch of ternary check("void f(char *p = 0) {\n" " std::cout << p ? *p : 0;\n" // Due to operator precedence, this is equivalent to: (std::cout << p) ? *p : 0; - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:18]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n" "[test.cpp:2:23]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", // duplicate @@ -4711,27 +4711,27 @@ class TestNullPointer : public TestFixture { check("void f(int *p = 0) {\n" " std::cout << (p ? *p : 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" " std::cout << p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" " std::cout << (p && p[0] ? *p : 42);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void isEmpty(int *p = 0) {\n" " return p && *p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int *p = 0) {\n" " return !p || *p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -4740,13 +4740,13 @@ class TestNullPointer : public TestFixture { check("void f(int *p = 0) {\n" " bar(p);\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" " printf(\"%p\", p);\n" " *p = 0;\n" - "}", dinit(CheckOptions, $.inconclusive = true)); + "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:3:6]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", errout_str()); // The init() function may or may not initialize p, but since the address @@ -4755,14 +4755,14 @@ class TestNullPointer : public TestFixture { check("void f(int *p = 0) {\n" " init(&p);\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void init(int* &g);\n" "void f(int *p = 0) {\n" " init(p);\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" @@ -4770,7 +4770,7 @@ class TestNullPointer : public TestFixture { " init(&p);\n" " }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int *p = 0) {\n" @@ -4778,12 +4778,12 @@ class TestNullPointer : public TestFixture { " throw SomeException;\n" " }\n" " *p = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int x, int *p = 0) {\n" " int var1 = x ? *p : 5;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:21]: (warning) Possible null pointer dereference if the default parameter value is used: p [nullPointerDefaultArg]\n", errout_str()); check("void f(int* i = nullptr) { *i = 0; }\n" // #11567 @@ -4798,7 +4798,7 @@ class TestNullPointer : public TestFixture { " unsigned int j;\n" " for (j = 0; j < b[0].a->size; ++j) {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -4822,33 +4822,33 @@ class TestNullPointer : public TestFixture { check("void foo(char *s) {\n" " char *p = s - 20;\n" "}\n" - "void bar() { foo(0); }"); + "void bar() { foo(0); }\n"); ASSERT_EQUALS("[test.cpp:2:15]: (error) Overflow in pointer arithmetic, NULL pointer is subtracted. [nullPointerArithmetic]\n", errout_str()); check("void foo(char *s) {\n" " if (!s) {}\n" " char *p = s - 20;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7] -> [test.cpp:3:15]: (warning) Either the condition '!s' is redundant or there is overflow in pointer subtraction. [nullPointerArithmeticRedundantCheck]\n", errout_str()); check("void foo(char *s) {\n" " s -= 20;\n" "}\n" - "void bar() { foo(0); }"); + "void bar() { foo(0); }\n"); ASSERT_EQUALS("[test.cpp:2:5]: (error) Overflow in pointer arithmetic, NULL pointer is subtracted. [nullPointerArithmetic]\n", errout_str()); check("void foo(char *s) {\n" " if (!s) {}\n" " s -= 20;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7] -> [test.cpp:3:5]: (warning) Either the condition '!s' is redundant or there is overflow in pointer subtraction. [nullPointerArithmeticRedundantCheck]\n", errout_str()); - check("int* f8() { int *x = NULL; return --x; }"); + check("int* f8() { int *x = NULL; return --x; }\n"); ASSERT_EQUALS("[test.cpp:1:35]: (error) Overflow in pointer arithmetic, NULL pointer is subtracted. [nullPointerArithmetic]\n", errout_str()); - check("int* f9() { int *x = NULL; return x--; }"); + check("int* f9() { int *x = NULL; return x--; }\n"); ASSERT_EQUALS("[test.cpp:1:36]: (error) Overflow in pointer arithmetic, NULL pointer is subtracted. [nullPointerArithmetic]\n", errout_str()); } @@ -4856,48 +4856,48 @@ class TestNullPointer : public TestFixture { check("void foo(char *s) {\n" " char * p = s + 20;\n" "}\n" - "void bar() { foo(0); }"); + "void bar() { foo(0); }\n"); ASSERT_EQUALS("[test.cpp:2:16]: (error) Pointer addition with NULL pointer. [nullPointerArithmetic]\n", errout_str()); check("void foo(char *s) {\n" " if (!s) {}\n" " char * p = s + 20;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7] -> [test.cpp:3:16]: (warning) Either the condition '!s' is redundant or there is pointer arithmetic with NULL pointer. [nullPointerArithmeticRedundantCheck]\n", errout_str()); check("void foo(char *s) {\n" " char * p = 20 + s;\n" "}\n" - "void bar() { foo(0); }"); + "void bar() { foo(0); }\n"); ASSERT_EQUALS("[test.cpp:2:17]: (error) Pointer addition with NULL pointer. [nullPointerArithmetic]\n", errout_str()); check("void foo(char *s) {\n" " if (!s) {}\n" " char * p = 20 + s;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7] -> [test.cpp:3:17]: (warning) Either the condition '!s' is redundant or there is pointer arithmetic with NULL pointer. [nullPointerArithmeticRedundantCheck]\n", errout_str()); check("void foo(char *s) {\n" " s += 20;\n" "}\n" - "void bar() { foo(0); }"); + "void bar() { foo(0); }\n"); ASSERT_EQUALS("[test.cpp:2:5]: (error) Pointer addition with NULL pointer. [nullPointerArithmetic]\n", errout_str()); check("void foo(char *s) {\n" " if (!s) {}\n" " s += 20;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7] -> [test.cpp:3:5]: (warning) Either the condition '!s' is redundant or there is pointer arithmetic with NULL pointer. [nullPointerArithmeticRedundantCheck]\n", errout_str()); - check("int* f7() { int *x = NULL; return ++x; }"); + check("int* f7() { int *x = NULL; return ++x; }\n"); ASSERT_EQUALS("[test.cpp:1:35]: (error) Pointer addition with NULL pointer. [nullPointerArithmetic]\n", errout_str()); - check("int* f10() { int *x = NULL; return x++; }"); + check("int* f10() { int *x = NULL; return x++; }\n"); ASSERT_EQUALS("[test.cpp:1:37]: (error) Pointer addition with NULL pointer. [nullPointerArithmetic]\n", errout_str()); check("class foo {};\n" "const char* get() const { return 0; }\n" - "void f(foo x) { if (get()) x += get(); }"); + "void f(foo x) { if (get()) x += get(); }\n"); ASSERT_EQUALS("", errout_str()); check("typedef struct { uint8_t* buf, *buf_end; } S;\n" // #11117 @@ -4913,7 +4913,7 @@ class TestNullPointer : public TestFixture { } void isPointerDeRefFunctionDecl() { - check("const char** get() { return 0; }"); + check("const char** get() { return 0; }\n"); ASSERT_EQUALS("", errout_str()); } @@ -4947,7 +4947,7 @@ class TestNullPointer : public TestFixture { "int main() {\n" " int *p = 0;\n" " f(p);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: error: Null pointer dereference: fp [ctunullpointer]\n" "[test.cpp:5:12]: note: Assignment 'p=0', assigned value is 0\n" "[test.cpp:6:4]: note: Calling function f, 1st argument is null\n" @@ -4957,7 +4957,7 @@ class TestNullPointer : public TestFixture { "void call(int x, int *p) { x++; use(p); }\n" "int main() {\n" " call(4,0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:25]: error: Null pointer dereference: p [ctunullpointer]\n" "[test.cpp:4:7]: note: Calling function call, 2nd argument is null\n" "[test.cpp:2:33]: note: Calling function use, 1st argument is null\n" @@ -4971,7 +4971,7 @@ class TestNullPointer : public TestFixture { "\n" "void f() {\n" " dostuff(a, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); ctu("void dostuff(int *x, int *y) {\n" @@ -4982,7 +4982,7 @@ class TestNullPointer : public TestFixture { "\n" "void f() {\n" " dostuff(a, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // else @@ -4993,7 +4993,7 @@ class TestNullPointer : public TestFixture { "\n" "void f() {\n" " dostuff(0, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ?, &&, || @@ -5003,14 +5003,14 @@ class TestNullPointer : public TestFixture { "\n" "void f() {\n" " dostuff(0, 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); ctu("void g(int* x) { *x; }\n" "void f(int* x) {\n" " if (x)\n" " g(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); ctu("size_t f(int* p) {\n" diff --git a/test/testother.cpp b/test/testother.cpp index b12e26e1ffa..3c301a3fc3c 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -398,7 +398,7 @@ class TestOther : public TestFixture { void emptyBrackets() { check("{\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -406,22 +406,22 @@ class TestOther : public TestFixture { void zeroDiv1() { // floating point division by zero => no error check("void foo() {\n" " cout << 1. / 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " cout << 42 / (double)0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " cout << 42 / (float)0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " cout << 42 / (int)0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (error) Division by zero. [zerodiv]\n", errout_str()); } @@ -434,34 +434,34 @@ class TestOther : public TestFixture { " sum += i;\n" " }\n" " cout<(fStepMain / fStepHelp);\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -592,7 +592,7 @@ class TestOther : public TestFixture { " << boost::format(\" %d :: %s <> %s\") % 0 % \"a\" % \"b\"\n" " << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -600,13 +600,13 @@ class TestOther : public TestFixture { check("void f(int a) {\n" " int res = (a+2)/0;\n" " int res = (a*2)/0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (error) Division by zero. [zerodiv]\n" "[test.cpp:3:18]: (error) Division by zero. [zerodiv]\n", errout_str()); check("void f() {\n" " int res = (a+2)/0;\n" " int res = (a*2)/0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -614,7 +614,7 @@ class TestOther : public TestFixture { // #8141 check("intmax_t f() {\n" " return 1 / imaxabs(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (error) Division by zero. [zerodiv]\n", errout_str()); } void zeroDiv13() { @@ -709,7 +709,7 @@ class TestOther : public TestFixture { "{\n" " uint16_t x = 0xFFFFU;\n" // UINT16_MAX=0xFFFF " return 42/(++x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:14]: (error) Division by zero. [zerodiv]\n", errout_str()); } @@ -736,25 +736,25 @@ class TestOther : public TestFixture { check("void f(unsigned int x) {\n" " int y = 17 / x;\n" " if (x > 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:14]: (warning) Either the condition 'x>0' is redundant or there is division by zero at line 2. [zerodivcond]\n", errout_str()); check("void f(unsigned int x) {\n" " int y = 17 / x;\n" " if (x >= 1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:14]: (warning) Either the condition 'x>=1' is redundant or there is division by zero at line 2. [zerodivcond]\n", errout_str()); check("void f(int x) {\n" " int y = 17 / x;\n" " if (x == 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:14]: (warning) Either the condition 'x==0' is redundant or there is division by zero at line 2. [zerodivcond]\n", errout_str()); check("void f(unsigned int x) {\n" " int y = 17 / x;\n" " if (x != 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:14]: (warning) Either the condition 'x!=0' is redundant or there is division by zero at line 2. [zerodivcond]\n", errout_str()); // function call @@ -762,7 +762,7 @@ class TestOther : public TestFixture { "void f2(unsigned int y) {\n" " f1(123,y);\n" " if (y>0){}\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:10] -> [test.cpp:1:28]: (warning) Either the condition 'y>0' is redundant or there is division by zero at line 1. [zerodivcond]\n", errout_str()); @@ -773,7 +773,7 @@ class TestOther : public TestFixture { " int y = 17 / x;\n" " x = some+calculation;\n" " if (x != 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); { @@ -784,7 +784,7 @@ class TestOther : public TestFixture { " int y = 17 / x;\n" " do_something();\n" " if (x != 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // function is called. but don't care, variable is local @@ -794,7 +794,7 @@ class TestOther : public TestFixture { " int y = 17 / x;\n" " do_something();\n" " if (x != 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:9] -> [test.cpp:4:14]: (warning) Either the condition 'x!=0' is redundant or there is division by zero at line 4. [zerodivcond]\n", errout_str()); } @@ -802,14 +802,14 @@ class TestOther : public TestFixture { "void f(int x) {\n" " int y = 17 / x;\n" " do_something(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int x;\n" "void f() {\n" " int y = 17 / x;\n" " while (y || x == 0) { x--; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket 5033 segmentation fault (valid code) in CheckOther::checkZeroDivisionOrUselessCondition @@ -818,33 +818,33 @@ class TestOther : public TestFixture { "double* p2= new double[1];\n" "double* p3= new double[1];\n" "double* pp[3] = {p1,p2,p3};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5105 - FP check("int f(int a, int b) {\n" " int r = a / b;\n" " if (func(b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Unknown types for b and c --> do not warn check("int f(int d) {\n" " int r = (a?b:c) / d;\n" " if (d == 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int a) {\n" " int r = a ? 1 / a : 0;\n" " if (a == 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int a) {\n" " int r = (a == 0) ? 0 : 1 / a;\n" " if (a == 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int g();\n" @@ -854,7 +854,7 @@ class TestOther : public TestFixture { " else if (x > 0) {}\n" " else\n" " a = b / -x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -901,35 +901,35 @@ class TestOther : public TestFixture { "{\n" " double x = 3.0 / 0.0 + 1.0;\n" " printf(\"%f\", x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19]: (style) Using NaN/Inf in a computation. [nanInArithmeticExpression]\n", errout_str()); check("void f()\n" "{\n" " double x = 3.0 / 0.0 - 1.0;\n" " printf(\"%f\", x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19]: (style) Using NaN/Inf in a computation. [nanInArithmeticExpression]\n", errout_str()); check("void f()\n" "{\n" " double x = 1.0 + 3.0 / 0.0;\n" " printf(\"%f\", x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25]: (style) Using NaN/Inf in a computation. [nanInArithmeticExpression]\n", errout_str()); check("void f()\n" "{\n" " double x = 1.0 - 3.0 / 0.0;\n" " printf(\"%f\", x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25]: (style) Using NaN/Inf in a computation. [nanInArithmeticExpression]\n", errout_str()); check("void f()\n" "{\n" " double x = 3.0 / 0.0;\n" " printf(\"%f\", x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -960,7 +960,7 @@ class TestOther : public TestFixture { " }\n" "\n" " return 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -970,7 +970,7 @@ class TestOther : public TestFixture { " Error e;\n" " e.SetValue(12);\n" " throw e;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -984,7 +984,7 @@ class TestOther : public TestFixture { " p = &i;\n" " }\n" " *p = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -992,7 +992,7 @@ class TestOther : public TestFixture { check("void foo()\n" "{\n" " int i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1003,7 +1003,7 @@ class TestOther : public TestFixture { " if (x) {\n" " for ( ; i < 10; ++i) ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) The scope of the variable 'i' can be reduced. [variableScope]\n", errout_str()); check("void f(int x) {\n" @@ -1011,7 +1011,7 @@ class TestOther : public TestFixture { " if (x) {\n" " for ( ; i < 10; ++i) ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x)\n" @@ -1021,7 +1021,7 @@ class TestOther : public TestFixture { " else {\n" " for ( ; i < 10; ++i) ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) The scope of the variable 'i' can be reduced. [variableScope]\n", errout_str()); } @@ -1035,7 +1035,7 @@ class TestOther : public TestFixture { " if (b) {\n" " c(i);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #5398 @@ -1044,14 +1044,14 @@ class TestOther : public TestFixture { " if (success) {\n" " foo(notReducable);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(Test &test) {\n" " int& x = test.getData();\n" " if (test.process())\n" " x = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f()\n" @@ -1066,7 +1066,7 @@ class TestOther : public TestFixture { " return 0;\n" " }\n" "}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int &x)\n" @@ -1077,7 +1077,7 @@ class TestOther : public TestFixture { " ++n;\n" " ++x;\n" " } while (x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1089,7 +1089,7 @@ class TestOther : public TestFixture { " if (x) {\n" " y++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1100,7 +1100,7 @@ class TestOther : public TestFixture { " BOOST_FOREACH(int edge, edges) {\n" " edgeResistance = (edge+1) / 2.0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) The scope of the variable 'edgeResistance' can be reduced. [variableScope]\n", errout_str()); } @@ -1116,7 +1116,7 @@ class TestOther : public TestFixture { " if (a == 2) {\n" " f.x();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class fred {\n" // #2062 @@ -1128,7 +1128,7 @@ class TestOther : public TestFixture { " if (a == 2) {\n" " f.x();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:10]: (style) The scope of the variable 'f' can be reduced. [variableScope]\n", errout_str()); check("struct S { int a, b; };\n" @@ -1149,7 +1149,7 @@ class TestOther : public TestFixture { " FOR {\n" " foo(x++);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1157,21 +1157,21 @@ class TestOther : public TestFixture { check("int f() {\n" " int x = 0;\n" " AB ab = { x, 0 };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" " int x = 0;\n" " if (a == 0) { ++x; }\n" " AB ab = { x, 0 };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() {\n" " int x = 0;\n" " if (a == 0) { ++x; }\n" " if (a == 1) { AB ab = { x, 0 }; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1182,7 +1182,7 @@ class TestOther : public TestFixture { " if (x)\n" " foo(i);\n" " foo(j);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) The scope of the variable 'i' can be reduced. [variableScope]\n", errout_str()); check("void f(int x) {\n" @@ -1191,7 +1191,7 @@ class TestOther : public TestFixture { " if (x)\n" " j = i;\n" " foo(j);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" @@ -1199,7 +1199,7 @@ class TestOther : public TestFixture { " x++;\n" " if (x == 5)\n" " foo(b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" @@ -1207,7 +1207,7 @@ class TestOther : public TestFixture { " x++;\n" " if (x == 5)\n" " foo(b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1218,7 +1218,7 @@ class TestOther : public TestFixture { " forever {\n" " if (i++ == 42) { break; }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1229,7 +1229,7 @@ class TestOther : public TestFixture { " if(a) {\n" " for ( ; i < 10; ++i) ;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1241,7 +1241,7 @@ class TestOther : public TestFixture { " else if(b);\n" " else if(c);\n" " else;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); } @@ -1251,7 +1251,7 @@ class TestOther : public TestFixture { " while((++a) < 56) {\n" " foo();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -1259,7 +1259,7 @@ class TestOther : public TestFixture { " do {\n" " foo();\n" " } while((++a) < 56);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -1268,7 +1268,7 @@ class TestOther : public TestFixture { " a = 64;\n" " foo(a);\n" " } while((++a) < 56);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -1277,7 +1277,7 @@ class TestOther : public TestFixture { " a = 64;\n" " foo(a);\n" " } while(z());\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) The scope of the variable 'a' can be reduced. [variableScope]\n", errout_str()); } @@ -1288,7 +1288,7 @@ class TestOther : public TestFixture { " x = stuff(x);\n" " morestuff(x);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) The scope of the variable 'x' can be reduced. [variableScope]\n", errout_str()); check("void f() {\n" @@ -1298,7 +1298,7 @@ class TestOther : public TestFixture { " morestuff(x);\n" " }\n" " if (b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) The scope of the variable 'x' can be reduced. [variableScope]\n", errout_str()); } @@ -1318,7 +1318,7 @@ class TestOther : public TestFixture { " x = foo();\n" " do_something(x);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) The scope of the variable 'x' can be reduced. [variableScope]\n", errout_str()); check("void f() {\n" @@ -1337,7 +1337,7 @@ class TestOther : public TestFixture { " x = foo();\n" " do_something(x);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -1352,7 +1352,7 @@ class TestOther : public TestFixture { " default:\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) The scope of the variable 'x' can be reduced. [variableScope]\n", errout_str()); check("void f() {\n" @@ -1369,7 +1369,7 @@ class TestOther : public TestFixture { " do_something(x);\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1379,7 +1379,7 @@ class TestOther : public TestFixture { " int b = a;\n" " if (b > 32) b = x;\n" " return b;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1388,7 +1388,7 @@ class TestOther : public TestFixture { " int test_value = 3;\n" " int test_array[1][1] = { { test_value } };\n" " return sizeof(test_array);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1401,7 +1401,7 @@ class TestOther : public TestFixture { " ++p;\n" " ++i;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // try to avoid an obvious false negative after applying the fix for the example above: check("void foo() {\n" @@ -1414,7 +1414,7 @@ class TestOther : public TestFixture { " ++p;\n" " ++i;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) The scope of the variable 'p' can be reduced. [variableScope]\n", errout_str()); } @@ -1424,7 +1424,7 @@ class TestOther : public TestFixture { " Test myTest([&](size_t aX){\n" " std::cout << myCounter += aX << std::endl;\n" " });\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1434,7 +1434,7 @@ class TestOther : public TestFixture { " if (cond) {\n" " r.dostuff();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) The scope of the variable 'r' can be reduced. [variableScope]\n", errout_str()); check("void f(Foo x) {\n" @@ -1442,7 +1442,7 @@ class TestOther : public TestFixture { " if (cond) {\n" " foo.dostuff();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1453,7 +1453,7 @@ class TestOther : public TestFixture { " currtime = time(&dummy);\n" " if (currtime > t) {}\n" " }\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:2:12]: (style) The scope of the variable 'currtime' can be reduced. [variableScope]\n", errout_str()); } @@ -1465,7 +1465,7 @@ class TestOther : public TestFixture { " if (cond2) { dostuff(key); }\n" " }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -1475,7 +1475,7 @@ class TestOther : public TestFixture { "#ifdef X\n" "#endif\n" " if (id == ABC) { return x; }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkP("void f() {\n" @@ -1483,7 +1483,7 @@ class TestOther : public TestFixture { "#endif\n" " int x = 0;\n" " if (id == ABC) { return x; }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: (style) The scope of the variable 'x' can be reduced. [variableScope]\n", errout_str()); } @@ -1517,7 +1517,7 @@ class TestOther : public TestFixture { " s = \"abc\";\n" " g(s);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) The scope of the variable 's' can be reduced. [variableScope]\n", errout_str()); check("auto foo(std::vector& vec, bool flag) {\n" @@ -1530,7 +1530,7 @@ class TestOther : public TestFixture { " iter = dummy.begin();\n" " }\n" " return *iter;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:28]: (style) Parameter 'vec' can be declared as reference to const [constParameterReference]\n", errout_str()); check("auto& foo(std::vector& vec, bool flag) {\n" @@ -1543,7 +1543,7 @@ class TestOther : public TestFixture { " iter = dummy.begin();\n" " }\n" " return *iter;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -2067,7 +2067,7 @@ class TestOther : public TestFixture { "void foo(Base* base)\n" "{\n" " Derived * d = (Derived *) base;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:19]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); checkOldStylePointerCast("class Base{};\n" @@ -2075,13 +2075,13 @@ class TestOther : public TestFixture { "void foo(Derived* derived)\n" "{\n" " Base * b = (Base *) derived;\n" // <- cast from derived to base is safe => cstyleCast - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); checkOldStylePointerCast("void foo(Base* base)\n" "{\n" " Derived * d = (Derived *) base;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); checkOldStylePointerCast("class Base{};\n" @@ -2089,7 +2089,7 @@ class TestOther : public TestFixture { "void foo(Base* base)\n" "{\n" " Derived * d = (const Derived *) base;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:19]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); checkOldStylePointerCast("class Base{};\n" @@ -2097,7 +2097,7 @@ class TestOther : public TestFixture { "void foo()\n" "{\n" " Derived * d = (const Derived *) ( new Base() );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:19]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); checkOldStylePointerCast("class Base{};\n" @@ -2105,102 +2105,102 @@ class TestOther : public TestFixture { "void foo()\n" "{\n" " Derived * d = (const Derived *) new Base();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:19]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); checkOldStylePointerCast("class Base{};\n" "void foo()\n" "{\n" " Base * b = (Base *) new short[10];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); checkOldStylePointerCast("class Base;\n" "void foo()\n" "{\n" " Base * b = (volatile Base *) derived;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); checkOldStylePointerCast("class Base;\n" "void foo()\n" "{\n" " Base * b = (volatile Base * const) derived;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); checkOldStylePointerCast("class Base;\n" "void foo()\n" "{\n" " Base * b = (const volatile Base *) derived;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); checkOldStylePointerCast("class Base;\n" "void foo()\n" "{\n" " Base * b = (const volatile Base * const) derived;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); checkOldStylePointerCast("class Base;\n" "void foo()\n" "{\n" " Base * b = (const Base *) ( new Derived() );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); checkOldStylePointerCast("class Base;\n" "void foo()\n" "{\n" " Base * b = (const Base *) new Derived();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); checkOldStylePointerCast("class Base;\n" "void foo()\n" "{\n" " Base * b = (const Base *) new short[10];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); checkOldStylePointerCast("class B;\n" "class A\n" "{\n" " virtual void abc(B *) const = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkOldStylePointerCast("class B;\n" "class A\n" "{\n" " virtual void abc(const B *) const = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3630 checkOldStylePointerCast("class SomeType{};\n" "class X : public Base {\n" " X() : Base((SomeType*)7) {}\n" // <- intToPointerCast - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOldStylePointerCast("class SomeType{};\n" "class X : public Base {\n" " X() : Base((SomeType*)0x7000) {}\n" // <- it's common in embedded code to cast address - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); checkOldStylePointerCast("class SomeType;\n" "class X : public Base {\n" " X() : Base((SomeType*)var) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:3:16]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); checkOldStylePointerCast("class SomeType;\n" "class X : public Base {\n" " X() : Base((SomeType*)0) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); // #5560 @@ -2210,7 +2210,7 @@ class TestOther : public TestFixture { "{ virtual G* createGui(S*, C*) const = 0; };\n" "\n" "class MS : public M\n" - "{ virtual void addController(C*) override {} };", Standards::CPP03); + "{ virtual void addController(C*) override {} };\n", Standards::CPP03); ASSERT_EQUALS("", errout_str()); // #6164 @@ -2219,7 +2219,7 @@ class TestOther : public TestFixture { "void testCC() {\n" " std::vector v;\n" " v.push_back((Base*)new Derived);\n" - "}"); + "}\n"); // FIXME write a dangerousTypeCast warning instead ASSERT_EQUALS("[test.cpp:5:15]: (style) C-style pointer casting [cstyleCast]\n", errout_str()); @@ -2348,23 +2348,23 @@ class TestOther : public TestFixture { void intToPointerCast() { // #3630 - checkIntToPointerCast("uint8_t* ptr = (uint8_t*)7;"); + checkIntToPointerCast("uint8_t* ptr = (uint8_t*)7;\n"); ASSERT_EQUALS("[test.cpp:1:16]: (portability) Casting non-zero decimal integer literal to pointer. [intToPointerCast]\n", errout_str()); - checkIntToPointerCast("void* ptr = (void*)7;"); + checkIntToPointerCast("void* ptr = (void*)7;\n"); ASSERT_EQUALS("[test.cpp:1:13]: (portability) Casting non-zero decimal integer literal to pointer. [intToPointerCast]\n", errout_str()); - checkIntToPointerCast("uint8_t* ptr = (uint8_t*)0;"); + checkIntToPointerCast("uint8_t* ptr = (uint8_t*)0;\n"); ASSERT_EQUALS("", errout_str()); - checkIntToPointerCast("uint8_t* ptr = (uint8_t*)0x7000;"); // <- it's common in embedded code to cast address + checkIntToPointerCast("uint8_t* ptr = (uint8_t*)0x7000;\n"); // <- it's common in embedded code to cast address ASSERT_EQUALS("", errout_str()); checkIntToPointerCast("struct S { int i; };\n" // #13886, don't crash - "int f() { return sizeof(((struct S*)0)->i); }"); + "int f() { return sizeof(((struct S*)0)->i); }\n"); ASSERT_EQUALS("", errout_str()); - checkIntToPointerCast("auto p = (int*)0b10;"); // #14180 + checkIntToPointerCast("auto p = (int*)0b10;\n"); // #14180 ASSERT_EQUALS("[test.cpp:1:10]: (portability) Casting non-zero binary integer literal to pointer. [intToPointerCast]\n", errout_str()); } @@ -2394,19 +2394,19 @@ class TestOther : public TestFixture { " float *f = new float[10];\n" " delete [] (double*)f;\n" " delete [] (long double const*)(new float[10]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:15]: (portability) Casting between float * and double * which have an incompatible binary data representation. [invalidPointerCast]\n" "[test.cpp:4:15]: (portability) Casting between float * and const long double * which have an incompatible binary data representation. [invalidPointerCast]\n", errout_str()); checkInvalidPointerCast("void test(const float* f) {\n" " double *d = (double*)f;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (portability) Casting between const float * and double * which have an incompatible binary data representation. [invalidPointerCast]\n", errout_str()); checkInvalidPointerCast("void test(double* d1) {\n" " long double *ld = (long double*)d1;\n" " double *d2 = (double*)ld;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:23]: (portability) Casting between double * and long double * which have an incompatible binary data representation. [invalidPointerCast]\n" "[test.cpp:3:18]: (portability) Casting between long double * and double * which have an incompatible binary data representation. [invalidPointerCast]\n", errout_str()); @@ -2414,148 +2414,148 @@ class TestOther : public TestFixture { " long double *d = (long double*)(i);\n" " double *d = (double*)(i);\n" " float *f = reinterpret_cast(i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (portability) Casting between signed int * and long double * which have an incompatible binary data representation. [invalidPointerCast]\n" "[test.cpp:3:17]: (portability) Casting between signed int * and double * which have an incompatible binary data representation. [invalidPointerCast]\n" "[test.cpp:4:16]: (portability) Casting between signed int * and float * which have an incompatible binary data representation. [invalidPointerCast]\n", errout_str()); checkInvalidPointerCast("float* test(unsigned int* i) {\n" " return (float*)i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (portability) Casting between unsigned int * and float * which have an incompatible binary data representation. [invalidPointerCast]\n", errout_str()); checkInvalidPointerCast("float* test(unsigned int* i) {\n" " return (float*)i[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInvalidPointerCast("float* test(double& d) {\n" " return (float*)&d;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (portability) Casting between double * and float * which have an incompatible binary data representation. [invalidPointerCast]\n", errout_str()); checkInvalidPointerCast("void test(float* data) {\n" " f.write((char*)data,sizeof(float));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInvalidPointerCast("void test(float* data) {\n" " f.write((char*)data,sizeof(float));\n" - "}", dinit(CheckInvalidPointerCastOptions, $.inconclusive = true)); // #3639 + "}\n", dinit(CheckInvalidPointerCastOptions, $.inconclusive = true)); // #3639 ASSERT_EQUALS("[test.cpp:2:13]: (portability, inconclusive) Casting from float * to char * is not portable due to different binary data representations on different platforms. [invalidPointerCast]\n", errout_str()); checkInvalidPointerCast("long long* test(float* f) {\n" " return (long long*)f;\n" - "}", dinit(CheckInvalidPointerCastOptions, $.portability = false)); + "}\n", dinit(CheckInvalidPointerCastOptions, $.portability = false)); ASSERT_EQUALS("", errout_str()); checkInvalidPointerCast("long long* test(float* f, char* c) {\n" " foo((long long*)f);\n" " return reinterpret_cast(c);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (portability) Casting from float * to signed long long * is not portable due to different binary data representations on different platforms. [invalidPointerCast]\n", errout_str()); - checkInvalidPointerCast("Q_DECLARE_METATYPE(int*)"); // #4135 - don't crash + checkInvalidPointerCast("Q_DECLARE_METATYPE(int*)\n"); // #4135 - don't crash } void passedByValue() { - check("void f(const std::string str) {}"); + check("void f(const std::string str) {}\n"); ASSERT_EQUALS("[test.cpp:1:26]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); - check("void f(std::unique_ptr ptr) {}"); + check("void f(std::unique_ptr ptr) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const std::shared_ptr ptr) {}"); + check("void f(const std::shared_ptr ptr) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const std::function ptr) {}"); + check("void f(const std::function ptr) {}\n"); ASSERT_EQUALS("", errout_str()); { - check("void f(const std::pair x) {}"); + check("void f(const std::pair x) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const std::pair x) {}"); + check("void f(const std::pair x) {}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); } - check("void f(const std::string::size_type x) {}"); + check("void f(const std::string::size_type x) {}\n"); ASSERT_EQUALS("", errout_str()); - check("class Foo;\nvoid f(const Foo foo) {}"); // Unknown class + check("class Foo;\nvoid f(const Foo foo) {}\n"); // Unknown class ASSERT_EQUALS("[test.cpp:2:18]: (performance, inconclusive) Function parameter 'foo' should be passed by const reference. [passedByValue]\n", errout_str()); - check("class Foo { std::vector v; };\nvoid f(const Foo foo) {}"); // Large class (STL member) + check("class Foo { std::vector v; };\nvoid f(const Foo foo) {}\n"); // Large class (STL member) ASSERT_EQUALS("[test.cpp:2:18]: (performance) Function parameter 'foo' should be passed by const reference. [passedByValue]\n", errout_str()); - check("class Foo { int i; };\nvoid f(const Foo foo) {}"); // Small class + check("class Foo { int i; };\nvoid f(const Foo foo) {}\n"); // Small class ASSERT_EQUALS("", errout_str()); - check("class Foo { int i[6]; };\nvoid f(const Foo foo) {}"); // Large class (array) + check("class Foo { int i[6]; };\nvoid f(const Foo foo) {}\n"); // Large class (array) ASSERT_EQUALS("[test.cpp:2:18]: (performance) Function parameter 'foo' should be passed by const reference. [passedByValue]\n", errout_str()); - check("class Foo { std::string* s; };\nvoid f(const Foo foo) {}"); // Small class (pointer) + check("class Foo { std::string* s; };\nvoid f(const Foo foo) {}\n"); // Small class (pointer) ASSERT_EQUALS("", errout_str()); - check("class Foo { static std::string s; };\nvoid f(const Foo foo) {}"); // Small class (static member) + check("class Foo { static std::string s; };\nvoid f(const Foo foo) {}\n"); // Small class (static member) ASSERT_EQUALS("", errout_str()); - check("class X { std::string s; }; class Foo : X { };\nvoid f(const Foo foo) {}"); // Large class (inherited) + check("class X { std::string s; }; class Foo : X { };\nvoid f(const Foo foo) {}\n"); // Large class (inherited) ASSERT_EQUALS("[test.cpp:2:18]: (performance) Function parameter 'foo' should be passed by const reference. [passedByValue]\n", errout_str()); - check("class X { std::string s; }; class Foo { X x; };\nvoid f(const Foo foo) {}"); // Large class (inherited) + check("class X { std::string s; }; class Foo { X x; };\nvoid f(const Foo foo) {}\n"); // Large class (inherited) ASSERT_EQUALS("[test.cpp:2:18]: (performance) Function parameter 'foo' should be passed by const reference. [passedByValue]\n", errout_str()); - check("void f(const std::string &str) {}"); + check("void f(const std::string &str) {}\n"); ASSERT_EQUALS("", errout_str()); // The idiomatic way of passing a std::string_view is by value - check("void f(const std::string_view str) {}"); + check("void f(const std::string_view str) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(std::string_view str) {}"); + check("void f(std::string_view str) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const std::string_view &str) {}"); + check("void f(const std::string_view &str) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const std::vector v) {}"); + check("void f(const std::vector v) {}\n"); ASSERT_EQUALS("[test.cpp:1:31]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); - check("void f(const std::vector v) {}"); + check("void f(const std::vector v) {}\n"); ASSERT_EQUALS("[test.cpp:1:39]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); - check("void f(const std::vector::size_type s) {}"); + check("void f(const std::vector::size_type s) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const std::vector &v) {}"); + check("void f(const std::vector &v) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const std::map &v) {}"); + check("void f(const std::map &v) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(const std::map v) {}"); + check("void f(const std::map v) {}\n"); ASSERT_EQUALS("[test.cpp:1:32]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); - check("void f(const std::map v) {}"); + check("void f(const std::map v) {}\n"); ASSERT_EQUALS("[test.cpp:1:48]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); - check("void f(const std::map v) {}"); + check("void f(const std::map v) {}\n"); ASSERT_EQUALS("[test.cpp:1:40]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); - check("void f(const std::map v) {}"); + check("void f(const std::map v) {}\n"); ASSERT_EQUALS("[test.cpp:1:40]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); - check("void f(const std::streamoff pos) {}"); + check("void f(const std::streamoff pos) {}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(std::initializer_list i) {}"); + check("void f(std::initializer_list i) {}\n"); ASSERT_EQUALS("", errout_str()); // #5824 - check("void log(const std::string& file, int line, const std::string& function, const std::string str, ...) {}"); + check("void log(const std::string& file, int line, const std::string& function, const std::string str, ...) {}\n"); ASSERT_EQUALS("", errout_str()); // #5534 @@ -2564,12 +2564,12 @@ class TestOther : public TestFixture { "class Plane {\n" " vec Refract(vec &vec) const;\n" " bool IntersectLinePlane(const vec &planeNormal);\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class X {\n" " virtual void func(const std::string str) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:41]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("enum X;\n" @@ -2586,7 +2586,7 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); check("enum X;\n" - "enum X { a, b, c };" + "enum X { a, b, c };\n" "void foo(X x4){}\n"); ASSERT_EQUALS("", errout_str()); @@ -2746,87 +2746,87 @@ class TestOther : public TestFixture { } void passedByValue_nonConst() { - check("void f(std::string str) {}"); + check("void f(std::string str) {}\n"); ASSERT_EQUALS("[test.cpp:1:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("void f(std::string str) {\n" " return str + x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("void f(std::string str) {\n" " std::cout << str;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("void f(std::string str) {\n" " std::cin >> str;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::string str) {\n" " std::string s2 = str;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (performance, inconclusive) Use const reference for 's2' to avoid unnecessary data copying. [redundantCopyLocalConst]\n" "[test.cpp:1:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("void f(std::string str) {\n" " std::string& s2 = str;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n" "[test.cpp:2:18]: (style) Variable 's2' can be declared as reference to const [constVariableReference]\n", errout_str()); check("void f(std::string str) {\n" " const std::string& s2 = str;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("void f(std::string str) {\n" " str = \"\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::string str) {\n" " foo(str);\n" // It could be that foo takes str as non-const-reference - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const std::string& str);\n" "void f(std::string str) {\n" " foo(str);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("void foo(std::string str);\n" "void f(std::string str) {\n" " foo(str);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("void foo(std::string& str);\n" "void f(std::string str) {\n" " foo(str);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(std::string* str);\n" "void f(std::string str) {\n" " foo(&str);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int& i1, const std::string& str, int& i2);\n" "void f(std::string str) {\n" " foo((a+b)*c, str, x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("std::string f(std::string str) {\n" " str += x;\n" " return str;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class X {\n" @@ -2835,7 +2835,7 @@ class TestOther : public TestFixture { "};\n" "Y f(X x) {\n" " x.func();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:7]: (performance) Function parameter 'x' should be passed by const reference. [passedByValue]\n", errout_str()); check("class X {\n" @@ -2843,17 +2843,17 @@ class TestOther : public TestFixture { "};\n" "Y f(X x) {\n" " x.func();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class X {\n" " void func(std::string str) {}\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:2:27]: (performance) Function parameter 'str' should be passed by const reference. [passedByValue]\n", errout_str()); check("class X {\n" " virtual void func(std::string str) {}\n" // Do not warn about virtual functions, if 'str' is not declared as const - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("class X {\n" @@ -2863,7 +2863,7 @@ class TestOther : public TestFixture { " char b;\n" "};\n" "void f(Y y) {\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:10]: (performance) Function parameter 'y' should be passed by const reference. [passedByValue]\n", errout_str()); check("class X {\n" @@ -2876,7 +2876,7 @@ class TestOther : public TestFixture { " char c;\n" "};\n" "void f(X x, Y y) {\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:15]: (performance) Function parameter 'y' should be passed by const reference. [passedByValue]\n", errout_str()); { @@ -2885,7 +2885,7 @@ class TestOther : public TestFixture { " uint64_t a;\n" " uint64_t b;\n" "};\n" - "void f(X x) {}"; + "void f(X x) {}\n"; /*const*/ Settings s32 = settingsBuilder(settings1).platform(Platform::Type::Unix32).build(); check(code, dinit(CheckOptions, $.settings = &s32)); @@ -2900,30 +2900,30 @@ class TestOther : public TestFixture { "\n" "void foo(Buffer& buffer) {\n" " getWriter()->operator<<(buffer);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void passedByValue_externC() { - check("struct X { int a[5]; }; void f(X v) { }"); + check("struct X { int a[5]; }; void f(X v) { }\n"); ASSERT_EQUALS("[test.cpp:1:34]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); - check("extern \"C\" { struct X { int a[5]; }; void f(X v) { } }"); + check("extern \"C\" { struct X { int a[5]; }; void f(X v) { } }\n"); ASSERT_EQUALS("", errout_str()); - check("struct X { int a[5]; }; extern \"C\" void f(X v) { }"); + check("struct X { int a[5]; }; extern \"C\" void f(X v) { }\n"); ASSERT_EQUALS("", errout_str()); - check("struct X { int a[5]; }; void f(const X v);"); + check("struct X { int a[5]; }; void f(const X v);\n"); ASSERT_EQUALS("", errout_str()); - check("struct X { int a[5]; }; void f(const X v) { (void) v; }"); + check("struct X { int a[5]; }; void f(const X v) { (void) v; }\n"); ASSERT_EQUALS("[test.cpp:1:40]: (performance) Function parameter 'v' should be passed by const reference. [passedByValue]\n", errout_str()); - check("extern \"C\" { struct X { int a[5]; }; void f(const X v); }"); + check("extern \"C\" { struct X { int a[5]; }; void f(const X v); }\n"); ASSERT_EQUALS("", errout_str()); - check("struct X { int a[5]; }; extern \"C\" void f(const X v) { }"); + check("struct X { int a[5]; }; extern \"C\" void f(const X v) { }\n"); ASSERT_EQUALS("", errout_str()); } @@ -2931,140 +2931,140 @@ class TestOther : public TestFixture { check("int f(std::vector x) {\n" " int& i = x[0];\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:24]: (performance) Function parameter 'x' should be passed by const reference. [passedByValue]\n" "[test.cpp:2:10]: (style) Variable 'i' can be declared as reference to const [constVariableReference]\n", errout_str()); check("int f(std::vector& x) {\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:25]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("int f(std::vector x) {\n" " const int& i = x[0];\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:24]: (performance) Function parameter 'x' should be passed by const reference. [passedByValue]\n", errout_str()); check("int f(std::vector x) {\n" " static int& i = x[0];\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:24]: (performance) Function parameter 'x' should be passed by const reference. [passedByValue]\n", errout_str()); check("int f(std::vector x) {\n" " int& i = x[0];\n" " i++;\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int& f(std::vector& x) {\n" " x.push_back(1);\n" " int& i = x[0];\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(const std::vector& x) {\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int& f(std::vector& x) {\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const int& f(std::vector& x) {\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:32]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("int f(std::vector& x) {\n" " x[0]++;\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int a; };\n" "A f(std::vector& x) {\n" " x[0].a = 1;\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int a(); };\n" "A f(std::vector& x) {\n" " x[0].a();\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int g(int& x);\n" "int f(std::vector& x) {\n" " g(x[0]);\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("template\n" "T f(T& x) {\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("template\n" "T f(T&& x) {\n" " return x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("template\n" "T f(T& x) {\n" " return x[0];\n" "}\n" - "void h() { std::vector v; h(v); }"); + "void h() { std::vector v; h(v); }\n"); ASSERT_EQUALS("", errout_str()); check("int f(int& x) {\n" " return std::move(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::ostream& os) {\n" " os << \"Hello\";\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int*);\n" "void f(int& x) {\n" " g(&x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { A(int*); };\n" "A f(int& x) {\n" " return A(&x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { A(int*); };\n" "A f(int& x) {\n" " return A{&x};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int& x, int& y) {\n" " y++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:13]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("struct A {\n" " explicit A(int& y) : x(&y) {}\n" " int * x = nullptr;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -3072,7 +3072,7 @@ class TestOther : public TestFixture { " void swap(A& a) {\n" " v.swap(a.v);\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -3083,24 +3083,24 @@ class TestOther : public TestFixture { "};\n" "void g(A& a) {\n" " a.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::vector& v) {\n" " for(auto&& x:v)\n" " x = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::vector& v) {\n" " for(auto x:v)\n" " x = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:26]: (style) Parameter 'v' can be declared as reference to const [constParameterReference]\n", errout_str()); check("void f(std::vector& v) {\n" " for(auto& x:v) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (style) Variable 'x' can be declared as reference to const [constVariableReference]\n", errout_str()); @@ -3121,32 +3121,32 @@ class TestOther : public TestFixture { check("void f(std::vector& v) {\n" " for(const auto& x:v) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:26]: (style) Parameter 'v' can be declared as reference to const [constParameterReference]\n", errout_str()); check("void f(int& i) {\n" " int& j = i;\n" " j++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::vector& v) {\n" " int& i = v[0];\n" " i++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::map >& m, unsigned int i) {\n" " std::map& members = m[i];\n" " members.clear();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" " int& x;\n" " A(int& y) : x(y)\n" " {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -3155,14 +3155,14 @@ class TestOther : public TestFixture { "struct B : A {\n" " B(int& x) : A(x)\n" " {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b, int& x, int& y) {\n" " auto& z = x;\n" " auto& w = b ? y : z;\n" " w = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -3170,7 +3170,7 @@ class TestOther : public TestFixture { "};\n" "int& f(S& s) {\n" " return s.i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int* f(std::list& x, unsigned int y) {\n" @@ -3179,7 +3179,7 @@ class TestOther : public TestFixture { " return &m;\n" " }\n" " return nullptr;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int& f(std::list& x, int& y) {\n" @@ -3188,7 +3188,7 @@ class TestOther : public TestFixture { " return m;\n" " }\n" " return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool from_string(int& t, const std::string& s) {\n" @@ -3232,7 +3232,7 @@ class TestOther : public TestFixture { check("struct T { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" @@ -3240,86 +3240,86 @@ class TestOther : public TestFixture { " const T& z = x;\n" // Make sure we find all assignments " T& y = x;\n" " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U& y = x\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " U& y = x;\n" " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " my::type& y = x;\n" // we don't know if y is const or not " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U& y = static_cast(x);\n" " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " U& y = static_cast(x);\n" " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U& y = dynamic_cast(x)\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U& y = dynamic_cast(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U& y = dynamic_cast(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " U& y = dynamic_cast(x);\n" " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U& y = dynamic_cast(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " U& y = dynamic_cast(x);\n" " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " U* y = dynamic_cast(&x);\n" " y->mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" @@ -3327,49 +3327,49 @@ class TestOther : public TestFixture { " x.dostuff();\n" " const U * y = dynamic_cast(&x);\n" " y->mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); TODO_ASSERT_EQUALS("can be const", errout_str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " U const * y = dynamic_cast(&x);\n" " y->mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); TODO_ASSERT_EQUALS("can be const", errout_str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U const * const * const * const y = dynamic_cast(&x);\n" " y->mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U const * const * const * const y = dynamic_cast(&x);\n" " y->mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); TODO_ASSERT_EQUALS("can be const", errout_str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U const * const * * const y = dynamic_cast(&x);\n" " y->mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " my::fancy const * const * const y = dynamic_cast const * const * const>(&x);\n" " y->mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U& y = (const U&)(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n" "[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); @@ -3378,13 +3378,13 @@ class TestOther : public TestFixture { " x.dostuff();\n" " U& y = (U&)(x);\n" " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " const U& y = (typename const U&)(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:18]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n" "[test.cpp:2:11]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); @@ -3393,14 +3393,14 @@ class TestOther : public TestFixture { " x.dostuff();\n" " U& y = (typename U&)(x);\n" " y.mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); check("struct T : public U { void dostuff() const {}};\n" "void a(T& x) {\n" " x.dostuff();\n" " U* y = (U*)(&x);\n" " y->mutate();\n" // to avoid warnings that y can be const - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: (warning) Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast]\n", errout_str()); check("struct C { void f() const; };\n" // #9875 - crash @@ -3408,7 +3408,7 @@ class TestOther : public TestFixture { "void foo(C& x) {\n" " x.f();\n" " foo( static_cast(0) );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (style) Parameter 'x' can be declared as reference to const [constParameterReference]\n", errout_str()); check("class a {\n" @@ -3616,7 +3616,7 @@ class TestOther : public TestFixture { "void bh(const std::list &ak, const std::list &al);\n" "void ah();\n" "void an();\n" - "void h();"); + "void h();\n"); ASSERT_EQUALS("[test.cpp:131:12]: (style) Variable 'tm' can be declared as pointer to const [constVariablePointer]\n" "[test.cpp:136:19]: (style) Variable 'af' can be declared as pointer to const [constVariablePointer]\n" "[test.cpp:137:12]: (style) Variable 'ag' can be declared as pointer to const [constVariablePointer]\n", @@ -3640,7 +3640,7 @@ class TestOther : public TestFixture { "D::D(int& i)\n" " : c(i)\n" "{\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class C\n" @@ -3660,7 +3660,7 @@ class TestOther : public TestFixture { "\n" "D::D(int& i) noexcept\n" " : c(i)\n" - "{}"); + "{}\n"); ASSERT_EQUALS("", errout_str()); check("class C\n" @@ -3681,7 +3681,7 @@ class TestOther : public TestFixture { "D::D(int& i)\n" " : c(i)\n" "{\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared as reference to const\n", "", errout_str()); check("class C\n" @@ -3702,7 +3702,7 @@ class TestOther : public TestFixture { "D::D(int& i)\n" " : c(i)\n" "{\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared as reference to const\n", "", errout_str()); check("class C\n" @@ -3723,13 +3723,13 @@ class TestOther : public TestFixture { "D::D(int& i)\n" " : c(0, i)\n" "{\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:16]: (style) Parameter 'i' can be declared as reference to const\n", "", errout_str()); check("void f(std::map> &map) {\n" // #10266 " for (auto &[slave, panels] : map)\n" " panels.erase(it);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S { void f(); int i; };\n" @@ -4080,7 +4080,7 @@ class TestOther : public TestFixture { "[test.cpp:10:25]: (style) Parameter 'v' can be declared as reference to const [constParameterReference]\n", errout_str()); - check("void push(V& v) { v.push_back({ .x = 1 }); }"); // #14010 + check("void push(V& v) { v.push_back({ .x = 1 }); }\n"); // #14010 ASSERT_EQUALS("", errout_str()); check("size_t* f(std::array& a) { return reinterpret_cast(a.data()); }\n"); // #14074 @@ -4170,7 +4170,7 @@ class TestOther : public TestFixture { void constParameterCallback() { check("int callback(std::vector& x) { return x[0]; }\n" - "void f() { dostuff(callback); }"); + "void f() { dostuff(callback); }\n"); ASSERT_EQUALS("[test.cpp:2:20] -> [test.cpp:1:32]: (style) Parameter 'x' can be declared as reference to const. However it seems that 'callback' is a callback function, if 'x' is declared with const you might also need to cast function pointer(s). [constParameterCallback]\n", errout_str()); // #9906 @@ -4188,13 +4188,13 @@ class TestOther : public TestFixture { "\n" "void EventEngine::signalEvent(ev::sig& signal, int revents) {\n" " switch (signal.signum) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:48] -> [test.cpp:13:40]: (style) Parameter 'signal' can be declared as reference to const. However it seems that 'signalEvent' is a callback function, if 'signal' is declared with const you might also need to cast function pointer(s). [constParameterCallback]\n", errout_str()); check("void f(int* p) {}\n" // 12843 "void g(std::map&m) {\n" " m[&f] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:1:13]: (style) Parameter 'p' can be declared as pointer to const. " "However it seems that 'f' is a callback function, if 'p' is declared with const you might also need to cast function pointer(s). [constParameterCallback]\n", errout_str()); @@ -4220,49 +4220,49 @@ class TestOther : public TestFixture { } void constPointer() { - check("void foo(int *p) { return *p; }"); + check("void foo(int *p) { return *p; }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { x = *p; }"); + check("void foo(int *p) { x = *p; }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { int &ref = *p; ref = 12; }"); + check("void foo(int *p) { int &ref = *p; ref = 12; }\n"); ASSERT_EQUALS("", errout_str()); - check("void foo(int *p) { x = *p + 10; }"); + check("void foo(int *p) { x = *p + 10; }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { return p[10]; }"); + check("void foo(int *p) { return p[10]; }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { int &ref = p[0]; ref = 12; }"); + check("void foo(int *p) { int &ref = p[0]; ref = 12; }\n"); ASSERT_EQUALS("", errout_str()); - check("void foo(int *p) { x[*p] = 12; }"); + check("void foo(int *p) { x[*p] = 12; }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { if (p) {} }"); + check("void foo(int *p) { if (p) {} }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { if (p || x) {} }"); + check("void foo(int *p) { if (p || x) {} }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { if (p == 0) {} }"); + check("void foo(int *p) { if (p == 0) {} }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { if (!p) {} }"); + check("void foo(int *p) { if (!p) {} }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { if (*p > 123) {} }"); + check("void foo(int *p) { if (*p > 123) {} }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { return *p + 1; }"); + check("void foo(int *p) { return *p + 1; }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(int *p) { return *p > 1; }"); + check("void foo(int *p) { return *p > 1; }\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n", errout_str()); - check("void foo(const int* c) { if (c == 0) {}; }"); + check("void foo(const int* c) { if (c == 0) {}; }\n"); ASSERT_EQUALS("", errout_str()); check("struct a { void b(); };\n" @@ -4295,59 +4295,59 @@ class TestOther : public TestFixture { " int& i = (*x)[0];\n" " i++;\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int a; };\n" "A f(std::vector* x) {\n" " x->front().a = 1;\n" " return x->front();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::vector* v) {\n" " for(auto&& x:*v)\n" " x = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" " int* x;\n" " A(int* y) : x(y)\n" " {}\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b, int* x, int* y) {\n" " int* z = x;\n" " int* w = b ? y : z;\n" " *w = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b, int* x, int* y) {\n" " int& z = *x;\n" " int& w = b ? *y : z;\n" " w = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class Base { virtual void dostuff(int *p) = 0; };\n" // #10397 - "class Derived: public Base { int x; void dostuff(int *p) override { x = *p; } };"); + "class Derived: public Base { int x; void dostuff(int *p) override { x = *p; } };\n"); ASSERT_EQUALS("", errout_str()); check("struct Data { char buf[128]; };\n" // #10483 "void encrypt(Data& data) {\n" " const char a[] = \"asfasd\";\n" " memcpy(data.buf, &a, sizeof(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10547 check("void foo(std::istream &istr) {\n" " unsigned char x[2];\n" " istr >> x[0];\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10744 @@ -4898,7 +4898,7 @@ class TestOther : public TestFixture { check("struct S {\n" // #14817 " explicit S(int *a) : m{ a[0], a[1] } {}\n" " int m[2];\n" - "}" + "}\n" "struct T {\n" " explicit T(int *a) : m{ &a[0], &a[1] } {}\n" " int* m[2];\n" @@ -5019,7 +5019,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:11] -> [test.cpp:9:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" @@ -5035,7 +5035,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:11] -> [test.cpp:11:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" @@ -5052,7 +5052,7 @@ class TestOther : public TestFixture { " }\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -5070,7 +5070,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -5085,7 +5085,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -5100,7 +5100,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -5117,7 +5117,7 @@ class TestOther : public TestFixture { " }\n" " bar(y);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -5134,7 +5134,7 @@ class TestOther : public TestFixture { " }\n" " bar(y);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -5149,7 +5149,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" @@ -5164,7 +5164,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:11] -> [test.cpp:10:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void bar() {}\n" // bar isn't noreturn @@ -5180,7 +5180,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:11] -> [test.cpp:11:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo(int a) {\n" @@ -5192,7 +5192,7 @@ class TestOther : public TestFixture { " case 3:\n" " strcpy(str, \"b'\");\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); TODO_ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:8]: (style) Buffer 'str' is being written before its old content has been used. 'break;' missing?\n", "", errout_str()); @@ -5206,7 +5206,7 @@ class TestOther : public TestFixture { " case 3:\n" " strncpy(str, \"b'\");\n" " }\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:8]: (style) Buffer 'str' is being written before its old content has been used. 'break;' missing?\n", "", errout_str()); @@ -5223,7 +5223,7 @@ class TestOther : public TestFixture { " strcpy(str, \"b'\");\n" " z++;\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); TODO_ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:10]: (style) Buffer 'str' is being written before its old content has been used. 'break;' missing?\n", "", errout_str()); @@ -5239,7 +5239,7 @@ class TestOther : public TestFixture { " strcpy(str, \"b'\");\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a) {\n" @@ -5252,7 +5252,7 @@ class TestOther : public TestFixture { " case 3:\n" " strcpy(str, \"b'\");\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); // Ticket #5158 "segmentation fault (valid code)" @@ -5285,7 +5285,7 @@ class TestOther : public TestFixture { " case 1: x = 3; goto a;\n" " case 1: x = 6; goto a;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5301,7 +5301,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:9] -> [test.cpp:9:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" "{\n" @@ -5316,7 +5316,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:9] -> [test.cpp:11:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" "{\n" @@ -5329,7 +5329,7 @@ class TestOther : public TestFixture { " ++y;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5342,7 +5342,7 @@ class TestOther : public TestFixture { " ++y;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5355,7 +5355,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:9] -> [test.cpp:9:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" "{\n" @@ -5370,7 +5370,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:9] -> [test.cpp:11:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" "{\n" @@ -5383,7 +5383,7 @@ class TestOther : public TestFixture { " --y;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5396,7 +5396,7 @@ class TestOther : public TestFixture { " --y;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5409,7 +5409,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:10] -> [test.cpp:9:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" "{\n" @@ -5424,7 +5424,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:10] -> [test.cpp:11:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" "{\n" @@ -5437,7 +5437,7 @@ class TestOther : public TestFixture { " y++;\n" " }\n" " bar(y);\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5450,7 +5450,7 @@ class TestOther : public TestFixture { " y++;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5463,7 +5463,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:10] -> [test.cpp:9:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" "{\n" @@ -5478,7 +5478,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:10] -> [test.cpp:11:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("void foo()\n" "{\n" @@ -5491,7 +5491,7 @@ class TestOther : public TestFixture { " y--;\n" " }\n" " bar(y);\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5504,7 +5504,7 @@ class TestOther : public TestFixture { " y--;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5520,7 +5520,7 @@ class TestOther : public TestFixture { " }\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5537,7 +5537,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5551,7 +5551,7 @@ class TestOther : public TestFixture { " y++;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5565,7 +5565,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5581,7 +5581,7 @@ class TestOther : public TestFixture { " }\n" " bar(y);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5597,7 +5597,7 @@ class TestOther : public TestFixture { " }\n" " bar(y);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5611,7 +5611,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" @@ -5625,7 +5625,7 @@ class TestOther : public TestFixture { " y = 3;\n" " }\n" " bar(y);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:10] -> [test.cpp:10:11]: (style) Variable 'y' is reassigned a value before the old one has been used. 'break;' missing? [redundantAssignInSwitch]\n", errout_str()); check("bool f() {\n" @@ -5643,7 +5643,7 @@ class TestOther : public TestFixture { " };\n" " ret = true;\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13] -> [test.cpp:14:9]: (style) Variable 'ret' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:8:13] -> [test.cpp:14:9]: (style) Variable 'ret' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:11:13] -> [test.cpp:14:9]: (style) Variable 'ret' is reassigned a value before the old one has been used. [redundantAssignment]\n", @@ -5662,7 +5662,7 @@ class TestOther : public TestFixture { " y |= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:9]: (style) Redundant bitwise operation on 'y' in 'switch' statement. 'break;' missing? [redundantBitwiseOperationInSwitch]\n", errout_str()); check("void foo(int a)\n" @@ -5676,7 +5676,7 @@ class TestOther : public TestFixture { " y = y | 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:9]: (style) Redundant bitwise operation on 'y' in 'switch' statement. 'break;' missing? [redundantBitwiseOperationInSwitch]\n", errout_str()); check("void foo(int a)\n" @@ -5690,7 +5690,7 @@ class TestOther : public TestFixture { " y |= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:9]: (style) Redundant bitwise operation on 'y' in 'switch' statement. 'break;' missing? [redundantBitwiseOperationInSwitch]\n", errout_str()); check("void foo(int a)\n" @@ -5705,7 +5705,7 @@ class TestOther : public TestFixture { " y |= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5720,7 +5720,7 @@ class TestOther : public TestFixture { " y |= z;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5735,7 +5735,7 @@ class TestOther : public TestFixture { " y |= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5750,7 +5750,7 @@ class TestOther : public TestFixture { " y |= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:11] -> [test.cpp:8:11]: (style) Variable 'y' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); check("void foo(int a)\n" @@ -5764,7 +5764,7 @@ class TestOther : public TestFixture { " y &= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:9]: (style) Redundant bitwise operation on 'y' in 'switch' statement. 'break;' missing? [redundantBitwiseOperationInSwitch]\n", errout_str()); check("void foo(int a)\n" @@ -5779,7 +5779,7 @@ class TestOther : public TestFixture { " y |= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5793,7 +5793,7 @@ class TestOther : public TestFixture { " y ^= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5807,7 +5807,7 @@ class TestOther : public TestFixture { " y |= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5821,7 +5821,7 @@ class TestOther : public TestFixture { " y &= 3;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5835,7 +5835,7 @@ class TestOther : public TestFixture { " y &= 2;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -5847,20 +5847,20 @@ class TestOther : public TestFixture { " continue;\n" " }\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:5:13]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("int foo(int a) {\n" " return 0;\n" " return(a-1);\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:5]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("int foo(int a) {\n" " A:" " return(0);\n" " goto A;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:5]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); constexpr char xmldata[] = "\n" @@ -5875,7 +5875,7 @@ class TestOther : public TestFixture { check("void foo() {\n" " exit(0);\n" " break;\n" - "}", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); + "}\n", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); ASSERT_EQUALS("[test.cpp:3:5]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("class NeonSession {\n" @@ -5884,16 +5884,16 @@ class TestOther : public TestFixture { "void NeonSession::exit()\n" "{\n" " SAL_INFO(\"ucb.ucp.webdav\", \"neon commands cannot be aborted\");\n" - "}", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); + "}\n", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); ASSERT_EQUALS("", errout_str()); check("void NeonSession::exit()\n" "{\n" " SAL_INFO(\"ucb.ucp.webdav\", \"neon commands cannot be aborted\");\n" - "}", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); + "}\n", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); ASSERT_EQUALS("", errout_str()); - check("void foo() { xResAccess->exit(); }", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); + check("void foo() { xResAccess->exit(); }\n", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5907,7 +5907,7 @@ class TestOther : public TestFixture { " c++;\n" " break;\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:7:13]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("void foo(int a)\n" @@ -5920,7 +5920,7 @@ class TestOther : public TestFixture { " c++;\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a)\n" @@ -5931,7 +5931,7 @@ class TestOther : public TestFixture { " break;\n" " }\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:6:13]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("void foo(int a)\n" @@ -5943,7 +5943,7 @@ class TestOther : public TestFixture { " }\n" " a+=2;\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:6:13]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("void foo(int a)\n" @@ -5954,50 +5954,50 @@ class TestOther : public TestFixture { " }\n" " a+=2;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo() {\n" " throw 0;\n" " return 1;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:5]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("void foo() {\n" " throw 0;\n" " return;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:5]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("int foo() {\n" " throw = 0;\n" " return 1;\n" - "}", dinit(CheckOptions, $.cpp = false, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.cpp = false, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("int foo() {\n" " return 0;\n" " return 1;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:5]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("int foo() {\n" " return 0;\n" " foo();\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:5]: (style) Statements following 'return' will never be executed. [unreachableCode]\n", errout_str()); check("int foo(int unused) {\n" " return 0;\n" " (void)unused;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("int foo(int unused1, int unused2) {\n" " return 0;\n" " (void)unused1;\n" " (void)unused2;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("int foo(int unused1, int unused2) {\n" @@ -6005,14 +6005,14 @@ class TestOther : public TestFixture { " (void)unused1;\n" " (void)unused2;\n" " foo();\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:5:5]: (style) Statements following 'return' will never be executed. [unreachableCode]\n", errout_str()); check("int foo() {\n" " if(bar)\n" " return 0;\n" " return 124;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo() {\n" @@ -6023,7 +6023,7 @@ class TestOther : public TestFixture { " return 0;\n" " }\n" " return 124;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:4:9]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); check("void foo() {\n" @@ -6031,7 +6031,7 @@ class TestOther : public TestFixture { " return;\n" " break;\n" " }\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:4:9]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); // #5707 @@ -6042,20 +6042,20 @@ class TestOther : public TestFixture { " }\n" " return 0;\n" " j=2;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:7:5]: (style) Statements following 'return' will never be executed. [unreachableCode]\n", errout_str()); check("int foo() {\n" " return 0;\n" " label:\n" " throw 0;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:3]: (style) Label 'label' is not used. [unusedLabel]\n", errout_str()); check("struct A {\n" " virtual void foo (P & Val) throw ();\n" " virtual void foo1 (P & Val) throw ();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo() {\n" @@ -6064,7 +6064,7 @@ class TestOther : public TestFixture { " bar();\n" " label:\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3457 check("int foo() {\n" @@ -6073,7 +6073,7 @@ class TestOther : public TestFixture { " bar();\n" " label:\n" " } while (true);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3457 check("int foo() {\n" @@ -6082,7 +6082,7 @@ class TestOther : public TestFixture { " bar();\n" " label:\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3457 // #3383. TODO: Use preprocessor @@ -6091,20 +6091,20 @@ class TestOther : public TestFixture { " return 0;\n" "\n" // #endif " return 1;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("int foo() {\n" "\n" // #ifdef A " return 0;\n" "\n" // #endif " return 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (style, inconclusive) Consecutive return, break, continue, goto or throw statements are unnecessary. [duplicateBreak]\n", errout_str()); // #4711 lambda functions check("int f() {\n" " return g([](int x){(void)x+1; return x;});\n" - "}", + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); @@ -6119,7 +6119,7 @@ class TestOther : public TestFixture { " __asm__ (\"rorw $8, %w0\" : \"=r\" (__v) : \"0\" (__x) : \"cc\");\n" " (void)__v;\n" " }));\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); // #6008 @@ -6128,7 +6128,7 @@ class TestOther : public TestFixture { " int sum = a_ + b_;\n" " return sum;\n" " };\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); // #5789 @@ -6136,20 +6136,20 @@ class TestOther : public TestFixture { " uint64_t enter, exit;\n" " uint64_t events;\n" " per_state_info() : enter(0), exit(0), events(0) {}\n" - "};", dinit(CheckOptions, $.inconclusive = false)); + "};\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); // #6664 check("void foo() {\n" " (beat < 100) ? (void)0 : exit(0);\n" " bar();\n" - "}", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); + "}\n", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " (beat < 100) ? exit(0) : (void)0;\n" " bar();\n" - "}", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); + "}\n", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); ASSERT_EQUALS("", errout_str()); // #8261 @@ -6157,13 +6157,13 @@ class TestOther : public TestFixture { TODO_ASSERT_THROW(check("void foo() {\n" " (beat < 100) ? (void)0 : throw(0);\n" " bar();\n" - "}", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)), InternalError); + "}\n", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)), InternalError); //ASSERT_EQUALS("", errout_str()); check("int foo() {\n" " exit(0);\n" " return 1;\n" // <- clarify for tools that function does not continue.. - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -6406,7 +6406,7 @@ class TestOther : public TestFixture { " case A||B:\n" " foo();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:15]: (warning, inconclusive) Found suspicious case label in switch(). Operator '&&' probably doesn't work as intended. [suspiciousCase]\n" "[test.cpp:5:16]: (warning, inconclusive) Found suspicious case label in switch(). Operator '||' probably doesn't work as intended. [suspiciousCase]\n" "[test.cpp:7:15]: (warning, inconclusive) Found suspicious case label in switch(). Operator '||' probably doesn't work as intended. [suspiciousCase]\n", errout_str()); @@ -6416,7 +6416,7 @@ class TestOther : public TestFixture { " case 1:\n" " a=A&&B;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // TODO Do not throw AST validation exception @@ -6425,19 +6425,19 @@ class TestOther : public TestFixture { " case A&&B?B:A:\n" " foo();\n" " }\n" - "}"), InternalError); + "}\n"), InternalError); //ASSERT_EQUALS("", errout_str()); } void suspiciousEqualityComparison() { check("void foo(int c) {\n" " if (x) c == 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead? [constStatement]\n", errout_str()); check("void foo(const int* c) {\n" " if (x) *c == 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead? [constStatement]\n", errout_str()); @@ -6445,90 +6445,90 @@ class TestOther : public TestFixture { " if (c == 1) {\n" " c = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int c) {\n" " c == 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead? [constStatement]\n", errout_str()); check("void foo(int c) {\n" " for (int i = 0; i == 10; i ++) {\n" " a ++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int c) {\n" " for (i == 0; i < 10; i ++) {\n" " c ++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead? [constStatement]\n", errout_str()); check("void foo(int c) {\n" " for (i == 1; i < 10; i ++) {\n" " c ++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead? [constStatement]\n", errout_str()); check("void foo(int c) {\n" " for (i == 2; i < 10; i ++) {\n" " c ++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:12]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead? [constStatement]\n", errout_str()); check("void foo(int c) {\n" " for (int i = 0; i < 10; i == c) {\n" " c ++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:31]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead? [constStatement]\n", errout_str()); check("void foo(int c) {\n" " for (; running == 1;) {\n" " c ++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int c) {\n" " printf(\"%i\", ({x==0;}));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int arg) {\n" " printf(\"%i\", ({int x = do_something(); x == 0;}));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int x) {\n" " printf(\"%i\", ({x == 0; x > 0 ? 10 : 20}));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (warning, inconclusive) Found suspicious equality comparison. Did you intend to assign a value instead? [constStatement]\n", errout_str()); check("void foo(int x) {\n" " for (const Token* end = tok->link(); tok != end; tok = (tok == end) ? end : tok->next()) {\n" " x++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int x) {\n" " for (int i = (x == 0) ? 0 : 5; i < 10; i ++) {\n" " x++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int x) {\n" " for (int i = 0; i < 10; i += (x == 5) ? 1 : 2) {\n" " x++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -6584,26 +6584,26 @@ class TestOther : public TestFixture { " int x = 1;\n" " x = x;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: (style) Redundant assignment of 'x' to itself. [selfAssignment]\n", errout_str()); check("void foo()\n" "{\n" " int x = x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (style) Redundant assignment of 'x' to itself. [selfAssignment]\n", errout_str()); check("struct A { int b; };\n" "void foo(A* a1, A* a2) {\n" " a1->b = a1->b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (style) Redundant assignment of 'a1->b' to itself. [selfAssignment]\n", errout_str()); check("int x;\n" "void f()\n" "{\n" " x = x = 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: (style) Redundant assignment of 'x' to itself. [selfAssignment]\n", errout_str()); // #4073 (segmentation fault) @@ -6611,59 +6611,59 @@ class TestOther : public TestFixture { "{\n" " if (a == 42)\n" " a = a;\n" - "}"); + "}\n"); check("void foo()\n" "{\n" " int x = 1;\n" " x = x + 1;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" " int *x = getx();\n" " *x = x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " BAR *x = getx();\n" " x = x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:7]: (style) Redundant assignment of 'x' to itself. [selfAssignment]\n", errout_str()); // #2502 - non-primitive type -> there might be some side effects check("void foo()\n" "{\n" " Fred fred; fred = fred;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " x = (x == 0);" " func(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " x = (x != 0);" " func(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ticket #3001 - false positive check("void foo(int x) {\n" " x = x ? x : 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3800 - false negative when variable is extern check("extern int i;\n" "void f() {\n" " i = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:7]: (style) Redundant assignment of 'i' to itself. [selfAssignment]\n", errout_str()); // #4291 - id for variables accessed through 'this' @@ -6673,7 +6673,7 @@ class TestOther : public TestFixture { "};\n" "void Foo::func() {\n" " this->var = var;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:15]: (style) Redundant assignment of 'this->var' to itself. [selfAssignment]\n", errout_str()); check("class Foo {\n" @@ -6682,7 +6682,7 @@ class TestOther : public TestFixture { "};\n" "Foo::Foo(int var) {\n" " this->var = var;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6406 - designated initializer doing bogus self assignment @@ -6692,7 +6692,7 @@ class TestOther : public TestFixture { "void something(void) {}\n" "void f() {\n" " struct callbacks ops = { .s = ops.s };\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:6]: (style) Redundant assignment of 'something' to itself.\n", "", errout_str()); check("class V\n" @@ -6707,12 +6707,12 @@ class TestOther : public TestFixture { " x = x; y = y; z = z;\n" " }\n" " double x, y, z;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:10:11]: (style) Redundant assignment of 'x' to itself. [selfAssignment]\n" "[test.cpp:10:18]: (style) Redundant assignment of 'y' to itself. [selfAssignment]\n" "[test.cpp:10:25]: (style) Redundant assignment of 'z' to itself. [selfAssignment]\n", errout_str()); - check("void f(int i) { i = !!i; }"); + check("void f(int i) { i = !!i; }\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -6782,7 +6782,7 @@ class TestOther : public TestFixture { " Lock(123);\n" " std::cout << \"hello\" << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:15:5]: (style) Instance of 'Lock' object is destroyed immediately. [unusedScopedObject]\n", errout_str()); } @@ -6801,7 +6801,7 @@ class TestOther : public TestFixture { "{\n" " CouldBeFunction ( 123 ) ;\n" " return 0 ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -6818,7 +6818,7 @@ class TestOther : public TestFixture { " error();\n" " do_something();\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); } @@ -6828,7 +6828,7 @@ class TestOther : public TestFixture { "{\n" " NotAFunction ( 123 );\n" " return 0 ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (style) Instance of 'NotAFunction' object is destroyed immediately. [unusedScopedObject]\n", errout_str()); } @@ -6838,7 +6838,7 @@ class TestOther : public TestFixture { "{\n" " NotAClass ( 123 ) ;\n" " return true ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (style) Instance of 'NotAClass' object is destroyed immediately. [unusedScopedObject]\n", errout_str()); } @@ -6847,7 +6847,7 @@ class TestOther : public TestFixture { "{\n" " if ( a > b ) return c == a ;\n" " return b == a ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -6857,7 +6857,7 @@ class TestOther : public TestFixture { "public:\n" "~Something ( ) ;\n" "Something ( ) ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -6876,7 +6876,7 @@ class TestOther : public TestFixture { " int a = 1;\n" " IncrementFunctor()(a);\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -6889,7 +6889,7 @@ class TestOther : public TestFixture { " };\n" " Foo();\n" " do_something();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (style) Instance of 'Foo' object is destroyed immediately. [unusedScopedObject]\n", errout_str()); } @@ -6901,7 +6901,7 @@ class TestOther : public TestFixture { "\n" "void fn() {\n" " Foo().bar();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -6930,7 +6930,7 @@ class TestOther : public TestFixture { "void foo() {\n" " stat(\"file.txt\", &st);\n" " do_something();\n" - "}"); + "}\n"); ASSERT_EQUALS("",errout_str()); check("struct AMethodObject {\n" // #4336 @@ -7084,7 +7084,7 @@ class TestOther : public TestFixture { "\n" " { sigaction(SIGHUP, &sa, 0); };\n" " { sigaction(SIGINT, &sa, 0); };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -7095,76 +7095,76 @@ class TestOther : public TestFixture { " };\n" "\n" " const AB ab[3] = { AB(0), AB(1), AB(2) };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void clarifyCalculation() { check("int f(char c) {\n" " return 10 * (c == 0) ? 1 : 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:26]: (style) Clarify calculation precedence for '*' and '?'. [clarifyCalculation]\n", errout_str()); check("void f(char c) {\n" " printf(\"%i\", 10 * (c == 0) ? 1 : 2);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:32]: (style) Clarify calculation precedence for '*' and '?'. [clarifyCalculation]\n", errout_str()); check("void f() {\n" " return (2*a)?b:c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char c) {\n" " printf(\"%i\", a + b ? 1 : 2);\n" - "}",dinit(CheckOptions, $.inconclusive = false)); + "}\n",dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:2:24]: (style) Clarify calculation precedence for '+' and '?'. [clarifyCalculation]\n", errout_str()); check("void f() {\n" " std::cout << x << y ? 2 : 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:25]: (style) Clarify calculation precedence for '<<' and '?'. [clarifyCalculation]\n", errout_str()); check("void f() {\n" " int ab = a - b ? 2 : 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (style) Clarify calculation precedence for '-' and '?'. [clarifyCalculation]\n", errout_str()); check("void f() {\n" " int ab = a | b ? 2 : 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (style) Clarify calculation precedence for '|' and '?'. [clarifyCalculation]\n", errout_str()); // ticket #195 check("int f(int x, int y) {\n" " return x >> ! y ? 8 : 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:21]: (style) Clarify calculation precedence for '>>' and '?'. [clarifyCalculation]\n", errout_str()); check("int f() {\n" " return shift < sizeof(int64_t)*8 ? 1 : 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { a = *p ? 1 : 2; }"); + check("void f() { a = *p ? 1 : 2; }\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int x) { const char *p = x & 1 ? \"1\" : \"0\"; }"); + check("void f(int x) { const char *p = x & 1 ? \"1\" : \"0\"; }\n"); ASSERT_EQUALS("", errout_str()); - check("void foo() { x = a % b ? \"1\" : \"0\"; }"); + check("void foo() { x = a % b ? \"1\" : \"0\"; }\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int x) { return x & 1 ? '1' : '0'; }"); + check("void f(int x) { return x & 1 ? '1' : '0'; }\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int x) { return x & 16 ? 1 : 0; }"); + check("void f(int x) { return x & 16 ? 1 : 0; }\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int x) { return x % 16 ? 1 : 0; }"); + check("void f(int x) { return x % 16 ? 1 : 0; }\n"); ASSERT_EQUALS("", errout_str()); - check("enum {X,Y}; void f(int x) { return x & Y ? 1 : 0; }"); + check("enum {X,Y}; void f(int x) { return x & Y ? 1 : 0; }\n"); ASSERT_EQUALS("", errout_str()); } @@ -7172,7 +7172,7 @@ class TestOther : public TestFixture { check("char* f(char* c) {\n" " *c++;\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:5]: (warning, inconclusive) Found suspicious operator '*', result is not used. [constStatement]\n" "[test.cpp:2:7]: (warning) In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'? [clarifyStatement]\n", @@ -7181,7 +7181,7 @@ class TestOther : public TestFixture { check("char* f(char** c) {\n" " *c[5]--;\n" " return *c;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:5]: (warning, inconclusive) Found suspicious operator '*', result is not used. [constStatement]\n" "[test.cpp:2:10]: (warning) In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'? [clarifyStatement]\n", @@ -7189,7 +7189,7 @@ class TestOther : public TestFixture { check("void f(Foo f) {\n" " *f.a++;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:5]: (warning, inconclusive) Found suspicious operator '*', result is not used. [constStatement]\n" "[test.cpp:2:9]: (warning) In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'? [clarifyStatement]\n", @@ -7197,7 +7197,7 @@ class TestOther : public TestFixture { check("void f(Foo f) {\n" " *f.a[5].v[3]++;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:5]: (warning, inconclusive) Found suspicious operator '*', result is not used. [constStatement]\n" "[test.cpp:2:17]: (warning) In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'? [clarifyStatement]\n", @@ -7205,7 +7205,7 @@ class TestOther : public TestFixture { check("void f(Foo f) {\n" " *f.a(1, 5).v[x + y]++;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:5]: (warning, inconclusive) Found suspicious operator '*', result is not used. [constStatement]\n" "[test.cpp:2:24]: (warning) In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'? [clarifyStatement]\n", @@ -7214,18 +7214,18 @@ class TestOther : public TestFixture { check("char* f(char* c) {\n" " (*c)++;\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(char* c) {\n" " bar(*c++);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("char*** f(char*** c) {\n" " ***c++;\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:5]: (warning, inconclusive) Found suspicious operator '*', result is not used. [constStatement]\n" "[test.cpp:2:9]: (warning) In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'? [clarifyStatement]\n", @@ -7234,7 +7234,7 @@ class TestOther : public TestFixture { check("char** f(char*** c) {\n" " **c[5]--;\n" " return **c;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:5]: (warning, inconclusive) Found suspicious operator '*', result is not used. [constStatement]\n" "[test.cpp:2:11]: (warning) In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'? [clarifyStatement]\n", @@ -7243,7 +7243,7 @@ class TestOther : public TestFixture { check("char*** f(char*** c) {\n" " (***c)++;\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const int*** p) {\n" // #10923 @@ -7253,12 +7253,12 @@ class TestOther : public TestFixture { check("void *f(char** c) {\n" " bar(**c++);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void *f(char* p) {\n" " for (p = path; *p++;) ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -7278,7 +7278,7 @@ class TestOther : public TestFixture { " b = 1;\n" " else\n" " b = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5] -> [test.cpp:2:5]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n", errout_str()); check("void f(int a, int &b) {\n" @@ -7289,7 +7289,7 @@ class TestOther : public TestFixture { " b = 2;\n" " } else\n" " b = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:3:9]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n", errout_str()); check("void f(int a, int &b) {\n" @@ -7301,7 +7301,7 @@ class TestOther : public TestFixture { " else\n" " b = 2;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:9] -> [test.cpp:5:9]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n", errout_str()); check("int f(int signed, unsigned char value) {\n" @@ -7311,7 +7311,7 @@ class TestOther : public TestFixture { " else\n" " ret = (unsigned char)value;\n" " return ret;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -7319,7 +7319,7 @@ class TestOther : public TestFixture { " __asm__(\"mov ax, bx\");\n" " else\n" " __asm__(\"mov bx, bx\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3407 check("void f() {\n" @@ -7327,7 +7327,7 @@ class TestOther : public TestFixture { " __asm__(\"mov ax, bx\");\n" " else\n" " __asm__(\"mov ax, bx\");\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5] -> [test.cpp:2:5]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n", errout_str()); } @@ -7341,7 +7341,7 @@ class TestOther : public TestFixture { " frac = front/(front-back);\n" " else\n" " frac = front/(front-back);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:3] -> [test.cpp:3:3]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n", errout_str()); check("void f()\n" @@ -7350,7 +7350,7 @@ class TestOther : public TestFixture { " { frac = front/(front-back);}\n" " else\n" " frac = front/((front-back));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:3] -> [test.cpp:3:3]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n", errout_str()); // No message about empty branches (#5354) @@ -7360,7 +7360,7 @@ class TestOther : public TestFixture { " {}\n" " else\n" " {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -7372,7 +7372,7 @@ class TestOther : public TestFixture { " DOSTUFF1\n" " else\n" " DOSTUFF2\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -7384,7 +7384,7 @@ class TestOther : public TestFixture { " } else {\n" " x = j;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:5:7] -> [test.cpp:3:5]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n" "[test.cpp:2:9]: (style) The scope of the variable 'j' can be reduced. [variableScope]\n", errout_str()); @@ -7397,7 +7397,7 @@ class TestOther : public TestFixture { " } else {\n" " x = j;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -7408,7 +7408,7 @@ class TestOther : public TestFixture { " } else {\n" " return new A::Z(true);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -7422,7 +7422,7 @@ class TestOther : public TestFixture { " unsigned int i = 0;\n" " j = i;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:7] -> [test.cpp:3:5]: (style, inconclusive) Found duplicate branches for 'if' and 'else'. [duplicateBranch]\n", errout_str()); check("void f(bool b) {\n" @@ -7434,7 +7434,7 @@ class TestOther : public TestFixture { " unsigned int i = 0;\n" " j = 1;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" @@ -7444,7 +7444,7 @@ class TestOther : public TestFixture { " } else {\n" " int i = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" @@ -7456,7 +7456,7 @@ class TestOther : public TestFixture { " int i = 0;\n" " j = i;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int i) {\n" @@ -7475,7 +7475,7 @@ class TestOther : public TestFixture { " } else {\n" " int i = 0;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" @@ -7483,14 +7483,14 @@ class TestOther : public TestFixture { " int i = 0;\n" " } else {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void duplicateExpression1() { check("void foo(int a) {\n" " if (a == a) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Same expression on both sides of '=='. [duplicateExpression]\n", errout_str()); check("void fun(int b) {\n" @@ -7499,7 +7499,7 @@ class TestOther : public TestFixture { " d > d &&\n" " e < e &&\n" " f ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (style) Same expression on both sides of '&&'. [duplicateExpression]\n" "[test.cpp:3:15]: (style) Same expression on both sides of '=='. [duplicateExpression]\n" "[test.cpp:4:15]: (style) Same expression on both sides of '>'. [duplicateExpression]\n" @@ -7507,82 +7507,82 @@ class TestOther : public TestFixture { check("void foo() {\n" " return a && a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style) Same expression on both sides of '&&'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " a = b && b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Same expression on both sides of '&&'. [duplicateExpression]\n", errout_str()); check("void foo(int b) {\n" " f(a,b == b);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Same expression on both sides of '=='. [duplicateExpression]\n", errout_str()); check("void foo(int b) {\n" " f(b == b, a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Same expression on both sides of '=='. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (x!=2 || x!=2) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style) Same expression on both sides of '||'. [duplicateExpression]\n", errout_str()); check("void foo(int a, int b) {\n" " if ((a < b) && (b > a)) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) Same expression on both sides of '&&' because 'aa' represent the same value. [knownConditionTrueFalse]\n", errout_str()); check("void foo(int a, int b) {\n" " if ((a <= b) && (b >= a)) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (style) Same expression on both sides of '&&' because 'a<=b' and 'b>=a' represent the same value. [knownConditionTrueFalse]\n", errout_str()); check("void foo() {\n" " if (x!=2 || y!=3 || x!=2) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (style) Same expression 'x!=2' found multiple times in chain of '||' operators. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (x!=2 && (x=y) && x!=2) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " if (a && b || a && b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (style) Same expression on both sides of '||'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (a && b || b && c) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " if (a && b | b && c) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (style) Same expression on both sides of '|'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if ((a + b) | (a + b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) Same expression on both sides of '|'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if ((a | b) & (a | b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) Same expression on both sides of '&'. [duplicateExpression]\n", errout_str()); check("void foo(int a, int b) {\n" " if ((a | b) == (a | b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) Same expression on both sides of '=='. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (a1[a2[c & 0xff] & 0xff]) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void d(const char f, int o, int v)\n" @@ -7590,127 +7590,127 @@ class TestOther : public TestFixture { " if (((f=='R') && (o == 1) && ((v < 2) || (v > 99))) ||\n" " ((f=='R') && (o == 2) && ((v < 2) || (v > 99))) ||\n" " ((f=='T') && (o == 2) && ((v < 200) || (v > 9999)))) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("int f(int x) { return x+x; }"); + check("int f(int x) { return x+x; }\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int x) { while (x+=x) ; }"); + check("void f(int x) { while (x+=x) ; }\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " if (a && b && b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (style) Same expression on both sides of '&&'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (a || b || b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (style) Same expression on both sides of '||'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (a / 1000 / 1000) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int foo(int i) {\n" " return i/i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Same expression on both sides of '/'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (a << 1 << 1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("int f() { return !!y; }"); // No FP + check("int f() { return !!y; }\n"); // No FP ASSERT_EQUALS("", errout_str()); // make sure there are not "same expression" fp when there are different casts - check("void f(long x) { if ((int32_t)x == (int64_t)x) {} }", + check("void f(long x) { if ((int32_t)x == (int64_t)x) {} }\n", dinit(CheckOptions, $.inconclusive = false) ); ASSERT_EQUALS("", errout_str()); // make sure there are not "same expression" fp when there are different ({}) expressions - check("void f(long x) { if (({ 1+2; }) == ({3+4;})) {} }"); + check("void f(long x) { if (({ 1+2; }) == ({3+4;})) {} }\n"); ASSERT_EQUALS("", errout_str()); // #5535: Reference named like its type - check("void foo() { UMSConfig& UMSConfig = GetUMSConfiguration(); }"); + check("void foo() { UMSConfig& UMSConfig = GetUMSConfiguration(); }\n"); ASSERT_EQUALS("[test.cpp:1:25]: (style) Variable 'UMSConfig' can be declared as reference to const [constVariableReference]\n", errout_str()); // #3868 - false positive (same expression on both sides of |) check("void f(int x) {\n" " a = x ? A | B | C\n" " : A | B;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const Bar &bar) {\n" " bool a = bar.isSet() && bar->isSet();\n" " bool b = bar.isSet() && bar.isSet();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:26]: (style) Same expression on both sides of '&&'. [duplicateExpression]\n", errout_str()); check("void foo(int a, int b) {\n" " if ((b + a) | (a + b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) Same expression on both sides of '|' because 'b+a' and 'a+b' represent the same value. [duplicateExpression]\n", errout_str()); check("void foo(const std::string& a, const std::string& b) {\n" " return a.find(b+\"&\") || a.find(\"&\"+b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a, int b) {\n" " if ((b > a) | (a > b)) {}\n" // > is not commutative - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(double a, double b) {\n" " if ((b + a) > (a + b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17]: (style) The comparison 'b+a > a+b' is always false because 'b+a' and 'a+b' represent the same value. [knownConditionTrueFalse]\n", errout_str()); check("void f(int x) {\n" " if ((x == 1) && (x == 0x00000001))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (style) Same expression on both sides of '&&' because 'x==1' and 'x==0x00000001' represent the same value. [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " enum { Four = 4 };\n" - " if (Four == 4) {}" - "}"); + " if (Four == 4) {}\n" + "}\n"); ASSERT_EQUALS("[test.cpp:3:14]: (style) The comparison 'Four == 4' is always true. [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " enum { Four = 4 };\n" " static_assert(Four == 4, \"\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " enum { Four = 4 };\n" " _Static_assert(Four == 4, \"\");\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " enum { Four = 4 };\n" " static_assert(4 == Four, \"\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " enum { FourInEnumOne = 4 };\n" " enum { FourInEnumTwo = 4 };\n" " if (FourInEnumOne == FourInEnumTwo) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:23]: (style) The comparison 'FourInEnumOne == FourInEnumTwo' is always true because 'FourInEnumOne' and 'FourInEnumTwo' represent the same value. [knownConditionTrueFalse]\n", errout_str()); @@ -7718,13 +7718,13 @@ class TestOther : public TestFixture { " enum { FourInEnumOne = 4 };\n" " enum { FourInEnumTwo = 4 };\n" " static_assert(FourInEnumOne == FourInEnumTwo, \"\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int a, int b) {\n" " if (sizeof(a) == sizeof(a)) { }\n" " if (sizeof(a) == sizeof(b)) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:19]: (style) Same expression on both sides of '=='. [duplicateExpression]\n", errout_str()); check("float bar(int) __attribute__((pure));\n" @@ -7733,7 +7733,7 @@ class TestOther : public TestFixture { " if (bar(a) == bar(a)) { }\n" " if (unknown(a) == unknown(a)) { }\n" " if (foo(a) == foo(a)) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:16]: (style) Same expression on both sides of '=='. [duplicateExpression]\n", errout_str()); } @@ -7743,25 +7743,25 @@ class TestOther : public TestFixture { " if (!(dbl == dbl)) have_nan = 1;\n" " if (flt != flt) have_nan = 1;\n" " return have_nan;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("float f(float x) { return x-x; }"); // ticket #4485 (Inf) + check("float f(float x) { return x-x; }\n"); // ticket #4485 (Inf) ASSERT_EQUALS("", errout_str()); - check("float f(float x) { return (X double)x == (X double)x; }", dinit(CheckOptions, $.inconclusive = false)); + check("float f(float x) { return (X double)x == (X double)x; }\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("struct X { float f; };\n" - "float f(struct X x) { return x.f == x.f; }"); + "float f(struct X x) { return x.f == x.f; }\n"); ASSERT_EQUALS("", errout_str()); check("struct X { int i; };\n" - "int f(struct X x) { return x.i == x.i; }"); + "int f(struct X x) { return x.i == x.i; }\n"); ASSERT_EQUALS("[test.cpp:2:32]: (style) Same expression on both sides of '=='. [duplicateExpression]\n", errout_str()); // #5284 - when type is unknown, assume it's float - check("int f() { return x==x; }"); + check("int f() { return x==x; }\n"); ASSERT_EQUALS("", errout_str()); } @@ -7778,7 +7778,7 @@ class TestOther : public TestFixture { check("void foo() {\n" " if (x() || x()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {\n" @@ -7787,7 +7787,7 @@ class TestOther : public TestFixture { "};\n" "void A::foo() const {\n" " if (bar() && bar()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:15]: (style) Same expression on both sides of '&&'. [duplicateExpression]\n", errout_str()); check("struct A {\n" @@ -7797,7 +7797,7 @@ class TestOther : public TestFixture { "};\n" "void A::foo() {\n" " if (bar() && bar()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class B {\n" @@ -7811,55 +7811,55 @@ class TestOther : public TestFixture { " A a;\n" " if (b.bar(1) && b.bar(1)) {}\n" " if (a.bar(1) && a.bar(1)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:11:18]: (style) Same expression on both sides of '&&'. [duplicateExpression]\n", errout_str()); check("class D { void strcmp(); };\n" "void foo() {\n" " D d;\n" " if (d.strcmp() && d.strcmp()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " if ((mystrcmp(a, b) == 0) || (mystrcmp(a, b) == 0)) {}\n" - "}", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); + "}\n", dinit(CheckOptions, $.inconclusive = false, $.settings = &settings)); ASSERT_EQUALS("[test.cpp:2:31]: (style) Same expression on both sides of '||'. [duplicateExpression]\n", errout_str()); check("void GetValue() { return rand(); }\n" "void foo() {\n" " if ((GetValue() == 0) || (GetValue() == 0)) { dostuff(); }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void __attribute__((const)) GetValue() { return X; }\n" "void foo() {\n" " if ((GetValue() == 0) || (GetValue() == 0)) { dostuff(); }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:27]: (style) Same expression on both sides of '||'. [duplicateExpression]\n", errout_str()); check("void GetValue() __attribute__((const));\n" "void GetValue() { return X; }\n" "void foo() {\n" " if ((GetValue() == 0) || (GetValue() == 0)) { dostuff(); }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:27]: (style) Same expression on both sides of '||'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (str == \"(\" || str == \"(\") {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20]: (style) Same expression on both sides of '||'. [duplicateExpression]\n", errout_str()); check("void foo() {\n" " if (bar(a) && !strcmp(a, b) && bar(a) && !strcmp(a, b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5334 check("void f(C *src) {\n" " if (x(src) || x(src))\n" " a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(A *src) {\n" @@ -7870,12 +7870,12 @@ class TestOther : public TestFixture { // #5819 check("Vector func(Vector vec1) {\n" " return fabs(vec1 & vec1 & vec1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("Vector func(int vec1) {\n" " return fabs(vec1 & vec1 & vec1);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:22]: (style) Same expression on both sides of '&'. [duplicateExpression]\n" "[test.cpp:2:29]: (style) Same expression on both sides of '&'. [duplicateExpression]\n", @@ -7886,25 +7886,25 @@ class TestOther : public TestFixture { void duplicateExpression4() { check("void foo() {\n" " if (*a++ != b || *a++ != b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " if (*a-- != b || *a-- != b) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // assignment check("void f() {\n" " while (*(a+=2)==*(b+=2) && *(a+=2)==*(b+=2)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void duplicateExpression5() { // #3749 - macros with same values check("void f() {\n" " if ($a == $a) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkP("#define X 1\n" @@ -7926,7 +7926,7 @@ class TestOther : public TestFixture { void duplicateExpression6() { // #4639 check("float IsNan(float value) { return !(value == value); }\n" "double IsNan(double value) { return !(value == value); }\n" - "long double IsNan(long double value) { return !(value == value); }"); + "long double IsNan(long double value) { return !(value == value); }\n"); ASSERT_EQUALS("", errout_str()); } @@ -7934,36 +7934,36 @@ class TestOther : public TestFixture { check("void f() {\n" " const int i = sizeof(int);\n" " if ( i != sizeof (int)){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:25] -> [test.cpp:3:12]: (style) The comparison 'i != sizeof(int)' is always false because 'i' and 'sizeof(int)' represent the same value. [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " const int i = sizeof(int);\n" " if ( sizeof (int) != i){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:25] -> [test.cpp:3:23]: (style) The comparison 'sizeof(int) != i' is always false because 'sizeof(int)' and 'i' represent the same value. [knownConditionTrueFalse]\n", errout_str()); - check("void f(int a = 1) { if ( a != 1){}}"); + check("void f(int a = 1) { if ( a != 1){}}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int a = 1;\n" " if ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:3:12]: (style) The comparison 'a != 1' is always false. [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " int a = 1;\n" " int b = 1;\n" " if ( a != b){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:3:13] -> [test.cpp:4:12]: (style) The comparison 'a != b' is always false because 'a' and 'b' represent the same value. [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " int a = 1;\n" " int b = a;\n" " if ( a != b){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13] -> [test.cpp:4:12]: (style) The comparison 'a != b' is always false because 'a' and 'b' represent the same value. [knownConditionTrueFalse]\n", errout_str()); check("void use(int);\n" @@ -7972,7 +7972,7 @@ class TestOther : public TestFixture { " int b = 1;\n" " use(b);\n" " if ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13] -> [test.cpp:6:12]: (style) The comparison 'a != 1' is always false. [knownConditionTrueFalse]\n", errout_str()); check("void use(int);\n" @@ -7981,7 +7981,7 @@ class TestOther : public TestFixture { " use(a);\n" " a = 2;\n" " if ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void use(int);\n" @@ -7990,38 +7990,38 @@ class TestOther : public TestFixture { " use(a);\n" " a = 1;\n" " if ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const int a = 1;\n" "void f() {\n" " if ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:15] -> [test.cpp:3:12]: (style) The comparison 'a != 1' is always false. [knownConditionTrueFalse]\n", errout_str()); check("int a = 1;\n" " void f() {\n" " if ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " static const int a = 1;\n" " if ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:26] -> [test.cpp:3:12]: (style) The comparison 'a != 1' is always false. [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" " static int a = 1;\n" " if ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int a = 1;\n" " if ( a != 1){\n" " a++;\n" - " }}"); + " }}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:3:12]: (style) The comparison 'a != 1' is always false. [knownConditionTrueFalse]\n", errout_str()); check("void f(int b) {\n" @@ -8030,13 +8030,13 @@ class TestOther : public TestFixture { " if ( a != 1){}\n" " a++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(bool a, bool b) {\n" " const bool c = a;\n" " return a && b && c;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20] -> [test.cpp:3:19]: (style) Same expression 'a' found multiple times in chain of '&&' operators because 'a' and 'c' represent the same value. [knownConditionTrueFalse]\n", errout_str()); @@ -8044,13 +8044,13 @@ class TestOther : public TestFixture { check("void f(const bool b) {\n" " const bool b1 = !b;\n" " if(!b && b1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20] -> [test.cpp:3:10]: (style) Same expression on both sides of '&&' because '!b' and 'b1' represent the same value. [knownConditionTrueFalse]\n", errout_str()); // 7284 check("void f(void) {\n" " if (a || !!a) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (style) Same expression on both sides of '||' because 'a' and '!!a' represent the same value. [knownConditionTrueFalse]\n", errout_str()); // 8205 @@ -8061,7 +8061,7 @@ class TestOther : public TestFixture { " if (Diag==0) {}\n" " break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15] -> [test.cpp:5:16]: (style) The comparison 'Diag == 0' is always true. [knownConditionTrueFalse]\n", errout_str()); // #9744 @@ -8089,13 +8089,13 @@ class TestOther : public TestFixture { " int b = a;\n" " a = 2;\n" " if ( b != a){}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int * a, int i) { int b = a[i]; a[i] = 2; if ( b != a[i]){}}"); + check("void f(int * a, int i) { int b = a[i]; a[i] = 2; if ( b != a[i]){}}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int * a, int i) { int b = *a; *a = 2; if ( b != *a){}}"); + check("void f(int * a, int i) { int b = *a; *a = 2; if ( b != *a){}}\n"); ASSERT_EQUALS("", errout_str()); check("struct A { int f() const; };\n" @@ -8106,7 +8106,7 @@ class TestOther : public TestFixture { " x = g();\n" " if (x.f() == a) break;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int i);\n" @@ -8119,14 +8119,14 @@ class TestOther : public TestFixture { " const bool x = a.f(A::B);\n" " const bool y = a.f(A::C);\n" " if(!x && !y) return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " const bool x = a.f(A::B);\n" " const bool y = a.f(A::C);\n" " if (!x && !y) return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool * const b);\n" @@ -8135,17 +8135,17 @@ class TestOther : public TestFixture { " bool y = true;\n" " f(&x);\n" " if (!x && !y) return;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " const int a = {};\n" " if(a == 1) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("volatile const int var = 42;\n" - "void f() { if(var == 42) {} }"); + "void f() { if(var == 42) {} }\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -8154,7 +8154,7 @@ class TestOther : public TestFixture { " c.a = &a;\n" " g(&c);\n" " if (a == 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -8164,7 +8164,7 @@ class TestOther : public TestFixture { " uint16_t x = 1000;\n" " uint8_t y = x;\n" " if (x != y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -8175,7 +8175,7 @@ class TestOther : public TestFixture { " const int b = a-1;\n" " const int c = a+1;\n" " return c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -8196,7 +8196,7 @@ class TestOther : public TestFixture { " setZoom(m_zoom + 1);\n" " double scale_ratio = getScale() / old_scale;\n" // <- FP " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -8205,14 +8205,14 @@ class TestOther : public TestFixture { "{\n" " int var = buffer[index - 1];\n" " return buffer[index - 1] - var;\n" // << - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:25] -> [test.cpp:4:34]: (style) Same expression on both sides of '-' because 'buffer[index-1]' and 'var' represent the same value. [duplicateExpression]\n", errout_str()); } void duplicateExpression13() { //#7899 check("void f() {\n" " if (sizeof(long) == sizeof(long long)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -8345,7 +8345,7 @@ class TestOther : public TestFixture { void duplicateExpression20() { check("enum { N = 1 };\n" // #14202 - "int f() { return N - 1; }"); + "int f() { return N - 1; }\n"); ASSERT_EQUALS("", errout_str()); } @@ -8411,23 +8411,23 @@ class TestOther : public TestFixture { check("void f() {\n" " int a = 1;\n" " while ( a != 1){}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:3:15]: (style) The comparison 'a != 1' is always false. [knownConditionTrueFalse]\n", errout_str()); - check("void f() { int a = 1; while ( a != 1){ a++; }}"); + check("void f() { int a = 1; while ( a != 1){ a++; }}\n"); ASSERT_EQUALS("", errout_str()); - check("void f() { int a = 1; for ( int i=0; i < 3 && a != 1; i++){ a++; }}"); + check("void f() { int a = 1; for ( int i=0; i < 3 && a != 1; i++){ a++; }}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int b) { int a = 1; while (b) { if ( a != 1){} b++; } a++; }"); + check("void f(int b) { int a = 1; while (b) { if ( a != 1){} b++; } a++; }\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " for(int i = 0; i < 10;) {\n" " if( i != 0 ) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:17] -> [test.cpp:3:15]: (style) The comparison 'i != 0' is always false. [knownConditionTrueFalse]\n", errout_str()); check("void f() {\n" @@ -8435,7 +8435,7 @@ class TestOther : public TestFixture { " if( i != 0 ) {}\n" " i++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -8443,14 +8443,14 @@ class TestOther : public TestFixture { " if( i != 0 ) { i++; }\n" " i++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " for(int i = 0; i < 10;) {\n" " if( i != 0 ) { i++; }\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -8459,7 +8459,7 @@ class TestOther : public TestFixture { " if( i != 0 ) {}\n" " i++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int b) {\n" @@ -8468,7 +8468,7 @@ class TestOther : public TestFixture { " if ( a != 1){}\n" " b++;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17] -> [test.cpp:4:16]: (style) The comparison 'a != 1' is always false. [knownConditionTrueFalse]\n", errout_str()); check("struct T {\n" // #11083 @@ -8511,35 +8511,35 @@ class TestOther : public TestFixture { void duplicateExpressionTernary() { // #6391 check("void f() {\n" " return A ? x : x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:18]: (style) Same expression in both branches of ternary operator. [duplicateExpressionTernary]\n", errout_str()); check("int f(bool b, int a) {\n" " const int c = a;\n" " return b ? a : c;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:19] -> [test.cpp:3:18]: (style) Same expression in both branches of ternary operator. [duplicateExpressionTernary]\n", errout_str()); check("void f() {\n" " return A ? x : z;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(unsigned char c) {\n" " x = y ? (signed char)c : (unsigned char)c;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("std::string stringMerge(std::string const& x, std::string const& y) {\n" // #7938 " return ((x > y) ? (y + x) : (x + y));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6426 { const char code[] = "void foo(bool flag) {\n" " bar( (flag) ? ~0u : ~0ul);\n" - "}"; + "}\n"; /*const*/ Settings settings = settings1; settings.platform.sizeof_int = 4; settings.platform.int_bit = 32; @@ -8559,31 +8559,31 @@ class TestOther : public TestFixture { void duplicateValueTernary() { check("void f() {\n" " if( a ? (b ? false:false): false ) ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:23]: (style) Same expression in both branches of ternary operator. [duplicateExpressionTernary]\n", errout_str()); - check("int f1(int a) {return (a == 1) ? (int)1 : 1; }"); + check("int f1(int a) {return (a == 1) ? (int)1 : 1; }\n"); ASSERT_EQUALS("[test.cpp:1:41]: (style) Same value in both branches of ternary operator. [duplicateValueTernary]\n", errout_str()); - check("int f2(int a) {return (a == 1) ? (int)1 : (int)1; }"); + check("int f2(int a) {return (a == 1) ? (int)1 : (int)1; }\n"); ASSERT_EQUALS("[test.cpp:1:41]: (style) Same expression in both branches of ternary operator. [duplicateExpressionTernary]\n", errout_str()); - check("int f3(int a) {return (a == 1) ? 1 : (int)1; }"); + check("int f3(int a) {return (a == 1) ? 1 : (int)1; }\n"); ASSERT_EQUALS("[test.cpp:1:36]: (style) Same value in both branches of ternary operator. [duplicateValueTernary]\n", errout_str()); - check("int f4(int a) {return (a == 1) ? 1 : 1; }"); + check("int f4(int a) {return (a == 1) ? 1 : 1; }\n"); ASSERT_EQUALS("[test.cpp:1:36]: (style) Same expression in both branches of ternary operator. [duplicateExpressionTernary]\n", errout_str()); - check("int f5(int a) {return (a == (int)1) ? (int)1 : 1; }"); + check("int f5(int a) {return (a == (int)1) ? (int)1 : 1; }\n"); ASSERT_EQUALS("[test.cpp:1:46]: (style) Same value in both branches of ternary operator. [duplicateValueTernary]\n", errout_str()); - check("int f6(int a) {return (a == (int)1) ? (int)1 : (int)1; }"); + check("int f6(int a) {return (a == (int)1) ? (int)1 : (int)1; }\n"); ASSERT_EQUALS("[test.cpp:1:46]: (style) Same expression in both branches of ternary operator. [duplicateExpressionTernary]\n", errout_str()); - check("int f7(int a) {return (a == (int)1) ? 1 : (int)1; }"); + check("int f7(int a) {return (a == (int)1) ? 1 : (int)1; }\n"); ASSERT_EQUALS("[test.cpp:1:41]: (style) Same value in both branches of ternary operator. [duplicateValueTernary]\n", errout_str()); - check("int f8(int a) {return (a == (int)1) ? 1 : 1; }"); + check("int f8(int a) {return (a == (int)1) ? 1 : 1; }\n"); ASSERT_EQUALS("[test.cpp:1:41]: (style) Same expression in both branches of ternary operator. [duplicateExpressionTernary]\n", errout_str()); check("struct Foo {\n" @@ -8637,10 +8637,10 @@ class TestOther : public TestFixture { } void duplicateValueTernarySizeof() { // #13773 - check("int f() { return x ? sizeof(uint32_t) : sizeof(unsigned int); }"); + check("int f() { return x ? sizeof(uint32_t) : sizeof(unsigned int); }\n"); ASSERT_EQUALS("", errout_str()); - check("int f() { return x ? sizeof(uint32_t) : sizeof(uint32_t); }"); + check("int f() { return x ? sizeof(uint32_t) : sizeof(uint32_t); }\n"); ASSERT_EQUALS("[test.cpp:1:39]: (style) Same expression in both branches of ternary operator. [duplicateExpressionTernary]\n", errout_str()); } @@ -8649,7 +8649,7 @@ class TestOther : public TestFixture { " if (I >= 0 && I < 3) {}\n" "}\n" "\n" - "static auto a = f<0>();"); + "static auto a = f<0>();\n"); ASSERT_EQUALS("", errout_str()); check("template\n" // #7754 @@ -8735,35 +8735,35 @@ class TestOther : public TestFixture { } void oppositeExpression() { - check("void f(bool a) { if(a && !a) {} }"); + check("void f(bool a) { if(a && !a) {} }\n"); ASSERT_EQUALS("[test.cpp:1:23]: (style) Opposite expression on both sides of '&&'. [oppositeExpression]\n", errout_str()); - check("void f(bool a) { if(a != !a) {} }"); + check("void f(bool a) { if(a != !a) {} }\n"); ASSERT_EQUALS("[test.cpp:1:23]: (style) Opposite expression on both sides of '!='. [oppositeExpression]\n", errout_str()); - check("void f(bool a) { if( a == !(a) ) {}}"); + check("void f(bool a) { if( a == !(a) ) {}}\n"); ASSERT_EQUALS("[test.cpp:1:24]: (style) Opposite expression on both sides of '=='. [oppositeExpression]\n", errout_str()); - check("void f(bool a) { if( a != !(a) ) {}}"); + check("void f(bool a) { if( a != !(a) ) {}}\n"); ASSERT_EQUALS("[test.cpp:1:24]: (style) Opposite expression on both sides of '!='. [oppositeExpression]\n", errout_str()); - check("void f(bool a) { if( !(a) == a ) {}}"); + check("void f(bool a) { if( !(a) == a ) {}}\n"); ASSERT_EQUALS("[test.cpp:1:27]: (style) Opposite expression on both sides of '=='. [oppositeExpression]\n", errout_str()); - check("void f(bool a) { if( !(a) != a ) {}}"); + check("void f(bool a) { if( !(a) != a ) {}}\n"); ASSERT_EQUALS("[test.cpp:1:27]: (style) Opposite expression on both sides of '!='. [oppositeExpression]\n", errout_str()); - check("void f(bool a) { if( !(!a) == !(a) ) {}}"); + check("void f(bool a) { if( !(!a) == !(a) ) {}}\n"); ASSERT_EQUALS("[test.cpp:1:28]: (style) Opposite expression on both sides of '=='. [oppositeExpression]\n", errout_str()); - check("void f(bool a) { if( !(!a) != !(a) ) {}}"); + check("void f(bool a) { if( !(!a) != !(a) ) {}}\n"); ASSERT_EQUALS("[test.cpp:1:28]: (style) Opposite expression on both sides of '!='. [oppositeExpression]\n", errout_str()); check("void f1(bool a) {\n" " const bool b = a;\n" " if( a == !(b) ) {}\n" " if( b == !(a) ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20] -> [test.cpp:3:11]: (style) Opposite expression on both sides of '=='. [oppositeExpression]\n" "[test.cpp:2:20] -> [test.cpp:4:11]: (style) Opposite expression on both sides of '=='. [oppositeExpression]\n", errout_str()); @@ -8771,26 +8771,26 @@ class TestOther : public TestFixture { " const bool b = *a;\n" " if( *a == !(b) ) {}\n" " if( b == !(*a) ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:20] -> [test.cpp:3:12]: (style) Opposite expression on both sides of '=='. [oppositeExpression]\n" "[test.cpp:2:20] -> [test.cpp:4:11]: (style) Opposite expression on both sides of '=='. [oppositeExpression]\n", errout_str()); - check("void f(bool a) { a = !a; }"); + check("void f(bool a) { a = !a; }\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int a) { if( a < -a ) {}}"); + check("void f(int a) { if( a < -a ) {}}\n"); ASSERT_EQUALS("[test.cpp:1:23]: (style) Opposite expression on both sides of '<'. [oppositeExpression]\n", errout_str()); - check("void f(int a) { a -= -a; }"); + check("void f(int a) { a -= -a; }\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int a) { a = a / (-a); }"); + check("void f(int a) { a = a / (-a); }\n"); ASSERT_EQUALS("", errout_str()); - check("bool f(int i){ return !((i - 1) & i); }"); + check("bool f(int i){ return !((i - 1) & i); }\n"); ASSERT_EQUALS("", errout_str()); - check("bool f(unsigned i){ return (x > 0) && (x & (x-1)) == 0; }"); + check("bool f(unsigned i){ return (x > 0) && (x & (x-1)) == 0; }\n"); ASSERT_EQUALS("", errout_str()); check("void A::f(bool a, bool c)\n" @@ -8798,27 +8798,27 @@ class TestOther : public TestFixture { " const bool b = a;\n" " if(c) { a = false; }\n" " if(b && !a) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(bool c) {\n" " const bool b = a;\n" " if(c) { a = false; }\n" " if(b && !a) { }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " bool x = a;\n" " dostuff();\n" " if (x && a) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " const bool b = g();\n" " if (!b && g()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const bool *a) {\n" @@ -8861,7 +8861,7 @@ class TestOther : public TestFixture { "void test() {\n" " int i = f();\n" " int j = f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct Foo { int f() const; int g() const; };\n" @@ -8869,7 +8869,7 @@ class TestOther : public TestFixture { " Foo f = Foo{};\n" " int i = f.f();\n" " int j = f.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct Foo { int f() const; int g() const; };\n" @@ -8878,7 +8878,7 @@ class TestOther : public TestFixture { " Foo f2 = Foo{};\n" " int i = f.f();\n" " int j = f.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:9] -> [test.cpp:5:9]: (style) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("int f() __attribute__((pure));\n" @@ -8886,7 +8886,7 @@ class TestOther : public TestFixture { "void test() {\n" " int i = 1 + f();\n" " int j = 1 + f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("int f() __attribute__((pure));\n" @@ -8894,7 +8894,7 @@ class TestOther : public TestFixture { "void test() {\n" " int i = f() + 1;\n" " int j = 1 + f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() __attribute__((pure));\n" @@ -8903,7 +8903,7 @@ class TestOther : public TestFixture { " int x = f();\n" " int i = x + 1;\n" " int j = f() + 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f() __attribute__((pure));\n" @@ -8911,7 +8911,7 @@ class TestOther : public TestFixture { "void test() {\n" " int i = f() + f();\n" " int j = f() + f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("int f(int) __attribute__((pure));\n" @@ -8919,7 +8919,7 @@ class TestOther : public TestFixture { "void test() {\n" " int i = f(0);\n" " int j = f(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("int f(int) __attribute__((pure));\n" @@ -8928,39 +8928,39 @@ class TestOther : public TestFixture { " const int x = 0;\n" " int i = f(0);\n" " int j = f(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test(const int * p, const int * q) {\n" " int i = *p;\n" " int j = *p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:9]: (style) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct A { int x; int y; };" "void test(A a) {\n" " int i = a.x;\n" " int j = a.x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:9]: (style) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("void test() {\n" " int i = 0;\n" " int j = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test() {\n" " int i = -1;\n" " int j = -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f(int);\n" "void test() {\n" " int i = f(0);\n" " int j = f(1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int f();\n" @@ -8968,21 +8968,21 @@ class TestOther : public TestFixture { "void test() {\n" " int i = f() || f();\n" " int j = f() && f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Foo {};\n" "void test() {\n" " Foo i = Foo();\n" " Foo j = Foo();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Foo {};\n" "void test() {\n" " Foo i = Foo{};\n" " Foo j = Foo{};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct Foo { int f() const; float g() const; };\n" @@ -8990,7 +8990,7 @@ class TestOther : public TestFixture { " Foo f = Foo{};\n" " int i = f.f();\n" " int j = f.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct Foo { int f(); int g(); };\n" @@ -8998,43 +8998,43 @@ class TestOther : public TestFixture { " Foo f = Foo{};\n" " int i = f.f();\n" " int j = f.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test() {\n" " int i = f();\n" " int j = f();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test(int x) {\n" " int i = ++x;\n" " int j = ++x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test(int x) {\n" " int i = x++;\n" " int j = x++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test(int x) {\n" " int i = --x;\n" " int j = --x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test(int x) {\n" " int i = x--;\n" " int j = x--;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void test(int x) {\n" " int i = x + 1;\n" " int j = 1 + x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -9043,7 +9043,7 @@ class TestOther : public TestFixture { "void foo(SW* x) {\n" " int start = x->first;\n" " int end = x->first;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'start' and 'end'. [duplicateAssignExpression]\n" "[test.cpp:2:14]: (style) Parameter 'x' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9052,7 +9052,7 @@ class TestOther : public TestFixture { "void foo(SW* x, int i, int j) {\n" " int start = x->first;\n" " int end = x->first;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'start' and 'end'. [duplicateAssignExpression]\n" "[test.cpp:2:14]: (style) Parameter 'x' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9062,13 +9062,13 @@ class TestOther : public TestFixture { " Foo f = Foo{};\n" " int i = f.f();\n" " int j = f.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("void test(const int * p) {\n" " int i = *p;\n" " int j = *p;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct Foo { int f() const; int g(int) const; };\n" @@ -9076,7 +9076,7 @@ class TestOther : public TestFixture { " Foo f = Foo{};\n" " int i = f.f();\n" " int j = f.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct Foo { int f() const; };\n" @@ -9084,7 +9084,7 @@ class TestOther : public TestFixture { " Foo f = Foo{};\n" " int i = f.f();\n" " int j = f.f();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); } @@ -9096,7 +9096,7 @@ class TestOther : public TestFixture { " int j = a.x;\n" " use(i);\n" " i = j;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct A { int x; int y; };" @@ -9106,7 +9106,7 @@ class TestOther : public TestFixture { " int j = a.x;\n" " use(j);\n" " j = i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); check("struct A { int x; int y; };" @@ -9116,7 +9116,7 @@ class TestOther : public TestFixture { " int j = a.x;\n" " use(j);\n" " if (i == j) {}\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); @@ -9128,7 +9128,7 @@ class TestOther : public TestFixture { " int j = a.x;\n" " use(j);\n" " if (i == a.x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); @@ -9140,7 +9140,7 @@ class TestOther : public TestFixture { " int j = a.x;\n" " use(i);\n" " if (j == a.x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:4:9] -> [test.cpp:3:9]: (style, inconclusive) Same expression used in consecutive assignments of 'i' and 'j'. [duplicateAssignExpression]\n", errout_str()); @@ -9171,7 +9171,7 @@ class TestOther : public TestFixture { " }\n" " previous = current;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:16:7] -> [test.cpp:15:7]: (style, inconclusive) Same expression used in consecutive assignments of 'current' and 'previous'. [duplicateAssignExpression]\n", errout_str()); } @@ -9187,21 +9187,21 @@ class TestOther : public TestFixture { " int b = x.f();\n" " (void)a;\n" " (void)b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:13] -> [test.cpp:7:13]: (style, inconclusive) Same expression used in consecutive assignments of 'a' and 'b'. [duplicateAssignExpression]\n", errout_str()); // Issue #8712 check("void f() {\n" " unsigned char d;\n" " d = d % 5;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("template \n" "T f() {\n" " T x = T();\n" "}\n" - "int &a = f();"); + "int &a = f();\n"); ASSERT_EQUALS("", errout_str()); // Issue #8713 @@ -9213,7 +9213,7 @@ class TestOther : public TestFixture { " uint32_t a = 42;\n" " uint32_t b = uint32_t(A ::B / 1024);\n" " int32_t c = int32_t(a / b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Issue #8709 @@ -9222,7 +9222,7 @@ class TestOther : public TestFixture { " switch (d) { case b:; }\n" " double e(b);\n" " if(e <= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10718 @@ -9243,7 +9243,7 @@ class TestOther : public TestFixture { " int val = 0;\n" " if (val < 0) continue;\n" " if ((val > 0)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:3:11]: (style) The comparison 'val < 0' is always false. [knownConditionTrueFalse]\n" "[test.cpp:2:13] -> [test.cpp:4:12]: (style) The comparison 'val > 0' is always false. [knownConditionTrueFalse]\n", errout_str()); @@ -9274,7 +9274,7 @@ class TestOther : public TestFixture { " if (val < 0) {\n" " if ((val > 0)) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:3:11]: (style) The comparison 'val < 0' is always false. [knownConditionTrueFalse]\n" "[test.cpp:2:13] -> [test.cpp:4:14]: (style) The comparison 'val > 0' is always false. [knownConditionTrueFalse]\n", errout_str()); @@ -9283,7 +9283,7 @@ class TestOther : public TestFixture { " if (val < 0) {\n" " if ((val < 0)) {}\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:3:11]: (style) The comparison 'val < 0' is always false. [knownConditionTrueFalse]\n" "[test.cpp:2:13] -> [test.cpp:4:14]: (style) The comparison 'val < 0' is always false. [knownConditionTrueFalse]\n", errout_str()); @@ -9292,25 +9292,25 @@ class TestOther : public TestFixture { " int foo = 0;\n" " if (activate) {}\n" " else if (foo) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void checkSignOfUnsignedVariable() { check("void foo() {\n" " for(unsigned char i = 10; i >= 0; i--) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:31]: (style) Unsigned expression 'i' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(bool b) {\n" " for(unsigned int i = 10; b || i >= 0; i--) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:35]: (style) Unsigned expression 'i' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); { const char code[] = "void foo(unsigned int x) {\n" " if (x < 0) {}\n" - "}"; + "}\n"; check(code, dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:2:9]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check(code, dinit(CheckOptions, $.inconclusive = false, $.verbose = true)); @@ -9319,19 +9319,19 @@ class TestOther : public TestFixture { check("void foo(unsigned int x) {\n" " if (x < 0u) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(int x) {\n" " if (x < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); { const char code[] = "void foo(unsigned x) {\n" " int y = 0;\n" " if (x < y) {}\n" - "}"; + "}\n"; check(code, dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:9]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check(code, dinit(CheckOptions, $.inconclusive = false, $.verbose = true)); @@ -9342,149 +9342,149 @@ class TestOther : public TestFixture { " if (b)\n" " y = 1;\n" " if (x < y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x) {\n" " if (0 > x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(unsigned int x) {\n" " if (0UL > x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(int x) {\n" " if (0 > x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x) {\n" " if (x >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Unsigned expression 'x' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(unsigned int x, unsigned y) {\n" " if (x - y >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Unsigned expression 'x-y' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(unsigned int x) {\n" " if (x >= 0ull) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Unsigned expression 'x' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(int x) {\n" " if (x >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x) {\n" " if (0 <= x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Unsigned expression 'x' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(unsigned int x) {\n" " if (0ll <= x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (style) Unsigned expression 'x' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(int x) {\n" " if (0 <= x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (x < 0 && y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (x < 0 && y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (0 > x && y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (0 > x && y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (x >= 0 && y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Unsigned expression 'x' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (x >= 0 && y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (y && x < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (y && x < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (y && 0 > x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (y && 0 > x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (y && x >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:14]: (style) Unsigned expression 'x' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (y && x >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (x < 0 || y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (x < 0 || y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (0 > x || y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (0 > x || y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(unsigned int x, bool y) {\n" " if (x >= 0 || y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) Unsigned expression 'x' can't be negative so it is unnecessary to test it. [unsignedPositive]\n", errout_str()); check("void foo(int x, bool y) {\n" " if (x >= 0 || y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #3233 - FP when template is used (template parameter is numeric constant) @@ -9492,7 +9492,7 @@ class TestOther : public TestFixture { const char code[] = "template void foo(unsigned int x) {\n" " if (x <= n);\n" "}\n" - "foo<0>();"; + "foo<0>();\n"; check(code, dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check(code); @@ -9502,7 +9502,7 @@ class TestOther : public TestFixture { { check("template void foo(unsigned int x) {\n" "if (x <= 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:7]: (style) Checking if unsigned expression 'x' is less than zero. [unsignedLessThanZero]\n", errout_str()); } @@ -9513,7 +9513,7 @@ class TestOther : public TestFixture { " {\n" " value = 0u;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:13]: (style) Checking if unsigned expression 'value' is less than zero. [unsignedLessThanZero]\n", errout_str()); // #9040 @@ -9530,7 +9530,7 @@ class TestOther : public TestFixture { " const uint32_t x = 0;\n" " constexpr const auto y = 0xFFFFU;\n" " if (y < x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (style) Checking if unsigned expression 'y' is less than zero. [unsignedLessThanZero]\n", errout_str()); // #12387 @@ -9542,14 +9542,14 @@ class TestOther : public TestFixture { "}\n" "void g() {\n" " f(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #13734 check("void f() {\n" " uint8_t a[N + 1];\n" " for (unsigned p = 0; p < (sizeof(a) / sizeof((a)[0])); ++p) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const unsigned char u) {\n" @@ -9561,7 +9561,7 @@ class TestOther : public TestFixture { " if (0 > u) {}\n" " if (0 <= u) {}\n" " if (0 >= u) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (style) Checking if unsigned expression 'u' is less than zero. [unsignedLessThanZero]\n" "[test.cpp:4:11]: (style) Unsigned expression 'u' can't be negative so it is unnecessary to test it. [unsignedPositive]\n" "[test.cpp:5:11]: (style) Checking if unsigned expression 'u' is less than zero. [unsignedLessThanZero]\n" @@ -9574,14 +9574,14 @@ class TestOther : public TestFixture { void checkSignOfPointer() { check("void foo(const int* x) {\n" " if (x >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) A pointer can not be negative so it is either pointless or an error to check if it is not. [pointerPositive]\n", errout_str()); { const char code[] = "void foo(const int* x) {\n" " int y = 0;\n" " if (x >= y) {}\n" - "}"; + "}\n"; check(code, dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:9]: (style) A pointer can not be negative so it is either pointless or an error to check if it is not. [pointerPositive]\n", errout_str()); check(code, dinit(CheckOptions, $.inconclusive = false, $.verbose = true)); @@ -9589,19 +9589,19 @@ class TestOther : public TestFixture { } check("void foo(const int* x) {\n" " if (*x >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const int* x) {\n" " if (x < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) A pointer can not be negative so it is either pointless or an error to check if it is. [pointerLessThanZero]\n", errout_str()); { const char code[] = "void foo(const int* x) {\n" " unsigned y = 0u;\n" " if (x < y) {}\n" - "}"; + "}\n"; check(code, dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:3:9]: (style) A pointer can not be negative so it is either pointless or an error to check if it is. [pointerLessThanZero]\n", errout_str()); @@ -9611,32 +9611,32 @@ class TestOther : public TestFixture { check("void foo(const int* x) {\n" " if (*x < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const int* x, const int* y) {\n" " if (x - y < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const int* x, const int* y) {\n" " if (x - y <= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const int* x, const int* y) {\n" " if (x - y > 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const int* x, const int* y) {\n" " if (x - y >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const Bar* x) {\n" " if (0 <= x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) A pointer can not be negative so it is either pointless or an error to check if it is not. [pointerPositive]\n", errout_str()); check("struct S {\n" @@ -9644,7 +9644,7 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first) {\n" " if (first.ptr >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:17]: (style) A pointer can not be negative so it is either pointless or an error to check if it is not. [pointerPositive]\n" "[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9654,7 +9654,7 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first, S* second) {\n" " if((first.ptr - second.ptr) >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:4:23]: (style) Parameter 'second' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9664,7 +9664,7 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first) {\n" " if((first.ptr) >= 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:18]: (style) A pointer can not be negative so it is either pointless or an error to check if it is not. [pointerPositive]\n" "[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9674,7 +9674,7 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first, S* second) {\n" " if(0 <= first.ptr - second.ptr) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:4:23]: (style) Parameter 'second' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9684,7 +9684,7 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first, S* second) {\n" " if(0 <= (first.ptr - second.ptr)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:4:23]: (style) Parameter 'second' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9694,7 +9694,7 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first, S* second) {\n" " if(first.ptr - second.ptr < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:4:23]: (style) Parameter 'second' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9704,7 +9704,7 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first, S* second) {\n" " if((first.ptr - second.ptr) < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:4:23]: (style) Parameter 'second' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9714,7 +9714,7 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first, S* second) {\n" " if(0 > first.ptr - second.ptr) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:4:23]: (style) Parameter 'second' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9724,69 +9724,69 @@ class TestOther : public TestFixture { "};\n" "void foo(S* first, S* second) {\n" " if(0 > (first.ptr - second.ptr)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (style) Parameter 'first' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:4:23]: (style) Parameter 'second' can be declared as pointer to const [constParameterPointer]\n", errout_str()); check("void foo(const int* x) {\n" " if (0 <= x[0]) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(Bar* x) {\n" " if (0 <= x.y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'x' can be declared as pointer to const [constParameterPointer]\n", errout_str()); check("void foo(Bar* x) {\n" " if (0 <= x->y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'x' can be declared as pointer to const [constParameterPointer]\n", errout_str()); check("void foo(Bar* x, Bar* y) {\n" " if (0 <= x->y - y->y ) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'x' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:1:23]: (style) Parameter 'y' can be declared as pointer to const [constParameterPointer]\n", errout_str()); check("void foo(const Bar* x) {\n" " if (0 > x) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:9]: (style) A pointer can not be negative so it is either pointless or an error to check if it is. [pointerLessThanZero]\n", errout_str()); check("void foo(const int* x) {\n" " if (0 > x[0]) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(Bar* x) {\n" " if (0 > x.y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'x' can be declared as pointer to const [constParameterPointer]\n", errout_str()); check("void foo(Bar* x) {\n" " if (0 > x->y) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:15]: (style) Parameter 'x' can be declared as pointer to const [constParameterPointer]\n", errout_str()); check("void foo() {\n" " int (*t)(void *a, void *b);\n" " if (t(a, b) < 0) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " int (*t)(void *a, void *b);\n" " if (0 > t(a, b)) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct object_info { int *typep; };\n" "void packed_object_info(struct object_info *oi) {\n" " if (oi->typep < 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style) A pointer can not be negative so it is either pointless or an error to check if it is. [pointerLessThanZero]\n" "[test.cpp:2:45]: (style) Parameter 'oi' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9794,7 +9794,7 @@ class TestOther : public TestFixture { check("struct object_info { int typep[10]; };\n" "void packed_object_info(struct object_info *oi) {\n" " if (oi->typep < 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style) A pointer can not be negative so it is either pointless or an error to check if it is. [pointerLessThanZero]\n" "[test.cpp:2:45]: (style) Parameter 'oi' can be declared as pointer to const [constParameterPointer]\n", errout_str()); @@ -9802,28 +9802,28 @@ class TestOther : public TestFixture { check("struct object_info { int *typep; };\n" "void packed_object_info(struct object_info *oi) {\n" " if (*oi->typep < 0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:45]: (style) Parameter 'oi' can be declared as pointer to const [constParameterPointer]\n", errout_str()); } void checkSuspiciousSemicolon1() { check("void foo() {\n" " for(int i = 0; i < 10; ++i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Empty block check("void foo() {\n" " for(int i = 0; i < 10; ++i); {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (warning) Suspicious use of ; at the end of 'for' statement. [suspiciousSemicolon]\n", errout_str()); check("void foo() {\n" " while (!quit); {\n" " do_something();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (warning) Suspicious use of ; at the end of 'while' statement. [suspiciousSemicolon]\n", errout_str()); } @@ -9832,21 +9832,21 @@ class TestOther : public TestFixture { " if (i == 1); {\n" " do_something();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:3]: (warning) Suspicious use of ; at the end of 'if' statement. [suspiciousSemicolon]\n", errout_str()); // Seen this in the wild check("void foo() {\n" " if (Match());\n" " do_something();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " if (Match());\n" " else\n" " do_something();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -9855,7 +9855,7 @@ class TestOther : public TestFixture { " {\n" " do_something();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -9864,7 +9864,7 @@ class TestOther : public TestFixture { " {\n" " do_something();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -9873,20 +9873,20 @@ class TestOther : public TestFixture { "void foo() {\n" " if (x == 123);\n" " REQUIRE(y=z);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void checkSuspiciousComparison() { checkP("void f(int a, int b) {\n" " a > b;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (warning, inconclusive) Found suspicious operator '>', result is not used. [constStatement]\n", errout_str()); checkP("void f() {\n" // #10607 " for (auto p : m)\n" " std::vector> k;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -9894,25 +9894,25 @@ class TestOther : public TestFixture { check("void foo(char *p) {\n" " char *a; a = malloc(1024);\n" " free(a + 10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error) Mismatching address is freed. The address you get from malloc() must be freed without offset. [invalidFree]\n", errout_str()); check("void foo(char *p) {\n" " char *a; a = malloc(1024);\n" " free(a - 10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error) Mismatching address is freed. The address you get from malloc() must be freed without offset. [invalidFree]\n", errout_str()); check("void foo(char *p) {\n" " char *a; a = malloc(1024);\n" " free(10 + a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:3]: (error) Mismatching address is freed. The address you get from malloc() must be freed without offset. [invalidFree]\n", errout_str()); check("void foo(char *p) {\n" " char *a; a = new char[1024];\n" " delete[] (a + 10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:16]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:3:3]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset. [invalidFree]\n", errout_str()); @@ -9920,7 +9920,7 @@ class TestOther : public TestFixture { check("void foo(char *p) {\n" " char *a; a = new char;\n" " delete a + 10;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:16]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:3:3]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset. [invalidFree]\n", errout_str()); @@ -9929,7 +9929,7 @@ class TestOther : public TestFixture { " char *a; a = new char;\n" " bar(a);\n" " delete a + 10;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char *p) {\n" @@ -9938,7 +9938,7 @@ class TestOther : public TestFixture { " bar(a);\n" " delete a + 10;\n" " delete b + 10;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:3]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset. [invalidFree]\n", errout_str()); check("void foo(char *p) {\n" @@ -9947,14 +9947,14 @@ class TestOther : public TestFixture { " bar(a, b);\n" " delete a + 10;\n" " delete b + 10;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(char *p) {\n" " char *a; a = new char;\n" " bar()\n" " delete a + 10;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:16]: (style) Parameter 'p' can be declared as pointer to const [constParameterPointer]\n" "[test.cpp:4:3]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset. [invalidFree]\n", errout_str()); @@ -9963,7 +9963,7 @@ class TestOther : public TestFixture { " char *ptr; ptr = malloc(42);\n" " ptr += xx;\n" " free(ptr + 1 - xx);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:3]: (error) Mismatching address is freed. The address you get from malloc() must be freed without offset. [invalidFree]\n", errout_str()); check("void foo(size_t xx) {\n" @@ -9971,7 +9971,7 @@ class TestOther : public TestFixture { " std::cout << ptr;\n" " ptr = otherPtr;\n" " free(otherPtr - xx - 1);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:9]: (style) Variable 'ptr' can be declared as pointer to const [constVariablePointer]\n", errout_str()); @@ -9981,7 +9981,7 @@ class TestOther : public TestFixture { check("const std::string& getA(){static std::string a;return a;}\n" "void foo() {\n" " const std::string a = getA();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:23]: (performance, inconclusive) Use const reference for 'a' to avoid unnecessary data copying. [redundantCopyLocalConst]\n", errout_str()); check("class A { public: A() {} char x[100]; };\n" @@ -9990,7 +9990,7 @@ class TestOther : public TestFixture { "{\n" " const A a = getA();\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13]: (performance, inconclusive) Use const reference for 'a' to avoid unnecessary data copying. [redundantCopyLocalConst]\n", errout_str()); check("const int& getA(){static int a;return a;}\n" @@ -9998,7 +9998,7 @@ class TestOther : public TestFixture { "{\n" " const int a = getA();\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("const int& getA(){static int a;return a;}\n" @@ -10007,7 +10007,7 @@ class TestOther : public TestFixture { " int getA = 0;\n" " const int a = getA + 3;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:1:12] -> [test.cpp:4:9]: (style) Local variable 'getA' shadows outer function [shadowFunction]\n", errout_str()); check("class A { public: A() {} char x[100]; };\n" @@ -10016,7 +10016,7 @@ class TestOther : public TestFixture { "{\n" " const A a(getA());\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13]: (performance, inconclusive) Use const reference for 'a' to avoid unnecessary data copying. [redundantCopyLocalConst]\n", errout_str()); check("const int& getA(){static int a;return a;}\n" @@ -10024,7 +10024,7 @@ class TestOther : public TestFixture { "{\n" " const int a(getA());\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class A{\n" @@ -10036,7 +10036,7 @@ class TestOther : public TestFixture { "{\n" " const A a = getA() + 1;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class A{\n" @@ -10048,7 +10048,7 @@ class TestOther : public TestFixture { "{\n" " const A a(getA()+1);\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5190 - FP when creating object with constructor that takes a reference @@ -10057,7 +10057,7 @@ class TestOther : public TestFixture { "const A &getA();\n" "void f() {\n" " const B b(getA());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class A {};\n" @@ -10065,7 +10065,7 @@ class TestOther : public TestFixture { "const A& getA();\n" "void f() {\n" " const B b{ getA() };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5618 @@ -10078,7 +10078,7 @@ class TestOther : public TestFixture { " const std::string temp = tok->str();\n" " tok->str(tok->strAt(2));\n" " }\n" - "}"; + "}\n"; check(code5618); ASSERT_EQUALS("", errout_str()); check(code5618, dinit(CheckOptions, $.inconclusive = false)); @@ -10089,7 +10089,7 @@ class TestOther : public TestFixture { "X f(const X &in) {\n" " const X s = f(in);\n" " return f(s);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #7981 - False positive redundantCopyLocalConst - const ref argument to ctor @@ -10101,7 +10101,7 @@ class TestOther : public TestFixture { " \n" "void foo() {\n" " const CD cd(CD::getOne());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" // #10545 @@ -10114,7 +10114,7 @@ class TestOther : public TestFixture { " if (i != 0)\n" " return old;\n" " return {};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct X { int x; };\n" // #10191 @@ -10296,62 +10296,62 @@ class TestOther : public TestFixture { "{\n" " int a; a = 123;\n" " (void)(a << -1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (error) Shifting by a negative value is undefined behaviour [shiftNegative]\n", errout_str()); check("void foo()\n" "{\n" " int a; a = 123;\n" " (void)(a >> -1);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:13]: (error) Shifting by a negative value is undefined behaviour [shiftNegative]\n", errout_str()); check("void foo()\n" "{\n" " int a; a = 123;\n" " a <<= -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Shifting by a negative value is undefined behaviour [shiftNegative]\n", errout_str()); check("void foo()\n" "{\n" " int a; a = 123;\n" " a >>= -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:6]: (error) Shifting by a negative value is undefined behaviour [shiftNegative]\n", errout_str()); check("void foo()\n" "{\n" " std::cout << -1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" " std::cout << a << -1 ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo()\n" "{\n" " std::cout << 3 << -1 ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " x = (-10+2) << 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:16]: (portability) Shifting a negative value is technically undefined behaviour [shiftNegativeLHS]\n", errout_str()); - check("x = y ? z << $-1 : 0;"); + check("x = y ? z << $-1 : 0;\n"); ASSERT_EQUALS("", errout_str()); // Negative LHS - check("const int x = -1 >> 2;"); + check("const int x = -1 >> 2;\n"); ASSERT_EQUALS("[test.cpp:1:18]: (portability) Shifting a negative value is technically undefined behaviour [shiftNegativeLHS]\n", errout_str()); // #6383 - unsigned type - check("const int x = (unsigned int)(-1) >> 2;"); + check("const int x = (unsigned int)(-1) >> 2;\n"); ASSERT_EQUALS("", errout_str()); // #7814 - UB happening in valueflowcode when it tried to compute shifts. check("int shift1() { return 1 >> -1 ;}\n" "int shift2() { return 1 << -1 ;}\n" "int shift3() { return -1 >> 1 ;}\n" - "int shift4() { return -1 << 1 ;}"); + "int shift4() { return -1 << 1 ;}\n"); ASSERT_EQUALS("[test.cpp:1:25]: (error) Shifting by a negative value is undefined behaviour [shiftNegative]\n" "[test.cpp:2:25]: (error) Shifting by a negative value is undefined behaviour [shiftNegative]\n" "[test.cpp:3:26]: (portability) Shifting a negative value is technically undefined behaviour [shiftNegativeLHS]\n" @@ -10400,7 +10400,7 @@ class TestOther : public TestFixture { " memset(a, 123, 5);\n" " memcpy(a, b, 5);\n" " memmove(a, b, 5);\n" - "}"); + "}\n"); ASSERT_EQUALS(// TODO "[test.cpp:4] -> [test.cpp:5]: (performance) Buffer 'a' is being written before its old content has been used.\n" "[test.cpp:3:5]: (warning, inconclusive) Array 'a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*a)'? [incompleteArrayFill]\n" "[test.cpp:4:5]: (warning, inconclusive) Array 'a' is filled incompletely. Did you forget to multiply the size given to 'memcpy()' with 'sizeof(*a)'? [incompleteArrayFill]\n" @@ -10411,7 +10411,7 @@ class TestOther : public TestFixture { "void f() {\n" " memset(::a, 123, 5);\n" " memset(Z::b.a, 123, 5);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4:5]: (warning, inconclusive) Array '::a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*::a)'? [incompleteArrayFill]\n" "[test.cpp:5]: (warning, inconclusive) Array 'Z::b.a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*Z::b.a)'?\n", "[test.cpp:4:5]: (warning, inconclusive) Array '::a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*::a)'? [incompleteArrayFill]\n", errout_str()); @@ -10419,45 +10419,45 @@ class TestOther : public TestFixture { check("void f() {\n" " Foo* a[5];\n" " memset(a, 'a', 5);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning, inconclusive) Array 'a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*a)'? [incompleteArrayFill]\n", errout_str()); check("class Foo {int a; int b;};\n" "void f() {\n" " Foo a[5];\n" " memset(a, 'a', 5);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (warning, inconclusive) Array 'a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*a)'? [incompleteArrayFill]\n", errout_str()); check("void f() {\n" " Foo a[5];\n" // Size of foo is unknown " memset(a, 'a', 5);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char a[5];\n" " memset(a, 'a', 5);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int a[5];\n" " memset(a+15, 'a', 5);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " bool a[5];\n" " memset(a, false, 5);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (portability, inconclusive) Array 'a' might be filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*a)'? [incompleteArrayFill]\n", errout_str()); check("void f() {\n" " const int n = 5;" " int a[n];\n" " memset(a, 0, n);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning, inconclusive) Array 'a' is filled incompletely. Did you forget to multiply the size given to 'memset()' with 'sizeof(*a)'? [incompleteArrayFill]\n", errout_str()); } @@ -10468,7 +10468,7 @@ class TestOther : public TestFixture { check("void f(int i) {\n" " i = 1;\n" " i = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:7]: style: Variable 'i' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:2:7]: note: i is assigned\n" "[test.cpp:3:7]: note: i is overwritten\n", errout_str()); @@ -10478,7 +10478,7 @@ class TestOther : public TestFixture { "void f() {\n" " i = 1;\n" " i = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: style: Variable 'i' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:7]: note: i is assigned\n" "[test.cpp:4:7]: note: i is overwritten\n", errout_str()); @@ -10487,7 +10487,7 @@ class TestOther : public TestFixture { " int i;\n" " i = 1;\n" " i = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: style: Variable 'i' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:7]: note: i is assigned\n" "[test.cpp:4:7]: note: i is overwritten\n", errout_str()); @@ -10496,14 +10496,14 @@ class TestOther : public TestFixture { " static int i;\n" " i = 1;\n" " i = 1;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); check("void f() {\n" " int i[10];\n" " i[2] = 1;\n" " i[2] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: style: Variable 'i[2]' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:10]: note: i[2] is assigned\n" "[test.cpp:4:10]: note: i[2] is overwritten\n", errout_str()); @@ -10513,14 +10513,14 @@ class TestOther : public TestFixture { " i[x] = 1;\n" " x=1;\n" " i[x] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const int x) {\n" " int i[10];\n" " i[x] = 1;\n" " i[x] = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: style: Variable 'i[x]' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:10]: note: i[x] is assigned\n" "[test.cpp:4:10]: note: i[x] is overwritten\n", errout_str()); @@ -10529,14 +10529,14 @@ class TestOther : public TestFixture { check("void f() {\n" " Foo& bar = foo();\n" " bar = x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " Foo& bar = foo();\n" " bar = x;\n" " bar = y;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); check("void f() {\n" @@ -10544,7 +10544,7 @@ class TestOther : public TestFixture { " bar = y();\n" " foo();\n" " bar = y();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Tests with function call between assignment @@ -10552,7 +10552,7 @@ class TestOther : public TestFixture { " i = 1;\n" " bar();\n" " i = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: style: Variable 'i' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:2:7]: note: i is assigned\n" "[test.cpp:4:7]: note: i is overwritten\n", errout_str()); @@ -10562,7 +10562,7 @@ class TestOther : public TestFixture { " i = 1;\n" " bar();\n" // Global variable might be accessed in bar() " i = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -10570,7 +10570,7 @@ class TestOther : public TestFixture { " i = 1;\n" " bar();\n" // bar() might call f() recursively. This could be a false positive in more complex examples (when value of i is used somewhere. See #4229) " i = 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -10578,7 +10578,7 @@ class TestOther : public TestFixture { " i = 1;\n" " bar();\n" " i = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:7]: style: Variable 'i' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:7]: note: i is assigned\n" "[test.cpp:5:7]: note: i is overwritten\n", errout_str()); @@ -10588,14 +10588,14 @@ class TestOther : public TestFixture { " i = 1;\n" " bar(i);\n" // Passed as argument " i = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " Foo bar = foo();\n" " bar();\n" // #5568. operator() called " bar = y();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Branch tests @@ -10603,7 +10603,7 @@ class TestOther : public TestFixture { " i = 1;\n" " if(x)\n" " i = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int i) {\n" @@ -10611,7 +10611,7 @@ class TestOther : public TestFixture { " i = 0;\n" " i = 1;\n" " i = 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:7]: style: Variable 'i' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:4:7]: note: i is assigned\n" "[test.cpp:5:7]: note: i is overwritten\n", errout_str()); @@ -10624,7 +10624,7 @@ class TestOther : public TestFixture { "void f() {\n" " x = 2;\n" " x = g();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int g() {\n" @@ -10633,7 +10633,7 @@ class TestOther : public TestFixture { "void f(int x) {\n" " x = 2;\n" " x = g();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:7]: style: Variable 'x' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:5:7]: note: x is assigned\n" "[test.cpp:6:7]: note: x is overwritten\n", errout_str()); @@ -10642,7 +10642,7 @@ class TestOther : public TestFixture { " Foo& bar = foo();\n" " bar = x;\n" " bar = y();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class C {\n" @@ -10654,7 +10654,7 @@ class TestOther : public TestFixture { "void C::f() {\n" " x = 2;\n" " x = g();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class C {\n" @@ -10666,7 +10666,7 @@ class TestOther : public TestFixture { "void C::f(Foo z) {\n" " x = 2;\n" " x = z.g();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // ({ }) @@ -10674,7 +10674,7 @@ class TestOther : public TestFixture { " int x;\n" " x = 321;\n" " x = ({ asm(123); })\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // from #3103 (avoid a false negative) @@ -10683,7 +10683,7 @@ class TestOther : public TestFixture { " x = 1;\n" " x = 1;\n" " return x + 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: style: Variable 'x' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:7]: note: x is assigned\n" "[test.cpp:4:7]: note: x is overwritten\n", errout_str()); @@ -10695,20 +10695,20 @@ class TestOther : public TestFixture { " if (y)\n" // <-- cppcheck does not know anything about 'y' " x = 2;\n" " return x + 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // initialization, assignment with 0 check("void f() {\n" // Ticket #4356 " int x = 0;\n" // <- ignore initialization with 0 " x = 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " state_t *x = NULL;\n" " x = dostuff();\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:12]: style: Variable 'x' can be declared as pointer to const [constVariablePointer]\n", errout_str()); @@ -10717,7 +10717,7 @@ class TestOther : public TestFixture { " state_t *x;\n" " x = NULL;\n" " x = dostuff();\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:12]: style: Variable 'x' can be declared as pointer to const [constVariablePointer]\n", errout_str()); @@ -10727,7 +10727,7 @@ class TestOther : public TestFixture { " bar(++x);\n" " x = 5;\n" " return bar(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // struct member.. @@ -10738,7 +10738,7 @@ class TestOther : public TestFixture { " ab.a = 1;\n" " ab.a = 2;\n" " return ab.a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:10]: style: Variable 'ab.a' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:5:10]: note: ab.a is assigned\n" "[test.cpp:6:10]: note: ab.a is overwritten\n", errout_str()); @@ -10750,7 +10750,7 @@ class TestOther : public TestFixture { " ab.a = 1;\n" " ab = do_something();\n" " return ab.a;\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); check("struct AB { int a; int b; };\n" @@ -10761,7 +10761,7 @@ class TestOther : public TestFixture { " do_something(&ab);\n" " ab.a = 2;\n" " return ab.a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct AB { int a; int b; };\n" @@ -10772,7 +10772,7 @@ class TestOther : public TestFixture { " do_something(&ab);\n" " ab.a = 2;\n" " return ab.a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct AB { int a; int b; };\n" @@ -10783,7 +10783,7 @@ class TestOther : public TestFixture { " ab++;\n" " ab->a = 1;\n" " ab->b = 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct AB { int a; int b; };\n" @@ -10794,20 +10794,20 @@ class TestOther : public TestFixture { " ab = x;\n" " ab->a = 1;\n" " ab->b = 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(struct AB *ab) {\n" // # " ab->data->x = 1;\n" " ab = &ab1;\n" " ab->data->x = 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #5964 check("void func(char *buffer, const char *format, int precision, unsigned value) {\n" " (precision < 0) ? sprintf(buffer, format, value) : sprintf(buffer, format, precision, value);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // don't crash @@ -10820,14 +10820,14 @@ class TestOther : public TestFixture { "void func(struct state *s) {\n" " s->foo[s->x++] = 2;\n" " s->d[1].fc.i++;\n" - "}"); + "}\n"); // #6525 - inline assembly check("void f(int i) {\n" " i = 1;\n" " asm(\"foo\");\n" " i = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #6555 @@ -10840,7 +10840,7 @@ class TestOther : public TestFixture { " catch (...) {\n" " barney(p);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" @@ -10852,7 +10852,7 @@ class TestOther : public TestFixture { " catch (...) {\n" " barney(x);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: style: The scope of the variable 'p' can be reduced. [variableScope]\n" "[test.cpp:2:11]: style: Variable 'p' can be declared as pointer to const [constVariablePointer]\n", errout_str()); @@ -10868,7 +10868,7 @@ class TestOther : public TestFixture { " catch (...) {\n" " barney(p);\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Member variable pointers @@ -10878,7 +10878,7 @@ class TestOther : public TestFixture { " memptr = &POD::b;\n" " if (memptr)\n" " memptr = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:12]: style: Variable 'memptr' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:12]: note: memptr is assigned\n" "[test.cpp:4:12]: note: memptr is overwritten\n", errout_str()); @@ -10888,7 +10888,7 @@ class TestOther : public TestFixture { "{\n" " var[0] = 0.2f;\n" " var[0] = 0.2f;\n" // <-- is initialized twice - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: style: Variable 'var[0]' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:10]: note: var[0] is assigned\n" "[test.cpp:4:10]: note: var[0] is overwritten\n", errout_str()); @@ -10897,7 +10897,7 @@ class TestOther : public TestFixture { "{\n" " *var = 0.2f;\n" " *var = 0.2f;\n" // <-- is initialized twice - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:8]: style: Variable '*var' is reassigned a value before the old one has been used. [redundantAssignment]\n" "[test.cpp:3:8]: note: *var is assigned\n" "[test.cpp:4:8]: note: *var is overwritten\n", errout_str()); @@ -10907,7 +10907,7 @@ class TestOther : public TestFixture { " volatile char *reg = (volatile char *)0x12345;\n" " *reg = 12;\n" " *reg = 34;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(std::map& m, int key, int value) {\n" // #6379 @@ -10924,28 +10924,28 @@ class TestOther : public TestFixture { check("void f() {\n" " int a = 0;\n" " a = 4;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " int a;\n" " a = 0;\n" " a = 4;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " unsigned a;\n" " a = 0u;\n" " a = 2u;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " void* a;\n" " a = (void*)0;\n" " a = p;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:10]: (style) Variable 'a' can be declared as pointer to const [constVariablePointer]\n", errout_str()); @@ -10954,7 +10954,7 @@ class TestOther : public TestFixture { " void* a;\n" " a = (void*)0U;\n" " a = p;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:10]: (style) Variable 'a' can be declared as pointer to const [constVariablePointer]\n", errout_str()); @@ -10968,7 +10968,7 @@ class TestOther : public TestFixture { " const char* p = \"abc\";\n" " p = \"def\";\n" " return p;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:19] -> [test.cpp:3:7]: (style) Redundant initialization for 's'. The initialized value is overwritten before it is read. [redundantInitialization]\n" "[test.cpp:7:19] -> [test.cpp:8:7]: (style) Redundant initialization for 'p'. The initialized value is overwritten before it is read. [redundantInitialization]\n", @@ -10984,7 +10984,7 @@ class TestOther : public TestFixture { " struct foo x;\n" " x.a = _mm_set1_ps(1.0);\n" " x.a = _mm_set1_ps(2.0);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:7] -> [test.cpp:8:7]: (style) Variable 'x.a' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); check("void f() {\n" @@ -10992,13 +10992,13 @@ class TestOther : public TestFixture { " ab.x = 23;\n" " ab.y = 41;\n" " ab.x = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:8] -> [test.cpp:5:8]: (style) Variable 'ab.x' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); check("void f() {\n" " struct AB ab = {0};\n" " ab = foo();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -11019,7 +11019,7 @@ class TestOther : public TestFixture { " u.l1 = 1;\n" " lTotal += u.b.b1;\n" " u.l1 = 2;\n" //Should not show RedundantAssignment - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); // Ticket #5115 "redundantAssignment when using a union" @@ -11037,7 +11037,7 @@ class TestOther : public TestFixture { " } u;\n" " u.l1 = 1;\n" " u.l1 = 2;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:13:10] -> [test.cpp:14:10]: (style) Variable 'u.l1' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); // Ticket #10093 "redundantAssignment when using a union" @@ -11061,7 +11061,7 @@ class TestOther : public TestFixture { " m.u16.ab = 47;\n" " m.u16.cd = 0;\n" " m.u16.ab = m.u32.abcd / 53;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); // Ticket #10093 "redundantAssignment when using a union" @@ -11079,7 +11079,7 @@ class TestOther : public TestFixture { " u.as_int = 42;\n" " fn(&u.as_char[0], 4);\n" " u.as_int = 0;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); // Ticket #5115 "redundantAssignment when using a union" @@ -11090,7 +11090,7 @@ class TestOther : public TestFixture { " } addr;\n" " addr.s8 = ptr;\n" " addr.u64 += 8;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("struct S {\n" // #12895 @@ -11167,7 +11167,7 @@ class TestOther : public TestFixture { " }\n" " catch (const uno::Exception&) {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void ConvertBitmapData(sal_uInt16 nDestBits) {\n" @@ -11176,7 +11176,7 @@ class TestOther : public TestFixture { " BitmapBuffer aDstBuf;\n" " aSrcBuf.mnBitCount = nDestBits;\n" " bConverted = ::ImplFastBitmapConversion( aDstBuf, aSrcBuf, aTwoRects );\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:3:24] -> [test.c:5:24]: (style) Variable 'aSrcBuf.mnBitCount' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); check("void ConvertBitmapData(sal_uInt16 nDestBits) {\n" " BitmapBuffer aSrcBuf;\n" @@ -11184,7 +11184,7 @@ class TestOther : public TestFixture { " BitmapBuffer aDstBuf;\n" " aSrcBuf.mnBitCount = nDestBits;\n" " bConverted = ::ImplFastBitmapConversion( aDstBuf, aSrcBuf, aTwoRects );\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:24] -> [test.cpp:5:24]: (style) Variable 'aSrcBuf.mnBitCount' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); @@ -11193,7 +11193,7 @@ class TestOther : public TestFixture { " C c;\n" " c = x;\n" " c = x;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7] -> [test.cpp:5:7]: (style, inconclusive) Variable 'c' is reassigned a value before the old one has been used if variable is no semaphore variable. [redundantAssignment]\n", errout_str()); } @@ -11207,7 +11207,7 @@ class TestOther : public TestFixture { " m->prev->next = m->next;\n" " m->next->prev = m->prev;\n" " return m->next;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -11221,7 +11221,7 @@ class TestOther : public TestFixture { " x = 6;\n" " f();\n" " return y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #10228 @@ -11241,7 +11241,7 @@ class TestOther : public TestFixture { " for (i = 0; i < 4; i++)\n" " buf[i] = 131;\n" " buf[i] = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void bar() {\n" // #9262 do-while with break @@ -11251,20 +11251,20 @@ class TestOther : public TestFixture { " if (foo()) break;\n" " x = 1;\n" " } while (false);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int num) {\n" // #9420 FP " int a = num;\n" " for (int b = 0; b < num; a = b++)\n" " dostuff(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(int num) {\n" // #9420 FN " int a = num;\n" " for (int b = 0; b < num; a = b++);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); } @@ -11277,7 +11277,7 @@ class TestOther : public TestFixture { " break;\n" " }\n" " ret = 3;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:13] -> [test.cpp:8:9]: (style) Variable 'ret' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); } @@ -11287,7 +11287,7 @@ class TestOther : public TestFixture { " *x = 23;\n" " foo(ptr);\n" " *x = 32;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8997 @@ -11297,7 +11297,7 @@ class TestOther : public TestFixture { " *p = 1;\n" " p += 1;\n" " *p = 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -11306,7 +11306,7 @@ class TestOther : public TestFixture { " *p = 1;\n" " if (condition) return;\n" " *p = 2;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -11318,7 +11318,7 @@ class TestOther : public TestFixture { " i += 2;\n" " arr[i] = 3;\n" " dostuff(arr);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -11332,9 +11332,9 @@ class TestOther : public TestFixture { " if (b) break;\n" " ret = 1;\n" " break;\n" - " }" + " }\n" " return ret;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int a, int b) {\n" @@ -11345,8 +11345,8 @@ class TestOther : public TestFixture { " if (b) break;\n" " ret = 1;\n" " break;\n" - " }" - "}"); + " }\n" + "}\n"); ASSERT_EQUALS("[test.cpp:5:13] -> [test.cpp:7:13]: (style) Variable 'ret' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str()); } @@ -11356,7 +11356,7 @@ class TestOther : public TestFixture { check("void f() {\n" " int err = -ENOMEM;\n" " err = dostuff();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: style: Redundant initialization for 'err'. The initialized value is overwritten before it is read. [redundantInitialization]\n" "[test.cpp:2:13]: note: err is initialized\n" "[test.cpp:3:9]: note: err is overwritten\n", @@ -11365,7 +11365,7 @@ class TestOther : public TestFixture { check("void f() {\n" " struct S s = {1,2,3};\n" " s = dostuff();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:7]: style: Redundant initialization for 's'. The initialized value is overwritten before it is read. [redundantInitialization]\n" "[test.cpp:2:16]: note: s is initialized\n" "[test.cpp:3:7]: note: s is overwritten\n", @@ -11374,7 +11374,7 @@ class TestOther : public TestFixture { check("void f() {\n" " int *p = NULL;\n" " p = dostuff();\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:10]: style: Variable 'p' can be declared as pointer to const [constVariablePointer]\n", errout_str()); @@ -11383,14 +11383,14 @@ class TestOther : public TestFixture { check("void f() {\n" " struct S s = {0};\n" " s = dostuff();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("namespace N { enum E {e0,e1}; }\n" "void f() {\n" " N::E e = N::e0;\n" // #9261 " e = dostuff();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #10143 @@ -11415,21 +11415,21 @@ class TestOther : public TestFixture { " char a[10];\n" " memcpy(a, foo, bar);\n" " memset(a, 0, bar);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (performance) Buffer 'a' is being written before its old content has been used.\n", errout_str()); check("void f() {\n" " char a[10];\n" " strcpy(a, foo);\n" " strncpy(a, 0, bar);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (performance) Buffer 'a' is being written before its old content has been used.\n", errout_str()); check("void f() {\n" " char a[10];\n" " sprintf(a, \"foo\");\n" " memmove(a, 0, bar);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (performance) Buffer 'a' is being written before its old content has been used.\n", errout_str()); check("void f(char *filename) {\n" @@ -11437,14 +11437,14 @@ class TestOther : public TestFixture { " strcpy(p, \"foo\");\n" " dostuff(filename);\n" " strcpy(p, \"foo\");\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Writing to different parts of a buffer check("void f(void* a) {\n" " memcpy(a, foo, bar);\n" " memset(a+5, 0, bar);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Use variable as second argument @@ -11452,7 +11452,7 @@ class TestOther : public TestFixture { " memset(a, 0, 5);\n" " memcpy(b, a, 5);\n" " memset(a, 1, 5);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // strcat is special @@ -11461,7 +11461,7 @@ class TestOther : public TestFixture { " strcpy(a, foo);\n" " strcat(a, bar);\n" // Not redundant " strcpy(a, x);\n" // Redundant - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (performance) Buffer 'a' is being written before its old content has been used.\n", errout_str()); // Tests with function call between copy @@ -11470,7 +11470,7 @@ class TestOther : public TestFixture { " snprintf(a, foo, bar);\n" " bar();\n" " memset(a, 0, size);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (performance) Buffer 'a' is being written before its old content has been used.\n", errout_str()); check("void* a;\n" @@ -11478,7 +11478,7 @@ class TestOther : public TestFixture { " memset(a, 0, size);\n" " bar();\n" // Global variable might be accessed in bar() " memset(a, 0, size);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -11486,7 +11486,7 @@ class TestOther : public TestFixture { " memset(a, 0, size);\n" " bar();\n" " memset(a, 0, size);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (performance) Buffer 'a' is being written before its old content has been used.\n", "", errout_str()); check("void bar(void* a) {}\n" @@ -11494,7 +11494,7 @@ class TestOther : public TestFixture { " memset(a, 0, size);\n" " bar(a);\n" // Passed as argument " memset(a, 0, size);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // Branch tests @@ -11502,7 +11502,7 @@ class TestOther : public TestFixture { " memset(a, 0, size);\n" " if(x)\n" " memset(a, 0, size);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #4455 - initialization of local buffer @@ -11510,14 +11510,14 @@ class TestOther : public TestFixture { " char buf[10];\n" " memset(buf, 0, 10);\n" " strcpy(buf, string);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(void) {\n" " char buf[10] = {0};\n" " memset(buf, 0, 10);\n" " strcpy(buf, string);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (performance) Buffer 'buf' is being written before its old content has been used.\n", errout_str()); // #5689 - use return value of strcpy @@ -11525,7 +11525,7 @@ class TestOther : public TestFixture { " int i = atoi(strcpy(a, foo));\n" " strncpy(a, 0, bar);\n" " return i;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #7175 - read+write @@ -11534,7 +11534,7 @@ class TestOther : public TestFixture { " strcpy(buf, x);\n" " strcpy(buf, dostuff(buf));\n" // <- read + write " strcpy(buf, x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -11542,7 +11542,7 @@ class TestOther : public TestFixture { " strcpy(buf, x);\n" " strcpy(buf, dostuff(buf));\n" " strcpy(buf, x);\n" - "}"); + "}\n"); TODO_ASSERT_EQUALS("error", "", errout_str()); } @@ -11612,17 +11612,17 @@ class TestOther : public TestFixture { void varFuncNullUB() { // #4482 check("void a(...);\n" - "void b() { a(NULL); }"); + "void b() { a(NULL); }\n"); ASSERT_EQUALS("[test.cpp:2:13]: (portability) Passing NULL after the last typed argument to a variadic function leads to undefined behaviour. [varFuncNullUB]\n", errout_str()); check("void a(char *p, ...);\n" - "void b() { a(NULL, 2); }"); + "void b() { a(NULL, 2); }\n"); ASSERT_EQUALS("", errout_str()); checkP("extern const int sentinel;\n" "void a(int, ...);\n" "#define b(x, ...) a((x), __VA_ARGS__, &sentinel)\n" - "void c() { b(1, NULL); }"); + "void c() { b(1, NULL); }\n"); ASSERT_EQUALS("", errout_str()); } @@ -11636,7 +11636,7 @@ class TestOther : public TestFixture { " bar(c);\n" " c = getchar();\n" " } ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (warning) Storing getchar() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f() {\n" @@ -11645,7 +11645,7 @@ class TestOther : public TestFixture { " {\n" " bar(c);\n" " } ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (warning) Storing getchar() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f() {\n" @@ -11655,7 +11655,7 @@ class TestOther : public TestFixture { " bar(c);\n" " c = getchar();\n" " } ;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (warning) Storing getchar() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f() {\n" @@ -11663,7 +11663,7 @@ class TestOther : public TestFixture { " while( EOF != ( c = getchar() ) )\n" " {\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:19]: (warning) Storing getchar() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f() {\n" @@ -11673,7 +11673,7 @@ class TestOther : public TestFixture { " bar(i);\n" " i = getchar();\n" " } ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -11683,7 +11683,7 @@ class TestOther : public TestFixture { " bar(i);\n" " i = getchar();\n" " } ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -11693,7 +11693,7 @@ class TestOther : public TestFixture { "do {\n" " c = getc (pFile);\n" "} while (c != EOF);" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (warning) Storing getc() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f (FILE * pFile){\n" @@ -11701,7 +11701,7 @@ class TestOther : public TestFixture { "do {\n" " c = getc (pFile);\n" "} while (EOF != c);" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:17]: (warning) Storing getc() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f (FILE * pFile){\n" @@ -11709,7 +11709,7 @@ class TestOther : public TestFixture { "do {\n" " i = getc (pFile);\n" "} while (i != EOF);" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f (FILE * pFile){\n" @@ -11717,7 +11717,7 @@ class TestOther : public TestFixture { "do {\n" " i = getc (pFile);\n" "} while (EOF != i);" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); @@ -11727,7 +11727,7 @@ class TestOther : public TestFixture { "do {\n" " c = fgetc (pFile);\n" "} while (c != EOF);" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (warning) Storing fgetc() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f (FILE * pFile){\n" @@ -11735,7 +11735,7 @@ class TestOther : public TestFixture { "do {\n" " c = fgetc (pFile);\n" "} while (EOF != c);" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:17]: (warning) Storing fgetc() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f (FILE * pFile){\n" @@ -11743,7 +11743,7 @@ class TestOther : public TestFixture { "do {\n" " c = fgetc (pFile);\n" "} while (EOF != c);" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f (FILE * pFile){\n" @@ -11751,7 +11751,7 @@ class TestOther : public TestFixture { "do {\n" " i = fgetc (pFile);\n" "} while (i != EOF);" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f (FILE * pFile){\n" @@ -11759,7 +11759,7 @@ class TestOther : public TestFixture { "do {\n" " i = fgetc (pFile);\n" "} while (EOF != i);" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // cin.get() @@ -11769,7 +11769,7 @@ class TestOther : public TestFixture { " std::cout << ch;\n" " ch = std::cin.get();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:18]: (warning) Storing cin.get() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f(){\n" @@ -11778,7 +11778,7 @@ class TestOther : public TestFixture { " std::cout << ch;\n" " ch = std::cin.get();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:11]: (warning) Storing cin.get() return value in char variable and then comparing with EOF. [checkCastIntToCharAndBack]\n", errout_str()); check("void f(){\n" @@ -11787,7 +11787,7 @@ class TestOther : public TestFixture { " std::cout << i;\n" " i = std::cin.get();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(){\n" @@ -11796,7 +11796,7 @@ class TestOther : public TestFixture { " std::cout << i;\n" " i = std::cin.get();\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -11805,32 +11805,32 @@ class TestOther : public TestFixture { " if (a < 0)\n" " return a++,\n" " do_something();\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Comma is used in return statement. The comma can easily be misread as a ';'.\n", "", errout_str()); check("int fun(int a) {\n" " if (a < 0)\n" " return a++, do_something();\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("int fun(int a) {\n" " if (a < 0)\n" " return a+5,\n" " do_something();\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Comma is used in return statement. The comma can easily be misread as a ';'.\n", "", errout_str()); check("int fun(int a) {\n" " if (a < 0)\n" " return a+5, do_something();\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("int fun(int a) {\n" " if (a < 0)\n" " return c::b;\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); // #4943 take care of C++11 initializer lists @@ -11841,7 +11841,7 @@ class TestOther : public TestFixture { " { \"2\" },\n" " { \"3\" }\n" " };\n" - "}", dinit(CheckOptions, $.inconclusive = false)); + "}\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); } @@ -11857,7 +11857,7 @@ class TestOther : public TestFixture { " explicit B(A a) : a(std::move(a)) {}\n" " void Init(A _a) { a = std::move(_a); }\n" " A a;" - "};", dinit(CheckOptions, $.inconclusive = false)); + "};\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("struct A\n" @@ -11870,7 +11870,7 @@ class TestOther : public TestFixture { " explicit B(A a) : a{std::move(a)} {}\n" " void Init(A _a) { a = std::move(_a); }\n" " A a;" - "};", dinit(CheckOptions, $.inconclusive = false)); + "};\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("struct A\n" @@ -11884,7 +11884,7 @@ class TestOther : public TestFixture { " void Init(A _a) { a = std::move(_a); }\n" " A a;" " A a2;" - "};", dinit(CheckOptions, $.inconclusive = false)); + "};\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); check("struct A\n" @@ -11898,7 +11898,7 @@ class TestOther : public TestFixture { " void Init(A _a) { a = std::move(_a); }\n" " A a;" " A a2;" - "};", dinit(CheckOptions, $.inconclusive = false)); + "};\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:8:14]: (performance) Function parameter 'a2' should be passed by const reference. [passedByValue]\n", errout_str()); check("struct A\n" @@ -11912,11 +11912,11 @@ class TestOther : public TestFixture { " void Init(A _a) { a = std::move(_a); }\n" " A a;" " A a2;" - "};", dinit(CheckOptions, $.inconclusive = false)); + "};\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("[test.cpp:8:14]: (performance) Function parameter 'a2' should be passed by const reference. [passedByValue]\n", errout_str()); check("std::map m;\n" // #10817 - "void f(const decltype(m)::const_iterator i) {}"); + "void f(const decltype(m)::const_iterator i) {}\n"); ASSERT_EQUALS("", errout_str()); check("int (*pf) (std::vector) = nullptr;\n" // #12118 @@ -11959,7 +11959,7 @@ class TestOther : public TestFixture { "};\n" "T f(T t) {\n" " return t;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // don't crash Settings settingsUnix32 = settingsBuilder().platform(Platform::Type::Unix32).build(); @@ -11976,33 +11976,33 @@ class TestOther : public TestFixture { // positive test check("bool f(int x){\n" " return isless(x,x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of two identical variables with isless(x,x) always evaluates to false. [comparisonFunctionIsAlwaysTrueOrFalse]\n", errout_str()); check("bool f(int x){\n" " return isgreater(x,x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of two identical variables with isgreater(x,x) always evaluates to false. [comparisonFunctionIsAlwaysTrueOrFalse]\n", errout_str()); check("bool f(int x){\n" " return islessgreater(x,x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of two identical variables with islessgreater(x,x) always evaluates to false. [comparisonFunctionIsAlwaysTrueOrFalse]\n", errout_str()); check("bool f(int x){\n" " return islessequal(x,x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of two identical variables with islessequal(x,x) always evaluates to true. [comparisonFunctionIsAlwaysTrueOrFalse]\n", errout_str()); check("bool f(int x){\n" " return isgreaterequal(x,x);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:11]: (warning) Comparison of two identical variables with isgreaterequal(x,x) always evaluates to true. [comparisonFunctionIsAlwaysTrueOrFalse]\n", errout_str()); // no warning should be reported for check("bool f(int x, int y){\n" " return isgreaterequal(x,y) && islessequal(x,y) && islessgreater(x,y) && isgreater(x,y) && isless(x,y);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -12010,7 +12010,7 @@ class TestOther : public TestFixture { // no signed integer overflow should happen check("void f(unsigned long long ull) {\n" " if (ull == 0x89504e470d0a1a0a || ull == 0x8a4d4e470d0a1a0a) ;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -12105,7 +12105,7 @@ class TestOther : public TestFixture { void test_isSameExpression() { // see #5738 check("bool isInUnoIncludeFile(StringRef name) {" " return name.startswith(SRCDIR \"/com/\") || name.startswith(SRCDIR \"/uno/\");\n" - "};", dinit(CheckOptions, $.inconclusive = false)); + "};\n", dinit(CheckOptions, $.inconclusive = false)); ASSERT_EQUALS("", errout_str()); } @@ -12114,7 +12114,7 @@ class TestOther : public TestFixture { " int counter = 0;\n" " InterlockedDecrement(&counter);\n" " whatever();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12123,7 +12123,7 @@ class TestOther : public TestFixture { " if (counter)\n" " return;\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12131,7 +12131,7 @@ class TestOther : public TestFixture { " InterlockedDecrement(&counter);\n" " if (!counter)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12140,7 +12140,7 @@ class TestOther : public TestFixture { " if (counter > 0)\n" " return;\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12149,7 +12149,7 @@ class TestOther : public TestFixture { " if (0 < counter)\n" " return;\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12157,7 +12157,7 @@ class TestOther : public TestFixture { " InterlockedDecrement(&counter);\n" " if (counter == 0)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12165,7 +12165,7 @@ class TestOther : public TestFixture { " InterlockedDecrement(&counter);\n" " if (0 == counter)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12174,7 +12174,7 @@ class TestOther : public TestFixture { " if (0 != counter)\n" " return;\n" " destroy()\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12183,7 +12183,7 @@ class TestOther : public TestFixture { " if (counter != 0)\n" " return;\n" " destroy()\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12191,7 +12191,7 @@ class TestOther : public TestFixture { " InterlockedDecrement(&counter);\n" " if (counter <= 0)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12199,7 +12199,7 @@ class TestOther : public TestFixture { " InterlockedDecrement(&counter);\n" " if (0 >= counter)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12208,7 +12208,7 @@ class TestOther : public TestFixture { " if (newCount)\n" " return;\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12216,7 +12216,7 @@ class TestOther : public TestFixture { " int newCount = InterlockedDecrement(&counter);\n" " if (!newCount)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12225,7 +12225,7 @@ class TestOther : public TestFixture { " if (newCount > 0)\n" " return;\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12234,7 +12234,7 @@ class TestOther : public TestFixture { " if (0 < newCount)\n" " return;\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12242,7 +12242,7 @@ class TestOther : public TestFixture { " int newCount = InterlockedDecrement(&counter);\n" " if (newCount == 0)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12250,7 +12250,7 @@ class TestOther : public TestFixture { " int newCount = InterlockedDecrement(&counter);\n" " if (0 == newCount)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12259,7 +12259,7 @@ class TestOther : public TestFixture { " if (0 != newCount)\n" " return;\n" " destroy()\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12268,7 +12268,7 @@ class TestOther : public TestFixture { " if (newCount != 0)\n" " return;\n" " destroy()\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12276,7 +12276,7 @@ class TestOther : public TestFixture { " int newCount = InterlockedDecrement(&counter);\n" " if (newCount <= 0)\n" " destroy();\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("void f() {\n" @@ -12284,7 +12284,7 @@ class TestOther : public TestFixture { " int newCount = InterlockedDecrement(&counter);\n" " if (0 >= newCount)\n" " destroy;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); checkInterlockedDecrement("int f() {\n" @@ -12295,7 +12295,7 @@ class TestOther : public TestFixture { " } else {\n" " return counter;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:16]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("int f() {\n" @@ -12306,7 +12306,7 @@ class TestOther : public TestFixture { " } else {\n" " return counter;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:16]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); @@ -12317,7 +12317,7 @@ class TestOther : public TestFixture { " return 0;\n" " }\n" " return counter;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:12]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("int f() {\n" @@ -12327,7 +12327,7 @@ class TestOther : public TestFixture { " return 0;\n" " }\n" " return counter;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:12]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("int f() {\n" @@ -12338,7 +12338,7 @@ class TestOther : public TestFixture { " } else\n" " return counter;\n" " \n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:16]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); checkInterlockedDecrement("int f() {\n" @@ -12349,21 +12349,21 @@ class TestOther : public TestFixture { " } else\n" " return counter;\n" " \n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:16]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead. [raceAfterInterlockedDecrement]\n", errout_str()); } void testUnusedLabel() { check("void f() {\n" " label:\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (style) Label 'label' is not used. [unusedLabel]\n", errout_str()); check("void f() {\n" " label:\n" " foo();\n" " goto label;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -12373,28 +12373,28 @@ class TestOther : public TestFixture { "}\n" "void g() {\n" " label:\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:5]: (style) Label 'label' is not used. [unusedLabel]\n", errout_str()); check("void f() {\n" " switch(a) {\n" " default:\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " class X {\n" " protected:\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " class X {\n" " my_protected:\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int test(char art) {\n" @@ -12406,7 +12406,7 @@ class TestOther : public TestFixture { " case 2:\n" " return 2;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Label 'caseZERO' is not used. Should this be a 'case' of the enclosing switch()? [unusedLabelSwitch]\n" "[test.cpp:5:5]: (warning) Label 'case1' is not used. Should this be a 'case' of the enclosing switch()? [unusedLabelSwitch]\n", errout_str()); @@ -12416,7 +12416,7 @@ class TestOther : public TestFixture { " return 2;\n" " }\n" " label:\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:5]: (style) Label 'label' is not used. [unusedLabel]\n", errout_str()); } @@ -12427,7 +12427,7 @@ class TestOther : public TestFixture { " goto END;\n" "#endif\n" "END:\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:1]: (style) Label 'END' is not used. There is #if in function body so the label might be used in code that is removed by the preprocessor. [unusedLabelConfiguration]\n", errout_str()); } @@ -12445,7 +12445,7 @@ class TestOther : public TestFixture { " END:\n" " return;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:10:5]: (warning) Label 'END' is not used. There is #if in function body so the label might be used in code that is removed by the preprocessor. Should this be a 'case' of the enclosing switch()? [unusedLabelSwitchConfiguration]\n", errout_str()); } @@ -12454,12 +12454,12 @@ class TestOther : public TestFixture { Settings s; check("void f() {\n" " label:\n" - "}", dinit(CheckOptions, $.settings = &s)); + "}\n", dinit(CheckOptions, $.settings = &s)); ASSERT_EQUALS("", errout_str()); s.premiumArgs = "--premium=misra-c-2012"; // <- activates unusedLabel checking check("void f() {\n" " label:\n" - "}", dinit(CheckOptions, $.settings = &s)); + "}\n", dinit(CheckOptions, $.settings = &s)); ASSERT_EQUALS("[test.cpp:2:5]: (style) Label 'label' is not used. [unusedLabel]\n", errout_str()); } @@ -12479,24 +12479,24 @@ class TestOther : public TestFixture { check("void f() {\n" " int x = dostuff();\n" " return x + x++;\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:3:12]: (error) Expression 'x+x++' depends on order of evaluation of side effects [unknownEvaluationOrder]\n", errout_str()); // #7226 check("long int f1(const char *exp) {\n" " return strtol(++exp, (char **)&exp, 10);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); check("long int f1(const char *exp) {\n" " return dostuff(++exp, exp, 10);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:2:23]: (error) Expression '++exp,exp' depends on order of evaluation of side effects [unknownEvaluationOrder]\n", errout_str()); check("void f() {\n" " int a;\n" " while (a=x(), a==123) {}\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); // # 8717 @@ -12521,25 +12521,25 @@ class TestOther : public TestFixture { check("void f(int i) {\n" " int n = ++i + i;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:15]: (error) Expression '++i+i' depends on order of evaluation of side effects [unknownEvaluationOrder]\n", errout_str()); check("long int f1(const char *exp) {\n" " return dostuff(++exp, ++exp, 10);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:23]: (portability) Expression '++exp,++exp' depends on order of evaluation of side effects. Behavior is Unspecified according to c++17 [unknownEvaluationOrder]\n" "[test.cpp:2:23]: (portability) Expression '++exp,++exp' depends on order of evaluation of side effects. Behavior is Unspecified according to c++17 [unknownEvaluationOrder]\n", errout_str()); check("void f(int i) {\n" " int n = (~(-(++i)) + i);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:22]: (error) Expression '~(-(++i))+i' depends on order of evaluation of side effects [unknownEvaluationOrder]\n", errout_str()); const Settings settings11 = settingsBuilder(settings0).cpp(Standards::CPP11).certainty(Certainty::inconclusive).build(); checkCustomSettings("void f(int i) {\n" " i = i++ + 2;\n" - "}", settings11); + "}\n", settings11); ASSERT_EQUALS("[test.cpp:2:11]: (error) Expression 'i+++2' depends on order of evaluation of side effects [unknownEvaluationOrder]\n", errout_str()); // #14431 @@ -12553,7 +12553,7 @@ class TestOther : public TestFixture { // self assignment check("void f() {\n" " int x = x = y + 1;\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS( "[test.c:2:9]: (style) Redundant assignment of 'x' to itself. [selfAssignment]\n" "[test.c:2:9]: (style) Redundant assignment of 'x' to itself. [selfAssignment]\n", // duplicate @@ -12565,7 +12565,7 @@ class TestOther : public TestFixture { checkP("#define X x\n" "void f(int x) {\n" " return x + X++;\n" - "}", dinit(CheckPOptions, $.cpp = false)); + "}\n", dinit(CheckPOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:3:12]: (error) Expression 'x+x++' depends on order of evaluation of side effects [unknownEvaluationOrder]\n", errout_str()); } @@ -12573,13 +12573,13 @@ class TestOther : public TestFixture { // FP check("void f(int id) {\n" " id = dostuff(id += 42);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); // FN check("void f(int id) {\n" " id = id + dostuff(id += 42);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); TODO_ASSERT_EQUALS("error", "", errout_str()); } @@ -12587,19 +12587,19 @@ class TestOther : public TestFixture { check("int f(void) {\n" " int t;\n" " return (unsigned char)(t=1,t^c);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); check("void f(void) {\n" " int t;\n" " dostuff(t=1,t^c);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:3:14]: (error) Expression 't=1,t^c' depends on order of evaluation of side effects [unknownEvaluationOrder]\n", errout_str()); check("void f(void) {\n" " int t;\n" " dostuff((t=1,t),2);\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); // #8230 @@ -12628,7 +12628,7 @@ class TestOther : public TestFixture { void testEvaluationOrderSizeof() { check("void f(char *buf) {\n" " dostuff(buf++, sizeof(*buf));" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("", errout_str()); } @@ -12647,7 +12647,7 @@ class TestOther : public TestFixture { " if (0 > d.n) {\n" " return;\n" " }\n" - "}", dinit(CheckOptions, $.cpp = false)); + "}\n", dinit(CheckOptions, $.cpp = false)); ASSERT_EQUALS("[test.c:8:11]: (style) Checking if unsigned expression 'd.n' is less than zero. [unsignedLessThanZero]\n" "[test.c:12:9]: (style) Checking if unsigned expression 'd.n' is less than zero. [unsignedLessThanZero]\n", errout_str()); @@ -12659,7 +12659,7 @@ class TestOther : public TestFixture { " A a;\n" " g(std::move(a));\n" " g(std::move(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:17]: (warning) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12673,7 +12673,7 @@ class TestOther : public TestFixture { " }\n" " B b1;\n" " B b2;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:6:24]: (warning) Access of moved variable 'b'. [accessMoved]\n", errout_str()); } @@ -12686,7 +12686,7 @@ class TestOther : public TestFixture { " {}\n" " B b1;\n" " B b2;\n" - "};"); + "};\n"); ASSERT_EQUALS("[test.cpp:5:19]: (warning) Access of moved variable 'b'. [accessMoved]\n", errout_str()); } @@ -12717,7 +12717,7 @@ class TestOther : public TestFixture { " A a;\n" " a = g(std::move(a));\n" " a = g(std::move(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -12727,7 +12727,7 @@ class TestOther : public TestFixture { " A a;\n" " B b = g(std::move(a));\n" " C c = g(std::move(a));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:23]: (warning) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12743,7 +12743,7 @@ class TestOther : public TestFixture { " h(a);\n" " a = b;\n" " h(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: (warning) Access of moved variable 'a'. [accessMoved]\n" "[test.cpp:8:7]: (warning) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12754,7 +12754,7 @@ class TestOther : public TestFixture { " A a;\n" " a.reset(g(std::move(a)));\n" " a.reset(g(std::move(a)));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -12766,7 +12766,7 @@ class TestOther : public TestFixture { " A c;\n" " b.reset(g(std::move(a)));\n" " c.reset(g(std::move(a)));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:25]: (warning) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12782,7 +12782,7 @@ class TestOther : public TestFixture { " h(a);\n" " a.reset(b);\n" " h(a);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: (warning) Access of moved variable 'a'. [accessMoved]\n" "[test.cpp:8:7]: (warning) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12794,7 +12794,7 @@ class TestOther : public TestFixture { " A b = std::move(a);\n" " g(a);\n" " A c = a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:7]: (warning) Access of moved variable 'a'. [accessMoved]\n" "[test.cpp:6:11]: (warning) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12806,7 +12806,7 @@ class TestOther : public TestFixture { " A b = std::move(a);\n" " g(a);\n" " A c = a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -12817,7 +12817,7 @@ class TestOther : public TestFixture { " A b = std::move(a);\n" " g(a);\n" " A c = a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:7]: (warning) Access of moved variable 'a'. [accessMoved]\n" "[test.cpp:6:11]: (warning) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12828,7 +12828,7 @@ class TestOther : public TestFixture { " A b = std::move(a);\n" " g(a);\n" " A c = a;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: (warning, inconclusive) Access of moved variable 'a'. [accessMoved]\n" "[test.cpp:5:11]: (warning, inconclusive) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12841,7 +12841,7 @@ class TestOther : public TestFixture { " if (i)\n" " return g(std::move(b));\n" " return h(std::move(a),std::move(b));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:7:24]: (warning) Access of moved variable 'a'. [accessMoved]\n", errout_str()); } @@ -12851,7 +12851,7 @@ class TestOther : public TestFixture { " g(std::move(v));\n" " v.clear();\n" " if (v.empty()) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -12861,7 +12861,7 @@ class TestOther : public TestFixture { " g(std::move(p));\n" " x = p->x;\n" " y = p->y;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (warning) Access of moved variable 'p'. [accessMoved]\n" "[test.cpp:5:9]: (warning) Access of moved variable 'p'. [accessMoved]\n", errout_str()); } @@ -12871,7 +12871,7 @@ class TestOther : public TestFixture { " std::string s1 = x;\n" " std::string s2 = std::move(s1);\n" " p = &s1;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -12880,16 +12880,16 @@ class TestOther : public TestFixture { " A a;\n" " gx(std::move(a).x());\n" " gy(std::move(a).y());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void moveAndLambda() { check("void f() {\n" " A a;\n" - " auto h = [a=std::move(a)](){return g(std::move(a));};" + " auto h = [a=std::move(a)](){return g(std::move(a));};\n" " b = a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -12960,7 +12960,7 @@ class TestOther : public TestFixture { "void f(T && t) {\n" " g(std::forward(t));\n" " T s = t;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:11]: (warning) Access of forwarded variable 't'. [accessForwarded]\n", errout_str()); } @@ -13093,7 +13093,7 @@ class TestOther : public TestFixture { "void Fred::func1(int a, int b, int c) { }\n" "void Fred::func2(int A, int B, int C) { }\n" "void Fred::func3(int a, int b, int c) { }\n" - "void Fred::func4(int A, int B, int C) { }"); + "void Fred::func4(int A, int B, int C) { }\n"); ASSERT_EQUALS("[test.cpp:3:16] -> [test.cpp:4:16]: (style, inconclusive) Function 'func2' argument 1 names different: declaration 'a' definition 'A'. [funcArgNamesDifferent]\n" "[test.cpp:3:23] -> [test.cpp:4:23]: (style, inconclusive) Function 'func2' argument 2 names different: declaration 'b' definition 'B'. [funcArgNamesDifferent]\n" "[test.cpp:3:30] -> [test.cpp:4:30]: (style, inconclusive) Function 'func2' argument 3 names different: declaration 'c' definition 'C'. [funcArgNamesDifferent]\n" @@ -13170,49 +13170,49 @@ class TestOther : public TestFixture { // #7846 - Syntax error when using C++11 braced-initializer in default argument void cpp11FunctionArgInit() { // syntax error is not expected - ASSERT_NO_THROW(check("\n void foo(int declaration = {}) {" + ASSERT_NO_THROW(check("\n void foo(int declaration = {}) {\n" "\n for (int i = 0; i < 10; i++) {}\n" - "\n }" - "\n ")); + "\n }\n" + "\n")); ASSERT_EQUALS("", errout_str()); } void shadowVariables() { check("int x;\n" - "void f() { int x; }"); + "void f() { int x; }\n"); ASSERT_EQUALS("[test.cpp:1:5] -> [test.cpp:2:16]: (style) Local variable 'x' shadows outer variable [shadowVariable]\n", errout_str()); check("int x();\n" - "void f() { int x; }"); + "void f() { int x; }\n"); ASSERT_EQUALS("[test.cpp:1:5] -> [test.cpp:2:16]: (style) Local variable 'x' shadows outer function [shadowFunction]\n", errout_str()); check("struct C {\n" " C(int x) : x(x) {}\n" // <- we do not want a FP here " int x;\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " if (cond) {int x;}\n" // <- not a shadow variable " int x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int size() {\n" " int size;\n" // <- not a shadow variable - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #8954 - lambda " int x;\n" - " auto f = [](){ int x; }" - "}"); + " auto f = [](){ int x; }\n" + "}\n"); ASSERT_EQUALS("", errout_str()); - check("void f(int x) { int x; }"); + check("void f(int x) { int x; }\n"); ASSERT_EQUALS("[test.cpp:1:12] -> [test.cpp:1:21]: (style) Local variable 'x' shadows outer argument [shadowArgument]\n", errout_str()); - check("class C { C(); void foo() { static int C = 0; } }"); // #9195 - shadow constructor + check("class C { C(); void foo() { static int C = 0; } }\n"); // #9195 - shadow constructor ASSERT_EQUALS("", errout_str()); check("struct C {\n" // #10091 - shadow destructor @@ -13221,7 +13221,7 @@ class TestOther : public TestFixture { " bool C{};\n" " }\n" "};\n" - "C::~C() = default;"); + "C::~C() = default;\n"); ASSERT_EQUALS("", errout_str()); // 10752 - no @@ -13232,7 +13232,7 @@ class TestOther : public TestFixture { " int i = 0;\n" " return i;\n" " }\n" - "};"); + "};\n"); ASSERT_EQUALS("", errout_str()); check("struct S {\n" @@ -13317,19 +13317,19 @@ class TestOther : public TestFixture { check("void g(int);\n" "void f(int x) {\n" " g((x & 0x01) >> 7);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:17]: (style) Argument '(x&0x01)>>7' to function g is always 0. It does not matter what value 'x' has. [knownArgument]\n", errout_str()); check("void g(int);\n" "void f(int x) {\n" " g((int)((x & 0x01) >> 7));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:6]: (style) Argument '(int)((x&0x01)>>7)' to function g is always 0. It does not matter what value 'x' has. [knownArgument]\n", errout_str()); check("void g(int, int);\n" "void f(int x) {\n" " g(x, (x & 0x01) >> 7);\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:20]: (style) Argument '(x&0x01)>>7' to function g is always 0. It does not matter what value 'x' has. [knownArgument]\n", errout_str()); @@ -13337,65 +13337,65 @@ class TestOther : public TestFixture { check("void g(int);\n" "void f(int x) {\n" " g(0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int);\n" "void h() { return 1; }\n" "void f(int x) {\n" " g(h());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int);\n" "void f(int x) {\n" " g(std::strlen(\"a\"));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int);\n" "void f(int x) {\n" " g((int)0);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(Foo *);\n" "void f() {\n" " g(reinterpret_cast(0));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int);\n" "void f(int x) {\n" " x = 0;\n" " g(x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int);\n" "void f() {\n" " const int x = 0;\n" " g(x + 1);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void g(int);\n" "void f() {\n" " char i = 1;\n" " g(static_cast(i));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("char *yytext;\n" "void re_init_scanner() {\n" " int size = 256;\n" " yytext = xmalloc(size * sizeof *yytext);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void foo(const char *c) {\n" " if (*c == '+' && (operand || !isalnum(*c))) {}\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #8986 @@ -13403,14 +13403,14 @@ class TestOther : public TestFixture { "void g() {\n" " const int x[] = { 10, 10 };\n" " f(x[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int);\n" "void g() {\n" " int x[] = { 10, 10 };\n" " f(x[0]);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style) Variable 'x' can be declared as const array [constVariable]\n", errout_str()); check("struct A { int x; };" @@ -13419,21 +13419,21 @@ class TestOther : public TestFixture { " A y;\n" " y.x = 1;\n" " g(y.x);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // allow known argument value in assert call check("void g(int);\n" "void f(int x) {\n" " ASSERT((int)((x & 0x01) >> 7));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9905 - expression that does not use integer calculation at all check("void foo() {\n" " const std::string heading = \"Interval\";\n" " std::cout << std::setw(heading.length());\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9909 - struct member with known value @@ -13444,7 +13444,7 @@ class TestOther : public TestFixture { "void growLongStack(LongStack* self) {\n" " self->maxsize = 32;\n" " dostuff(self->maxsize * sizeof(intptr_t));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #11894 @@ -13539,7 +13539,7 @@ class TestOther : public TestFixture { " bar(P, N); \n" " if (c ? a : b)\n" " baz(P, N); \n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -13552,7 +13552,7 @@ class TestOther : public TestFixture { " diff = 1;\n" " }\n" " return diff;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:15] -> [test.cpp:5:8] -> [test.cpp:3:15] -> [test.cpp:5:14] -> [test.cpp:5:12]: (error) Comparing pointers that point to different objects [comparePointers]\n", errout_str()); @@ -13563,7 +13563,7 @@ class TestOther : public TestFixture { " int* xp = &x;\n" " int* yp = &y;\n" " return xp > yp;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:9] -> [test.cpp:4:15] -> [test.cpp:3:9] -> [test.cpp:5:15] -> [test.cpp:6:15]: (error) Comparing pointers that point to different objects [comparePointers]\n" "[test.cpp:4:10]: (style) Variable 'xp' can be declared as pointer to const [constVariablePointer]\n" @@ -13574,7 +13574,7 @@ class TestOther : public TestFixture { " int x = 0;\n" " int y = 1;\n" " return &x > &y;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:9] -> [test.cpp:4:12] -> [test.cpp:3:9] -> [test.cpp:4:17] -> [test.cpp:4:15]: (error) Comparing pointers that point to different objects [comparePointers]\n", errout_str()); @@ -13586,7 +13586,7 @@ class TestOther : public TestFixture { " int* xp = &x.data;\n" " int* yp = &y.data;\n" " return xp > yp;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:3:7] -> [test.cpp:5:15] -> [test.cpp:4:7] -> [test.cpp:6:15] -> [test.cpp:7:15]: (error) Comparing pointers that point to different objects [comparePointers]\n" "[test.cpp:5:10]: (style) Variable 'xp' can be declared as pointer to const [constVariablePointer]\n" @@ -13600,7 +13600,7 @@ class TestOther : public TestFixture { " int* xp = &x->data;\n" " int* yp = &y->data;\n" " return xp > yp;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:10] -> [test.cpp:3:12] -> [test.cpp:5:15] -> [test.cpp:2:16] -> [test.cpp:4:12] -> [test.cpp:6:15] -> [test.cpp:7:15]: (error) Comparing pointers that point to different objects [comparePointers]\n" "[test.cpp:5:10]: (style) Variable 'xp' can be declared as pointer to const [constVariablePointer]\n" @@ -13609,7 +13609,7 @@ class TestOther : public TestFixture { check("bool f(int * xp, int* yp) {\n" " return &xp > &yp;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:1:14] -> [test.cpp:2:12] -> [test.cpp:1:23] -> [test.cpp:2:18] -> [test.cpp:2:16]: (error) Comparing pointers that point to different objects [comparePointers]\n", errout_str()); @@ -13618,7 +13618,7 @@ class TestOther : public TestFixture { " int x = 0;\n" " int y = 1;\n" " return &x - &y;\n" - "}"); + "}\n"); ASSERT_EQUALS( "[test.cpp:2:9] -> [test.cpp:4:12] -> [test.cpp:3:9] -> [test.cpp:4:17] -> [test.cpp:4:15]: (error) Subtracting pointers that point to different objects [subtractPointers]\n", errout_str()); @@ -13628,19 +13628,19 @@ class TestOther : public TestFixture { " int* xp = &x[0];\n" " int* yp = &x[1];\n" " return xp > yp;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:10]: (style) Variable 'xp' can be declared as pointer to const [constVariablePointer]\n" "[test.cpp:4:10]: (style) Variable 'yp' can be declared as pointer to const [constVariablePointer]\n", errout_str()); check("bool f(const int * xp, const int* yp) {\n" " return xp > yp;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("bool f(const int & x, const int& y) {\n" " return &x > &y;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int& g();\n" @@ -13650,7 +13650,7 @@ class TestOther : public TestFixture { " const int* xp = &x;\n" " const int* yp = &y;\n" " return xp > yp;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("struct A {int data;};\n" @@ -13660,7 +13660,7 @@ class TestOther : public TestFixture { " int* xp = &x->data;\n" " int* yp = &y->data;\n" " return xp > yp;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:10]: (style) Variable 'xp' can be declared as pointer to const [constVariablePointer]\n" "[test.cpp:6:10]: (style) Variable 'yp' can be declared as pointer to const [constVariablePointer]\n", errout_str()); @@ -13711,21 +13711,21 @@ class TestOther : public TestFixture { " return A::Hash{}(a);\n" " }\n" " };\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } void moduloOfOne() { check("void f(unsigned int x) {\n" " int y = x % 1;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:13]: (style) Modulo of one is always equal to zero [moduloofone]\n", errout_str()); check("void f() {\n" " for (int x = 1; x < 10; x++) {\n" " int y = 100 % x;\n" " }\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(int i, int j) {\n" // #11191 @@ -13758,44 +13758,44 @@ class TestOther : public TestFixture { " union { int i; float f; } u;\n" " u.i = 0;\n" " u.i = u.f;\n" // <- error - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:9]: (error) Overlapping read/write of union is undefined behavior [overlappingWriteUnion]\n", errout_str()); check("void foo() {\n" // #11013 " union { struct { uint8_t a; uint8_t b; }; uint16_t c; } u;\n" " u.a = u.b = 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // memcpy check("void foo() {\n" " char a[10];\n" " memcpy(&a[5], &a[4], 2u);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Overlapping read/write in memcpy() is undefined behavior [overlappingWriteFunction]\n", errout_str()); check("void foo() {\n" " char a[10];\n" " memcpy(a+5, a+4, 2u);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Overlapping read/write in memcpy() is undefined behavior [overlappingWriteFunction]\n", errout_str()); check("void foo() {\n" " char a[10];\n" " memcpy(a, a+1, 2u);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Overlapping read/write in memcpy() is undefined behavior [overlappingWriteFunction]\n", errout_str()); check("void foo() {\n" " char a[8];\n" " memcpy(&a[0], &a[4], 4u);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("_Bool a[10];\n" // #10350 "void foo() {\n" " memcpy(&a[5], &a[4], 2u * sizeof(a[0]));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Overlapping read/write in memcpy() is undefined behavior [overlappingWriteFunction]\n", errout_str()); check("int K[2];\n" // #12638 @@ -13804,7 +13804,7 @@ class TestOther : public TestFixture { " memcpy(&K[1], &K[0], sizeof(K[0]));\n" " memcpy(p, p + 1, sizeof(*p));\n" " memcpy(p + 1, p, sizeof(*p));\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("int K[2];\n" @@ -13813,7 +13813,7 @@ class TestOther : public TestFixture { " memcpy(&K[1], &K[0], 2 *sizeof(K[0]));\n" " memcpy(p, p + 1, 2 * sizeof(*p));\n" " memcpy(p + 1, p, 2 * sizeof(*p));\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Overlapping read/write in memcpy() is undefined behavior [overlappingWriteFunction]\n" "[test.cpp:4:5]: (error) Overlapping read/write in memcpy() is undefined behavior [overlappingWriteFunction]\n" "[test.cpp:5:5]: (error) Overlapping read/write in memcpy() is undefined behavior [overlappingWriteFunction]\n" @@ -13824,25 +13824,25 @@ class TestOther : public TestFixture { check("void foo() {\n" " wchar_t a[10];\n" " wmemcpy(&a[5], &a[4], 2u);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Overlapping read/write in wmemcpy() is undefined behavior [overlappingWriteFunction]\n", errout_str()); check("void foo() {\n" " wchar_t a[10];\n" " wmemcpy(a+5, a+4, 2u);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Overlapping read/write in wmemcpy() is undefined behavior [overlappingWriteFunction]\n", errout_str()); check("void foo() {\n" " wchar_t a[10];\n" " wmemcpy(a, a+1, 2u);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (error) Overlapping read/write in wmemcpy() is undefined behavior [overlappingWriteFunction]\n", errout_str()); // strcpy check("void foo(char *ptr) {\n" " strcpy(ptr, ptr);\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:2:5]: (error) Overlapping read/write in strcpy() is undefined behavior [overlappingWriteFunction]\n", errout_str()); } @@ -13899,7 +13899,7 @@ class TestOther : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:4:17]: (style) Pointer expression 'a.x' converted to bool is always true. [knownPointerToBool]\n", errout_str()); - check("void f(bool* b) { if (b) *b = true; }"); + check("void f(bool* b) { if (b) *b = true; }\n"); ASSERT_EQUALS("", errout_str()); check("bool f() {\n" @@ -13947,7 +13947,7 @@ class TestOther : public TestFixture { "void f() {\n" " bool b[2] = {};\n" " g(b);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -14146,7 +14146,7 @@ class TestOther : public TestFixture { " union bad_union_0 bad1 = {0};\n" " e(&bad1);\n" " bad_union_1 bad2 = {0};\n" - "}"); + "}\n"); const std::string exp = unionZeroInitMessage(20, 28, "bad0", "i") + unionZeroInitMessage(21, 21, "bad1", "i64") + unionZeroInitMessage(23, 15, "bad2", "i"); @@ -14157,7 +14157,7 @@ class TestOther : public TestFixture { check( "void foo(void) {\n" " union { int c; char s8[2]; } u = {0};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -14173,7 +14173,7 @@ class TestOther : public TestFixture { " } s1;\n" " } s0;\n" " } u = {0};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -14181,7 +14181,7 @@ class TestOther : public TestFixture { check( "union u {\n" " Unknown x;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -14201,7 +14201,7 @@ class TestOther : public TestFixture { "\n" "void foo(void) {\n" " Evex evex = {0};\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } }; diff --git a/test/testpostfixoperator.cpp b/test/testpostfixoperator.cpp index 2277039820f..85568c974ac 100644 --- a/test/testpostfixoperator.cpp +++ b/test/testpostfixoperator.cpp @@ -71,7 +71,7 @@ class TestPostfixOperator : public TestFixture { " k--;\n" " std::cout << k << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class K {};" @@ -82,7 +82,7 @@ class TestPostfixOperator : public TestFixture { " k++;\n" " std::cout << k << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("struct K {};" @@ -90,14 +90,14 @@ class TestPostfixOperator : public TestFixture { "{\n" " K k(0);\n" " k++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("struct K {};\n" "void foo(K& k)\n" "{\n" " k++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("union K {};" @@ -105,7 +105,7 @@ class TestPostfixOperator : public TestFixture { "{\n" " K k(0);\n" " k++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:5]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("class K {};" @@ -118,7 +118,7 @@ class TestPostfixOperator : public TestFixture { " }\n" " std::cout << k << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:9]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("class K {};" @@ -132,7 +132,7 @@ class TestPostfixOperator : public TestFixture { " k++;\n" " std::cout << k << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:5]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); @@ -144,7 +144,7 @@ class TestPostfixOperator : public TestFixture { " k--;\n" " std::cout << k << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:5:5]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("class K {};" @@ -155,7 +155,7 @@ class TestPostfixOperator : public TestFixture { " ++k;\n" " std::cout << k << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class K {};" @@ -166,7 +166,7 @@ class TestPostfixOperator : public TestFixture { " --k;\n" " std::cout << k << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); // #9042 @@ -177,7 +177,7 @@ class TestPostfixOperator : public TestFixture { "};\n" "template \n" "class s {};\n" - "using BOOL = char;"); + "using BOOL = char;\n"); ASSERT_EQUALS("", errout_str()); } @@ -188,7 +188,7 @@ class TestPostfixOperator : public TestFixture { " std::cout << i << std::endl;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class K {};\n" @@ -198,7 +198,7 @@ class TestPostfixOperator : public TestFixture { " std::cout << i << std::endl;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:28]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("class K {};\n" @@ -208,7 +208,7 @@ class TestPostfixOperator : public TestFixture { " std::cout << i << std::endl;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("class K {};\n" @@ -218,7 +218,7 @@ class TestPostfixOperator : public TestFixture { " std::cout << i << std::endl;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:27]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("class K {};\n" @@ -228,7 +228,7 @@ class TestPostfixOperator : public TestFixture { " std::cout << i << std::endl;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); check("void f(const std::string &s) {\n" // #7731 @@ -246,7 +246,7 @@ class TestPostfixOperator : public TestFixture { " k++;\n" " std::cout << k << std::endl;\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:5]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); } @@ -261,7 +261,7 @@ class TestPostfixOperator : public TestFixture { " }\n" " v.clear();\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:6:64]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("int main() {\n" @@ -275,7 +275,7 @@ class TestPostfixOperator : public TestFixture { " it++;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:8]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("int main() {\n" @@ -288,7 +288,7 @@ class TestPostfixOperator : public TestFixture { " it++;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:8:8]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("int main() {\n" @@ -302,14 +302,14 @@ class TestPostfixOperator : public TestFixture { " rit--;\n" " }\n" " return 0;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:9:8]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); } void test2168() { ASSERT_THROW_INTERNAL(check("--> declare allocator lock here\n" - "int main(){}"), + "int main(){}\n"), AST); } @@ -317,7 +317,7 @@ class TestPostfixOperator : public TestFixture { check("void f(int* p){\n" " p++;\n" " std::cout << *p;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -327,7 +327,7 @@ class TestPostfixOperator : public TestFixture { "\n" "void f() {\n" " p++;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -335,7 +335,7 @@ class TestPostfixOperator : public TestFixture { check("bool foo() {\n" " std::vector::iterator aIter(aImport.begin());\n" " aIter++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:3:5]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); } @@ -344,14 +344,14 @@ class TestPostfixOperator : public TestFixture { " class A {}; class B {A a;};\n" " B b;\n" " b.a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:7]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("bool foo() {\n" " class A {}; class B {A a;};\n" " B b;\n" " foo(b.a++);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -360,7 +360,7 @@ class TestPostfixOperator : public TestFixture { " class A {};\n" " A a;\n" " i++, a++;\n" - "}"); + "}\n"); ASSERT_EQUALS("[test.cpp:4:10]: (performance) Prefer prefix ++/-- operators for non-primitive types. [postfixOperator]\n", errout_str()); check("bool foo(int i) {\n" @@ -368,7 +368,7 @@ class TestPostfixOperator : public TestFixture { " A a;\n" " foo(i, a++);\n" " foo(a++, i);\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } @@ -380,7 +380,7 @@ class TestPostfixOperator : public TestFixture { " a += i;\n" " }\n" " return a;\n" - "}"); + "}\n"); ASSERT_EQUALS("", errout_str()); } }; diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 55fcafd4f4f..f1cffe50486 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -57,7 +57,7 @@ class TestPreprocessor : public TestFixture { std::string expandMacros_(const char* file, int line, const char (&code)[size], ErrorLogger &errorLogger) const { simplecpp::OutputList outputList; std::vector files; - simplecpp::TokenList tokens1 = simplecpp::TokenList(code, files, "file.cpp", &outputList); + simplecpp::TokenList tokens1 = simplecpp::TokenList(code, files, "file.cpp", {}, &outputList); Preprocessor p(tokens1, settingsDefault, errorLogger, Path::identify(tokens1.getFiles()[0], false)); ASSERT_LOC(p.loadFiles(files), file, line); simplecpp::TokenList tokens2 = p.preprocess("", files, outputList); @@ -75,7 +75,7 @@ class TestPreprocessor : public TestFixture { throw std::runtime_error("token list not empty"); simplecpp::OutputList outputList; - const simplecpp::TokenList tokens1(code, files, file0, &outputList); + const simplecpp::TokenList tokens1(code, files, file0, dui, &outputList); // Preprocess.. simplecpp::TokenList tokens2(files); @@ -124,7 +124,7 @@ class TestPreprocessor : public TestFixture { simplecpp::OutputList outputList; std::vector files; - simplecpp::TokenList tokens({code, size}, files, Path::simplifyPath(filename), &outputList); + simplecpp::TokenList tokens({code, size}, files, Path::simplifyPath(filename), {}, &outputList); // TODO: we should be using the actual Preprocessor implementation Preprocessor preprocessor(tokens, settings, errorlogger, Path::identify(tokens.getFiles()[0], false)); @@ -399,7 +399,7 @@ class TestPreprocessor : public TestFixture { ASSERT(settings.library.load("", library, false).errorcode == Library::ErrorCode::OK); std::vector files; simplecpp::OutputList outputList; - simplecpp::TokenList tokens(code,files,"test.c",&outputList); + simplecpp::TokenList tokens(code, files, "test.c", {}, &outputList); Preprocessor preprocessor(tokens, settings, *this, Standards::Language::C); std::set configs = { "" }; std::set configDefines = { "__cplusplus" }; @@ -410,9 +410,11 @@ class TestPreprocessor : public TestFixture { settings.library.defines().end(), std::inserter(configDefines, configDefines.end()), getDefineName); - preprocessor.setLoadCallback([&](simplecpp::FileData &data) { - Preprocessor::removeComments(data.tokens); - preprocessor.getConfigs(data.filename, data.tokens, configDefines, configs); + preprocessor.setLoadCallback([&](simplecpp::FileData &data, bool loaded) { + if (loaded) { + Preprocessor::removeComments(data.tokens); + preprocessor.getConfigs(data.filename, data.tokens, configDefines, configs); + } }); preprocessor.removeComments(); preprocessor.getConfigs(configDefines, configs); @@ -429,8 +431,10 @@ class TestPreprocessor : public TestFixture { std::vector files; simplecpp::TokenList tokens(code,files,"test.c"); Preprocessor preprocessor(tokens, settingsDefault, *this, Standards::Language::C); - preprocessor.setLoadCallback([](simplecpp::FileData &data) { - Preprocessor::removeComments(data.tokens); + preprocessor.setLoadCallback([](simplecpp::FileData &data, bool loaded) { + if (loaded) { + Preprocessor::removeComments(data.tokens); + } }); preprocessor.removeComments(); ASSERT(preprocessor.loadFiles(files)); @@ -442,7 +446,7 @@ class TestPreprocessor : public TestFixture { "cpp\n" "#else\n" "c\n" - "#endif"; + "#endif\n"; { // Preprocess => actual result.. @@ -498,7 +502,7 @@ class TestPreprocessor : public TestFixture { { ScopedFile header("ab.h", "#error hello world!\n"); const auto settings = dinit(Settings, $.userDefines = "TEST"); - const char code[] = "#include \"ab.h\""; + const char code[] = "#include \"ab.h\"\n"; (void)getcodeforcfg(settings, *this, code, "TEST", "test.c"); ASSERT_EQUALS("[ab.h:1:2]: (error) #error hello world! [preprocessorErrorDirective]\n", errout_str()); } @@ -508,7 +512,7 @@ class TestPreprocessor : public TestFixture { ScopedFile header("ab.h", ""); const auto settings = dinit(Settings, $.userDefines = "TEST"); const char code[] = "#include \"ab.h\"\n" - "#error aaa"; + "#error aaa\n"; (void)getcodeforcfg(settings, *this, code, "TEST", "test.c"); ASSERT_EQUALS("[test.c:2:2]: (error) #error aaa [preprocessorErrorDirective]\n", errout_str()); } @@ -577,7 +581,7 @@ class TestPreprocessor : public TestFixture { "\n" "#ifndef C\n" "#error aa\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("A=A;B=B;C\nA=A;C\nC\n", getConfigsStr(filedata)); } @@ -618,7 +622,7 @@ class TestPreprocessor : public TestFixture { // Handling include guards.. const char filedata[] = "#include \"abc.h\"\n" "#ifdef ABC\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\nABC=ABC\n", getConfigsStr(filedata)); } @@ -954,7 +958,7 @@ class TestPreprocessor : public TestFixture { void ticket_4922() { // #4922 const char code[] = "__asm__ \n" "{ int extern __value) 0; (double return (\"\" } extern\n" - "__typeof __finite (__finite) __finite __inline \"__GI___finite\");"; + "__typeof __finite (__finite) __finite __inline \"__GI___finite\");\n"; (void)getcode(settings0, *this, code); } @@ -1065,7 +1069,7 @@ class TestPreprocessor : public TestFixture { void macro_simple16() { // # 4703 const char filedata[] = "#define MACRO( A, B, C ) class A##B##C##Creator {};\n" - "MACRO( B\t, U , G )"; + "MACRO( B\t, U , G )\n"; ASSERT_EQUALS("\nclass BUGCreator { } ;", expandMacros(filedata, *this)); } @@ -1073,41 +1077,41 @@ class TestPreprocessor : public TestFixture { // It would probably be OK if the generated code was // "\n123+$123" since the first 123 comes from the source code const char filedata[] = "#define MACRO(A) A+123\n" - "MACRO(123)"; + "MACRO(123)\n"; ASSERT_EQUALS("\n123 + 123", expandMacros(filedata, *this)); } void macro_simple18() { // (1e-7) const char filedata1[] = "#define A (1e-7)\n" - "a=A;"; + "a=A;\n"; ASSERT_EQUALS("\na = ( 1e-7 ) ;", expandMacros(filedata1, *this)); const char filedata2[] = "#define A (1E-7)\n" - "a=A;"; + "a=A;\n"; ASSERT_EQUALS("\na = ( 1E-7 ) ;", expandMacros(filedata2, *this)); const char filedata3[] = "#define A (1e+7)\n" - "a=A;"; + "a=A;\n"; ASSERT_EQUALS("\na = ( 1e+7 ) ;", expandMacros(filedata3, *this)); const char filedata4[] = "#define A (1.e+7)\n" - "a=A;"; + "a=A;\n"; ASSERT_EQUALS("\na = ( 1.e+7 ) ;", expandMacros(filedata4, *this)); const char filedata5[] = "#define A (1.7f)\n" - "a=A;"; + "a=A;\n"; ASSERT_EQUALS("\na = ( 1.7f ) ;", expandMacros(filedata5, *this)); const char filedata6[] = "#define A (.1)\n" - "a=A;"; + "a=A;\n"; ASSERT_EQUALS("\na = ( .1 ) ;", expandMacros(filedata6, *this)); const char filedata7[] = "#define A (1.)\n" - "a=A;"; + "a=A;\n"; ASSERT_EQUALS("\na = ( 1. ) ;", expandMacros(filedata7, *this)); const char filedata8[] = "#define A (8.0E+007)\n" - "a=A;"; + "a=A;\n"; ASSERT_EQUALS("\na = ( 8.0E+007 ) ;", expandMacros(filedata8, *this)); } @@ -1279,8 +1283,8 @@ class TestPreprocessor : public TestFixture { void macro_NULL() { // See ticket #4482 - UB when passing NULL to variadic function - ASSERT_EQUALS("\n0", expandMacros("#define null 0\nnull", *this)); - TODO_ASSERT_EQUALS("\nNULL", "\n0", expandMacros("#define NULL 0\nNULL", *this)); // TODO: Let the tokenizer handle NULL? + ASSERT_EQUALS("\n0", expandMacros("#define null 0\nnull\n", *this)); + TODO_ASSERT_EQUALS("\nNULL\n", "\n0", expandMacros("#define NULL 0\nNULL\n", *this)); // TODO: Let the tokenizer handle NULL? } void string1() { @@ -1530,7 +1534,7 @@ class TestPreprocessor : public TestFixture { "#pragma asm foo\n" " mov r1, 11\n" "#pragma endasm bar\n" - "bbb"; + "bbb\n"; // Preprocess => actual result.. const std::map actual = getcode(settings0, *this, filedata); @@ -1544,7 +1548,7 @@ class TestPreprocessor : public TestFixture { const char filedata[] = "#pragma asm\n" " mov @w1, 11\n" "#pragma endasm ( temp=@w1 )\n" - "bbb"; + "bbb\n"; // Preprocess => actual result.. const std::map actual = getcode(settings0, *this, filedata); @@ -1666,7 +1670,7 @@ class TestPreprocessor : public TestFixture { "#else\n" "#define N 20\n" "#endif\n" - "N"; + "N\n"; // Preprocess => actual result.. const std::map actual = getcode(settings0, *this, filedata); @@ -1734,14 +1738,14 @@ class TestPreprocessor : public TestFixture { const char filedata[] = "#define A 0\n" "#if A\n" "FOO\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("", getcodeforcfg(settings0, *this, filedata,"","test.c")); } { const char filedata[] = "#define A 1\n" "#if A==1\n" "FOO\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\n\nFOO", getcodeforcfg(settings0, *this, filedata,"","test.c")); } } @@ -1751,7 +1755,7 @@ class TestPreprocessor : public TestFixture { "#define B A\n" "#if (B==A) || (B==C)\n" "FOO\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\n\n\nFOO", getcodeforcfg(settings0, *this, filedata,"","test.c")); } @@ -1759,7 +1763,7 @@ class TestPreprocessor : public TestFixture { const char filedata[] = "#define A 0\n" "#if (A==0)\n" "FOO\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\n\nFOO", getcodeforcfg(settings0, *this, filedata,"","test.c")); } @@ -1767,7 +1771,7 @@ class TestPreprocessor : public TestFixture { const char filedata[] = "#define X +123\n" "#if X==123\n" "FOO\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\n\nFOO", getcodeforcfg(settings0, *this, filedata,"","test.c")); } @@ -1777,7 +1781,7 @@ class TestPreprocessor : public TestFixture { "#define B (A & 0x00f0)\n" "#if B==0x0010\n" "FOO\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\n\n\nFOO", getcodeforcfg(settings0, *this, filedata,"","test.c")); } { @@ -1786,14 +1790,14 @@ class TestPreprocessor : public TestFixture { "#define C (B & A)\n" "#if C==0x0010\n" "FOO\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\n\n\n\nFOO", getcodeforcfg(settings0, *this, filedata,"","test.c")); } { const char filedata[] = "#define A (1+A)\n" // don't hang for recursive macros "#if A==1\n" "FOO\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\n\nFOO", getcodeforcfg(settings0, *this, filedata,"","test.c")); } } @@ -1925,7 +1929,7 @@ class TestPreprocessor : public TestFixture { const char filedata[] = "#ifndef A\n" "#define A(x) x\n" "#endif\n" - "A(123);"; + "A(123);\n"; // Preprocess => actual result.. const std::map actual = getcode(settings0, *this, filedata); @@ -2111,7 +2115,7 @@ class TestPreprocessor : public TestFixture { } void remarkComment4() { - const char code[] = "//REMARK /"; + const char code[] = "//REMARK /\n"; const auto remarkComments = getRemarkComments(code, *this); ASSERT_EQUALS(0, remarkComments.size()); } @@ -2160,19 +2164,19 @@ class TestPreprocessor : public TestFixture { void predefine5() { // #3737, #5119 - automatically define __cplusplus // #3737... - const char code[] = "#ifdef __cplusplus\n123\n#endif"; + const char code[] = "#ifdef __cplusplus\n123\n#endif\n"; ASSERT_EQUALS("", getcodeforcfg(settings0, *this, code, "", "test.c")); ASSERT_EQUALS("\n123", getcodeforcfg(settings0, *this, code, "", "test.cpp")); } void predefine6() { // automatically define __STDC_VERSION__ - const char code[] = "#ifdef __STDC_VERSION__\n123\n#endif"; + const char code[] = "#ifdef __STDC_VERSION__\n123\n#endif\n"; ASSERT_EQUALS("\n123", getcodeforcfg(settings0, *this, code, "", "test.c")); ASSERT_EQUALS("", getcodeforcfg(settings0, *this, code, "", "test.cpp")); } void strictAnsi() { - const char code[] = "#ifdef __STRICT_ANSI__\n123\n#endif"; + const char code[] = "#ifdef __STRICT_ANSI__\n123\n#endif\n"; Settings settings; settings.standards.setStd("gnu99"); @@ -2324,7 +2328,7 @@ class TestPreprocessor : public TestFixture { "#define bar foo\n" "#define baz bar+0\n" "#if 0\n" - "#endif"; + "#endif\n"; ASSERT_EQUALS("\n", getConfigsStr(filedata)); } @@ -2733,27 +2737,27 @@ class TestPreprocessor : public TestFixture { void getConfigsInvalid() { // #14732 { - const char filedata[] = "#if<"; + const char filedata[] = "#if<\n"; ASSERT_EQUALS("\n", getConfigsStr(filedata)); } { - const char filedata[] = "#if>"; + const char filedata[] = "#if>\n"; ASSERT_EQUALS("\n", getConfigsStr(filedata)); } { - const char filedata[] = "#if=="; + const char filedata[] = "#if==\n"; ASSERT_EQUALS("\n", getConfigsStr(filedata)); } { - const char filedata[] = "#if<="; + const char filedata[] = "#if<=\n"; ASSERT_EQUALS("\n", getConfigsStr(filedata)); } { - const char filedata[] = "#if>="; + const char filedata[] = "#if>=\n"; ASSERT_EQUALS("\n", getConfigsStr(filedata)); } { - const char filedata[] = "#if!"; + const char filedata[] = "#if!\n"; ASSERT_EQUALS("\n", getConfigsStr(filedata)); } } @@ -2764,7 +2768,7 @@ class TestPreprocessor : public TestFixture { "#elif sizeof(unsigned short) == 4\n" "Fred & Wilma\n" "#else\n" - "#endif"; + "#endif\n"; const std::map actual = getcode(settings0, *this, code); ASSERT_EQUALS("\nFred & Wilma", actual.at("")); @@ -2792,7 +2796,7 @@ class TestPreprocessor : public TestFixture { void garbage() { const char filedata[] = "V\n" "#define X b #endif #line 0 \"x\" ;\n" - "#if ! defined ( Y ) #endif"; + "#if ! defined ( Y ) #endif\n"; // Preprocess => don't crash.. (void)getcode(settings0, *this, filedata); @@ -2816,7 +2820,7 @@ class TestPreprocessor : public TestFixture { ScopedFile header("header.h", ""); - const char code[] = "#include \"header.h\""; + const char code[] = "#include \"header.h\"\n"; (void)getcodeforcfg(settings, *this, code, "", "test.c"); ASSERT_EQUALS("", errout_str()); @@ -2831,7 +2835,7 @@ class TestPreprocessor : public TestFixture { ); setTemplateFormat("simple"); - const char code[] = "#include \"header.h\""; + const char code[] = "#include \"header.h\"\n"; (void)getcodeforcfg(settings, *this, code, "", "test.c"); ASSERT_EQUALS("test.c:1:2: information: Include file: \"header.h\" not found. [missingInclude]\n", errout_str()); @@ -2848,7 +2852,7 @@ class TestPreprocessor : public TestFixture { ScopedFile header("header.h", "", "inc"); - const char code[] = "#include \"header.h\""; + const char code[] = "#include \"header.h\"\n"; (void)getcodeforcfg(settings, *this, code, "", "test.c"); ASSERT_EQUALS("test.c:1:2: information: Include file: \"header.h\" not found. [missingInclude]\n", errout_str()); @@ -2866,7 +2870,7 @@ class TestPreprocessor : public TestFixture { ScopedFile header("header.h", "", "inc"); - const char code[] = "#include \"inc/header.h\""; + const char code[] = "#include \"inc/header.h\"\n"; (void)getcodeforcfg(settings, *this, code, "", "test.c"); ASSERT_EQUALS("", errout_str()); @@ -2884,7 +2888,7 @@ class TestPreprocessor : public TestFixture { ScopedFile header("header.h", "", Path::getCurrentPath()); - std::string code("#include \"" + header.path() + "\""); + std::string code("#include \"" + header.path() + "\"\n"); (void)getcodeforcfg(settings, *this, code.data(), code.size(), "", "test.c"); ASSERT_EQUALS("", errout_str()); @@ -2901,7 +2905,7 @@ class TestPreprocessor : public TestFixture { const std::string header = Path::join(Path::getCurrentPath(), "header.h"); - std::string code("#include \"" + header + "\""); + std::string code("#include \"" + header + "\"\n"); (void)getcodeforcfg(settings, *this, code.data(), code.size(), "", "test.c"); ASSERT_EQUALS("test.c:1:2: information: Include file: \"" + header + "\" not found. [missingInclude]\n", errout_str()); @@ -2918,7 +2922,7 @@ class TestPreprocessor : public TestFixture { ScopedFile header("header.h", ""); - const char code[] = "#include "; + const char code[] = "#include \n"; (void)getcodeforcfg(settings, *this, code, "", "test.c"); ASSERT_EQUALS("test.c:1:2: information: Include file: not found. Please note: Standard library headers do not need to be provided to get proper results. [missingIncludeSystem]\n", errout_str()); @@ -2933,7 +2937,7 @@ class TestPreprocessor : public TestFixture { ); setTemplateFormat("simple"); - const char code[] = "#include "; + const char code[] = "#include \n"; (void)getcodeforcfg(settings, *this, code, "", "test.c"); ASSERT_EQUALS("test.c:1:2: information: Include file: not found. Please note: Standard library headers do not need to be provided to get proper results. [missingIncludeSystem]\n", errout_str()); @@ -2951,7 +2955,7 @@ class TestPreprocessor : public TestFixture { ScopedFile header("header.h", "", "system"); - const char code[] = "#include "; + const char code[] = "#include \n"; (void)getcodeforcfg(settings, *this, code, "", "test.c"); ASSERT_EQUALS("", errout_str()); @@ -2969,7 +2973,7 @@ class TestPreprocessor : public TestFixture { ScopedFile header("header.h", "", Path::getCurrentPath()); - std::string code("#include <" + header.path() + ">"); + std::string code("#include <" + header.path() + ">\n"); (void)getcodeforcfg(settings, *this, code.data(), code.size(), "", "test.c"); ASSERT_EQUALS("", errout_str()); @@ -2986,7 +2990,7 @@ class TestPreprocessor : public TestFixture { const std::string header = Path::join(Path::getCurrentPath(), "header.h"); - std::string code("#include <" + header + ">"); + std::string code("#include <" + header + ">\n"); (void)getcodeforcfg(settings, *this, code.data(), code.size(), "", "test.c"); ASSERT_EQUALS("test.c:1:2: information: Include file: <" + header + "> not found. Please note: Standard library headers do not need to be provided to get proper results. [missingIncludeSystem]\n", errout_str()); @@ -3008,7 +3012,7 @@ class TestPreprocessor : public TestFixture { const char code[] = "#include \"missing.h\"\n" "#include \n" "#include \n" - "#include \"header2.h\""; + "#include \"header2.h\"\n"; (void)getcodeforcfg(settings, *this, code, "", "test.c"); ASSERT_EQUALS("test.c:1:2: information: Include file: \"missing.h\" not found. [missingInclude]\n" @@ -3068,8 +3072,8 @@ class TestPreprocessor : public TestFixture { std::vector files; simplecpp::TokenList tokens(code, files, "test.c"); - ScopedFile header1("header1.h", "1"); - ScopedFile header2("header2.h", "2"); + ScopedFile header1("header1.h", "1\n"); + ScopedFile header2("header2.h", "2\n"); Settings settings; Preprocessor preprocessor(tokens, settings, *this, Standards::Language::CPP); @@ -3087,7 +3091,7 @@ class TestPreprocessor : public TestFixture { } void hasInclude() { - const char code[] = "#if __has_include()\n123\n#endif"; + const char code[] = "#if __has_include()\n123\n#endif\n"; Settings settings; settings.standards.setStd("c++11"); @@ -3107,7 +3111,7 @@ class TestPreprocessor : public TestFixture { // #11928 / #10045 const char code[] = "void f(long l) {\n" " if (l > INT_MAX) {}\n" - "}"; + "}\n"; const std::string actual = getcodeforcfg(settings0, *this, code, "", "test.c"); ASSERT_EQUALS("void f ( long l ) {\n" "if ( l > $2147483647 ) { }\n" @@ -3116,9 +3120,9 @@ class TestPreprocessor : public TestFixture { void hashCalculation() { // #12383 - const char code[] = "int a;"; - const char code2[] = "int a;"; // extra space - const char code3[] = "\n\nint a;"; // extra new line + const char code[] = "int a;\n"; + const char code2[] = "int a;\n"; // extra space + const char code3[] = "\n\nint a;\n"; // extra new line ASSERT_EQUALS(getHash(code), getHash(code)); ASSERT_EQUALS(getHash(code2), getHash(code2)); @@ -3130,7 +3134,7 @@ class TestPreprocessor : public TestFixture { void standard() { - const char code[] = "int a;"; + const char code[] = "int a;\n"; // TODO: this bypasses the standard determined from the settings - the parameter should not be exposed simplecpp::DUI dui; @@ -3171,7 +3175,7 @@ class TestPreprocessor : public TestFixture { std::vector files; TokenList tokenlist{settingsDefault, Standards::Language::CPP}; // TODO: can this happen from application code? if yes we need to turn it into a proper error - ASSERT_THROW_EQUALS(preprocess(code, files, "test.cpp", tokenlist, dui), std::runtime_error, "unexpected simplecpp::Output type 9"); + ASSERT_THROW_EQUALS(preprocess(code, files, "test.cpp", tokenlist, dui), std::runtime_error, "unexpected simplecpp::Output type 12"); ASSERT(!tokenlist.front()); // nothing is tokenized when an unknown standard is provided } } @@ -3181,8 +3185,8 @@ class TestPreprocessor : public TestFixture { const char inc[] = "class A {\n" "public:\n" " void f() {}\n" - "};"; - const char code[] = R"(#include "test.h")"; + "};\n"; + const char code[] = "#include \"test.h\"\n"; ScopedFile header("test.h", inc); const std::string processed = getcodeforcfg(settingsDefault, *this, code, "", "test.cpp"); ASSERT_EQUALS( @@ -3197,7 +3201,7 @@ class TestPreprocessor : public TestFixture { void pragmaAsm() { - const char code[] = "#pragma asm"; + const char code[] = "#pragma asm\n"; ASSERT_THROW_INTERNAL(getcodeforcfg(settingsDefault, *this, code, "", "test.cpp"), InternalError::SYNTAX); } }; diff --git a/test/testprogrammemory.cpp b/test/testprogrammemory.cpp index 688efa0075b..c37431de608 100644 --- a/test/testprogrammemory.cpp +++ b/test/testprogrammemory.cpp @@ -39,7 +39,7 @@ class TestProgramMemory : public TestFixture { } void copyOnWrite() const { - SimpleTokenList tokenlist("1+1;"); + SimpleTokenList tokenlist("1+1;\n"); Token* tok = tokenlist.front(); const nonneg int id = 123; tok->exprId(id); diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index b37ed03db34..475d03c696d 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -372,7 +372,7 @@ class TestSimplifyTemplate : public TestFixture { void template1() { const char code[] = "template T f(T val) { T a; }\n" - "f(10);"; + "f(10);\n"; const char expected[] = "int f ( int val ) ; " "f ( 10 ) ; " @@ -383,7 +383,7 @@ class TestSimplifyTemplate : public TestFixture { void template2() { const char code[] = "template class Fred { T a; };\n" - "Fred fred;"; + "Fred fred;\n"; const char expected[] = "class Fred ; " "Fred fred ; " @@ -394,7 +394,7 @@ class TestSimplifyTemplate : public TestFixture { void template3() { const char code[] = "template class Fred { T data[sz]; };\n" - "Fred fred;"; + "Fred fred;\n"; const char expected[] = "class Fred ; " "Fred fred ; " @@ -405,7 +405,7 @@ class TestSimplifyTemplate : public TestFixture { void template4() { const char code[] = "template class Fred { Fred(); };\n" - "Fred fred;"; + "Fred fred;\n"; const char expected[] = "class Fred ; " "Fred fred ; " @@ -417,7 +417,7 @@ class TestSimplifyTemplate : public TestFixture { void template5() { const char code[] = "template class Fred { };\n" "template Fred::Fred() { }\n" - "Fred fred;"; + "Fred fred;\n"; const char expected[] = "class Fred ; " "Fred fred ; " @@ -430,7 +430,7 @@ class TestSimplifyTemplate : public TestFixture { void template6() { const char code[] = "template class Fred { };\n" "Fred fred1;\n" - "Fred fred2;"; + "Fred fred2;\n"; const char expected[] = "class Fred ; " "Fred fred1 ; " @@ -531,7 +531,7 @@ class TestSimplifyTemplate : public TestFixture { "template < typename T > class A { void f ( ) { B < T > a ; a = B < T > :: g ( ) ; T b ; b = 0 ; if ( b ) { b = 0 ; } } } ; " "template < typename T > B < T > h ( ) { return B < T > ( ) ; }", tok(code)); - ASSERT_EQUALS("class A { template < typename T > int foo ( T d ) ; } ;", tok("class A{ template int foo(T d);};")); + ASSERT_EQUALS("class A { template < typename T > int foo ( T d ) ; } ;", tok("class A{ template int foo(T d);};\n")); } void template9() { @@ -636,7 +636,7 @@ class TestSimplifyTemplate : public TestFixture { " y(AA::create(new CC(AA(), 0)))\n" " {}\n" "\n" - "int yy[AA::size()];"; + "int yy[AA::size()];\n"; const char expected[] = "class BB { } ; " "class AA ; " "class AA ; " @@ -712,7 +712,7 @@ class TestSimplifyTemplate : public TestFixture { " vec(const vec& v) {}\n" // <- never used don't instantiate "};\n" "\n" - "vec<4> v;"; + "vec<4> v;\n"; const char expected2[] = "struct vec<4> ; " "vec<4> v ; " "struct vec<4> { " @@ -770,7 +770,7 @@ class TestSimplifyTemplate : public TestFixture { void template18() { const char code[] = "template class foo { T a; };\n" - "foo *f;"; + "foo *f;\n"; const char expected[] = "class foo ; " "foo * f ; " @@ -815,7 +815,7 @@ class TestSimplifyTemplate : public TestFixture { void template21() { { const char code[] = "template struct Fred { T a; };\n" - "Fred fred;"; + "Fred fred;\n"; const char expected[] = "struct Fred ; " "Fred fred ; " @@ -826,7 +826,7 @@ class TestSimplifyTemplate : public TestFixture { { const char code[] = "template struct Fred { T data[sz]; };\n" - "Fred fred;"; + "Fred fred;\n"; const char expected[] = "struct Fred ; " "Fred fred ; " @@ -837,7 +837,7 @@ class TestSimplifyTemplate : public TestFixture { { const char code[] = "template struct Fred { Fred(); };\n" - "Fred fred;"; + "Fred fred;\n"; const char expected[] = "struct Fred ; " "Fred fred ; " @@ -849,7 +849,7 @@ class TestSimplifyTemplate : public TestFixture { { const char code[] = "template struct Fred { };\n" "Fred fred1;\n" - "Fred fred2;"; + "Fred fred2;\n"; const char expected[] = "struct Fred ; " "Fred fred1 ; " @@ -862,7 +862,7 @@ class TestSimplifyTemplate : public TestFixture { void template22() { const char code[] = "template struct Fred { T a; };\n" - "Fred fred;"; + "Fred fred;\n"; const char expected[] = "struct Fred ; " "Fred fred ; " @@ -875,7 +875,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "template void foo() { }\n" "void bar() {\n" " std::cout << (foo());\n" - "}"; + "}\n"; const char expected[] = "void foo ( ) ; " "void bar ( ) {" @@ -896,7 +896,7 @@ class TestSimplifyTemplate : public TestFixture { "template class bitset: B\n" "{};\n" "\n" - "bitset<1> z;"; + "bitset<1> z;\n"; const char expected[] = "struct B<4> ; " "class bitset<1> ; " "bitset<1> z ; " @@ -914,7 +914,7 @@ class TestSimplifyTemplate : public TestFixture { "template class bitset: B<((sizeof(int)) ? : 1)>\n" "{};\n" "\n" - "bitset<1> z;"; + "bitset<1> z;\n"; const char expected[] = "struct B<4> ; " "class bitset<1> ; " "bitset<1> z ; " @@ -937,7 +937,7 @@ class TestSimplifyTemplate : public TestFixture { void template27() { // #3350 - template inside macro call - const char code[] = "X(template class Fred);"; + const char code[] = "X(template class Fred);\n"; ASSERT_THROW_INTERNAL(tok(code), SYNTAX); } @@ -954,19 +954,19 @@ class TestSimplifyTemplate : public TestFixture { void template30() { // #3529 - template < template < .. - const char code[] = "template class A, class B> void f(){}"; + const char code[] = "template class A, class B> void f(){}\n"; ASSERT_EQUALS("template < template < class > class A , class B > void f ( ) { }", tok(code)); } void template31() { // #4010 - template reference type - const char code[] = "template struct A{}; A a;"; + const char code[] = "template struct A{}; A a;\n"; ASSERT_EQUALS("struct A ; " "A a ; " "struct A { } ;", tok(code)); // #7409 - rvalue - const char code2[] = "template struct A{}; A a;"; + const char code2[] = "template struct A{}; A a;\n"; ASSERT_EQUALS("struct A ; " "A a ; " "struct A { } ;", tok(code2)); @@ -996,7 +996,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "template struct A { };\n" "template struct B { };\n" "template struct C { A > > ab; };\n" - "C c;"; + "C c;\n"; ASSERT_EQUALS("struct A>> ; " "struct B> ; " "struct C ; " @@ -1011,7 +1011,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "struct A { };\n" "template struct B { };\n" "template struct C { };\n" - "C< B > c;"; + "C< B > c;\n"; ASSERT_EQUALS("struct A { } ; " "template < class T > struct B { } ; " // <- redundant.. but nevermind "struct C> ; " @@ -1026,13 +1026,13 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "namespace abc {\n" "template struct X { void f(X &x) {} };\n" "}\n" - "template <> int X::Y(0);"; + "template <> int X::Y(0);\n"; (void)tok(code); } void template35() { // #4074 - "A<'x'> a;" is not recognized as template instantiation const char code[] = "template class A {};\n" - "A <'x'> a;"; + "A <'x'> a;\n"; ASSERT_EQUALS("class A<'x'> ; " "A<'x'> a ; " "class A<'x'> { } ;", tok(code)); @@ -1041,7 +1041,7 @@ class TestSimplifyTemplate : public TestFixture { void template36() { // #4310 - Passing unknown template instantiation as template argument const char code[] = "template struct X { T t; };\n" "template struct Y { Foo < X< Bar > > _foo; };\n" // <- Bar is unknown - "Y bar;"; + "Y bar;\n"; ASSERT_EQUALS("struct X> ; " "struct Y ; " "Y bar ; " @@ -1055,7 +1055,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "class A { };\n" "template class B {};\n" "B b1;\n" - "B b2;"; + "B b2;\n"; ASSERT_EQUALS("class A { } ; class B ; B b1 ; B b2 ; class B { } ;", tok(code)); } @@ -1063,7 +1063,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "struct A { };\n" "template class B {};\n" "B b1;\n" - "B b2;"; + "B b2;\n"; ASSERT_EQUALS("struct A { } ; class B ; B b1 ; B b2 ; class B { } ;", tok(code)); } @@ -1071,7 +1071,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "enum A { };\n" "template class B {};\n" "B b1;\n" - "B b2;"; + "B b2;\n"; ASSERT_EQUALS("enum A { } ; class B ; B b1 ; B b2 ; class B { } ;", tok(code)); } @@ -1079,7 +1079,7 @@ class TestSimplifyTemplate : public TestFixture { void template_unhandled() { // An unhandled template usage should not be simplified.. - ASSERT_EQUALS("x < int > ( ) ;", tok("x();")); + ASSERT_EQUALS("x < int > ( ) ;", tok("x();\n")); } void template38() { // #4832 - Crash on C++11 right angle brackets @@ -1113,21 +1113,21 @@ class TestSimplifyTemplate : public TestFixture { } void template39() { // #4742 - Used to freeze in 1.60 - const char code[] = "template struct vector {" - " operator T() const;" - "};" - "void f() {" - " vector> v;" - " const vector vi = static_cast>(v);" - "}"; + const char code[] = "template struct vector {\n" + " operator T() const;\n" + "};\n" + "void f() {\n" + " vector> v;\n" + " const vector vi = static_cast>(v);\n" + "}\n"; (void)tok(code); } void template40() { // #5055 - false negatives when there is template specialization outside struct - const char code[] = "struct A {" - " template struct X { T t; };" - "};" - "template<> struct A::X { int *t; };"; + const char code[] = "struct A {\n" + " template struct X { T t; };\n" + "};\n" + "template<> struct A::X { int *t; };\n"; const char expected[] = "struct A { " "struct X ; " "template < typename T > struct X { T t ; } ; " @@ -1138,13 +1138,13 @@ class TestSimplifyTemplate : public TestFixture { void template41() { // #4710 - const in template instantiation not handled perfectly const char code1[] = "template struct X { };\n" - "void f(const X x) { }"; + "void f(const X x) { }\n"; ASSERT_EQUALS("struct X ; " "void f ( const X x ) { } " "struct X { } ;", tok(code1)); const char code2[] = "template T f(T t) { return t; }\n" - "int x() { return f(123); }"; + "int x() { return f(123); }\n"; ASSERT_EQUALS("int f ( int t ) ; " "int x ( ) { return f ( 123 ) ; } " "int f ( int t ) { return t ; }", tok(code2)); @@ -1158,7 +1158,7 @@ class TestSimplifyTemplate : public TestFixture { " }() + ^ {\n" " return sizeof...(args);\n" " }();\n" - "}"; + "}\n"; ASSERT_THROW_INTERNAL(tok(code), SYNTAX); } @@ -1176,7 +1176,7 @@ class TestSimplifyTemplate : public TestFixture { "int main(void) {\n" " C ca;\n" " return 0;\n" - "}"; + "}\n"; const char expected[] = "struct E ; " "struct C> ; " "struct C ; " @@ -1215,14 +1215,14 @@ class TestSimplifyTemplate : public TestFixture { } void template44() { // #5297 - const char code[] = "template struct StackContainer {" - " void foo(int i) {" - " if (0 >= 1 && i<0) {}" - " }" - "};" - "template class ZContainer : public StackContainer {};" - "struct FGSTensor {};" - "class FoldedZContainer : public ZContainer {};"; + const char code[] = "template struct StackContainer {\n" + " void foo(int i) {\n" + " if (0 >= 1 && i<0) {}\n" + " }\n" + "};\n" + "template class ZContainer : public StackContainer {};\n" + "struct FGSTensor {};\n" + "class FoldedZContainer : public ZContainer {};\n"; const char expected[] = "struct StackContainer ; " "class ZContainer ; " "struct FGSTensor { } ; " @@ -1237,14 +1237,14 @@ class TestSimplifyTemplate : public TestFixture { } void template45() { // #5814 - const char code[] = "namespace Constants { const int fourtytwo = 42; } " - "template struct TypeMath { " - " static const int mult = sizeof(T) * U; " - "}; " - "template struct FOO { " - " enum { value = TypeMath::mult }; " - "}; " - "FOO foo;"; + const char code[] = "namespace Constants { const int fourtytwo = 42; }\n" + "template struct TypeMath {\n" + " static const int mult = sizeof(T) * U;\n" + "};\n" + "template struct FOO {\n" + " enum { value = TypeMath::mult };\n" + "};\n" + "FOO foo;\n"; const char expected[] = "namespace Constants { const int fourtytwo = 42 ; } " "struct TypeMath ; " "struct FOO ; " @@ -1260,32 +1260,32 @@ class TestSimplifyTemplate : public TestFixture { } void template46() { // #5816 - ASSERT_NO_THROW(tok("template struct A { static const int value = 0; }; " - "template struct B { " - " enum { value = A::value }; " - "};")); + ASSERT_NO_THROW(tok("template struct A { static const int value = 0; };\n" + "template struct B {\n" + " enum { value = A::value };\n" + "};\n")); ASSERT_EQUALS("", errout_str()); - ASSERT_NO_THROW(tok("template struct A {}; " - "enum { e = sizeof(A) }; " - "template struct B {};")); + ASSERT_NO_THROW(tok("template struct A {};\n" + "enum { e = sizeof(A) };\n" + "template struct B {};\n")); ASSERT_EQUALS("", errout_str()); - ASSERT_NO_THROW(tok("template struct A { static const int value = 0; }; " - "template struct B { typedef int type; }; " - "template struct C { " - " enum { value = A::type, int>::value }; " - "};")); + ASSERT_NO_THROW(tok("template struct A { static const int value = 0; };\n" + "template struct B { typedef int type; };\n" + "template struct C {\n" + " enum { value = A::type, int>::value };\n" + "};\n")); ASSERT_EQUALS("", errout_str()); } void template47() { // #6023 - ASSERT_NO_THROW(tok("template > class C1 {}; " - "class C2 : public C1 {};")); + ASSERT_NO_THROW(tok("template > class C1 {};\n" + "class C2 : public C1 {};\n")); ASSERT_EQUALS("", errout_str()); } void template48() { // #6134 (hang) - (void)tok("template int f( { } ); " - "int foo = f<1>(0);"); + (void)tok("template int f( { } );\n" + "int foo = f<1>(0);\n"); ASSERT_EQUALS("", errout_str()); } @@ -1327,17 +1327,17 @@ class TestSimplifyTemplate : public TestFixture { } void template52() { // #6437 - const char code[] = "template int sum() { " - " return value + sum(); " - "} " - "template int calculate_value() { " - " if (x != y) { " - " return sum(); " - " } else { " - " return 0; " - " } " - "} " - "int value = calculate_value<1,1>();"; + const char code[] = "template int sum() {\n" + " return value + sum();\n" + "}\n" + "template int calculate_value() {\n" + " if (x != y) {\n" + " return sum();\n" + " } else {\n" + " return 0;\n" + " }\n" + "}\n" + "int value = calculate_value<1,1>();\n"; const char expected[] = "int sum<0> ( ) ; " "int calculate_value<1,1> ( ) ; " "int value ; value = calculate_value<1,1> ( ) ; " @@ -1355,13 +1355,13 @@ class TestSimplifyTemplate : public TestFixture { } void template53() { // #4335 - const char code[] = "template struct Factorial { " - " enum { value = N * Factorial::value }; " - "};" - "template <> struct Factorial<0> { " - " enum { value = 1 }; " - "};" - "const int x = Factorial<4>::value;"; + const char code[] = "template struct Factorial {\n" + " enum { value = N * Factorial::value };\n" + "};\n" + "template <> struct Factorial<0> {\n" + " enum { value = 1 };\n" + "};\n" + "const int x = Factorial<4>::value;\n"; const char expected[] = "struct Factorial<0> ; " "struct Factorial<4> ; " "struct Factorial<3> ; " @@ -1388,12 +1388,12 @@ class TestSimplifyTemplate : public TestFixture { } void template54() { // #6587 (use-after-free) - (void)tok("template _Tp* fn(); " - "template struct A { " - " template ())> " - " struct B { }; " - "}; " - "A a;"); + (void)tok("template _Tp* fn();\n" + "template struct A {\n" + " template ())>\n" + " struct B { };\n" + "};\n" + "A a;\n"); } void template55() { // #6604 @@ -1407,7 +1407,7 @@ class TestSimplifyTemplate : public TestFixture { "{\n" " friend struct ConstCastHelper, T>;\n" " AtSmartPtr(const AtSmartPtr& r);\n" - "};")); + "};\n")); // Similar problem can also happen with ... ASSERT_EQUALS( @@ -1427,16 +1427,16 @@ class TestSimplifyTemplate : public TestFixture { " (A*)(p);\n" " }\n" "};\n" - "A a(0);")); + "A a(0);\n")); } void template56() { // #7117 - const char code[] = "template struct Foo { " - " std::array mfoo; " - "}; " - "void foo() { " - " Foo myFoo; " - "}"; + const char code[] = "template struct Foo {\n" + " std::array mfoo;\n" + "};\n" + "void foo() {\n" + " Foo myFoo;\n" + "}\n"; const char expected[] = "struct Foo ; " "void foo ( ) { " "Foo myFoo ; " @@ -1449,7 +1449,7 @@ class TestSimplifyTemplate : public TestFixture { void template57() { // #7891 const char code[] = "template struct Test { Test(T); };\n" - "Test test( 0 );"; + "Test test( 0 );\n"; const char exp[] = "struct Test ; " "Test test ( 0 ) ; " "struct Test { Test ( unsigned long ) ; } ;"; @@ -1463,7 +1463,7 @@ class TestSimplifyTemplate : public TestFixture { "}\n" "void foo() {\n" " TestArithmetic();\n" - "}"; + "}\n"; const char exp[] = "void TestArithmetic ( ) ; " "void foo ( ) {" " TestArithmetic ( ) ; " @@ -1489,7 +1489,7 @@ class TestSimplifyTemplate : public TestFixture { "}\n" "int main () {\n" " return diagonalGroupTest<4>();\n" - "}"; + "}\n"; const char exp[] = "struct Factorial<0> ; " "struct Factorial<4> ; " "struct Factorial<3> ; " @@ -1511,7 +1511,7 @@ class TestSimplifyTemplate : public TestFixture { "template void f() {}\n" "template void h() { f::type(0)>(); }\n" "\n" - "void j() { h(); }"; + "void j() { h(); }\n"; const char exp[] = "struct S ; " "void f::type(0)> ( ) ; " "void h ( ) ; " @@ -1534,7 +1534,7 @@ class TestSimplifyTemplate : public TestFixture { " void f1(Bar x) {}\n" " Foo> f2() { }\n" "};\n" - "Bar c;"; + "Bar c;\n"; const char exp[] = "struct Foo> ; " "struct Bar ; " "Bar c ; " @@ -1551,7 +1551,7 @@ class TestSimplifyTemplate : public TestFixture { "template void f() { x = y ? C1::allocate(1) : 0; }\n" "template class C3 {};\n" "template C3::C3(const C3 &v) { C1 c1; }\n" - "C3 c3;"; + "C3 c3;\n"; const char exp[] = "struct C1 ; " "template < class T > void f ( ) { x = y ? ( C1 < int > :: allocate ( 1 ) ) : 0 ; } " "class C3 ; " @@ -1563,8 +1563,8 @@ class TestSimplifyTemplate : public TestFixture { } void template63() { // #8576 - const char code[] = "template struct TestClass { T m_hi; };" - "TestClass> objTest3;"; + const char code[] = "template struct TestClass { T m_hi; };\n" + "TestClass> objTest3;\n"; const char exp[] = "struct TestClass> ; " "TestClass> objTest3 ; " "struct TestClass> { std :: auto_ptr < v > m_hi ; } ;"; @@ -1585,7 +1585,7 @@ class TestSimplifyTemplate : public TestFixture { " t_func<0>();\n" " t_func<1>();\n" "}\n" - "};"; + "};\n"; const char exp[] = "bool foo ( ) ; " "struct A { " "void t_func<0> ( ) ; " @@ -1623,7 +1623,7 @@ class TestSimplifyTemplate : public TestFixture { "int main() {\n" " AssociationDAGlobalGraphObserver grObs;\n" " return 1;\n" - "}"; + "}\n"; const char exp[] = "namespace bpp " "{ " "class AssociationDAGraphImplObserver ; " @@ -1643,7 +1643,7 @@ class TestSimplifyTemplate : public TestFixture { " const int ** foo();\n" "};\n" "template const int ** Fred::foo() { return nullptr; }\n" - "Fred fred;"; + "Fred fred;\n"; const char exp[] = "struct Fred ; " "Fred fred ; " "struct Fred { " @@ -1666,7 +1666,7 @@ class TestSimplifyTemplate : public TestFixture { "template Container::Container(const Container & x) { nElements = x.nElements; c = x.c; }\n" "template Container & Container::operator = (const Container & x) { mElements = x.mElements; c = x.c; return *this; }\n" "template Container::~Container() {}\n" - "Container intContainer;"; + "Container intContainer;\n"; const char expected[] = "struct Container ; " "Container intContainer ; " @@ -1691,7 +1691,7 @@ class TestSimplifyTemplate : public TestFixture { " char dummy[sizeof(T)];\n" " T value;\n" "};\n" - "Fred fred;"; + "Fred fred;\n"; const char exp[] = "union Fred ; " "Fred fred ; " "union Fred { " @@ -1706,7 +1706,7 @@ class TestSimplifyTemplate : public TestFixture { " int test;\n" " template T lookup() { return test; }\n" " int Fun() { return lookup(); }\n" - "};"; + "};\n"; const char exp[] = "class Test { " "int test ; " "int lookup ( ) ; " @@ -1724,7 +1724,7 @@ class TestSimplifyTemplate : public TestFixture { "template\n" "class Bar : private Bar {\n" " void foo() { }\n" - "};"; + "};\n"; const char exp[] = "template < typename T , typename V , int KeySize = 0 > class Bar ; " "class Bar ; " "class Bar { " @@ -1756,7 +1756,7 @@ class TestSimplifyTemplate : public TestFixture { " return f1(pInterface, interface_type::static_type());\n" "}\n" "\n" - "Reference< class XPropertyList > dostuff();"; + "Reference< class XPropertyList > dostuff();\n"; const char exp[] = "int f1 ( int * pInterface , int x ) { return 0 ; } " "class Reference ; " "Reference dostuff ( ) ; " @@ -1769,7 +1769,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "template class Tokenizer;\n" "const Tokenizer *tokenizer() const;\n" "template \n" - "Tokenizer::Tokenizer() { }"; + "Tokenizer::Tokenizer() { }\n"; const char exp[] = "template < typename N , typename P > class Tokenizer ; " "const Tokenizer < Node , Path > * tokenizer ( ) const ; " "template < typename N , typename P > " @@ -1781,7 +1781,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "template\n" "void keep_range(T& value, const T mini, const T maxi){}\n" "template void keep_range(float& v, const float l, const float u);\n" - "template void keep_range(int& v, const int l, const int u);"; + "template void keep_range(int& v, const int l, const int u);\n"; const char exp[] = "void keep_range ( float & value , const float mini , const float maxi ) ; " "void keep_range ( int & value , const int mini , const int maxi ) ; " "void keep_range ( float & value , const float mini , const float maxi ) { } " @@ -1794,7 +1794,7 @@ class TestSimplifyTemplate : public TestFixture { "class PushBackStreamBuf {\n" "public:\n" " void pushBack(const BTlist &vec);\n" - "};"; + "};\n"; const char exp[] = "class BTlist ; " "class PushBackStreamBuf { " "public: " @@ -1807,7 +1807,7 @@ class TestSimplifyTemplate : public TestFixture { void template75() { const char code[] = "template\n" "T foo(T& value){ return value; }\n" - "template std::vector> foo>>(std::vector>& v);"; + "template std::vector> foo>>(std::vector>& v);\n"; const char exp[] = "std :: vector < std :: vector < int > > foo>> ( std :: vector < std :: vector < int > > & value ) ; " "std :: vector < std :: vector < int > > foo>> ( std :: vector < std :: vector < int > > & value ) { return value ; }"; ASSERT_EQUALS(exp, tok(code)); @@ -1837,7 +1837,7 @@ class TestSimplifyTemplate : public TestFixture { "int main() {\n" " std::cout << is_void::value << std::endl;\n" " std::cout << is_void::value << std::endl;\n" - "}"; + "}\n"; const char exp[] = "struct is_void ; " "struct is_void ; " "struct is_void : std :: true_type { } ; " @@ -1852,7 +1852,7 @@ class TestSimplifyTemplate : public TestFixture { void template78() { const char code[] = "template \n" "struct Base { };\n" - "struct S : Base ::Type { };"; + "struct S : Base ::Type { };\n"; const char exp[] = "struct Base ; " "struct S : Base :: Type { } ; " "struct Base { } ;"; @@ -1870,7 +1870,7 @@ class TestSimplifyTemplate : public TestFixture { "void some_func() {\n" " Foo x;\n" " x.foo();\n" - "}"; + "}\n"; const char exp[] = "class Foo { " "public: " "void foo ( ) ; " @@ -1891,7 +1891,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "class Fred {\n" " template T foo(T t) const { return t; }\n" "};\n" - "const void * p = Fred::foo(nullptr);"; + "const void * p = Fred::foo(nullptr);\n"; const char exp[] = "class Fred { " "const void * foo ( const void * t ) const ; " "} ; " @@ -1909,7 +1909,7 @@ class TestSimplifyTemplate : public TestFixture { "SortWith::SortWith(Type) {}\n" "int main() {\n" " SortWith(0);\n" - "}"; + "}\n"; const char exp[] = "template < typename Type > " "struct SortWith { " "SortWith ( Type ) ; " @@ -1939,7 +1939,7 @@ class TestSimplifyTemplate : public TestFixture { " swizzle<1>(tt2);\n" " tvec3 tt3;\n" " swizzle<2,3>(tt3);\n" - "}"; + "}\n"; const char exp[] = "const int f16 = 16 ; " "class tvec2 ; " "class tvec3 ; " @@ -1970,7 +1970,7 @@ class TestSimplifyTemplate : public TestFixture { "MultiConsumer::MultiConsumer() : sizeBuffer(0) {}\n" "MultiReads::MultiReads() {\n" " mc = new MultiConsumer();\n" - "}"; + "}\n"; const char exp[] = "template < typename Task > " // TODO: this should be expanded "class MultiConsumer { " "MultiConsumer ( ) ; " @@ -1988,7 +1988,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "template \n" "auto d() -> typename a::e {\n" " d();\n" - "}"; + "}\n"; const char exp[] = "template < class b , int c , class > " "auto d ( ) . a < decltype ( b { } ) > :: e { " "d < int , c , int > ( ) ; " @@ -1999,8 +1999,8 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "template \n" "auto d() -> typename a::e {\n" " d();\n" - "}" - "void foo() { d(); }"; + "}\n" + "void foo() { d(); }\n"; const char exp[] = "auto d ( ) . a < char > :: e ; " "auto d ( ) . a < int > :: e ; " "void foo ( ) { d ( ) ; } " @@ -2024,7 +2024,7 @@ class TestSimplifyTemplate : public TestFixture { "extern template void C::foo();\n" "template\n" "template::value)>::type>\n" - "void C::foo() {}"; + "void C::foo() {}\n"; // @todo the output is very wrong but we are only worried about the crash for now (void)tok(code); } @@ -2040,7 +2040,7 @@ class TestSimplifyTemplate : public TestFixture { "template \n" "S U::u;\n" "template S U::u;\n" - "S &i = U::u;"; + "S &i = U::u;\n"; (void)tok(code); } @@ -2048,7 +2048,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "template\n" "T f1(T t) { return t; }\n" "template const char * f1(const char *);\n" - "template const char & f1(const char &);"; + "template const char & f1(const char &);\n"; const char exp[] = "const char * f1 ( const char * t ) ; " "const char & f1 ( const char & t ) ; " "const char * f1 ( const char * t ) { return t ; } " @@ -2075,7 +2075,7 @@ class TestSimplifyTemplate : public TestFixture { "int main() {\n" " CTest::Greeting(true);\n" " return 0;\n" - "}"; + "}\n"; const char exp[] = "class CTest { " "public: " "static void Greeting ( bool ) ; " @@ -2105,7 +2105,7 @@ class TestSimplifyTemplate : public TestFixture { "template void Fred::foo();\n" "template void Fred::foo();\n" "template <> void Fred::foo() { }\n" - "template <> void Fred::foo() { }"; + "template <> void Fred::foo() { }\n"; const char exp[] = "struct Fred { " "static void foo ( ) ; " "static void foo ( ) ; " @@ -2123,7 +2123,7 @@ class TestSimplifyTemplate : public TestFixture { const char code[] = "template struct S1 {};\n" "void f(S1) {}\n" "template \n" - "decltype(S1().~S1()) fun1() {};"; + "decltype(S1().~S1()) fun1() {};\n"; const char exp[] = "struct S1 ; " "void f ( S1 ) { } " "template < typename T > " @@ -2138,7 +2138,7 @@ class TestSimplifyTemplate : public TestFixture { "template<> char foo(char a) { return a; }\n" "template<> int foo(int a) { return a; }\n" "template float foo(float);\n" - "template double foo(double);"; + "template double foo(double);\n"; const char exp[] = "int foo ( int a ) ; " "char foo ( char a ) ; " "float foo ( float t ) ; " @@ -2156,7 +2156,7 @@ class TestSimplifyTemplate : public TestFixture { " template<> int foo(int a) { return a; }\n" "};\n" "template float Fred::foo(float);\n" - "template double Fred::foo(double);"; + "template double Fred::foo(double);\n"; const char exp[] = "struct Fred { " "int foo ( int a ) ; " "char foo ( char a ) ; " @@ -2181,7 +2181,7 @@ class TestSimplifyTemplate : public TestFixture { " template float NS2::foo(float);\n" " template bool NS1::NS2::foo(bool);\n" "}\n" - "template double NS1::NS2::foo(double);"; + "template double NS1::NS2::foo(double);\n"; const char exp[] = "namespace NS1 { " "namespace NS2 { " "int foo ( int a ) ; " @@ -2214,7 +2214,7 @@ class TestSimplifyTemplate : public TestFixture { " template float NS::foo(float);\n" " template bool NS1::NS::foo(bool);\n" "}\n" - "template double NS1::NS::foo(double);"; + "template double NS1::NS::foo(double);\n"; const char exp[] = "namespace NS1 { " "namespace NS { " "int foo ( int a ) ; " @@ -2245,7 +2245,7 @@ class TestSimplifyTemplate : public TestFixture { " foo(2);\n" " foo(3.14);\n" " foo(3.14f);\n" - "}"; + "}\n"; const char exp[] = "void foo ( const double & d ) ; " "void foo ( const float & t ) ; " "void foo ( const int & t ) ; " @@ -2274,7 +2274,7 @@ class TestSimplifyTemplate : public TestFixture { "void Vector2::process() {\n" " ForEach();\n" "}\n" - "Vector2 c;"; + "Vector2 c;\n"; const char exp[] = "void ForEach ( ) ; " "class Vector2 ; " "Vector2 c ; " @@ -2304,7 +2304,7 @@ class TestSimplifyTemplate : public TestFixture { "Array matmul() {\n" " return foo( );\n" "}\n" - "template Array> matmul>();"; + "template Array> matmul>();\n"; const char exp[] = "class Array ; " "class Array> ; " "class Array ; " @@ -2332,7 +2332,7 @@ class TestSimplifyTemplate : public TestFixture { "template<>\n" "int Value = 456;\n" "float f = Value;\n" - "int i = Value;"; + "int i = Value;\n"; const char exp[] = "float Value ; Value = 123 ; " "int Value ; Value = 456 ; " "float f ; f = Value ; " @@ -2351,7 +2351,7 @@ class TestSimplifyTemplate : public TestFixture { "long f0 = fib<0>;\n" "long f1 = fib<1>;\n" "long f2 = fib<2>;\n" - "long f3 = fib<3>;"; + "long f3 = fib<3>;\n"; const char exp[] = "constexpr long fib<2> = fib<1> + fib<0> ; " "constexpr long fib<3> = fib<2> + fib<1> ; " "constexpr long fib<0> = 0 ; " @@ -2411,7 +2411,7 @@ class TestSimplifyTemplate : public TestFixture { "}\n" "using namespace NS1::NS2::NS3::NS4;\n" "Fred fred_bool1;\n" - "NS1::NS2::NS3::NS4::Fred fred_int1;"; + "NS1::NS2::NS3::NS4::Fred fred_int1;\n"; const char exp[] = "namespace NS1 { " "namespace NS2 { " "namespace NS3 { " @@ -2489,7 +2489,7 @@ class TestSimplifyTemplate : public TestFixture { " unique_ptr_with_deleter tmp(new A(), [](A* a) {\n" " delete a;\n" " });\n" - "}"; + "}\n"; const char exp[] = "class A { } ; " "static void func ( ) { " "std :: unique_ptr < A , std :: function < void ( A * ) > > tmp ( new A ( ) , [ ] ( A * a ) { " @@ -2537,7 +2537,7 @@ class TestSimplifyTemplate : public TestFixture { " using ArrayType = std::vector;\n" " void func(typename ArrayType::size_type i) {\n" " }\n" - "};"; + "};\n"; const char exp[] = "class A { " "public: " @@ -2558,7 +2558,7 @@ class TestSimplifyTemplate : public TestFixture { "}\n" "void f() {\n" " if(std::is_floating_point::value) {}\n" - "}"; + "}\n"; const char exp[] = "namespace ns { " "template < class T > " "struct is_floating_point " @@ -2583,7 +2583,7 @@ class TestSimplifyTemplate : public TestFixture { " return t;\n" " }\n" "}\n" - "sample::Sample s1;"; + "sample::Sample s1;\n"; const char exp[] = "namespace sample { " "class Sample ; " "} " @@ -2609,7 +2609,7 @@ class TestSimplifyTemplate : public TestFixture { " BOOST_HANA_CONSTANT_CHECK ( hana :: equal (\n" " hana :: at_key ( hana :: make_map ( p < 0 , 0 > ( ) ) , key < 0 > ( ) ) ,\n" " val < 0 > ( ) ) ) ;\n" - "}"; + "}\n"; const char exp[] = "auto key<0> ( ) ; " "auto val<0> ( ) ; " "auto p<0,0> ( ) ; " @@ -2629,7 +2629,7 @@ class TestSimplifyTemplate : public TestFixture { "template