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();
|
simplifyStd();
|
||||||
|
|
||||||
simplifyGoto();
|
|
||||||
|
|
||||||
if (_settings->terminated())
|
if (_settings->terminated())
|
||||||
return false;
|
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()
|
void Tokenizer::simplifyNestedStrcat()
|
||||||
{
|
{
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
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;
|
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% { }'*/
|
/** Simplify useless C++ empty namespaces, like: 'namespace %var% { }'*/
|
||||||
void simplifyEmptyNamespaces();
|
void simplifyEmptyNamespaces();
|
||||||
|
|
||||||
|
|
|
@ -284,7 +284,6 @@ private:
|
||||||
Tokenizer tokenizer(&settings, &logger);
|
Tokenizer tokenizer(&settings, &logger);
|
||||||
std::istringstream istr(code);
|
std::istringstream istr(code);
|
||||||
tokenizer.tokenize(istr, filename);
|
tokenizer.tokenize(istr, filename);
|
||||||
tokenizer.simplifyGoto();
|
|
||||||
|
|
||||||
// Check..
|
// Check..
|
||||||
CheckOther checkOther(&tokenizer, &settings, &logger);
|
CheckOther checkOther(&tokenizer, &settings, &logger);
|
||||||
|
@ -2811,11 +2810,7 @@ private:
|
||||||
" return;\n"
|
" return;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"}");
|
||||||
// This fails because Tokenizer::simplifyGoto() copies the "leave:" block
|
ASSERT_EQUALS("", errout.str());
|
||||||
// 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());
|
|
||||||
|
|
||||||
check_preprocess_suppress(
|
check_preprocess_suppress(
|
||||||
"void foo() {\n"
|
"void foo() {\n"
|
||||||
|
|
|
@ -180,14 +180,6 @@ private:
|
||||||
TEST_CASE(calculations);
|
TEST_CASE(calculations);
|
||||||
TEST_CASE(comparisons);
|
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
|
//remove dead code after flow control statements
|
||||||
TEST_CASE(flowControl);
|
TEST_CASE(flowControl);
|
||||||
|
|
||||||
|
@ -520,20 +512,6 @@ private:
|
||||||
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)0);"));
|
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)0);"));
|
||||||
ASSERT_EQUALS("return str ;", tok("return (char *)str;"));
|
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 ((char)*a)"));
|
||||||
ASSERT_EQUALS("if ( & a )", tok("if ((int)&a)"));
|
ASSERT_EQUALS("if ( & a )", tok("if ((int)&a)"));
|
||||||
ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*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 )"));
|
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() {
|
void flowControl() {
|
||||||
std::list<std::string> beforedead;
|
std::list<std::string> beforedead;
|
||||||
//beforedead.push_back("return");
|
//beforedead.push_back("return");
|
||||||
|
@ -8334,7 +7881,7 @@ private:
|
||||||
" }\n"
|
" }\n"
|
||||||
" } while ((t = type[c]) == LET && catenate());\n"
|
" } while ((t = type[c]) == LET && catenate());\n"
|
||||||
"}\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));
|
tok(code, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue