From 5f6ef537aa9abefbc568538ed671e263cc0261d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 14 May 2025 17:17:44 +0200 Subject: [PATCH] Fix #13847 (simplifyTypedef should not simplify ) --- lib/tokenize.cpp | 33 +++++---------------------------- lib/tokenize.h | 3 --- test/testsimplifytypedef.cpp | 10 +++++++++- test/testtokenize.cpp | 13 +++++++++++++ 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d5aa81172f8..ce36f8ff323 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -503,31 +503,6 @@ Token *Tokenizer::processFunc(Token *tok2, bool inOperator) return const_cast(processFunc(const_cast(tok2), inOperator)); } -void Tokenizer::simplifyUsingToTypedef() -{ - if (!isCPP() || mSettings.standards.cpp < Standards::CPP11) - return; - - for (Token *tok = list.front(); tok; tok = tok->next()) { - // using a::b; => typedef a::b b; - if ((Token::Match(tok, "[;{}] using %name% :: %name% ::|;") && !tok->tokAt(2)->isKeyword()) || - (Token::Match(tok, "[;{}] using :: %name% :: %name% ::|;") && !tok->tokAt(3)->isKeyword())) { - Token *endtok = tok->tokAt(5); - if (Token::Match(endtok, "%name%")) - endtok = endtok->next(); - while (Token::Match(endtok, ":: %name%")) - endtok = endtok->tokAt(2); - if (endtok && endtok->str() == ";") { - if (endtok->strAt(-1) == endtok->strAt(-3)) - continue; - tok->next()->str("typedef"); - endtok = endtok->previous(); - endtok->insertToken(endtok->str()); - } - } - } -} - void Tokenizer::simplifyTypedefLHS() { if (!list.front()) @@ -1157,9 +1132,6 @@ void Tokenizer::simplifyTypedefCpp() // add global namespace std::vector spaceInfo(1); - // Convert "using a::b;" to corresponding typedef statements - simplifyUsingToTypedef(); - const std::time_t maxTime = mSettings.typedefMaxTime > 0 ? std::time(nullptr) + mSettings.typedefMaxTime: 0; const bool doProgress = (mSettings.reportProgress != -1) && !list.getFiles().empty(); @@ -1975,6 +1947,11 @@ void Tokenizer::simplifyTypedefCpp() } if (Token::Match(tok2->tokAt(-1), "class|struct|union") && tok2->strAt(-1) == typeStart->str()) tok2->deletePrevious(); + + if (cpp && Token::Match(tok2->previous(), "using %name% ::|;")) { + tok2->previous()->str("typedef"); + tok2->insertToken(tok2->str()); + } tok2->str(typeStart->str()); // restore qualification if it was removed diff --git a/lib/tokenize.h b/lib/tokenize.h index fab0a348cf3..9770ec2d288 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -218,9 +218,6 @@ class CPPCHECKLIB Tokenizer { */ Token * simplifyAddBracesPair(Token *tok, bool commandWithCondition); - // Convert "using ...;" to corresponding typedef - void simplifyUsingToTypedef(); - /** * typedef A mytype; * mytype c; diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 90146a46d2e..f77ad41889e 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -249,8 +249,8 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedefTokenColumn3); TEST_CASE(typedefInfo1); - TEST_CASE(typedefInfo2); + TEST_CASE(typedefInfo3); } struct TokOptions @@ -4562,6 +4562,14 @@ class TestSimplifyTypedef : public TestFixture { " \n" " \n",xml); } + + void typedefInfo3() { + const std::string xml = dumpTypedefInfo("int main() {\n" + " using x::a;\n" + " b = a + 2;\n" + "}\n"); + ASSERT_EQUALS("",xml); + } }; REGISTER_TEST(TestSimplifyTypedef) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 21302952660..09e8039daa6 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -80,6 +80,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(tokenize38); // #9569 TEST_CASE(tokenize39); // #9771 TEST_CASE(tokenize40); // #13181 + TEST_CASE(tokenize41); // #13847 TEST_CASE(validate); @@ -860,6 +861,18 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void tokenize41() { // #13847 + const char code[] = "int main() {\n" + " using x::a;\n" + " b = a + 2;\n" + "}\n"; + ASSERT_EQUALS("int main ( ) {\n" + "\n" + "b = x :: a + 2 ;\n" + "}", tokenizeAndStringify(code)); + (void)errout_str(); + } + void validate() { // C++ code in C file ASSERT_THROW_INTERNAL(tokenizeAndStringify(";using namespace std;",false,Platform::Type::Native,false), SYNTAX);