diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 859cf0160..73535d410 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7386,7 +7386,26 @@ void Tokenizer::simplifyEnum() } else if (tok2->str() == "{") { - ++level; + // Is the same enum redefined? + const Token *begin = end->link(); + if (tok2->fileIndex() == begin->fileIndex() && + tok2->linenr() == begin->linenr() && + Token::Match(begin->tokAt(-2), "enum %type% {") && + Token::Match(tok2->tokAt(-2), "enum %type% {") && + begin->strAt(-1) == tok2->strAt(-1)) + { + // remove duplicate enum + Token * startToken = tok2->tokAt(-3); + tok2 = tok2->link()->next(); + Token::eraseTokens(startToken, tok2); + if (!tok2) + break; + } + else + { + // Not a duplicate enum.. + ++level; + } } else if (!pattern.empty() && Token::Match(tok2, pattern.c_str())) { @@ -7396,7 +7415,7 @@ void Tokenizer::simplifyEnum() else if (inScope && !exitThisScope && tok2->str() == enumName->str()) { if (Token::simpleMatch(tok2->previous(), "::") || - (tok2->next() && Token::simpleMatch(tok2->next(), "::"))) + Token::simpleMatch(tok2->next(), "::")) { // Don't replace this enum if it's preceded or followed by "::" } diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 59050cddf..eaedfb297 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -269,6 +269,7 @@ private: TEST_CASE(enum14); TEST_CASE(enum15); TEST_CASE(enum16); // ticket #1988 + TEST_CASE(enum17); // ticket #2381 (duplicate enums) // remove "std::" on some standard functions TEST_CASE(removestd); @@ -5892,6 +5893,15 @@ private: ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); } + void enum17() // ticket #2381 + { + // if header is included twice its enums will be duplicated + const char code[] = "enum ab { a=0, b };" + "enum ab { a=0, b };\n"; + ASSERT_EQUALS(";", tok(code, false)); + ASSERT_EQUALS("", errout.str()); + } + void removestd() { ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));