From 1975875587fb0184b78c3669923893468004b1a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 20 Dec 2025 20:20:31 +0100 Subject: [PATCH 1/8] 2.19.0: set version (#8053) --- 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 3595154f7ae..44ccc0afc92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.13) -project(Cppcheck VERSION 2.18.99 LANGUAGES CXX) +project(Cppcheck VERSION 2.19.0 LANGUAGES CXX) include(cmake/options.cmake) diff --git a/cli/main.cpp b/cli/main.cpp index d2a8417560e..19919ceb953 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -20,7 +20,7 @@ /** * * @mainpage Cppcheck - * @version 2.18.99 + * @version 2.19.0 * * @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 3a7c5918b45..75ce07f65e8 100644 --- a/lib/version.h +++ b/lib/version.h @@ -20,8 +20,8 @@ #ifndef versionH #define versionH -#define CPPCHECK_VERSION_STRING "2.19 dev" -#define CPPCHECK_VERSION 2,18,99,0 +#define CPPCHECK_VERSION_STRING "2.19.0" +#define CPPCHECK_VERSION 2,19,0,0 #define LEGALCOPYRIGHT L"Copyright (C) 2007-2025 Cppcheck team." diff --git a/man/manual.md b/man/manual.md index d8da119f388..e51a14b5ee7 100644 --- a/man/manual.md +++ b/man/manual.md @@ -1,6 +1,6 @@ --- title: Cppcheck manual -subtitle: Version 2.19 dev +subtitle: Version 2.19.0 author: Cppcheck team lang: en documentclass: report diff --git a/man/reference-cfg-format.md b/man/reference-cfg-format.md index 7a9e3b6dee7..893f290bdf0 100644 --- a/man/reference-cfg-format.md +++ b/man/reference-cfg-format.md @@ -1,6 +1,6 @@ --- title: Cppcheck .cfg format -subtitle: Version 2.19 dev +subtitle: Version 2.19.0 author: Cppcheck team lang: en documentclass: report diff --git a/man/writing-addons.md b/man/writing-addons.md index da21ea513ad..c51a74db42c 100644 --- a/man/writing-addons.md +++ b/man/writing-addons.md @@ -1,6 +1,6 @@ --- title: Writing addons -subtitle: Version 2.19 dev +subtitle: Version 2.19.0 author: Cppcheck team lang: en documentclass: report diff --git a/win_installer/productInfo.wxi b/win_installer/productInfo.wxi index d07ce1136c9..e1301ae2a7f 100644 --- a/win_installer/productInfo.wxi +++ b/win_installer/productInfo.wxi @@ -1,8 +1,8 @@ - + - + From 250bd08f5669315ff12ef253e9fede697f8f6d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 21 Dec 2025 13:20:34 +0100 Subject: [PATCH 2/8] 2.19: release makefile (#8054) --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 71b62bab7fc..a1d7066a2f2 100644 --- a/Makefile +++ b/Makefile @@ -132,9 +132,11 @@ ifeq (clang++, $(findstring clang++,$(CXX))) CPPCHK_GLIBCXX_DEBUG= endif ifndef CXXFLAGS - CXXFLAGS=-pedantic -Wall -Wextra -Wcast-qual -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wno-long-long -Wpacked -Wredundant-decls -Wundef -Wno-sign-compare -Wno-multichar -Woverloaded-virtual -g + CXXFLAGS=-O2 -Wall -Wno-sign-compare -Wno-multichar endif +override CPPFLAGS += -DNDEBUG + ifeq (g++, $(findstring g++,$(CXX))) override CXXFLAGS += -pipe endif @@ -385,7 +387,7 @@ dmake: tools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) run-dmake: dmake - ./dmake + ./dmake --release clean: rm -f build/*.cpp build/*.o lib/*.o cli/*.o frontend/*.o test/*.o tools/dmake/*.o externals/*/*.o testrunner dmake cppcheck cppcheck.exe cppcheck.1 From f41c5bca9486b8c75a3683477fdd36137a79ffdb Mon Sep 17 00:00:00 2001 From: Tomo Dote Date: Sun, 21 Dec 2025 21:20:12 +0900 Subject: [PATCH 3/8] update japanese translation (#8056) only update Japanese translation --- gui/cppcheck_ja.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index ce3b3e1911c..461f1ef3f07 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -1093,7 +1093,7 @@ Parameters: -l(line) (file) EULA... - + EULA... @@ -1773,7 +1773,7 @@ Options: Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. - + #R 限定的 -- 開発者が直接的に結果を得るための解析を意味します。解析は限定的で高速ですがより少ない結果になります。 @@ -1860,7 +1860,7 @@ Options: 2025 - 2025 + 2025 @@ -2052,7 +2052,7 @@ Options: Note: Open source Cppcheck does not fully implement Misra C 2012 - + 注意: オープンソースのCppcheckはMisra C 2012を完全にサポートしていません。 @@ -2463,12 +2463,12 @@ Options: Recheck %1 file(s) - + 再チェック %1 件のファイル Hide %1 result(s) - + 非表示 %1 件の結果 @@ -2883,7 +2883,7 @@ To toggle what kind of errors are shown, open view menu. Max count: - + #M 最大数: From 9730a448fb7e9c205b7ec47b7ba88c5406954538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 21 Dec 2025 13:48:14 +0100 Subject: [PATCH 4/8] Revert "Fixed #14169 (cmake: ts files generated by cmake is not robust) (#8047)" This reverts commit 11fa27df223ca9c17a5065b55d07bae984fc0227. --- gui/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 458569872c1..ff329ad1163 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -12,8 +12,11 @@ CheckOptions: file(GLOB hdrs "*.h") file(GLOB srcs "*.cpp") file(GLOB uis "*.ui") + file(GLOB tss "*.ts") QT_WRAP_UI(uis_hdrs ${uis}) QT_ADD_RESOURCES(resources "gui.qrc") + # TODO: passing "-no-obsolete" here breaks the translations + QT_CREATE_TRANSLATION(qms ${CMAKE_CURRENT_SOURCE_DIR} ${tss}) list(APPEND cppcheck-gui-deps ${hdrs} ${uis_hdrs} ${resources} ${qms}) add_custom_target(gui-build-deps SOURCES ${cppcheck-gui-deps}) From 67caad0d26631c5c72276b0b92d2f17decd8539c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 2 Jan 2026 13:59:40 +0100 Subject: [PATCH 5/8] Fix #14359 (GUI: Duplicate warnings are not filtered out) (#8077) --- gui/resultstree.cpp | 9 +++++++++ gui/resultstree.h | 3 +++ gui/test/resultstree/testresultstree.cpp | 13 +++++++++++++ gui/test/resultstree/testresultstree.h | 1 + 4 files changed, 26 insertions(+) diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index 53f4a5f9ab9..78d56929b48 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -239,6 +239,11 @@ bool ResultsTree::addErrorItem(const ErrorItem& errorItem) if (errorItem.errorPath.isEmpty()) return false; + const QString s = errorItem.toString(); + if (mErrorList.contains(s)) + return false; + mErrorList.append(s); + QSharedPointer errorItemPtr{new ErrorItem(errorItem)}; if (mReportType != ReportType::normal) { @@ -393,6 +398,8 @@ ResultItem *ResultsTree::findFileItem(const QString &name) const void ResultsTree::clear() { + mErrorList.clear(); + mModel->removeRows(0, mModel->rowCount()); if (const ProjectFile *activeProject = ProjectFile::getActiveProject()) { @@ -419,6 +426,7 @@ void ResultsTree::clear(const QString &filename) if (stripped == fileItem->text() || filename == fileItem->errorItem->file0) { mModel->removeRow(i); + mErrorList.removeAll(fileItem->errorItem->toString()); break; } } @@ -436,6 +444,7 @@ void ResultsTree::clearRecheckFile(const QString &filename) storedfile = ((!mCheckPath.isEmpty() && storedfile.startsWith(mCheckPath)) ? storedfile.mid(mCheckPath.length() + 1) : storedfile); if (actualfile == storedfile) { mModel->removeRow(i); + mErrorList.removeAll(fileItem->errorItem->toString()); break; } } diff --git a/gui/resultstree.h b/gui/resultstree.h index 9537d6d929a..87907bc5d95 100644 --- a/gui/resultstree.h +++ b/gui/resultstree.h @@ -568,6 +568,9 @@ protected slots: QStringList mHiddenMessageId; + // List of existing errors so we can avoid duplicates + QStringList mErrorList; + QItemSelectionModel* mSelectionModel{}; ThreadHandler *mThread{}; diff --git a/gui/test/resultstree/testresultstree.cpp b/gui/test/resultstree/testresultstree.cpp index be09034609f..8208ca0343e 100644 --- a/gui/test/resultstree/testresultstree.cpp +++ b/gui/test/resultstree/testresultstree.cpp @@ -134,6 +134,19 @@ void TestResultsTree::test1() const QCOMPARE(tree.isRowHidden(0,QModelIndex()), false); // Show item } +void TestResultsTree::duplicateResults() const +{ + // #14359 - filter out duplicate warnings + ResultsTree tree(nullptr); + + ErrorItem errorItem; + errorItem.summary = errorItem.message = "test"; + errorItem.severity = Severity::error; + errorItem.errorPath << QErrorPathItem(); + QVERIFY(tree.addErrorItem(errorItem)); + QVERIFY(!tree.addErrorItem(errorItem)); +} + static QErrorPathItem createErrorPathItem(QString file, int line, int column, QString info) { QErrorPathItem ret; ret.file = std::move(file); diff --git a/gui/test/resultstree/testresultstree.h b/gui/test/resultstree/testresultstree.h index 1e743581bac..108ed098eb5 100644 --- a/gui/test/resultstree/testresultstree.h +++ b/gui/test/resultstree/testresultstree.h @@ -23,6 +23,7 @@ class TestResultsTree : public QObject { private slots: void test1() const; + void duplicateResults() const; void multiLineResult() const; void resultsInSameFile() const; void testReportType() const; From 4edd35c36b56e776a12d7dbb461046ef6bc658a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 2 Jan 2026 12:08:32 +0100 Subject: [PATCH 6/8] Fix #14360 (CI: Update Cppcheck Premium license) (#8078) --- .github/workflows/cppcheck-premium.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cppcheck-premium.yml b/.github/workflows/cppcheck-premium.yml index 42bca8a6ebb..5cb63ca4d5e 100644 --- a/.github/workflows/cppcheck-premium.yml +++ b/.github/workflows/cppcheck-premium.yml @@ -45,9 +45,9 @@ jobs: - name: Generate a license file run: | echo cppcheck > cppcheck.lic - echo 251231 >> cppcheck.lic + echo 261231 >> cppcheck.lic echo 80000 >> cppcheck.lic - echo 4f8dc8e7c8bb288f >> cppcheck.lic + echo 4b64673f03fb6230 >> cppcheck.lic echo path:lib >> cppcheck.lic - name: Check From 549aacbcb956f475b002b7d5a35c8ff31ec8a008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 2 Jan 2026 17:53:19 +0100 Subject: [PATCH 7/8] 2.19.1: set version (#8080) --- CMakeLists.txt | 2 +- cli/main.cpp | 2 +- lib/version.h | 6 +++--- man/manual.md | 2 +- man/reference-cfg-format.md | 2 +- man/writing-addons.md | 2 +- win_installer/productInfo.wxi | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44ccc0afc92..7471d0c1fe6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.13) -project(Cppcheck VERSION 2.19.0 LANGUAGES CXX) +project(Cppcheck VERSION 2.19.1 LANGUAGES CXX) include(cmake/options.cmake) diff --git a/cli/main.cpp b/cli/main.cpp index 19919ceb953..dfe2d17527e 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -20,7 +20,7 @@ /** * * @mainpage Cppcheck - * @version 2.19.0 + * @version 2.19.1 * * @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 75ce07f65e8..d35d1f5195c 100644 --- a/lib/version.h +++ b/lib/version.h @@ -20,9 +20,9 @@ #ifndef versionH #define versionH -#define CPPCHECK_VERSION_STRING "2.19.0" -#define CPPCHECK_VERSION 2,19,0,0 +#define CPPCHECK_VERSION_STRING "2.19.1" +#define CPPCHECK_VERSION 2,19,1,0 -#define LEGALCOPYRIGHT L"Copyright (C) 2007-2025 Cppcheck team." +#define LEGALCOPYRIGHT L"Copyright (C) 2007-2026 Cppcheck team." #endif diff --git a/man/manual.md b/man/manual.md index e51a14b5ee7..4213cd1318a 100644 --- a/man/manual.md +++ b/man/manual.md @@ -1,6 +1,6 @@ --- title: Cppcheck manual -subtitle: Version 2.19.0 +subtitle: Version 2.19.1 author: Cppcheck team lang: en documentclass: report diff --git a/man/reference-cfg-format.md b/man/reference-cfg-format.md index 893f290bdf0..891d44aa528 100644 --- a/man/reference-cfg-format.md +++ b/man/reference-cfg-format.md @@ -1,6 +1,6 @@ --- title: Cppcheck .cfg format -subtitle: Version 2.19.0 +subtitle: Version 2.19.1 author: Cppcheck team lang: en documentclass: report diff --git a/man/writing-addons.md b/man/writing-addons.md index c51a74db42c..b33a54e5ff1 100644 --- a/man/writing-addons.md +++ b/man/writing-addons.md @@ -1,6 +1,6 @@ --- title: Writing addons -subtitle: Version 2.19.0 +subtitle: Version 2.19.1 author: Cppcheck team lang: en documentclass: report diff --git a/win_installer/productInfo.wxi b/win_installer/productInfo.wxi index e1301ae2a7f..78150400e3e 100644 --- a/win_installer/productInfo.wxi +++ b/win_installer/productInfo.wxi @@ -1,8 +1,8 @@ - + - + From eb0e35daf136be456d3dd6c8983b10dbac0bafb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 28 Jan 2026 11:48:42 +0100 Subject: [PATCH 8/8] Fix #14419 and #14444: Issues with AST/value type for enum declarations (#8160) --- lib/symboldatabase.cpp | 2 +- lib/tokenlist.cpp | 7 +++++++ test/testsymboldatabase.cpp | 18 ++++++++++++++++++ test/testtokenize.cpp | 6 ++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d4107884642..498befce004 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6849,7 +6849,7 @@ void SymbolDatabase::setValueType(Token* tok, const Enumerator& enumerator, cons if (valuetype.type == ValueType::Type::UNKNOWN_TYPE) valuetype.fromLibraryType(type->expressionString(), mSettings); - if (valuetype.isIntegral()) { + if (valuetype.sign == ValueType::UNKNOWN_SIGN && valuetype.isIntegral()) { if (type->isSigned()) valuetype.sign = ValueType::Sign::SIGNED; else if (type->isUnsigned()) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 2953b0c895d..8785c10d988 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1585,6 +1585,13 @@ static Token * createAstAtToken(Token *tok) if (Token::Match(tok2, "%var% [;,)]")) return tok2; } + if (Token::Match(tok, "enum class| %name%| :")) { + if (Token::simpleMatch(tok->next(), "class")) + tok = tok->next(); + if (Token::Match(tok->next(), "%name%")) + tok = tok->next(); + return tok->next(); + } if (Token *const endTok = skipMethodDeclEnding(tok)) { Token *tok2 = tok; do { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index b33dcdbc30a..cc7464c70fc 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -464,6 +464,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(enum17); TEST_CASE(enum18); TEST_CASE(enum19); + TEST_CASE(enum20); // #14419 TEST_CASE(struct1); @@ -6860,6 +6861,23 @@ class TestSymbolDatabase : public TestFixture { } } + void enum20() { // #14419 + { + GET_SYMBOL_DB("enum class myclass : uint8_t { A = 0U };\n"); + const Token *A = Token::findsimplematch(tokenizer.tokens(), "A"); + ASSERT(A && A->valueType() && A->valueType()->isEnum()); + ASSERT_EQUALS_ENUM(ValueType::CHAR, A->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::UNSIGNED, A->valueType()->sign); + } + { + GET_SYMBOL_DB("enum myclass : uint8_t { A = 0U };\n"); + const Token *A = Token::findsimplematch(tokenizer.tokens(), "A"); + ASSERT(A && A->valueType() && A->valueType()->isEnum()); + ASSERT_EQUALS_ENUM(ValueType::CHAR, A->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::UNSIGNED, A->valueType()->sign); + } + } + void struct1() { GET_SYMBOL_DB_C("struct deer {\n" " uint16_t a;\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index c9d1b8336ab..5f3e6e02468 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -420,6 +420,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(astdesignatedinit); TEST_CASE(astrvaluedecl); TEST_CASE(astorkeyword); + TEST_CASE(astenumdecl); TEST_CASE(startOfExecutableScope); @@ -7373,6 +7374,11 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("ifsp.\"\"==sp.0==||(", testAst("void f() { if (s.p == \"\" or s.p == 0) {} }")); } + void astenumdecl() { + ASSERT_EQUALS("A0U=", testAst("enum class myclass : unsigned char { A = 0U, };")); + ASSERT_EQUALS("A0U=", testAst("enum myclass : unsigned char { A = 0U, };")); + } + #define isStartOfExecutableScope(offset, code) isStartOfExecutableScope_(offset, code, __FILE__, __LINE__) template bool isStartOfExecutableScope_(int offset, const char (&code)[size], const char* file, int line) {