From 8b518bf80b704f0e884740ebfd30a4d0434b6246 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Apr 2024 07:27:46 +0200 Subject: [PATCH] Partial fix for #12014 Outer typedef incorrectly applied within namespace (#6288) --- lib/tokenize.cpp | 22 +++++++++++++++++----- test/testsimplifytypedef.cpp | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f28f16e0105..5ac73edeae0 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1125,6 +1125,18 @@ void Tokenizer::simplifyTypedef() simplifyTypedefCpp(); } +static bool isEnumScope(const Token* tok) +{ + if (!Token::simpleMatch(tok, "{")) + return false; + tok = tok->previous(); + while (tok && !tok->isKeyword() && Token::Match(tok, "%name%|::|:")) + tok = tok->previous(); + if (Token::simpleMatch(tok, "class")) + tok = tok->previous(); + return Token::simpleMatch(tok, "enum"); +} + void Tokenizer::simplifyTypedefCpp() { bool isNamespace = false; @@ -1622,7 +1634,7 @@ void Tokenizer::simplifyTypedefCpp() bool globalScope = false; int classLevel = spaceInfo.size(); bool inTypeDef = false; - bool inEnumClass = false; + bool inEnum = false; std::string removed; std::string classPath; for (size_t i = 1; i < spaceInfo.size(); ++i) { @@ -1676,7 +1688,7 @@ void Tokenizer::simplifyTypedefCpp() if (memberScope == 0) inMemberFunc = false; } - inEnumClass = false; + inEnum = false; if (classLevel > 1 && tok2 == spaceInfo[classLevel - 1].bodyEnd2) { --classLevel; @@ -1736,8 +1748,8 @@ void Tokenizer::simplifyTypedefCpp() } ++scope; } - if (Token::Match(tok2->tokAt(-3), "enum class %name%")) - inEnumClass = true; + if (isEnumScope(tok2)) + inEnum = true; } // keep track of scopes within member function @@ -1863,7 +1875,7 @@ void Tokenizer::simplifyTypedefCpp() } } - simplifyType = simplifyType && (!inEnumClass || Token::simpleMatch(tok2->previous(), "=")); + simplifyType = simplifyType && (!inEnum || !Token::simpleMatch(tok2->next(), "=")); simplifyType = simplifyType && !(Token::simpleMatch(tok2->next(), "<") && Token::simpleMatch(typeEnd, ">")); if (simplifyType) { diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 4970e863c5d..be8a599bc1f 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -215,6 +215,7 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedef149); TEST_CASE(simplifyTypedef150); TEST_CASE(simplifyTypedef151); + TEST_CASE(simplifyTypedef152); TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -3543,6 +3544,25 @@ class TestSimplifyTypedef : public TestFixture { ASSERT_EQUALS(exp, tok(code)); } + void simplifyTypedef152() { + const char* code{}, *exp{}; + code = "namespace O { struct T {}; }\n" + "typedef O::T S;\n" + "namespace M {\n" + " enum E { E0, S = 1 };\n" + " enum class F : ::std::int8_t { F0, S = 1 };\n" + "}\n" + "namespace N { enum { G0, S = 1 }; }\n"; + exp = "namespace O { struct T { } ; } " + "namespace M { " + "enum E { E0 , S = 1 } ; " + "enum class F : :: std :: int8_t { F0 , S = 1 } ; " + "}" + " namespace N { enum Anonymous0 { G0 , S = 1 } ; " + "}"; + ASSERT_EQUALS(exp, tok(code)); + } + void simplifyTypedefFunction1() { { const char code[] = "typedef void (*my_func)();\n"