From 918b4d859fbce947c155abce2ecb7a87c297410c Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Sun, 26 Jun 2011 23:53:16 +0300 Subject: [PATCH] Fixed #2860, False positive: Returning value of strncat() reported as memory leak http://sourceforge.net/apps/trac/cppcheck/ticket/2860 --- lib/tokenize.cpp | 22 +++++++++++++++++++++- lib/tokenize.h | 6 ++++++ test/testsimplifytokens.cpp | 18 ++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7255d79ca..eda0aa41b 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -286,6 +286,7 @@ Token *Tokenizer::copyTokens(Token *dest, const Token *first, const Token *last) tok2->isSigned(tok->isSigned()); tok2->isLong(tok->isLong()); tok2->isUnused(tok->isUnused()); + tok2->varId(tok->varId()); // Check for links and fix them up if (tok2->str() == "(" || tok2->str() == "[" || tok2->str() == "{") @@ -4655,6 +4656,8 @@ bool Tokenizer::simplifyTokenList() } } + simplifyReturn(); + removeRedundantAssignment(); simplifyComma(); @@ -8401,7 +8404,6 @@ void Tokenizer::simplifyEnum() } } - void Tokenizer::simplifyStd() { std::set f; @@ -9889,3 +9891,21 @@ void Tokenizer::removeUnnecessaryQualification() } } +void Tokenizer::simplifyReturn() +{ + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (Token::Match(tok, "return strncat ( %any% , %any% , %any% ) ;")) + { + // Change to: strncat ( %any% , %any% , %any% ) ; + tok->deleteNext(); + tok->str("strncat"); + + // Change to: strncat ( %any% , %any% , %any% ) ; return %any% ; + tok->tokAt(8)->insertToken("return"); + copyTokens(tok->tokAt(9), tok->tokAt(2), tok->tokAt(2)); + tok->tokAt(10)->insertToken(";"); + } + } +} + diff --git a/lib/tokenize.h b/lib/tokenize.h index ecf2c52ab..577bbbef4 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -666,6 +666,12 @@ public: return _varId; } + /** + * Simplify e.g. 'return(strncat(temp,"a",1));' into + * strncat(temp,"a",1); return temp; + */ + void simplifyReturn(); + private: /** Disable copy constructor, no implementation */ Tokenizer(const Tokenizer &); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 33d92c4b4..dd59165db 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -358,6 +358,7 @@ private: TEST_CASE(simplifyIfNotNull); TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault TEST_CASE(simplifyVarDecl2); // ticket # 2834 segmentation fault + TEST_CASE(return_strncat); // ticket # 2860 Returning value of strncat() reported as memory leak } std::string tok(const char code[], bool simplify = true) @@ -7080,6 +7081,23 @@ private: tok(code, false); ASSERT_EQUALS("", errout.str()); } + + 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)); + } }; REGISTER_TEST(TestSimplifyTokens)