Skip to content

Commit 44b9221

Browse files
authored
Fix #14955: Bad varid for enumerator with using namespace (#8773)
1 parent cb6d92e commit 44b9221

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

lib/tokenize.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5270,7 +5270,16 @@ void Tokenizer::setVarIdPass2()
52705270
std::map<const Token *, std::string> endOfScope;
52715271
std::list<std::string> scope;
52725272
std::list<const Token *> usingnamespaces;
5273+
const Token *enumEnd = nullptr;
52735274
for (Token *tok = list.front(); tok; tok = tok->next()) {
5275+
if (isEnumStart(tok)) {
5276+
enumEnd = tok->link();
5277+
continue;
5278+
}
5279+
if (tok == enumEnd) {
5280+
enumEnd = nullptr;
5281+
continue;
5282+
}
52745283
if (!tok->previous() || Token::Match(tok->previous(), "[;{}]")) {
52755284
if (Token::Match(tok, "using namespace %name% ::|;")) {
52765285
Token *endtok = tok->tokAt(2);
@@ -5300,7 +5309,8 @@ void Tokenizer::setVarIdPass2()
53005309
tok = tok->next()->findClosingBracket()->next();
53015310
else if (usingnamespaces.empty() || tok->varId() || !tok->isName() || tok->isStandardType() || tok->tokType() == Token::eKeyword || tok->tokType() == Token::eBoolean ||
53025311
Token::Match(tok->previous(), ".|namespace|class|struct|&|&&|*|> %name%") || Token::Match(tok->previous(), "%type%| %name% ( %type%|)") || Token::Match(tok, "public:|private:|protected:") ||
5303-
(!tok->next() && Token::Match(tok->previous(), "}|; %name%")))
5312+
(!tok->next() && Token::Match(tok->previous(), "}|; %name%")) ||
5313+
(enumEnd && Token::Match(tok->previous(), "{|, %name% =|,|}")))
53045314
continue;
53055315

53065316
if (tok->strAt(-1) == "::" && tok->tokAt(-2) && tok->tokAt(-2)->isName())

test/testtokenize.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class TestTokenizer : public TestFixture {
9393
TEST_CASE(tokenize41); // #13847
9494
TEST_CASE(tokenize42); // #13861
9595
TEST_CASE(tokenize43); // #13861
96+
TEST_CASE(tokenize44); // #14955
9697

9798
TEST_CASE(validate);
9899

@@ -949,6 +950,21 @@ class TestTokenizer : public TestFixture {
949950
(void)errout_str();
950951
}
951952

953+
void tokenize44() { // #14955
954+
const char code[] = "namespace O {}\n"
955+
"namespace N {\n"
956+
" using namespace O;\n"
957+
" enum class E { E0 };\n"
958+
" E E0 = E::E0;\n"
959+
"}\n";
960+
const char expected[] = "2: namespace N {\n"
961+
"3: using namespace O ;\n"
962+
"4: enum class E { E0 } ;\n"
963+
"5: E E0@1 ; E0@1 = E :: E0 ;\n"
964+
"6: }\n";
965+
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
966+
}
967+
952968
void validate() {
953969
// C++ code in C file
954970
ASSERT_THROW_INTERNAL(tokenizeAndStringify(";using namespace std;",dinit(TokenizeOptions, $.expand = false, $.cpp = false)), SYNTAX);

0 commit comments

Comments
 (0)