Fix #763 (Tokenizer: Goto incorrectly simplified)

http://sourceforge.net/apps/trac/cppcheck/ticket/763
This commit is contained in:
Reijo Tomperi 2009-10-01 10:25:32 +03:00
parent e3e8224b4e
commit 39092150e2
2 changed files with 67 additions and 26 deletions

View File

@ -1605,12 +1605,6 @@ void Tokenizer::simplifyTokenList()
simplifyGoto(); simplifyGoto();
// TODO, simplifyDoWhileAddBraces and simplifyIfAddBraces calls
// should be removed from here, but currently simplifyGoto
// removes braces which causes some tests to fail.
simplifyDoWhileAddBraces();
simplifyIfAddBraces();
// Combine wide strings // Combine wide strings
for (Token *tok = _tokens; tok; tok = tok->next()) for (Token *tok = _tokens; tok; tok = tok->next())
{ {
@ -3513,27 +3507,19 @@ void Tokenizer::simplifyGoto()
Token *token = *it; Token *token = *it;
if (token->next()->str() == name) if (token->next()->str() == name)
{ {
Token *openBrace = NULL;
// Delete the "goto name;" // Delete the "goto name;"
token = token->previous(); token = token->previous();
token->deleteNext(); token->deleteNext();
token->deleteNext(); token->deleteNext();
token->deleteNext(); token->deleteNext();
const bool endpar(token->str() == ")");
if (endpar)
{
token->insertToken("{");
token = token->next();
openBrace = token;
}
// Insert the statements.. // Insert the statements..
bool ret = false; bool ret = false;
std::list<Token*> links; std::list<Token*> links;
std::list<Token*> links2;
std::list<Token*> links3;
int lev = 0; int lev = 0;
bool quit = false;
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
{ {
if (tok2->str() == "}") if (tok2->str() == "}")
@ -3541,13 +3527,10 @@ void Tokenizer::simplifyGoto()
--lev; --lev;
if (lev < 0) if (lev < 0)
break; break;
continue;
} }
if (tok2->str() == "{") if (tok2->str() == "{")
{ {
++lev; ++lev;
continue;
} }
else if (tok2->str() == "return") else if (tok2->str() == "return")
ret = true; ret = true;
@ -3569,6 +3552,41 @@ void Tokenizer::simplifyGoto()
Token::createMutualLinks(links.back(), token); Token::createMutualLinks(links.back(), token);
links.pop_back(); links.pop_back();
} }
else if (token->str() == "{")
{
links2.push_back(token);
}
else if (token->str() == "}")
{
if (links2.size() == 0)
{
// This should never happen at this point
syntaxError(token, '}');
return;
}
Token::createMutualLinks(links2.back(), token);
links2.pop_back();
}
else if (token->str() == "[")
{
links3.push_back(token);
}
else if (token->str() == "]")
{
if (links3.size() == 0)
{
// This should never happen at this point
syntaxError(token, ']');
return;
}
Token::createMutualLinks(links3.back(), token);
links3.pop_back();
}
if (quit)
break;
} }
if (!ret) if (!ret)
@ -3578,12 +3596,6 @@ void Tokenizer::simplifyGoto()
token->insertToken(";"); token->insertToken(";");
token = token->next(); token = token->next();
} }
if (endpar)
{
token->insertToken("}");
token = token->next();
Token::createMutualLinks(openBrace, token);
}
} }
} }

View File

@ -1539,6 +1539,35 @@ private:
ASSERT_EQUALS(expect, tok(code)); ASSERT_EQUALS(expect, tok(code));
} }
{
const char code[] = "void foo(int x)\n"
"{\n"
" if (a())\n"
" goto out;\n"
" b();\n"
"out:\n"
" if (x)\n"
" {\n"
" x++; b[0]=x;\n"
" }\n"
"}";
const char expect[] = "void foo ( int x ) "
"{ "
"if ( a ( ) ) "
"{ "
"if ( x ) "
"{ x ++ ; b [ 0 ] = x ; } "
"return ; "
"} "
"b ( ) ; "
"if ( x ) "
"{ x ++ ; b [ 0 ] = x ; } "
"}";
ASSERT_EQUALS(expect, tok(code));
}
{ {
const char code[] = "class NoLabels { bool varOne : 1 ; bool varTwo : 1 ; } ;"; const char code[] = "class NoLabels { bool varOne : 1 ; bool varTwo : 1 ; } ;";
ASSERT_EQUALS(code, tok(code)); ASSERT_EQUALS(code, tok(code));