Fixed #2536 (cppcheck hangs with 100% cpu load)

This commit is contained in:
Robert Reif 2011-02-03 07:58:49 +01:00 committed by Daniel Marjamäki
parent 8288c28b3f
commit e9ec4bc3e4
2 changed files with 39 additions and 5 deletions

View File

@ -824,7 +824,8 @@ void Tokenizer::simplifyTypedef()
if (_errorLogger && !_files.empty()) if (_errorLogger && !_files.empty())
_errorLogger->reportProgress(_files[0], "Tokenize (typedef)", tok->progressValue()); _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"); isNamespace = (tok->str() == "namespace");
hasClass = true; hasClass = true;
@ -7549,7 +7550,8 @@ void Tokenizer::simplifyEnum()
int classLevel = 0; int classLevel = 0;
for (Token *tok = _tokens; tok; tok = tok->next()) 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(); className = tok->next()->str();
classLevel = 0; classLevel = 0;
@ -7569,7 +7571,7 @@ void Tokenizer::simplifyEnum()
continue; continue;
} }
else if (Token::Match(tok, "enum class|struct| {|:") || 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 *tok1;
Token *start = tok; Token *start = tok;
@ -7590,12 +7592,19 @@ void Tokenizer::simplifyEnum()
offset = 3; offset = 3;
// check for forward declaration // check for forward declaration
/** @todo start substitution check at forward declaration */
const Token *temp = tok->tokAt(offset); const Token *temp = tok->tokAt(offset);
while (!Token::Match(temp, "{|;")) while (!Token::Match(temp, "{|;"))
temp = temp->next(); temp = temp->next();
if (temp->str() == ";") if (temp->str() == ";")
{
/** @todo start substitution check at forward declaration */
// delete forward declaration
tok->deleteThis();
tok->deleteThis();
tok->deleteThis();
tok->deleteThis();
continue; continue;
}
typeTokenStart = tok->tokAt(offset); typeTokenStart = tok->tokAt(offset);
typeTokenEnd = typeTokenStart; 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() == "{") if (tok->tokAt(1)->str() == "{")
tok1 = tok->tokAt(2); tok1 = tok->tokAt(2);
else if (tok->tokAt(1)->str() == ":") else if (tok->tokAt(1)->str() == ":")
@ -9254,6 +9273,12 @@ void Tokenizer::simplifyQtSignalsSlots()
Token *tok = _tokens; Token *tok = _tokens;
while ((tok = const_cast<Token *>(Token::findmatch(tok, "class %var% :")))) while ((tok = const_cast<Token *>(Token::findmatch(tok, "class %var% :"))))
{ {
if (tok->previous() && tok->previous()->str() == "enum")
{
tok = tok->tokAt(2);
continue;
}
// count { and } for tok2 // count { and } for tok2
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) for (Token *tok2 = tok; tok2; tok2 = tok2->next())
@ -9341,7 +9366,8 @@ void Tokenizer::removeUnnecessaryQualification()
std::stack<ClassInfo> classInfo; std::stack<ClassInfo> classInfo;
for (Token *tok = _tokens; tok; tok = tok->next()) 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(); tok = tok->next();
ClassInfo info; ClassInfo info;

View File

@ -278,6 +278,7 @@ private:
TEST_CASE(enum16); // ticket #1988 TEST_CASE(enum16); // ticket #1988
TEST_CASE(enum17); // ticket #2381 (duplicate enums) TEST_CASE(enum17); // ticket #2381 (duplicate enums)
TEST_CASE(enum18); // #2466 (array with same name as enum constant) TEST_CASE(enum18); // #2466 (array with same name as enum constant)
TEST_CASE(enum19); // ticket #2536
// remove "std::" on some standard functions // remove "std::" on some standard functions
TEST_CASE(removestd); TEST_CASE(removestd);
@ -6099,6 +6100,13 @@ private:
ASSERT_EQUALS("; void f ( ) { a [ 0 ] ; }", tok(code, false)); 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() void removestd()
{ {
ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);")); ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));