Skip to content

Commit d204c5f

Browse files
committed
Tokenizer: Cleanup stuff in simplifyTokenList2
1 parent 63e567e commit d204c5f

2 files changed

Lines changed: 0 additions & 315 deletions

File tree

lib/tokenize.cpp

Lines changed: 0 additions & 293 deletions
Original file line numberDiff line numberDiff line change
@@ -5187,33 +5187,6 @@ bool Tokenizer::simplifyTokenList2()
51875187

51885188
removeRedundantSemicolons();
51895189

5190-
simplifyFlowControl();
5191-
5192-
simplifyRedundantConsecutiveBraces();
5193-
5194-
simplifyEmptyNamespaces();
5195-
5196-
validate();
5197-
5198-
Token::assignProgressValues(list.front());
5199-
5200-
list.front()->assignIndexes();
5201-
5202-
list.createAst();
5203-
// needed for #7208 (garbage code) and #7724 (ast max depth limit)
5204-
list.validateAst();
5205-
5206-
// Create symbol database and then remove const keywords
5207-
createSymbolDatabase();
5208-
mSymbolDatabase->setValueTypeInTokenList(true);
5209-
5210-
ValueFlow::setValues(&list, mSymbolDatabase, mErrorLogger, mSettings);
5211-
5212-
if (Settings::terminated())
5213-
return false;
5214-
5215-
printDebugOutput(2);
5216-
52175190
return true;
52185191
}
52195192
//---------------------------------------------------------------------------
@@ -5766,82 +5739,6 @@ void Tokenizer::simplifyEmptyNamespaces()
57665739
}
57675740
}
57685741

5769-
void Tokenizer::simplifyFlowControl()
5770-
{
5771-
for (Token *begin = list.front(); begin; begin = begin->next()) {
5772-
5773-
if (Token::Match(begin, "(|[") ||
5774-
(begin->str() == "{" && begin->previous() && begin->strAt(-1) == "="))
5775-
begin = begin->link();
5776-
5777-
//function scope
5778-
if (!Token::simpleMatch(begin, ") {") && !Token::Match(begin, ") %name% {"))
5779-
continue;
5780-
5781-
Token* end = begin->linkAt(1+(begin->next()->str() == "{" ? 0 : 1));
5782-
int indentLevel = 0;
5783-
bool stilldead = false;
5784-
5785-
for (Token *tok = begin; tok && tok != end; tok = tok->next()) {
5786-
if (Token::Match(tok, "(|[")) {
5787-
tok = tok->link();
5788-
continue;
5789-
}
5790-
5791-
if (tok->str() == "{") {
5792-
if (tok->previous() && tok->previous()->str() == "=") {
5793-
tok = tok->link();
5794-
continue;
5795-
}
5796-
++indentLevel;
5797-
} else if (tok->str() == "}") {
5798-
if (indentLevel == 0)
5799-
break;
5800-
--indentLevel;
5801-
if (stilldead) {
5802-
eraseDeadCode(tok, nullptr);
5803-
if (indentLevel == 1 || tok->next()->str() != "}" || !Token::Match(tok->next()->link()->previous(), ";|{|}|do {"))
5804-
stilldead = false;
5805-
continue;
5806-
}
5807-
}
5808-
5809-
if (indentLevel == 0)
5810-
continue;
5811-
5812-
if (Token::Match(tok,"continue|break ;")) {
5813-
tok = tok->next();
5814-
eraseDeadCode(tok, nullptr);
5815-
5816-
} else if (Token::Match(tok,"return|goto") ||
5817-
(Token::Match(tok->previous(), "[;{}] %name% (") &&
5818-
mSettings->library.isnoreturn(tok)) ||
5819-
(isCPP() && tok->str() == "throw")) {
5820-
if (tok->next()->str() == "}")
5821-
syntaxError(tok->next()); // invalid code like in #6731
5822-
//TODO: ensure that we exclude user-defined 'exit|abort|throw', except for 'noreturn'
5823-
//catch the first ';'
5824-
for (Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
5825-
if (Token::Match(tok2, "(|[")) {
5826-
tok2 = tok2->link();
5827-
} else if (tok2->str() == ";") {
5828-
tok = tok2;
5829-
eraseDeadCode(tok, nullptr);
5830-
break;
5831-
} else if (Token::Match(tok2, "[{}]"))
5832-
break;
5833-
}
5834-
//if everything is removed, then remove also the code after an inferior scope
5835-
//only if the actual scope is not special
5836-
if (indentLevel > 1 && tok->next()->str() == "}" && Token::Match(tok->next()->link()->previous(), ";|{|}|do {"))
5837-
stilldead = true;
5838-
}
5839-
}
5840-
begin = end;
5841-
}
5842-
}
5843-
5844-
58455742
void Tokenizer::removeRedundantSemicolons()
58465743
{
58475744
for (Token *tok = list.front(); tok; tok = tok->next()) {
@@ -7399,196 +7296,6 @@ bool Tokenizer::isScopeNoReturn(const Token *endScopeToken, bool *unknown) const
73997296

74007297
//---------------------------------------------------------------------------
74017298

7402-
void Tokenizer::eraseDeadCode(Token *begin, const Token *end)
7403-
{
7404-
if (!begin)
7405-
return;
7406-
const bool isgoto = Token::Match(begin->tokAt(-2), "goto %name% ;");
7407-
int indentlevel = 1;
7408-
int indentcase = 0;
7409-
int indentswitch = 0;
7410-
int indentlabel = 0;
7411-
int roundbraces = 0;
7412-
int indentcheck = 0;
7413-
std::vector<int> switchindents;
7414-
bool checklabel = false;
7415-
Token *tok = begin;
7416-
Token *tokcheck = nullptr;
7417-
while (tok->next() && tok->next() != end) {
7418-
if (tok->next()->str() == "(") {
7419-
++roundbraces;
7420-
tok->deleteNext();
7421-
continue;
7422-
} else if (tok->next()->str() == ")") {
7423-
if (!roundbraces)
7424-
break; //too many ending round parentheses
7425-
--roundbraces;
7426-
tok->deleteNext();
7427-
continue;
7428-
}
7429-
7430-
if (roundbraces) {
7431-
tok->deleteNext();
7432-
continue;
7433-
}
7434-
7435-
if (Token::Match(tok, "[{};] switch (")) {
7436-
if (!checklabel) {
7437-
if (!indentlabel) {
7438-
//remove 'switch ( ... )'
7439-
Token::eraseTokens(tok, tok->linkAt(2)->next());
7440-
} else {
7441-
tok = tok->linkAt(2);
7442-
}
7443-
if (tok->next()->str() == "{") {
7444-
++indentswitch;
7445-
indentcase = indentlevel + 1;
7446-
switchindents.push_back(indentcase);
7447-
}
7448-
} else {
7449-
tok = tok->linkAt(2);
7450-
if (Token::simpleMatch(tok, ") {")) {
7451-
++indentswitch;
7452-
indentcase = indentlevel + 1;
7453-
switchindents.push_back(indentcase);
7454-
}
7455-
}
7456-
} else if (tok->next()->str() == "{") {
7457-
++indentlevel;
7458-
if (!checklabel) {
7459-
checklabel = true;
7460-
tokcheck = tok;
7461-
indentcheck = indentlevel;
7462-
indentlabel = 0;
7463-
}
7464-
tok = tok->next();
7465-
} else if (tok->next()->str() == "}") {
7466-
--indentlevel;
7467-
if (!indentlevel)
7468-
break;
7469-
7470-
if (!checklabel) {
7471-
tok->deleteNext();
7472-
} else {
7473-
if (indentswitch && indentlevel == indentcase)
7474-
--indentlevel;
7475-
if (indentlevel < indentcheck) {
7476-
const Token *end2 = tok->next();
7477-
tok = end2->link()->previous(); //return to initial '{'
7478-
if (indentswitch && Token::simpleMatch(tok, ") {") && Token::Match(tok->link()->tokAt(-2), "[{};] switch ("))
7479-
tok = tok->link()->tokAt(-2); //remove also 'switch ( ... )'
7480-
Token::eraseTokens(tok, end2->next());
7481-
checklabel = false;
7482-
tokcheck = nullptr;
7483-
indentcheck = 0;
7484-
} else {
7485-
tok = tok->next();
7486-
}
7487-
}
7488-
if (indentswitch && indentlevel <= indentcase) {
7489-
--indentswitch;
7490-
switchindents.pop_back();
7491-
if (!indentswitch)
7492-
indentcase = 0;
7493-
else
7494-
indentcase = switchindents[indentswitch-1];
7495-
}
7496-
} else if (Token::Match(tok, "[{};:] case")) {
7497-
const Token *tok2 = Token::findsimplematch(tok->next(), ": ;", end);
7498-
if (!tok2) {
7499-
tok->deleteNext();
7500-
continue;
7501-
}
7502-
if (indentlevel == 1)
7503-
break; //it seems like the function was called inside a case-default block.
7504-
if (indentlevel == indentcase)
7505-
++indentlevel;
7506-
tok2 = tok2->next();
7507-
if (!checklabel || !indentswitch) {
7508-
Token::eraseTokens(tok, tok2->next());
7509-
} else {
7510-
tok = const_cast<Token *>(tok2);
7511-
}
7512-
} else if (Token::Match(tok, "[{};] default : ;")) {
7513-
if (indentlevel == 1)
7514-
break; //it seems like the function was called inside a case-default block.
7515-
if (indentlevel == indentcase)
7516-
++indentlevel;
7517-
if (!checklabel || !indentswitch) {
7518-
tok->deleteNext(3);
7519-
} else {
7520-
tok = tok->tokAt(3);
7521-
}
7522-
} else if (Token::Match(tok, "[{};] %name% : ;") && tok->next()->str() != "default") {
7523-
if (checklabel) {
7524-
indentlabel = indentlevel;
7525-
tok = tokcheck->next();
7526-
checklabel = false;
7527-
indentlevel = indentcheck;
7528-
} else {
7529-
if (indentswitch) {
7530-
//Before stopping the function, since the 'switch()'
7531-
//instruction is removed, there's no sense to keep the
7532-
//case instructions. Remove them, if there are any.
7533-
Token *tok2 = tok->tokAt(3);
7534-
int indentlevel2 = indentlevel;
7535-
while (tok2->next() && tok2->next() != end) {
7536-
if (Token::Match(tok2->next(), "{|[|(")) {
7537-
tok2 = tok2->next()->link();
7538-
} else if (Token::Match(tok2, "[{};:] case")) {
7539-
const Token *tok3 = Token::findsimplematch(tok2->next(), ": ;", end);
7540-
if (!tok3) {
7541-
tok2 = tok2->next();
7542-
continue;
7543-
}
7544-
Token::eraseTokens(tok2, tok3->next());
7545-
} else if (Token::Match(tok2, "[{};] default : ;")) {
7546-
tok2->deleteNext(3);
7547-
} else if (tok2->next()->str() == "}") {
7548-
--indentlevel2;
7549-
if (indentlevel2 <= indentcase)
7550-
break;
7551-
tok2 = tok2->next();
7552-
} else {
7553-
tok2 = tok2->next();
7554-
}
7555-
}
7556-
}
7557-
break; //stop removing tokens, we arrived to the label.
7558-
}
7559-
} else if (isgoto && Token::Match(tok, "[{};] do|while|for|BOOST_FOREACH")) {
7560-
//it's possible that code inside loop is not dead,
7561-
//because of the possible presence of the label pointed by 'goto'
7562-
const Token *start = tok->tokAt(2);
7563-
if (start && start->str() == "(")
7564-
start = start->link()->next();
7565-
if (start && start->str() == "{") {
7566-
std::string labelpattern = "[{};] " + begin->previous()->str() + " : ;";
7567-
bool simplify = true;
7568-
for (Token *tok2 = start->next(); tok2 != start->link(); tok2 = tok2->next()) {
7569-
if (Token::Match(tok2, labelpattern.c_str())) {
7570-
simplify = false;
7571-
break;
7572-
}
7573-
}
7574-
//bailout for now
7575-
if (!simplify)
7576-
break;
7577-
}
7578-
tok->deleteNext();
7579-
} else {
7580-
// no need to keep the other strings, remove them.
7581-
if (tok->strAt(1) == "while") {
7582-
if (tok->str() == "}" && tok->link()->strAt(-1) == "do")
7583-
tok->link()->previous()->deleteThis();
7584-
}
7585-
tok->deleteNext();
7586-
}
7587-
}
7588-
}
7589-
7590-
//---------------------------------------------------------------------------
7591-
75927299
void Tokenizer::syntaxError(const Token *tok, const std::string &code) const
75937300
{
75947301
printDebugOutput(0);

lib/tokenize.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -159,23 +159,6 @@ class CPPCHECKLIB Tokenizer {
159159
void splitTemplateRightAngleBrackets(bool check);
160160

161161

162-
/**
163-
* Deletes dead code between 'begin' and 'end'.
164-
* In general not everything can be erased, such as:
165-
* - code after labels;
166-
* - code outside the scope where the function is called;
167-
* - code after a change of scope caused by 'switch(...);'
168-
* instructions, like 'case %any%;' or 'default;'
169-
* Also, if the dead code contains a 'switch' block
170-
* and inside it there's a label, the function removes all
171-
* the 'switch(..)' tokens and every occurrence of 'case %any%; | default;'
172-
* expression, such as the 'switch' block is reduced to a simple block.
173-
*
174-
* @param begin Tokens after this have a possibility to be erased.
175-
* @param end Tokens before this have a possibility to be erased.
176-
*/
177-
static void eraseDeadCode(Token *begin, const Token *end);
178-
179162
/**
180163
* Calculates sizeof value for given type.
181164
* @param type Token which will contain e.g. "int", "*", or string.
@@ -332,11 +315,6 @@ class CPPCHECKLIB Tokenizer {
332315
/** Simplify useless C++ empty namespaces, like: 'namespace %name% { }'*/
333316
void simplifyEmptyNamespaces();
334317

335-
/** Simplify redundant code placed after control flow statements :
336-
* 'return', 'throw', 'goto', 'break' and 'continue'
337-
*/
338-
void simplifyFlowControl();
339-
340318
/** Simplify "if else" */
341319
void elseif();
342320

0 commit comments

Comments
 (0)