Tokenizer: Removed simplifyGoto as it's the cause of various FPs I see
This commit is contained in:
parent
4eb746d7cc
commit
0203a4a6f5
199
lib/tokenize.cpp
199
lib/tokenize.cpp
|
@ -3530,8 +3530,6 @@ bool Tokenizer::simplifyTokenList2()
|
|||
|
||||
simplifyStd();
|
||||
|
||||
simplifyGoto();
|
||||
|
||||
if (_settings->terminated())
|
||||
return false;
|
||||
|
||||
|
@ -7205,203 +7203,6 @@ void Tokenizer::simplifyOffsetPointerDereference()
|
|||
}
|
||||
}
|
||||
|
||||
void Tokenizer::simplifyGoto()
|
||||
{
|
||||
std::list<Token *> gotos;
|
||||
unsigned int indentlevel = 0;
|
||||
unsigned int indentspecial = 0;
|
||||
Token *beginfunction = 0;
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "(" || tok->str() == "[")
|
||||
tok = tok->link();
|
||||
|
||||
else if (Token::Match(tok, "class|namespace|struct|union %type% :|{")) {
|
||||
tok = tok->tokAt(2);
|
||||
while (tok && !Token::Match(tok, "[;{=]"))
|
||||
tok = tok->next();
|
||||
if (tok && tok->str() == "{")
|
||||
++indentspecial;
|
||||
else if (!tok)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, "namespace|struct|union {")) {
|
||||
tok = tok->next();
|
||||
++indentspecial;
|
||||
}
|
||||
|
||||
else if (tok->str() == "{") {
|
||||
if ((!beginfunction && !indentlevel) ||
|
||||
(tok->previous() && tok->previous()->str() == "="))
|
||||
tok = tok->link();
|
||||
else
|
||||
++indentlevel;
|
||||
}
|
||||
|
||||
else if (tok->str() == "}") {
|
||||
if (indentlevel == 0) {
|
||||
if (indentspecial)
|
||||
--indentspecial;
|
||||
} else {
|
||||
--indentlevel;
|
||||
if (indentlevel == 0) {
|
||||
gotos.clear();
|
||||
beginfunction = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!indentlevel && Token::Match(tok, ") const| {"))
|
||||
beginfunction = tok;
|
||||
|
||||
else if (indentlevel && Token::Match(tok, "[{};] goto %var% ;"))
|
||||
gotos.push_back(tok->next());
|
||||
|
||||
else if (indentlevel == 1 && Token::Match(tok, "[{};] %var% : ;") && tok->next()->str() != "default") {
|
||||
// Is this label at the end..
|
||||
bool end = false;
|
||||
unsigned int level = 0;
|
||||
for (const Token *tok2 = tok->tokAt(3); tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == "(" || tok2->str() == "[")
|
||||
tok2 = tok2->link();
|
||||
|
||||
else if (tok2->str() == "{") {
|
||||
++level;
|
||||
}
|
||||
|
||||
else if (tok2->str() == "}") {
|
||||
if (!level) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
--level;
|
||||
}
|
||||
|
||||
if ((Token::Match(tok2, "[{};] %var% : ;") && tok2->next()->str() != "default") ||
|
||||
Token::Match(tok2, "[{};] goto %var% ;")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!end)
|
||||
continue;
|
||||
|
||||
const std::string name(tok->next()->str());
|
||||
|
||||
tok->deleteNext(3);
|
||||
|
||||
// This label is at the end of the function.. replace all matching goto statements..
|
||||
for (std::list<Token *>::iterator it = gotos.begin(); it != gotos.end(); ++it) {
|
||||
Token *token = *it;
|
||||
if (token->next()->str() == name) {
|
||||
// Delete the "goto name;"
|
||||
token = token->previous();
|
||||
// change 'tok' before 'goto' if it coincides with the ';' token after 'name'
|
||||
if (token->tokAt(3) == tok)
|
||||
tok = token;
|
||||
token->deleteNext(3);
|
||||
|
||||
// Insert the statements..
|
||||
bool ret = false; // is there return
|
||||
bool ret2 = false; // is there return in indentlevel 0
|
||||
std::list<Token*> links;
|
||||
std::list<Token*> links2;
|
||||
std::list<Token*> links3;
|
||||
unsigned int lev = 0;
|
||||
unsigned int roundbraces = 0;
|
||||
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == ")") {
|
||||
if (!roundbraces)
|
||||
break;
|
||||
--roundbraces;
|
||||
}
|
||||
if (tok2->str() == "(")
|
||||
++roundbraces;
|
||||
|
||||
if (!roundbraces && tok2->str() == "}") {
|
||||
if (!lev)
|
||||
break;
|
||||
--lev;
|
||||
} else if (!roundbraces && tok2->str() == "{") {
|
||||
++lev;
|
||||
} else if (!roundbraces && tok2->str() == "return") {
|
||||
ret = true;
|
||||
if (indentlevel == 1 && lev == 0)
|
||||
ret2 = true;
|
||||
}
|
||||
token->insertToken(tok2->str());
|
||||
token = token->next();
|
||||
token->linenr(tok2->linenr());
|
||||
token->varId(tok2->varId());
|
||||
if (ret2 && roundbraces == 0 && tok2->str() == ";") {
|
||||
break;
|
||||
}
|
||||
if (token->str() == "(") {
|
||||
links.push_back(token);
|
||||
} else if (token->str() == ")") {
|
||||
if (links.empty()) {
|
||||
// This should never happen at this point
|
||||
syntaxError(token, ')');
|
||||
return;
|
||||
}
|
||||
|
||||
Token::createMutualLinks(links.back(), token);
|
||||
links.pop_back();
|
||||
} else if (token->str() == "{") {
|
||||
links2.push_back(token);
|
||||
} else if (token->str() == "}") {
|
||||
if (links2.empty()) {
|
||||
// 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.empty()) {
|
||||
// This should never happen at this point
|
||||
syntaxError(token, ']');
|
||||
return;
|
||||
}
|
||||
|
||||
Token::createMutualLinks(links3.back(), token);
|
||||
links3.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
token->insertToken(";");
|
||||
token->insertToken("return");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// goto the end of the function
|
||||
if (tok->str() == "{")
|
||||
tok = tok->link();
|
||||
else {
|
||||
while (tok) {
|
||||
if (tok->str() == "{")
|
||||
tok = tok->link();
|
||||
else if (tok->str() == "}")
|
||||
break;
|
||||
tok = tok->next();
|
||||
}
|
||||
}
|
||||
if (!tok)
|
||||
break;
|
||||
gotos.clear();
|
||||
beginfunction = 0;
|
||||
indentlevel = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tokenizer::simplifyNestedStrcat()
|
||||
{
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
|
|
|
@ -369,9 +369,6 @@ public:
|
|||
*/
|
||||
bool simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsigned int varid, const std::string &structname, std::string &value, unsigned int valueVarId, bool valueIsPointer, const Token * const valueToken, int indentlevel) const;
|
||||
|
||||
/** Replace a "goto" with the statements */
|
||||
void simplifyGoto();
|
||||
|
||||
/** Simplify useless C++ empty namespaces, like: 'namespace %var% { }'*/
|
||||
void simplifyEmptyNamespaces();
|
||||
|
||||
|
|
|
@ -284,7 +284,6 @@ private:
|
|||
Tokenizer tokenizer(&settings, &logger);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, filename);
|
||||
tokenizer.simplifyGoto();
|
||||
|
||||
// Check..
|
||||
CheckOther checkOther(&tokenizer, &settings, &logger);
|
||||
|
@ -2811,11 +2810,7 @@ private:
|
|||
" return;\n"
|
||||
" }\n"
|
||||
"}");
|
||||
// This fails because Tokenizer::simplifyGoto() copies the "leave:" block
|
||||
// into where the goto is, but because it contains a "return", it omits
|
||||
// copying a final return after the block.
|
||||
TODO_ASSERT_EQUALS("",
|
||||
"[test.cpp:5]: (style) Switch falls through case without comment. 'break;' missing?\n", errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check_preprocess_suppress(
|
||||
"void foo() {\n"
|
||||
|
|
|
@ -180,14 +180,6 @@ private:
|
|||
TEST_CASE(calculations);
|
||||
TEST_CASE(comparisons);
|
||||
|
||||
// Simplify goto..
|
||||
TEST_CASE(goto1);
|
||||
TEST_CASE(goto2);
|
||||
TEST_CASE(goto3); // #3138
|
||||
TEST_CASE(goto4); // #3459
|
||||
TEST_CASE(goto5); // #3705 - return ({asm("");});
|
||||
TEST_CASE(goto6);
|
||||
|
||||
//remove dead code after flow control statements
|
||||
TEST_CASE(flowControl);
|
||||
|
||||
|
@ -520,20 +512,6 @@ private:
|
|||
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)0);"));
|
||||
ASSERT_EQUALS("return str ;", tok("return (char *)str;"));
|
||||
|
||||
{
|
||||
const char code[] = "static void crash()\n"
|
||||
"{\n"
|
||||
" goto err_exit;\n"
|
||||
"err_exit:\n"
|
||||
" (void)foo();\n"
|
||||
"}\n";
|
||||
|
||||
const char expected[] = "static void crash ( ) "
|
||||
"{ foo ( ) ; return ; }";
|
||||
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
||||
ASSERT_EQUALS("if ( * a )", tok("if ((char)*a)"));
|
||||
ASSERT_EQUALS("if ( & a )", tok("if ((int)&a)"));
|
||||
ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)"));
|
||||
|
@ -3137,437 +3115,6 @@ private:
|
|||
ASSERT_EQUALS("( 6 )", tok("( 1 > 2 && 3 > 4 ? 5 : 6 )"));
|
||||
}
|
||||
|
||||
void goto1() {
|
||||
{
|
||||
const char code[] = "void foo()\n"
|
||||
"{\n"
|
||||
" if (a())\n"
|
||||
" {\n"
|
||||
" goto out;\n"
|
||||
" }\n"
|
||||
" b();\n"
|
||||
"out:\n"
|
||||
" c();\n"
|
||||
"}";
|
||||
|
||||
errout.str("");
|
||||
Settings settings;
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
tokenizer.simplifyTokenList2();
|
||||
|
||||
const char expect[] = "\n\n##file 0\n"
|
||||
"1: void foo ( )\n"
|
||||
"2: {\n"
|
||||
"3: if ( a ( ) )\n"
|
||||
"4: {\n"
|
||||
"5:\n|\n8:\n"
|
||||
"9: c ( ) ; return ; }\n"
|
||||
"7: b ( ) ;\n"
|
||||
"8:\n"
|
||||
"9: c ( ) ;\n"
|
||||
"10: }\n";
|
||||
|
||||
ASSERT_EQUALS(expect, tokenizer.tokens()->stringifyList());
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "void foo()\n"
|
||||
"{\n"
|
||||
" if (a())\n"
|
||||
" goto out;\n"
|
||||
" b();\n"
|
||||
"out:\n"
|
||||
" if (c())\n"
|
||||
" d();\n"
|
||||
"}";
|
||||
|
||||
|
||||
errout.str("");
|
||||
Settings settings;
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
tokenizer.simplifyTokenList2();
|
||||
|
||||
const char expect[] = "\n\n##file 0\n"
|
||||
"1: void foo ( )\n"
|
||||
"2: {\n"
|
||||
"3: if ( a ( ) ) {\n"
|
||||
"4:\n5:\n6:\n"
|
||||
"7: if ( c ( ) ) {\n"
|
||||
"8: d ( ) ; } return ; }\n"
|
||||
"5: b ( ) ;\n"
|
||||
"6:\n"
|
||||
"7: if ( c ( ) ) {\n"
|
||||
"8: d ( ) ; }\n"
|
||||
"9: }\n";
|
||||
|
||||
ASSERT_EQUALS(expect, tokenizer.tokens()->stringifyList());
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "void foo()\n"
|
||||
"{\n"
|
||||
" if (a())\n"
|
||||
" goto out;\n"
|
||||
" b();\n"
|
||||
"out:\n"
|
||||
" if (c())\n"
|
||||
" {\n"
|
||||
" d();\n"
|
||||
" }\n"
|
||||
"}";
|
||||
|
||||
const char expect[] = "void foo ( ) "
|
||||
"{ "
|
||||
"if ( a ( ) ) "
|
||||
"{ "
|
||||
"if ( c ( ) ) "
|
||||
"{ d ( ) ; } "
|
||||
"return ; "
|
||||
"} "
|
||||
"b ( ) ; "
|
||||
"if ( c ( ) ) "
|
||||
"{ d ( ) ; } "
|
||||
"}";
|
||||
|
||||
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 expect[] = "class NoLabels { bool varOne ; bool varTwo ; } ;";
|
||||
ASSERT_EQUALS(expect, tok(code));
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "void foo ( ) { int var ; var = x < y ? y : z ; } ;";
|
||||
ASSERT_EQUALS(code, tok(code));
|
||||
}
|
||||
}
|
||||
|
||||
void goto2() {
|
||||
// Don't simplify goto inside function call (macro)
|
||||
const char code[] = "void f ( ) { slist_iter ( if ( a ) { goto dont_write ; } dont_write : ; x ( ) ; ) ; }";
|
||||
ASSERT_EQUALS(code, tok(code));
|
||||
|
||||
//ticket #3229 (segmentation fault)
|
||||
ASSERT_EQUALS("void f ( ) { MACRO ( return ; ) return ; }",tok("void f ( ) {goto label; label: MACRO(return;)}"));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "class A"
|
||||
"{"
|
||||
" int a; "
|
||||
" double b; "
|
||||
" A() : b(3.22)"
|
||||
" {"
|
||||
" goto source ;"
|
||||
" bleeh;"
|
||||
" source:"
|
||||
" a = 322;"
|
||||
" }"
|
||||
"}"
|
||||
"class A1 : public A"
|
||||
"{"
|
||||
" int a1; "
|
||||
" double b1; "
|
||||
" A1() : b1(3.22)"
|
||||
" {"
|
||||
" goto source1 ;"
|
||||
" bleeh1;"
|
||||
" source1:"
|
||||
" a = 322;"
|
||||
" }"
|
||||
"}";
|
||||
const char expected[] = "class A "
|
||||
"{"
|
||||
" int a ;"
|
||||
" double b ;"
|
||||
" A ( ) : b ( 3.22 )"
|
||||
" {"
|
||||
" a = 322 ;"
|
||||
" return ;"
|
||||
" } "
|
||||
"} "
|
||||
"class A1 : public A "
|
||||
"{"
|
||||
" int a1 ;"
|
||||
" double b1 ;"
|
||||
" A1 ( ) : b1 ( 3.22 )"
|
||||
" {"
|
||||
" a = 322 ;"
|
||||
" return ;"
|
||||
" } "
|
||||
"}";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
}
|
||||
|
||||
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 goto5() {
|
||||
const char code[] = "int foo() {\n"
|
||||
" goto err;\n"
|
||||
"err:\n"
|
||||
" return ( { __asm__(X); } ); "
|
||||
"}\n";
|
||||
ASSERT_EQUALS("int foo ( ) {"
|
||||
" return { asm ( \"X\" ) ; } ;"
|
||||
" return { asm ( \"X\" ) ; } ; "
|
||||
"}", tok(code));
|
||||
}
|
||||
|
||||
void goto6() { // from code in linux that wasn't handled well
|
||||
const char code1[] = "static void a() {\n"
|
||||
"unlock:\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"static void b() {\n"
|
||||
" if (c)\n"
|
||||
" goto defer;\n"
|
||||
"defer:\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS("static void a ( ) { } "
|
||||
"static void b ( ) { if ( c ) { return ; } }", tok(code1));
|
||||
|
||||
const char code2[] = "void a()\n"
|
||||
"{\n"
|
||||
" if (x) {}\n"
|
||||
"unlock:\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void b()\n"
|
||||
"{\n"
|
||||
" { goto defer; }\n"
|
||||
"defer:\n"
|
||||
"}";
|
||||
ASSERT_EQUALS("void a ( ) { if ( x ) { } } void b ( ) { return ; }", tok(code2));
|
||||
}
|
||||
|
||||
void flowControl() {
|
||||
std::list<std::string> beforedead;
|
||||
//beforedead.push_back("return");
|
||||
|
@ -8334,7 +7881,7 @@ private:
|
|||
" }\n"
|
||||
" } while ((t = type[c]) == LET && catenate());\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS("int evallex ( ) { int c ; int t ; do { c = macroid ( c ) ; if ( c == EOF_CHAR || c == '\n' ) { } t = type [ c ] ; } while ( t == LET && catenate ( ) ) ; }",
|
||||
ASSERT_EQUALS("int evallex ( ) { int c ; int t ; again : ; do { c = macroid ( c ) ; if ( c == EOF_CHAR || c == '\n' ) { } t = type [ c ] ; } while ( t == LET && catenate ( ) ) ; }",
|
||||
tok(code, true));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue