Really fixed #4024. Now the simplification won't be done on non-executive scopes.
This commit is contained in:
parent
70de691551
commit
1d8240356b
104
lib/tokenize.cpp
104
lib/tokenize.cpp
|
@ -3615,58 +3615,74 @@ void Tokenizer::simplifyRealloc()
|
||||||
|
|
||||||
void Tokenizer::simplifyFlowControl()
|
void Tokenizer::simplifyFlowControl()
|
||||||
{
|
{
|
||||||
unsigned int indentlevel = 0;
|
|
||||||
bool stilldead = false;
|
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
|
||||||
if (tok->str() == "(" || tok->str() == "[") {
|
|
||||||
tok = tok->link();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tok->str() == "{") {
|
for (Token *begin = list.front(); begin; begin = begin->next()) {
|
||||||
if (tok->previous() && tok->previous()->str() == "=") {
|
|
||||||
|
if (begin->str() == "(" || begin->str() == "[" ||
|
||||||
|
(begin->str() == "{" && begin->previous() && begin->strAt(-1) == "="))
|
||||||
|
begin = begin->link();
|
||||||
|
|
||||||
|
//function scope
|
||||||
|
if (!Token::simpleMatch(begin, ") {") && !Token::Match(begin, ") %var% {"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Token *end = begin->linkAt(1+(begin->next()->str() == "{" ? 0 : 1));
|
||||||
|
unsigned int indentlevel = 0;
|
||||||
|
bool stilldead = false;
|
||||||
|
|
||||||
|
for (Token *tok = begin; tok != end; tok = tok->next()) {
|
||||||
|
if (tok->str() == "(" || tok->str() == "[") {
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++indentlevel;
|
|
||||||
} else if (tok->str() == "}") {
|
|
||||||
if (!indentlevel)
|
|
||||||
break;
|
|
||||||
--indentlevel;
|
|
||||||
if (stilldead) {
|
|
||||||
eraseDeadCode(tok, 0);
|
|
||||||
if (indentlevel == 1 || tok->next()->str() != "}" || !Token::Match(tok->next()->link()->previous(), ";|{|}|do {"))
|
|
||||||
stilldead = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!indentlevel)
|
if (tok->str() == "{") {
|
||||||
continue;
|
if (tok->previous() && tok->previous()->str() == "=") {
|
||||||
|
tok = tok->link();
|
||||||
if (Token::Match(tok,"continue|break ;")) {
|
continue;
|
||||||
tok = tok->next();
|
}
|
||||||
eraseDeadCode(tok, 0);
|
++indentlevel;
|
||||||
|
} else if (tok->str() == "}") {
|
||||||
} else if (Token::Match(tok,"return|goto") ||
|
if (!indentlevel)
|
||||||
(Token::Match(tok,"exit|abort") && !Token::Match(tok->previous(),"%type%")) ||
|
|
||||||
(tok->str() == "throw" && !isC())) {
|
|
||||||
//catch the first ';'
|
|
||||||
for (Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
|
|
||||||
if (tok2->str() == "(" || tok2->str() == "[") {
|
|
||||||
tok2 = tok2->link();
|
|
||||||
} else if (tok2->str() == ";") {
|
|
||||||
tok = tok2;
|
|
||||||
eraseDeadCode(tok, 0);
|
|
||||||
break;
|
break;
|
||||||
} else if (Token::Match(tok2, "[{}]"))
|
--indentlevel;
|
||||||
break; //Wrong code.
|
if (stilldead) {
|
||||||
|
eraseDeadCode(tok, 0);
|
||||||
|
if (indentlevel == 1 || tok->next()->str() != "}" || !Token::Match(tok->next()->link()->previous(), ";|{|}|do {"))
|
||||||
|
stilldead = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!indentlevel)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Token::Match(tok,"continue|break ;")) {
|
||||||
|
tok = tok->next();
|
||||||
|
eraseDeadCode(tok, 0);
|
||||||
|
|
||||||
|
} else if (Token::Match(tok,"return|goto") ||
|
||||||
|
(Token::Match(tok,"exit|abort")) ||
|
||||||
|
(tok->str() == "throw" && !isC())) {
|
||||||
|
//TODO: ensure that we exclude user-defined 'exit|abort|throw', except for 'noreturn'
|
||||||
|
//catch the first ';'
|
||||||
|
for (Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
|
||||||
|
if (tok2->str() == "(" || tok2->str() == "[") {
|
||||||
|
tok2 = tok2->link();
|
||||||
|
} else if (tok2->str() == ";") {
|
||||||
|
tok = tok2;
|
||||||
|
eraseDeadCode(tok, 0);
|
||||||
|
break;
|
||||||
|
} else if (Token::Match(tok2, "[{}]"))
|
||||||
|
break; //Wrong code.
|
||||||
|
}
|
||||||
|
//if everything is removed, then remove also the code after an inferior scope
|
||||||
|
//only if the actual scope is not special
|
||||||
|
if (indentlevel > 1 && tok->next()->str() == "}" && Token::Match(tok->next()->link()->previous(), ";|{|}|do {"))
|
||||||
|
stilldead = true;
|
||||||
}
|
}
|
||||||
//if everything is removed, then remove also the code after an inferior scope
|
|
||||||
//only if the actual scope is not special
|
|
||||||
if (indentlevel > 1 && tok->next()->str() == "}" && Token::Match(tok->next()->link()->previous(), ";|{|}|do {"))
|
|
||||||
stilldead = true;
|
|
||||||
}
|
}
|
||||||
|
begin = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3491,6 +3491,31 @@ private:
|
||||||
"} ;";
|
"} ;";
|
||||||
ASSERT_EQUALS(expected, tok(code));
|
ASSERT_EQUALS(expected, tok(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "class abort { };\n"
|
||||||
|
"\n"
|
||||||
|
"class Fred\n"
|
||||||
|
"{\n"
|
||||||
|
" public:\n"
|
||||||
|
" bool foo() const { return f; }\n"
|
||||||
|
" abort exit();\n"
|
||||||
|
"\n"
|
||||||
|
" private:\n"
|
||||||
|
"bool f;\n"
|
||||||
|
"};\n";
|
||||||
|
const char expected[] = "class abort { } ; "
|
||||||
|
"class Fred "
|
||||||
|
"{"
|
||||||
|
" public:"
|
||||||
|
" bool foo ( ) const { return f ; }"
|
||||||
|
" abort exit ( ) ;"
|
||||||
|
""
|
||||||
|
" private:"
|
||||||
|
" bool f ; "
|
||||||
|
"} ;";
|
||||||
|
ASSERT_EQUALS(expected, tok(code));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void strcat1() {
|
void strcat1() {
|
||||||
|
|
Loading…
Reference in New Issue