Remove reduntant if sentences that are never executed.
This commit is contained in:
parent
615095fca2
commit
496b09a377
|
@ -217,7 +217,7 @@ private:
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
for (const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next())
|
for (const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||||
ostr << " " << tok->str();
|
ostr << " " << tok->str();
|
||||||
ASSERT_EQUALS( std::string(" void f ( ) { if ( true ) ; }"), ostr.str() );
|
ASSERT_EQUALS( std::string(" void f ( ) { ; }"), ostr.str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplify_known_variables()
|
void simplify_known_variables()
|
||||||
|
|
122
tokenize.cpp
122
tokenize.cpp
|
@ -1033,10 +1033,132 @@ void Tokenizer::simplifyTokenList()
|
||||||
modified |= simplifyCasts();
|
modified |= simplifyCasts();
|
||||||
modified |= simplifyFunctionReturn();
|
modified |= simplifyFunctionReturn();
|
||||||
modified |= simplifyKnownVariables();
|
modified |= simplifyKnownVariables();
|
||||||
|
modified |= removeReduntantConditions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool Tokenizer::removeReduntantConditions()
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
for ( TOKEN *tok = _tokens; tok; tok = tok->next() )
|
||||||
|
{
|
||||||
|
if (!TOKEN::Match(tok, "if ( %bool% )"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Find matching else
|
||||||
|
const TOKEN *elseTag = 0;
|
||||||
|
if( TOKEN::Match( tok->tokAt( 4 ), "{" ) )
|
||||||
|
{
|
||||||
|
// Find the closing "}"
|
||||||
|
int indentLevel = 0;
|
||||||
|
for ( const TOKEN *closing = tok->tokAt( 5 ); closing; closing = closing->next() )
|
||||||
|
{
|
||||||
|
if( TOKEN::Match( closing, "{" ) )
|
||||||
|
{
|
||||||
|
indentLevel++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( TOKEN::Match( closing, "}" ) )
|
||||||
|
indentLevel--;
|
||||||
|
|
||||||
|
if( indentLevel >= 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Closing } is found.
|
||||||
|
elseTag = closing->next();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Find the closing ";"
|
||||||
|
for ( const TOKEN *closing = tok->tokAt( 4 ); closing; closing = closing->next() )
|
||||||
|
{
|
||||||
|
if( TOKEN::Match( closing, ";" ) )
|
||||||
|
{
|
||||||
|
elseTag = closing->next();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool boolValue = false;
|
||||||
|
if( tok->tokAt( 2 )->str() == "true" )
|
||||||
|
boolValue = true;
|
||||||
|
|
||||||
|
if( elseTag && TOKEN::Match( elseTag, "else" ) )
|
||||||
|
{
|
||||||
|
if( TOKEN::Match( elseTag->next(), "if" ) )
|
||||||
|
{
|
||||||
|
// Handle "else if"
|
||||||
|
if( boolValue == false )
|
||||||
|
{
|
||||||
|
// Convert "if( false ) {aaa;} else if() {bbb;}" => "if() {bbb;}"
|
||||||
|
TOKEN::eraseTokens( tok, elseTag->tokAt( 1 ) );
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Keep first if, remove every else if and else after it
|
||||||
|
|
||||||
|
// TODO, implement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle else
|
||||||
|
if( boolValue == false )
|
||||||
|
{
|
||||||
|
// Convert "if( false ) {aaa;} else {bbb;}" => "{bbb;}" or ";{bbb;}"
|
||||||
|
if( tok->previous() )
|
||||||
|
tok = tok->previous();
|
||||||
|
else
|
||||||
|
tok->setstr( ";" );
|
||||||
|
|
||||||
|
TOKEN::eraseTokens( tok, elseTag->tokAt( 1 ) );
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Convert "if( true ) {aaa;} else {bbb;}" => "{aaa;}"
|
||||||
|
|
||||||
|
// TODO, implement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle if without else
|
||||||
|
if( boolValue == false )
|
||||||
|
{
|
||||||
|
// Remove if and its content
|
||||||
|
if( tok->previous() )
|
||||||
|
tok = tok->previous();
|
||||||
|
else
|
||||||
|
tok->setstr( ";" );
|
||||||
|
|
||||||
|
TOKEN::eraseTokens( tok, elseTag );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// convert "if( true ) {aaa;}" => "{aaa;}"
|
||||||
|
if( tok->previous() )
|
||||||
|
tok = tok->previous();
|
||||||
|
else
|
||||||
|
tok->setstr( ";" );
|
||||||
|
|
||||||
|
TOKEN::eraseTokens( tok, tok->tokAt( 5 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool Tokenizer::simplifyConditions()
|
bool Tokenizer::simplifyConditions()
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,6 +101,13 @@ private:
|
||||||
*/
|
*/
|
||||||
bool simplifyConditions();
|
bool simplifyConditions();
|
||||||
|
|
||||||
|
/** Remove reduntant code, e.g. if( false ) { int a; } should be
|
||||||
|
* removed, because it is never executed.
|
||||||
|
* @return true if something is modified
|
||||||
|
* false if nothing is done.
|
||||||
|
*/
|
||||||
|
bool removeReduntantConditions();
|
||||||
|
|
||||||
/** Simplify casts
|
/** Simplify casts
|
||||||
* @return true if something is modified
|
* @return true if something is modified
|
||||||
* false if nothing is done.
|
* false if nothing is done.
|
||||||
|
|
Loading…
Reference in New Issue