From 39092150e248adb34a47accfd4a074f67a1bc50e Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Thu, 1 Oct 2009 10:25:32 +0300 Subject: [PATCH] Fix #763 (Tokenizer: Goto incorrectly simplified) http://sourceforge.net/apps/trac/cppcheck/ticket/763 --- src/tokenize.cpp | 64 ++++++++++++++++++++++--------------- test/testsimplifytokens.cpp | 29 +++++++++++++++++ 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/src/tokenize.cpp b/src/tokenize.cpp index fca453c91..bb1a60f1b 100644 --- a/src/tokenize.cpp +++ b/src/tokenize.cpp @@ -1605,12 +1605,6 @@ void Tokenizer::simplifyTokenList() 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 for (Token *tok = _tokens; tok; tok = tok->next()) { @@ -3513,27 +3507,19 @@ void Tokenizer::simplifyGoto() Token *token = *it; if (token->next()->str() == name) { - Token *openBrace = NULL; - // Delete the "goto name;" token = token->previous(); token->deleteNext(); token->deleteNext(); token->deleteNext(); - const bool endpar(token->str() == ")"); - if (endpar) - { - token->insertToken("{"); - token = token->next(); - openBrace = token; - } - // Insert the statements.. bool ret = false; - std::list links; + std::list links2; + std::list links3; int lev = 0; + bool quit = false; for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { if (tok2->str() == "}") @@ -3541,13 +3527,10 @@ void Tokenizer::simplifyGoto() --lev; if (lev < 0) break; - - continue; } if (tok2->str() == "{") { ++lev; - continue; } else if (tok2->str() == "return") ret = true; @@ -3569,6 +3552,41 @@ void Tokenizer::simplifyGoto() Token::createMutualLinks(links.back(), token); 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) @@ -3578,12 +3596,6 @@ void Tokenizer::simplifyGoto() token->insertToken(";"); token = token->next(); } - if (endpar) - { - token->insertToken("}"); - token = token->next(); - Token::createMutualLinks(openBrace, token); - } } } diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index bc18372c8..ede53bb74 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -1539,6 +1539,35 @@ private: 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 ; } ;"; ASSERT_EQUALS(code, tok(code));