Fixed ticket #346 (adding a "const" token prevents detection of memory leak)

http://sourceforge.net/apps/trac/cppcheck/ticket/346
This commit is contained in:
Slava Semushin 2009-06-15 00:32:34 +07:00
parent 3b73fc6494
commit 8c327f82b3
4 changed files with 54 additions and 5 deletions

View File

@ -1544,11 +1544,17 @@ void CheckMemoryLeakInFunction::check()
if (sz < 1) if (sz < 1)
sz = 1; sz = 1;
if (Token::Match(tok, "[{};] %type% * %var% [;=]")) if (Token::Match(tok, "[{};] %type% * const| %var% [;=]"))
checkScope(tok->next(), tok->strAt(3), classmember, sz); {
const int varname_tok = (tok->tokAt(3)->str() != "const" ? 3 : 4);
checkScope(tok->next(), tok->strAt(varname_tok), classmember, sz);
}
else if (Token::Match(tok, "[{};] %type% %type% * %var% [;=]")) else if (Token::Match(tok, "[{};] %type% %type% * const| %var% [;=]"))
checkScope(tok->next(), tok->strAt(4), classmember, sz); {
const int varname_tok = (tok->tokAt(4)->str() != "const" ? 4 : 5);
checkScope(tok->next(), tok->strAt(varname_tok), classmember, sz);
}
} }
} }
} }

View File

@ -2165,6 +2165,18 @@ bool Tokenizer::simplifyVarDecl()
tok2 = NULL; tok2 = NULL;
} }
else if (Token::Match(tok2, "%type% * const %var% ,|="))
{
if (tok2->tokAt(3)->str() != "operator")
{
tok2 = tok2->tokAt(4); // The ',' token
}
else
{
tok2 = NULL;
}
}
else if (Token::Match(tok2, "%type% %var% [ %num% ] ,")) else if (Token::Match(tok2, "%type% %var% [ %num% ] ,"))
{ {
tok2 = tok2->tokAt(5); // The ',' token tok2 = tok2->tokAt(5); // The ',' token
@ -2215,7 +2227,7 @@ bool Tokenizer::simplifyVarDecl()
{ {
// "type var =" => "type var; var =" // "type var =" => "type var; var ="
Token *VarTok = type0->tokAt(typelen); Token *VarTok = type0->tokAt(typelen);
if (VarTok->str()[0] == '*') while (Token::Match(VarTok, "*|const"))
VarTok = VarTok->next(); VarTok = VarTok->next();
InsertTokens(eq, VarTok, 2); InsertTokens(eq, VarTok, 2);
eq->str(";"); eq->str(";");

View File

@ -227,6 +227,15 @@ private:
" int *a = new int[10];\n" " int *a = new int[10];\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: a\n", errout.str());
// ticket #346
check("void f()\n"
"{\n"
" int * const a = new int[10];\n"
" const int * const b = new int[10];\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: a\n[test.cpp:5]: (error) Memory leak: b\n",
errout.str());
} }
void simple2() void simple2()

View File

@ -144,6 +144,7 @@ private:
TEST_CASE(vardecl1); TEST_CASE(vardecl1);
TEST_CASE(vardecl2); TEST_CASE(vardecl2);
TEST_CASE(vardecl3); TEST_CASE(vardecl3);
TEST_CASE(vardecl4);
TEST_CASE(volatile_variables); TEST_CASE(volatile_variables);
TEST_CASE(syntax_error); TEST_CASE(syntax_error);
@ -2043,6 +2044,27 @@ private:
ASSERT_EQUALS("void f ( ) { char * p ; p = foo < 10 , char > ( ) ; }", actual); ASSERT_EQUALS("void f ( ) { char * p ; p = foo < 10 , char > ( ) ; }", actual);
} }
void vardecl4()
{
// ticket #346
const char code1[] = "void *p = NULL;";
const char res1[] = "void * p ; p = NULL ;";
ASSERT_EQUALS(res1, tokenizeAndStringify(code1));
const char code2[] = "const void *p = NULL;";
const char res2[] = "const void * p ; p = NULL ;";
ASSERT_EQUALS(res2, tokenizeAndStringify(code2));
const char code3[] = "void * const p = NULL;";
const char res3[] = "void * const p ; p = NULL ;";
ASSERT_EQUALS(res3, tokenizeAndStringify(code3));
const char code4[] = "const void * const p = NULL;";
const char res4[] = "const void * const p ; p = NULL ;";
ASSERT_EQUALS(res4, tokenizeAndStringify(code4));
}
void volatile_variables() void volatile_variables()
{ {
const char code[] = "volatile int a=0;\n" const char code[] = "volatile int a=0;\n"