diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index a99cc2898..c9fc01b1a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3681,41 +3681,7 @@ bool Tokenizer::simplifyTokenList() } }*/ - // simplify "x=realloc(y,0);" => "free(y); x=0;".. - // and "x = realloc (0, n);" => "x = malloc(n);" - for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "[;{}:] %var% = realloc ( %var% , 0 ) ;")) { - const std::string varname(tok->next()->str()); - const unsigned int varid(tok->next()->varId()); - - // Delete the "%var% =" - tok->deleteNext(2); - - // Change function name "realloc" to "free" - tok->next()->str("free"); - - // delete the ", 0" - tok = tok->tokAt(3); - tok->deleteNext(2); - - // goto the ";" - tok = tok->tokAt(2); - - // insert "var=0;" - tok->insertToken(";"); - tok->insertToken("0"); - tok->insertToken("="); - tok->insertToken(varname); - tok->next()->varId(varid); - } else if (Token::Match(tok, "[;{}:] %var% = realloc ( 0 , %num% ) ;")) { - tok = tok->tokAt(3); - // Change function name "realloc" to "malloc" - tok->str("malloc"); - - // delete "0 ," - tok->next()->deleteNext(2); - } - } + simplifyRealloc(); // Change initialisation of variable to assignment simplifyInitVar(); @@ -3880,6 +3846,51 @@ void Tokenizer::removeRedundantAssignment() } } +void Tokenizer::simplifyRealloc() +{ + for (Token *tok = _tokens; tok; tok = tok->next()) { + if (tok->str() == "(" || tok->str() == "[" || + (tok->str() == "{" && tok->previous() && tok->previous()->str() == "=")) + tok = tok->link(); + else if (Token::Match(tok, "[;{}] %var% = realloc (")) { + tok = tok->tokAt(3); + if (Token::Match(tok->next(), "( 0 ,")) { + //no "x = realloc(0,);" + if (!Token::Match(tok->next()->link(), ") ;") || tok->next()->link()->previous() == tok->tokAt(3)) + continue; + + // delete "0 ," + tok->next()->deleteNext(2); + + // Change function name "realloc" to "malloc" + tok->str("malloc"); + tok = tok->next()->link(); + } else { + Token *tok2 = tok->next()->link()->tokAt(-2); + //no "x = realloc(,0);" + if (!Token::simpleMatch(tok2, ", 0 ) ;") || tok2 == tok->tokAt(2)) + continue; + + //remove ", 0" + tok2 = tok2->previous(); + tok2->deleteNext(2); + //change "realloc" to "free" + tok->str("free"); + //insert "0" after "var =" + tok = tok->previous(); + tok->insertToken("0"); + //move "var = 0" between "free(...)" and ";" + tok2 = tok2->next(); + Token::move(tok->previous(), tok->next(), tok2); + //add missing ";" after "free(...)" + tok2->insertToken(";"); + //goto before last ";" and continue + tok = tok->next(); + } + } + } +} + void Tokenizer::simplifyFlowControl() { unsigned int indentlevel = 0; diff --git a/lib/tokenize.h b/lib/tokenize.h index 7d1f89056..83c39b52b 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -232,6 +232,12 @@ public: /** Remove redundant assignment */ void removeRedundantAssignment(); + /** Simplifies some realloc usage like + * 'x = realloc (0, n);' => 'x = malloc(n);' + * 'x = realloc (y, 0);' => 'x = 0; free(y);' + */ + void simplifyRealloc(); + /** * Replace sizeof() to appropriate size. */ @@ -245,9 +251,7 @@ public: /** * Simplify variable initialization - * ; int *p(0); - * => - * ; int *p = 0; + * '; int *p(0);' => '; int *p = 0;' */ void simplifyInitVar(); Token * initVar(Token * tok); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 5be7295ca..f0aab91ee 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -7001,12 +7001,14 @@ private: } void simplifyRealloc() { - ASSERT_EQUALS("; free ( p ) ; p = 0 ;", - tok("; p = realloc(p,0);")); - ASSERT_EQUALS("; p = malloc ( 100 ) ;", - tok("; p = realloc(0, 100);")); - ASSERT_EQUALS("; p = malloc ( 0 ) ;", - tok("; p = realloc(0, sizeof(char)*0);")); + ASSERT_EQUALS("; free ( p ) ; p = 0 ;", tok("; p = realloc(p, 0);")); + ASSERT_EQUALS("; p = malloc ( 100 ) ;", tok("; p = realloc(0, 100);")); + ASSERT_EQUALS("; p = malloc ( 0 ) ;", tok("; p = realloc(0, 0);")); + ASSERT_EQUALS("; free ( q ) ; p = 0 ;", tok("; p = realloc(q, 0);")); + ASSERT_EQUALS("; free ( * q ) ; p = 0 ;", tok("; p = realloc(*q, 0);")); + ASSERT_EQUALS("; free ( f ( z ) ) ; p = 0 ;", tok("; p = realloc(f(z), 0);")); + ASSERT_EQUALS("; p = malloc ( n * m ) ;", tok("; p = realloc(0, n*m);")); + ASSERT_EQUALS("; p = malloc ( f ( 1 ) ) ;", tok("; p = realloc(0, f(1));")); } void simplifyErrNoInWhile() {