From f3cccd06d3d6b836bd8f9c4d16139fafceeea70a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 5 Mar 2024 17:56:52 +0100 Subject: [PATCH] Fix #12486 Improve simplification of using statements (#6080) --- lib/tokenize.cpp | 21 +++++++++++---- test/testsimplifytemplate.cpp | 2 +- test/testsimplifyusing.cpp | 49 +++++++++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index eea73d69248..953de6f64b1 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2845,13 +2845,21 @@ bool Tokenizer::simplifyUsing() if (!Token::Match(tok, "using ::| %name% ::")) continue; Token* end = tok->tokAt(3); - while (end && end->str() != ";") - end = end->next(); + while (end && !Token::Match(end, "[;,]")) { + if (end->str() == "<" && end->link()) // skip template args + end = end->link()->next(); + else + end = end->next(); + } if (!end) continue; - if (!end->tokAt(-1)->isNameOnly()) // e.g. operator= + if (!end->tokAt(-1)->isNameOnly() || end->tokAt(-2)->isLiteral()) // e.g. operator=, operator""sv continue; - tok->insertToken(end->strAt(-1))->insertToken("="); + tok->insertToken(end->strAt(-1))->insertToken("=")->isSimplifiedTypedef(true); + if (end->str() == ",") { // comma-separated list + end->str(";"); + end->insertToken("using"); + } tok = end; } @@ -2922,8 +2930,11 @@ bool Tokenizer::simplifyUsing() std::string scope = currentScope->fullName; Token *usingStart = tok; Token *start; - if (tok->strAt(2) == "=") + if (tok->strAt(2) == "=") { + if (currentScope->type == ScopeInfo3::Record && tok->tokAt(2)->isSimplifiedTypedef()) // don't simplify within class definition + continue; start = tok->tokAt(3); + } else start = tok->linkAt(2)->tokAt(3); Token *usingEnd = findSemicolon(start); diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 152281a4ebc..951d1aa23cf 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -2880,7 +2880,7 @@ class TestSimplifyTemplate : public TestFixture { "struct f> ; " "} " "} " - "b :: f> g1 ; struct b :: B<0> { } ; " + "b :: f> g1 ; struct b :: B<0> { using d = B<0> :: d ; } ; " "struct b :: f> { } ;"; ASSERT_EQUALS(exp, tok(code)); } diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index f1a3ff49a94..abf15dd0048 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -683,14 +683,47 @@ class TestSimplifyUsing : public TestFixture { ASSERT_EQUALS("", errout.str()); } - void simplifyUsing30() { // #8454 - const char code[] = "using std::to_string;\n" - "void f() {\n" - " std::string str = to_string(1);\n" - "}\n"; - const char expected[] = "void f ( ) { std :: string str ; str = std :: to_string ( 1 ) ; }"; - ASSERT_EQUALS(expected, tok(code, Platform::Type::Native, /*debugwarnings*/ true)); - ASSERT_EQUALS("", errout.str()); + void simplifyUsing30() { + { + const char code[] = "using std::to_string;\n" // #8454 + "void f() {\n" + " std::string str = to_string(1);\n" + "}\n"; + const char expected[] = "void f ( ) { std :: string str ; str = std :: to_string ( 1 ) ; }"; + ASSERT_EQUALS(expected, tok(code, Platform::Type::Native, /*debugwarnings*/ true)); + ASSERT_EQUALS("", errout.str()); + } + { + const char code[] = "using std::cout, std::endl, std::cerr, std::ostringstream;\n" + "cerr << \"abc\";\n"; + const char expected[] = "std :: cerr << \"abc\" ;"; + ASSERT_EQUALS(expected, tok(code, Platform::Type::Native, /*debugwarnings*/ true)); + ASSERT_EQUALS("", errout.str()); + } + { + const char code[] = "using std::string_view_literals::operator\"\"sv;\n"; + const char expected[] = "using std :: string_view_literals :: operator\"\"sv ;"; + ASSERT_EQUALS(expected, tok(code, Platform::Type::Native, /*debugwarnings*/ true)); + ASSERT_EQUALS("", errout.str()); + } + { + const char code[] = "template \n" + "class vector : public ::std::vector {\n" + "public:\n" + " using ::std::vector::vector;\n" + " vector() {}\n" + "};\n" + "vector v;\n"; + const char expected[] = "class vector ; " + "vector v ; " + "class vector : public :: std :: vector { " + "public: " + "using vector = :: std :: vector :: vector ; " + "vector ( ) { } " + "} ;"; + ASSERT_EQUALS(expected, tok(code, Platform::Type::Native, /*debugwarnings*/ true)); + ASSERT_EQUALS("", errout.str()); + } } void simplifyUsing8970() {