Improve simplifyReturnStrncat when each argument is not composed by one token.

This commit is contained in:
Edoardo Prezioso 2012-01-26 16:09:32 +01:00
parent 20372eecfa
commit f428a29d8e
2 changed files with 90 additions and 23 deletions

View File

@ -4515,12 +4515,12 @@ bool Tokenizer::simplifyConditions()
for (Token *tok = _tokens; tok; tok = tok->next()) { for (Token *tok = _tokens; tok; tok = tok->next()) {
if (Token::Match(tok, "! %num%") || Token::Match(tok, "! %bool%")) { if (Token::Match(tok, "! %num%") || Token::Match(tok, "! %bool%")) {
if (tok->next()->str() == "0" || tok->next()->str() == "false") tok->deleteThis();
if (tok->str() == "0" || tok->str() == "false")
tok->str("true"); tok->str("true");
else else
tok->str("false"); tok->str("false");
tok->deleteNext();
ret = true; ret = true;
} }
@ -9115,15 +9115,46 @@ void Tokenizer::unnecessaryQualificationError(const Token *tok, const std::strin
void Tokenizer::simplifyReturnStrncat() void Tokenizer::simplifyReturnStrncat()
{ {
for (Token *tok = _tokens; tok; tok = tok->next()) { for (Token *tok = _tokens; tok; tok = tok->next()) {
if (Token::Match(tok, "return strncat ( %any% , %any% , %any% ) ;")) { if (Token::simpleMatch(tok, "return strncat (") &&
// Change to: strncat ( %any% , %any% , %any% ) ; Token::simpleMatch(tok->linkAt(2), ") ;") &&
tok->deleteNext(); tok->strAt(3) != ")" && tok->strAt(3) != ",") {
tok->str("strncat");
// Change to: strncat ( %any% , %any% , %any% ) ; return %any% ; //first argument
tok->tokAt(8)->insertToken("return"); Token *tok2 = tok->tokAt(3);
copyTokens(tok->tokAt(9), tok->tokAt(2), tok->tokAt(2));
tok->tokAt(10)->insertToken(";"); //check if there are at least three arguments
for (unsigned char 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 ','
Token *end = tok->next()->nextArgument()->tokAt(-2);
//all the first argument is copied
copyTokens(tok2, tok->next(), end);
tok2->insertToken("return");
} }
} }
} }

View File

@ -7546,19 +7546,55 @@ private:
} }
void return_strncat() { void return_strncat() {
const char code[] = "char *f()\n" {
"{\n" const char code[] = "char *f()\n"
" char *temp=malloc(2);\n" "{\n"
" strcpy(temp,\"\");\n" " char *temp=malloc(2);\n"
" return (strncat(temp,\"a\",1));\n" " strcpy(temp,\"\");\n"
"}"; " return (strncat(temp,\"a\",1));\n"
ASSERT_EQUALS("char * f ( ) { " "}";
"char * temp ; " ASSERT_EQUALS("char * f ( ) {"
"temp = malloc ( 2 ) ; " " char * temp ;"
"strcpy ( temp , \"\" ) ; " " temp = malloc ( 2 ) ;"
"strncat ( temp , \"a\" , 1 ) ; " " strcpy ( temp , \"\" ) ;"
"return temp ; " " strncat ( temp , \"a\" , 1 ) ;"
"}", tok(code, true)); " 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 void removeRedundantFor() { // ticket #3069