Fixed ticket #3138 (Tokenizer: remove unreachable code below goto inside a namespace|class|struct block)

This commit is contained in:
Edoardo Prezioso 2011-10-15 11:35:45 +02:00
parent f95b692a69
commit 57ead6988e
2 changed files with 192 additions and 9 deletions

View File

@ -7333,30 +7333,39 @@ void Tokenizer::simplifyGoto()
{
std::list<Token *> gotos;
unsigned int indentlevel = 0;
unsigned int indentspecial = 0;
Token *beginfunction = 0;
for (Token *tok = _tokens; tok; tok = tok->next()) {
if (tok->str() == "{") {
if (beginfunction == 0 && indentlevel == 0 && tok->link())
if ((tok->tokAt(-2) && Token::Match(tok->tokAt(-2),"namespace|struct|class|union %var% {")) ||
(tok->previous() && Token::Match(tok->previous(),"namespace {")))
++indentspecial;
else if (!beginfunction && !indentlevel)
tok = tok->link();
else
++indentlevel;
}
else if (tok->str() == "}") {
if (indentlevel == 0)
break; // break out - it seems the code is wrong
--indentlevel;
if (indentlevel == 0) {
gotos.clear();
beginfunction = 0;
if (!indentlevel) {
if (indentspecial)
--indentspecial;
else
break; // break out - it seems the code is wrong
} else {
--indentlevel;
if (!indentlevel) {
gotos.clear();
beginfunction = 0;
}
}
}
else if (indentlevel > 0 && tok->str() == "(") {
else if (indentlevel && tok->str() == "(") {
tok = tok->link();
}
else if (indentlevel == 0 && Token::Match(tok, ") const| {")) {
else if (!indentlevel && Token::Match(tok, ") const| {")) {
gotos.clear();
beginfunction = tok;
}

View File

@ -154,6 +154,8 @@ private:
// Simplify goto..
TEST_CASE(goto1);
TEST_CASE(goto2);
// ticket #3138
TEST_CASE(goto3);
//remove redundant code after flow control statements
TEST_CASE(return1);
@ -2895,6 +2897,178 @@ private:
ASSERT_EQUALS(code, tok(code));
}
void goto3() {
// Simplify goto inside the namespace|struct|class|union block
{
const char code[] = "namespace A1"
"{"
" void foo()"
" {"
" goto source ;"
" bleeh;"
" source:"
" boo();"
" }"
"}";
const char expected[] = "namespace A1 "
"{"
" void foo ( )"
" {"
" boo ( ) ; return ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "class A"
"{"
" int n,m;"
" A()"
" {"
" goto source ;"
" bleeh;"
" source:"
" boo();"
" }"
" void boo();"
"}";
const char expected[] = "class A "
"{"
" int n ; int m ;"
" A ( )"
" {"
" boo ( ) ; return ;"
" }"
" void boo ( ) ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "struct A"
"{"
" int n,m;"
" A() : m(0)"
" {"
" goto source;"
" bleeh;"
" source:"
" n=10;"
" }"
"}";
const char expected[] = "struct A "
"{"
" int n ; int m ;"
" A ( ) : m ( 0 )"
" {"
" n = 10 ; return ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "namespace A1"
"{"
" class A"
" {"
" int n,m;"
" A()"
" {"
" goto source ;"
" bleeh;"
" source:"
" boo();"
" }"
" void boo();"
" }"
"}";
const char expected[] = "namespace A1 "
"{"
" class A"
" {"
" int n ; int m ;"
" A ( )"
" {"
" boo ( ) ; return ;"
" }"
" void boo ( ) ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "namespace A1"
"{"
" namespace AA1"
" {"
" void foo1()"
" {"
" goto source1 ;"
" bleeh;"
" source1:"
" boo1();"
" }"
" }"
" namespace AA2"
" {"
" void foo2()"
" {"
" goto source2 ;"
" bleeh;"
" source2:"
" boo2();"
" }"
" }"
"}";
const char expected[] = "namespace A1 "
"{"
" namespace AA1"
" {"
" void foo1 ( )"
" {"
" boo1 ( ) ; return ;"
" }"
" }"
" namespace AA2"
" {"
" void foo2 ( )"
" {"
" boo2 ( ) ; return ;"
" }"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "union A1"
"{"
" int a; "
" double b; "
" A1() : b(3.22)"
" {"
" goto source ;"
" bleeh;"
" source:"
" a = 322;"
" }"
"}";
const char expected[] = "union A1 "
"{"
" int a ;"
" double b ;"
" A1 ( ) : b ( 3.22 )"
" {"
" a = 322 ; return ;"
" } "
"}";
ASSERT_EQUALS(expected, tok(code));
}
}
void return1() {
ASSERT_EQUALS("void f ( ) { return ; }", tok("void f() { return; foo();}"));
ASSERT_EQUALS("void f ( int n ) { if ( n ) { return ; } foo ( ) ; }",tok("void f(int n) { if (n) return; foo();}"));