Temporary workaround to ticket #3459 (Simplify goto before loop) :

don't simplify code which contains the label pointed by 'goto'.
This commit is contained in:
Edoardo Prezioso 2012-01-27 16:56:12 +01:00
parent 6314d04a04
commit 0dd4b9ad3a
2 changed files with 46 additions and 0 deletions

View File

@ -7567,6 +7567,7 @@ void Tokenizer::eraseDeadCode(Token *begin, const Token *end)
{
if (!begin)
return;
bool isgoto = Token::Match(begin->tokAt(-2), "goto %var% ;");
unsigned int indentlevel = 1,
indentcase = 0,
indentswitch = 0,
@ -7698,6 +7699,26 @@ void Tokenizer::eraseDeadCode(Token *begin, const Token *end)
}
break; //stop removing tokens, we arrived to the label.
}
} else if (isgoto && Token::Match(tok, "[{};] do|while|for|BOOST_FOREACH")) {
//it's possible that code inside loop is not dead,
//because of the possible presence of the label pointed by 'goto'
std::string labelpattern = "[{};] " + begin->previous()->str() + " : ;";
Token *start = tok->tokAt(2);
if (start && start->str() == "(")
start = start->link()->next();
if (start && start->str() == "{") {
bool simplify = true;
for (Token *tok2 = start->next(); tok2 != start->link(); tok2 = tok2->next()) {
if (Token::Match(tok2, labelpattern.c_str())) {
simplify = false;
break;
}
}
//bailout for now
if (!simplify)
break;
}
tok->deleteNext();
} else { //no need to keep the other strings, remove them.
tok->deleteNext();
}

View File

@ -162,6 +162,8 @@ private:
TEST_CASE(goto2);
// ticket #3138
TEST_CASE(goto3);
// ticket #3459
TEST_CASE(goto4);
//remove dead code after flow control statements
TEST_CASE(flowControl);
@ -3180,6 +3182,29 @@ private:
}
}
void goto4() {
const char code[] = "int main()\n"
"{\n"
" goto SkipIncr;\n"
" do {\n"
" f();\n"
" SkipIncr:\n"
" printf(\".\");\n"
" } while (bar());\n"
"}\n";
const char expected[] = "int main ( ) "
"{"
" goto SkipIncr ;"
" do {"
" f ( ) ;"
" SkipIncr : ;"
" printf ( \".\" ) ;"
" } while ( bar ( ) ) ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
void flowControl() {
std::list<std::string> beforedead;
beforedead.push_back("return");