Tokenizer: remove stuff from simplifyTokenList2

This commit is contained in:
Daniel Marjamäki 2022-06-17 09:44:58 +02:00
parent 3612ddb3f5
commit aa8c17a701
3 changed files with 3 additions and 437 deletions

View File

@ -5380,13 +5380,6 @@ bool Tokenizer::simplifyTokenList2()
simplifyIfAndWhileAssign();
// replace strlen(str)
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "strlen ( %str% )")) {
tok->str(MathLib::toString(Token::getStrLength(tok->tokAt(2))));
tok->deleteNext(3);
}
}
bool modified = true;
while (modified) {
@ -5397,7 +5390,6 @@ bool Tokenizer::simplifyTokenList2()
modified |= simplifyConditions();
modified |= simplifyFunctionReturn();
modified |= simplifyKnownVariables();
modified |= simplifyStrlen();
modified |= removeRedundantConditions();
modified |= simplifyRedundantParentheses();
@ -5406,25 +5398,6 @@ bool Tokenizer::simplifyTokenList2()
validate();
}
// simplify redundant loops
simplifyWhile0();
removeRedundantFor();
// Remove redundant parentheses in return..
for (Token *tok = list.front(); tok; tok = tok->next()) {
while (Token::simpleMatch(tok, "return (")) {
Token *tok2 = tok->next()->link();
if (Token::simpleMatch(tok2, ") ;")) {
tok->deleteNext();
tok2->deleteThis();
} else {
break;
}
}
}
simplifyReturnStrncat();
simplifyComma();
removeRedundantSemicolons();
@ -6195,90 +6168,6 @@ bool Tokenizer::removeRedundantConditions()
return ret;
}
void Tokenizer::removeRedundantFor()
{
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "[;{}] for ( %name% = %num% ; %name% < %num% ; ++| %name% ++| ) {") ||
Token::Match(tok, "[;{}] for ( %type% %name% = %num% ; %name% < %num% ; ++| %name% ++| ) {")) {
// Same variable name..
const Token* varTok = tok->tokAt(3);
const bool type = varTok->next()->isName();
if (type)
varTok = varTok->next();
const std::string varname(varTok->str());
const int varid(varTok->varId());
if (varname != varTok->strAt(4))
continue;
const Token *vartok2 = tok->linkAt(2)->previous();
if (vartok2->str() == "++")
vartok2 = vartok2->previous();
else if (vartok2->strAt(-1) != "++")
continue;
if (varname != vartok2->str())
continue;
// Check that the difference of the numeric values is 1
const MathLib::bigint num1(MathLib::toLongNumber(varTok->strAt(2)));
const MathLib::bigint num2(MathLib::toLongNumber(varTok->strAt(6)));
if (num1 + 1 != num2)
continue;
// check how loop variable is used in loop..
bool read = false;
bool write = false;
const Token* end = tok->linkAt(2)->next()->link();
for (const Token *tok2 = tok->linkAt(2); tok2 != end; tok2 = tok2->next()) {
if (tok2->str() == varname) {
if (tok2->previous()->isArithmeticalOp() &&
tok2->next() &&
(tok2->next()->isArithmeticalOp() || tok2->next()->str() == ";")) {
read = true;
} else {
read = write = true;
break;
}
}
}
// Simplify loop if loop variable isn't written
if (!write) {
Token* bodyBegin = tok->linkAt(2)->next();
// remove "for ("
tok->deleteNext(2);
// If loop variable is read then keep assignment before
// loop body..
if (type) {
tok->insertToken("{");
Token::createMutualLinks(tok->next(), bodyBegin->link());
bodyBegin->deleteThis();
tok = tok->tokAt(6);
} else if (read) {
// goto ";"
tok = tok->tokAt(4);
} else {
// remove "x = 0 ;"
tok->deleteNext(4);
}
// remove "x < 1 ; x ++ )"
tok->deleteNext(7);
if (!type) {
// Add assignment after the loop body so the loop variable
// get the correct end value
Token *tok2 = tok->next()->link();
tok2->insertToken(";");
tok2->insertToken(MathLib::toString(num2));
tok2->insertToken("=");
tok2->insertToken(varname);
tok2->next()->varId(varid);
}
}
}
}
}
void Tokenizer::removeRedundantSemicolons()
{
@ -10163,59 +10052,6 @@ std::string Tokenizer::simplifyString(const std::string &source)
return str;
}
void Tokenizer::simplifyWhile0()
{
for (Token *tok = list.front(); tok; tok = tok->next()) {
// while (0)
const bool while0(Token::Match(tok->previous(), "[{};] while ( 0|false )"));
// for (0) - not banal, ticket #3140
const bool for0((Token::Match(tok->previous(), "[{};] for ( %name% = %num% ; %name% < %num% ;") &&
tok->strAt(2) == tok->strAt(6) && tok->strAt(4) == tok->strAt(8)) ||
(Token::Match(tok->previous(), "[{};] for ( %type% %name% = %num% ; %name% < %num% ;") &&
tok->strAt(3) == tok->strAt(7) && tok->strAt(5) == tok->strAt(9)));
if (!while0 && !for0)
continue;
if (while0 && tok->previous()->str() == "}") {
// find "do"
Token *tok2 = tok->previous()->link();
tok2 = tok2->previous();
if (tok2 && tok2->str() == "do") {
const bool flowmatch = Token::findmatch(tok2, "continue|break", tok) != nullptr;
// delete "do ({)"
tok2->deleteThis();
if (!flowmatch)
tok2->deleteThis();
// delete "(}) while ( 0 ) (;)"
tok = tok->previous();
tok->deleteNext(4); // while ( 0 )
if (tok->next() && tok->next()->str() == ";")
tok->deleteNext(); // ;
if (!flowmatch)
tok->deleteThis(); // }
continue;
}
}
// remove "while (0) { .. }"
if (Token::simpleMatch(tok->next()->link(), ") {")) {
Token *end = tok->next()->link(), *old_prev = tok->previous();
end = end->next()->link();
if (Token::Match(tok, "for ( %name% ="))
old_prev = end->link();
eraseDeadCode(old_prev, end->next());
if (old_prev && old_prev->next())
tok = old_prev->next();
else
break;
}
}
}
void Tokenizer::simplifyFunctionTryCatch()
{
if (!isCPP())
@ -11821,53 +11657,6 @@ void Tokenizer::removeUnnecessaryQualification()
}
}
void Tokenizer::simplifyReturnStrncat()
{
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::simpleMatch(tok, "return strncat (") &&
Token::simpleMatch(tok->linkAt(2), ") ;") &&
tok->strAt(3) != ")" && tok->strAt(3) != ",") {
//first argument
Token *tok2 = tok->tokAt(3);
//check if there are at least three arguments
for (int i = 0; i < 2; ++i) {
tok2 = tok2->nextArgument();
if (!tok2) {
tok = tok->linkAt(2)->next();
break;
}
}
if (!tok2)
continue;
tok2 = tok2->nextArgument();
//we want only three arguments
if (tok2) {
tok = tok->linkAt(2)->next();
continue;
}
// Remove 'return'
tok->deleteThis();
// Add 'return arg1 ;' after 'strncat(arg1, arg2, arg3);'
tok = tok->next();
tok2 = tok->link()->next();
tok2->insertToken(";");
//the last token of the first argument before ','
const Token * const end = tok->next()->nextArgument()->tokAt(-2);
//all the first argument is copied
TokenList::copyTokens(tok2, tok->next(), end);
tok2->insertToken("return");
}
}
}
void Tokenizer::printUnknownTypes() const
{
if (!mSymbolDatabase)
@ -12036,20 +11825,6 @@ void Tokenizer::simplifyMathExpressions()
}
}
bool Tokenizer::simplifyStrlen()
{
// replace strlen(str)
bool modified=false;
for (Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "strlen ( %str% )")) {
tok->str(MathLib::toString(Token::getStrLength(tok->tokAt(2))));
tok->deleteNext(3);
modified=true;
}
}
return modified;
}
void Tokenizer::prepareTernaryOpForAST()
{
// http://en.cppreference.com/w/cpp/language/operator_precedence says about ternary operator:

View File

@ -410,13 +410,6 @@ public:
*/
bool removeRedundantConditions();
/**
* Remove redundant for:
* "for (x=0;x<1;x++) { }" => "{ x = 1; }"
*/
void removeRedundantFor();
/**
* Reduces "; ;" to ";", except in "( ; ; )"
*/
@ -531,11 +524,6 @@ public:
private:
/**
* simplify "while (0)"
*/
void simplifyWhile0();
/**
* Simplify while(func(f))
*/
@ -762,12 +750,6 @@ private:
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers,
nonneg int *varId_);
/**
* Simplify e.g. 'return(strncat(temp,"a",1));' into
* strncat(temp,"a",1); return temp;
*/
void simplifyReturnStrncat();
/**
* Output list of unknown types.
*/

View File

@ -66,7 +66,6 @@ private:
TEST_CASE(redundant_plus);
TEST_CASE(redundant_plus_numbers);
TEST_CASE(parentheses1);
TEST_CASE(parenthesesVar); // Remove redundant parentheses around variable .. "( %name% )"
TEST_CASE(declareVar);
TEST_CASE(declareArray);
@ -99,9 +98,6 @@ private:
TEST_CASE(sizeofsizeof);
TEST_CASE(casting);
TEST_CASE(strlen1);
TEST_CASE(strlen2);
TEST_CASE(namespaces);
// Assignment in condition..
@ -155,11 +151,6 @@ private:
TEST_CASE(pointeralias3);
TEST_CASE(pointeralias4);
// simplify "while (0)"
TEST_CASE(while0);
// ticket #3140
TEST_CASE(while0for);
// x = realloc(y,0); => free(y);x=0;
TEST_CASE(simplifyRealloc);
@ -189,17 +180,8 @@ private:
TEST_CASE(simplifyFunctionPointer); // ticket #5339 (simplify function pointer after comma)
TEST_CASE(redundant_semicolon);
TEST_CASE(simplifyFunctionReturn);
TEST_CASE(return_strncat); // ticket # 2860 Returning value of strncat() reported as memory leak
// #3069 : for loop with 1 iteration
// for (x=0;x<1;x++) { .. }
// The for is redundant
TEST_CASE(removeRedundantFor);
TEST_CASE(consecutiveBraces);
TEST_CASE(undefinedSizeArray);
@ -2084,32 +2066,6 @@ private:
ASSERT_EQUALS("{ while ( x ( ) == -1 ) { } }", tok("{while((x()) == -1){ }}"));
}
void parenthesesVar() {
// remove parentheses..
ASSERT_EQUALS("a = p ;", tok("a = (p);"));
ASSERT_EQUALS("void f ( ) { if ( a < p ) { } }", tok("void f(){if(a<(p)){}}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p == -1 ) { } }", tok("void f(){int p; if((p)==-1){}}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( -1 == p ) { } }", tok("void f(){int p; if(-1==(p)){}}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p ) { } }", tok("void f(){int p; if((p)){}}"));
ASSERT_EQUALS("void f ( ) { return p ; }", tok("void f(){return (p);}"));
ASSERT_EQUALS("void f ( ) { int * p ; if ( * p == 0 ) { } }", tok("void f(){int *p; if (*(p) == 0) {}}"));
ASSERT_EQUALS("void f ( ) { int * p ; if ( * p == 0 ) { } }", tok("void f(){int *p; if (*p == 0) {}}"));
ASSERT_EQUALS("void f ( int & p ) { p = 1 ; }", tok("void f(int &p) {(p) = 1;}"));
ASSERT_EQUALS("void f ( ) { int p [ 10 ] ; p [ 0 ] = 1 ; }", tok("void f(){int p[10]; (p)[0] = 1;}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p == 0 ) { } }", tok("void f(){int p; if ((p) == 0) {}}"));
ASSERT_EQUALS("void f ( ) { int * p ; * p = 1 ; }", tok("void f(){int *p; *(p) = 1;}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p ) { } p = 1 ; }", tok("void f(){int p; if ( p ) { } (p) = 1;}"));
ASSERT_EQUALS("void f ( ) { a . b ; }", tok("void f ( ) { ( & a ) -> b ; }")); // Ticket #5776
// keep parentheses..
ASSERT_EQUALS("b = a ;", tok("b = (char)a;"));
ASSERT_EQUALS("cast < char * > ( p ) ;", tok("cast<char *>(p);"));
ASSERT_EQUALS("void f ( ) { return ( a + b ) * c ; }", tok("void f(){return (a+b)*c;}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( 2 * p == 0 ) { } }", tok("void f(){int p; if (2*p == 0) {}}"));
ASSERT_EQUALS("void f ( ) { DIR * f ; f = opendir ( dirname ) ; if ( closedir ( f ) ) { } }", tok("void f(){DIR * f = opendir(dirname);if (closedir(f)){}}"));
ASSERT_EQUALS("void foo ( int p ) { if ( p >= 0 ) { ; } }", tok("void foo(int p){if((p)>=0);}"));
}
void declareVar() {
const char code[] = "void f ( ) { char str [ 100 ] = \"100\" ; }";
ASSERT_EQUALS(code, tok(code));
@ -2627,7 +2583,7 @@ private:
" sizeof 1;\n"
" while (0);\n"
"}\n";
ASSERT_EQUALS("void f ( ) { sizeof ( 1 ) ; }", tok(code));
ASSERT_EQUALS("void f ( ) { sizeof ( 1 ) ; while ( false ) { ; } }", tok(code));
ASSERT_EQUALS("", errout.str());
}
@ -2879,53 +2835,13 @@ private:
"{\n"
" return dynamic_cast<Foo *>((bar()));\n"
"}\n";
const char expected[] = "void f ( ) { return bar ( ) ; }";
const char expected[] = "void f ( ) { return ( bar ( ) ) ; }";
ASSERT_EQUALS(expected, tok(code));
}
}
void strlen1() {
ASSERT_EQUALS("4", tok("strlen(\"abcd\")"));
{
const char code[] = "void f()\n"
"{\n"
" const char *s = \"abcd\";\n"
" strlen(s);\n"
"}\n";
const char expected[] = "void f ( ) "
"{"
" const char * s ;"
" s = \"abcd\" ;"
" 4 ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
{
const char code[] = "void f()\n"
"{\n"
" const char s [ ] = \"abcd\";\n"
" strlen(s);\n"
"}\n";
const char expected[] = "void f ( ) "
"{"
" const char s [ 5 ] = \"abcd\" ;"
" 4 ; "
"}";
ASSERT_EQUALS(expected, tok(code));
}
}
void strlen2() {
// #4530 - make sure calculation with strlen is simplified
ASSERT_EQUALS("i = -4 ;",
tok("i = (strlen(\"abcd\") - 8);"));
}
void namespaces() {
{
@ -3003,7 +2919,7 @@ private:
"f = fopen ( \"foo\" , \"r\" ) ; "
"if ( f == NULL ) "
"{ "
"return -1 ; "
"return ( -1 ) ; "
"} "
"fclose ( f ) ; "
"}";
@ -4119,26 +4035,6 @@ private:
ASSERT_EQUALS(expected, tok(code));
}
void while0() {
ASSERT_EQUALS("void foo ( ) { x = 1 ; }", tok("void foo() { do { x = 1 ; } while (0);}"));
ASSERT_EQUALS("void foo ( ) { return 0 ; }", tok("void foo() { do { return 0; } while (0);}"));
ASSERT_EQUALS("void foo ( ) { goto label ; }", tok("void foo() { do { goto label; } while (0); }"));
ASSERT_EQUALS("void foo ( ) { continue ; }", tok("void foo() { do { continue ; } while (0); }"));
ASSERT_EQUALS("void foo ( ) { break ; }", tok("void foo() { do { break; } while (0); }"));
ASSERT_EQUALS("void foo ( ) { }", tok("void foo() { while (false) { a; } }"));
ASSERT_EQUALS("void foo ( ) { }", tok("void foo() { while (false) { switch (n) { case 0: return; default: break; } n*=1; } }"));
}
void while0for() {
// for (condition is always false)
ASSERT_EQUALS("void f ( ) { int i ; for ( i = 0 ; i < 0 ; i ++ ) { } }", tok("void f() { int i; for (i = 0; i < 0; i++) { a; } }"));
//ticket #3140
ASSERT_EQUALS("void f ( ) { int i ; for ( i = 0 ; i < 0 ; i ++ ) { } }", tok("void f() { int i; for (i = 0; i < 0; i++) { foo(); break; } }"));
ASSERT_EQUALS("void f ( ) { int i ; for ( i = 0 ; i < 0 ; i ++ ) { } }", tok("void f() { int i; for (i = 0; i < 0; i++) { foo(); continue; } }"));
// #8059
ASSERT_EQUALS("void f ( ) { int i ; for ( i = 0 ; i < 0 ; ++ i ) { } return i ; }", tok("void f() { int i; for (i=0;i<0;++i){ dostuff(); } return i; }"));
}
void simplifyRealloc() {
ASSERT_EQUALS("; free ( p ) ; p = 0 ;", tok("; p = realloc(p, 0);"));
ASSERT_EQUALS("; p = malloc ( 100 ) ;", tok("; p = realloc(0, 100);"));
@ -4602,11 +4498,6 @@ private:
ASSERT_EQUALS("f ( double x , double ( * y ) ( ) ) ;", tok("f (double x, double (*y) ());", true));
}
void redundant_semicolon() {
ASSERT_EQUALS("void f ( ) { ; }", tok("void f() { ; }", false));
ASSERT_EQUALS("void f ( ) { ; }", tok("void f() { do { ; } while (0); }", true));
}
void simplifyFunctionReturn() {
{
const char code[] = "typedef void (*testfp)();\n"
@ -4665,88 +4556,6 @@ private:
}
}
void return_strncat() {
{
const char code[] = "char *f()\n"
"{\n"
" char *temp=malloc(2);\n"
" strcpy(temp,\"\");\n"
" return (strncat(temp,\"a\",1));\n"
"}";
ASSERT_EQUALS("char * f ( ) {"
" char * temp ;"
" temp = malloc ( 2 ) ;"
" strcpy ( temp , \"\" ) ;"
" strncat ( temp , \"a\" , 1 ) ;"
" return temp ; "
"}", tok(code, true));
}
{
const char code[] = "char *f()\n"
"{\n"
" char **temp=malloc(8);\n"
" *temp = malloc(2);\n"
" strcpy(*temp,\"\");\n"
" return (strncat(*temp,\"a\",1));\n"
"}";
ASSERT_EQUALS("char * f ( ) {"
" char * * temp ;"
" temp = malloc ( 8 ) ;"
" * temp = malloc ( 2 ) ;"
" strcpy ( * temp , \"\" ) ;"
" strncat ( * temp , \"a\" , 1 ) ;"
" return * temp ; "
"}", tok(code, true));
}
{
const char code[] = "char *f()\n"
"{\n"
" char **temp=malloc(8);\n"
" *temp = malloc(2);\n"
" strcpy(*temp,\"\");\n"
" return (strncat(temp[0],foo(b),calc(c-d)));\n"
"}";
ASSERT_EQUALS("char * f ( ) {"
" char * * temp ;"
" temp = malloc ( 8 ) ;"
" * temp = malloc ( 2 ) ;"
" strcpy ( * temp , \"\" ) ;"
" strncat ( temp [ 0 ] , foo ( b ) , calc ( c - d ) ) ;"
" return temp [ 0 ] ; "
"}", tok(code, true));
}
}
void removeRedundantFor() { // ticket #3069
{
const char code[] = "void f() {"
" for(x=0;x<1;x++) {"
" y = 1;"
" }"
"}";
ASSERT_EQUALS("void f ( ) { { y = 1 ; } x = 1 ; }", tok(code, true));
}
{
const char code[] = "void f() {"
" for(x=0;x<1;x++) {"
" y = 1 + x;"
" }"
"}";
ASSERT_EQUALS("void f ( ) { x = 0 ; { y = 1 + x ; } x = 1 ; }", tok(code, true));
}
{
const char code[] = "void f() {"
" foo();"
" for(int x=0;x<1;x++) {"
" y = 1 + x;"
" }"
"}";
ASSERT_EQUALS("void f ( ) { foo ( ) ; { int x = 0 ; y = 1 + x ; } }", tok(code, true));
}
}
void consecutiveBraces() {
ASSERT_EQUALS("void f ( ) { }", tok("void f(){{}}", true));
ASSERT_EQUALS("void f ( ) { }", tok("void f(){{{}}}", true));