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 96c69bb4dd9..dce13cb7dd2 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"