From 57ead6988e80a9abe9132eb6fc56d42df6467569 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sat, 15 Oct 2011 11:35:45 +0200 Subject: [PATCH] Fixed ticket #3138 (Tokenizer: remove unreachable code below goto inside a namespace|class|struct block) --- lib/tokenize.cpp | 27 ++++-- test/testsimplifytokens.cpp | 174 ++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+), 9 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 95466dd00..cff265107 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7333,30 +7333,39 @@ void Tokenizer::simplifyGoto() { std::list 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; } diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 3a765706f..a14d1dafa 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -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();}"));