From e9ec4bc3e41cd13307c9e9c75ea49d65a4dd558d Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Thu, 3 Feb 2011 07:58:49 +0100 Subject: [PATCH] Fixed #2536 (cppcheck hangs with 100% cpu load) --- lib/tokenize.cpp | 36 +++++++++++++++++++++++++++++++----- test/testsimplifytokens.cpp | 8 ++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 49d752020..5c7cfaf2d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -824,7 +824,8 @@ void Tokenizer::simplifyTypedef() if (_errorLogger && !_files.empty()) _errorLogger->reportProgress(_files[0], "Tokenize (typedef)", tok->progressValue()); - if (Token::Match(tok, "class|struct|namespace %any%")) + if (Token::Match(tok, "class|struct|namespace %any%") && + (!tok->previous() || (tok->previous() && tok->previous()->str() != "enum"))) { isNamespace = (tok->str() == "namespace"); hasClass = true; @@ -7549,7 +7550,8 @@ void Tokenizer::simplifyEnum() int classLevel = 0; for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "class|struct|namespace %any%")) + if (Token::Match(tok, "class|struct|namespace %any%") && + (!tok->previous() || (tok->previous() && tok->previous()->str() != "enum"))) { className = tok->next()->str(); classLevel = 0; @@ -7569,7 +7571,7 @@ void Tokenizer::simplifyEnum() continue; } else if (Token::Match(tok, "enum class|struct| {|:") || - Token::Match(tok, "enum class|struct| %type% {|:")) + Token::Match(tok, "enum class|struct| %type% {|:|;")) { Token *tok1; Token *start = tok; @@ -7590,12 +7592,19 @@ void Tokenizer::simplifyEnum() offset = 3; // check for forward declaration - /** @todo start substitution check at forward declaration */ const Token *temp = tok->tokAt(offset); while (!Token::Match(temp, "{|;")) temp = temp->next(); if (temp->str() == ";") + { + /** @todo start substitution check at forward declaration */ + // delete forward declaration + tok->deleteThis(); + tok->deleteThis(); + tok->deleteThis(); + tok->deleteThis(); continue; + } typeTokenStart = tok->tokAt(offset); typeTokenEnd = typeTokenStart; @@ -7609,6 +7618,16 @@ void Tokenizer::simplifyEnum() } } + // check for forward declaration + else if (Token::Match(tok->next(), "%type% ;")) + { + /** @todo start substitution check at forward declaration */ + // delete forward declaration + tok->deleteThis(); + tok->deleteThis(); + continue; + } + if (tok->tokAt(1)->str() == "{") tok1 = tok->tokAt(2); else if (tok->tokAt(1)->str() == ":") @@ -9254,6 +9273,12 @@ void Tokenizer::simplifyQtSignalsSlots() Token *tok = _tokens; while ((tok = const_cast(Token::findmatch(tok, "class %var% :")))) { + if (tok->previous() && tok->previous()->str() == "enum") + { + tok = tok->tokAt(2); + continue; + } + // count { and } for tok2 unsigned int indentlevel = 0; for (Token *tok2 = tok; tok2; tok2 = tok2->next()) @@ -9341,7 +9366,8 @@ void Tokenizer::removeUnnecessaryQualification() std::stack classInfo; for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "class|struct %type% :|{")) + if (Token::Match(tok, "class|struct %type% :|{") && + (!tok->previous() || (tok->previous() && tok->previous()->str() != "enum"))) { tok = tok->next(); ClassInfo info; diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 9ba7bc197..0de4ff250 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -278,6 +278,7 @@ private: TEST_CASE(enum16); // ticket #1988 TEST_CASE(enum17); // ticket #2381 (duplicate enums) TEST_CASE(enum18); // #2466 (array with same name as enum constant) + TEST_CASE(enum19); // ticket #2536 // remove "std::" on some standard functions TEST_CASE(removestd); @@ -6099,6 +6100,13 @@ private: ASSERT_EQUALS("; void f ( ) { a [ 0 ] ; }", tok(code, false)); } + void enum19() // ticket #2536 + { + const char code[] = "enum class E1;\n" + "enum class E2 : int;\n"; + ASSERT_EQUALS(";", tok(code, false)); + } + void removestd() { ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));