From a8f83c1c52fb5e50b20c1e668bb33c4a863876ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 15 Jan 2026 10:50:53 +0100 Subject: [PATCH 1/4] Fixup #14396 (Update value for INT64_MIN, value should be a signed expression) (#8126) --- cfg/std.cfg | 14 +++++++------- test/cfg/std.c | 11 +++++++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index dfb4acddcf4..6cd0c371a5e 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -3,16 +3,16 @@ - - + + - - - + + + - - + + diff --git a/test/cfg/std.c b/test/cfg/std.c index b96f1bf8317..adc147c2333 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -38,6 +38,17 @@ #include #include +void test_int32_min() { + // cppcheck-suppress shiftNegativeLHS + // cppcheck-suppress shiftTooManyBits ; tests that INT32_MIN is a 32-bit expression (not 64-bit expression) + (void)(INT32_MIN >> 40); +} + +void test_int64_min() { + // cppcheck-suppress compareValueOutOfTypeRangeError ; tests that INT64_MIN is a signed expression + if (INT64_MIN < 0) {} +} + size_t invalidFunctionArgStr_wcslen(void) { const wchar_t terminated0[] = L"ABCDEF49620910"; From d329ee97447ea0c7b6506e097c7727cb42b40aa7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 17 Jan 2026 12:43:39 +0100 Subject: [PATCH 2/4] Fix #14400 FP syntaxError for trailing return type (#8127) Co-authored-by: chrchr-github --- lib/tokenize.cpp | 2 +- test/testtokenize.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 96c69bb4dd9..57f04b5f6e9 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -110,7 +110,7 @@ static bool isClassStructUnionEnumStart(const Token * tok) const Token * tok2 = tok->previous(); while (tok2 && !Token::Match(tok2, "class|struct|union|enum|{|}|)|;|>|>>")) tok2 = tok2->previous(); - return Token::Match(tok2, "class|struct|union|enum"); + return Token::Match(tok2, "class|struct|union|enum") && !Token::simpleMatch(tok2->tokAt(-1), "->"); } //--------------------------------------------------------------------------- diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index dcbbd0201af..e58be1c0d87 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -7683,6 +7683,12 @@ class TestTokenizer : public TestFixture { ASSERT_NO_THROW(tokenizeAndStringify("struct S { unsigned u:2, :30; };")); // #14393 + ASSERT_NO_THROW(tokenizeAndStringify("struct S {};\n" // #14400 + "auto f(bool b) -> struct S {\n" + " if (b) {}\n" + " return {};\n" + "};\n")); + ignore_errout(); } From ae060dedb4649f849de5f2c20770900d955301f4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 17 Jan 2026 14:25:56 +0100 Subject: [PATCH 3/4] Fix #14395 FP syntaxError for lambda in for loop (#8125) --- lib/tokenize.cpp | 12 +++++++----- test/testtokenize.cpp | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 57f04b5f6e9..8c324a72701 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8830,17 +8830,19 @@ void Tokenizer::findGarbageCode() const continue; // count number of semicolons int semicolons = 0, colons = 0; - const Token* const startTok = tok; - tok = tok->linkAt(1)->previous(); // find ")" of the for-loop - // walk backwards until we find the beginning (startTok) of the for() again - for (; tok != startTok; tok = tok->previous()) { + const Token* const endTok = tok->linkAt(1); + for (tok = tok->tokAt(2); tok != endTok; tok = tok->next()) { + if (const Token* lam = findLambdaEndTokenWithoutAST(tok)) { + tok = lam; + continue; + } if (tok->str() == ";") { // do the counting semicolons++; } else if (tok->str() == ":") { if (tok->strAt(-1) == ",") syntaxError(tok); colons++; - } else if (tok->str() == ")") { // skip pairs of ( ) + } else if (tok->str() == "(") { // skip pairs of ( ) tok = tok->link(); } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index e58be1c0d87..aafbeafc58f 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -7689,6 +7689,10 @@ class TestTokenizer : public TestFixture { " return {};\n" "};\n")); + ASSERT_NO_THROW(tokenizeAndStringify("void f() {\n" // #14395 + " for (int i : [](int a, int b) { ++a; ++b; return std::vector{a, b}; }(1, 2)) {}\n" + "}\n")); + ignore_errout(); } From 16fc50c7c7c3ff63a1355fea8cb1d25326c2921e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:18:54 +0100 Subject: [PATCH 4/4] Fix #10252 debug: Failed to parse 'x'. The checking continues anyway. (#8129) Co-authored-by: chrchr-github --- .github/workflows/CI-unixish.yml | 2 +- lib/tokenize.cpp | 35 ++++++++++++++++++++++++++++++-- test/testsimplifyusing.cpp | 18 ++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index e37d88767ec..14682a41a56 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -716,7 +716,7 @@ jobs: ./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 --addon=naming.json --enable=internal lib || ec=1 # check gui with qt settings mkdir b2 - ./cppcheck $selfcheck_options $cppcheck_options $gui_options --cppcheck-build-dir=b2 --addon=naming.json --suppress=simplifyUsing:*/moc_*.cpp -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui || ec=1 + ./cppcheck $selfcheck_options $cppcheck_options $gui_options --cppcheck-build-dir=b2 --addon=naming.json -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 diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8c324a72701..d4755fc1260 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3211,6 +3211,8 @@ bool Tokenizer::simplifyUsing() } Token * arrayStart = nullptr; + Token * fpArgList = nullptr; + Token * fpQual = nullptr; // parse the type Token *type = start; @@ -3310,6 +3312,18 @@ bool Tokenizer::simplifyUsing() } while (type && type->str() == "["); } + // check for function pointer + if (type && type->str() == "(") { + if (Token::simpleMatch(type->link(), ") (")) { + fpArgList = type->link()->next(); + fpQual = type; + type = type->link()->linkAt(1)->next(); + } else if (type->link()->next() == usingEnd) { + fpArgList = type; + type = usingEnd; + } + } + // make sure we are in a good state if (!tok1 || !tok1->next()) break; // bail @@ -3325,6 +3339,24 @@ bool Tokenizer::simplifyUsing() tok1->deleteThis(); substitute = true; } + } else if (fpArgList && fpQual && Token::Match(tok1->next(), "%name%")) { + // function pointer + TokenList::copyTokens(tok1->next(), fpArgList, usingEnd->previous()); + Token* const copyEnd = TokenList::copyTokens(tok1, start, fpQual->link()->previous()); + tok1->deleteThis(); + Token* const rightPar = copyEnd->next()->insertToken(")"); + Token::createMutualLinks(tok1->next(), rightPar); + substitute = true; + } else if (fpArgList && !fpQual && Token::Match(tok1->next(), "* const| %name%")) { + // function pointer + Token* const dest = tok1->tokAt(tok1->strAt(2) == "const" ? 3 : 2); + Token* const copyEndArgs = TokenList::copyTokens(dest, fpArgList, usingEnd->previous()); + Token* const copyEndRet = TokenList::copyTokens(tok1, start, fpArgList->previous()); + Token* const leftPar = copyEndRet->insertToken("("); + Token* const rightPar = copyEndArgs->link()->tokAt(-1)->insertToken(")"); + Token::createMutualLinks(leftPar, rightPar); + tok1->deleteThis(); + substitute = true; } else { // add some qualification back if needed std::string removed1 = std::move(removed); @@ -6931,8 +6963,7 @@ void Tokenizer::simplifyFunctionParameters() } // Find the function e.g. foo( x ) or foo( x, y ) - else if (Token::Match(tok, "%name% ( %name% [,)]") && - !(tok->strAt(-1) == ":" || tok->strAt(-1) == "," || tok->strAt(-1) == "::")) { + else if (Token::Match(tok, "%name% ( %name% [,)]") && !Token::Match(tok->tokAt(-1), ":|,|::|=")) { // We have found old style function, now we need to change it // First step: Get list of argument names in parentheses diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index fa067f822ce..c73e4c3ac1d 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -73,6 +73,7 @@ class TestSimplifyUsing : public TestFixture { TEST_CASE(simplifyUsing34); TEST_CASE(simplifyUsing35); TEST_CASE(simplifyUsing36); + TEST_CASE(simplifyUsing37); TEST_CASE(simplifyUsing8970); TEST_CASE(simplifyUsing8971); @@ -882,6 +883,23 @@ class TestSimplifyUsing : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void simplifyUsing37() { + const char code1[] = "using fp1_t = int(*)(int);\n" + "using fp2_t = int(* const)(int);\n" + "fp1_t fp1;\n" + "fp2_t fp2;\n"; + const char expected1[] = "int ( * fp1 ) ( int ) ; int ( * const fp2 ) ( int ) ;"; + ASSERT_EQUALS(expected1, tok(code1)); + ASSERT_EQUALS("", errout_str()); + + const char code2[] = "using f_t = int(int);\n" + "f_t* fp1;\n" + "f_t* const fp2;\n"; + const char expected2[] = "int ( * fp1 ) ( int ) ; int ( * const fp2 ) ( int ) ;"; + ASSERT_EQUALS(expected2, tok(code2)); + ASSERT_EQUALS("", errout_str()); + } + void simplifyUsing8970() { const char code[] = "using V = std::vector;\n" "struct A {\n"