dereferencing deallocated memory: it is ok to take the address to deallocated memory but it is not ok to dereference the address
This commit is contained in:
parent
45f8560537
commit
6f646246ee
|
@ -273,7 +273,7 @@ void CheckMemoryLeak::deallocDeallocError(const Token *tok, const std::string &v
|
||||||
|
|
||||||
void CheckMemoryLeak::deallocuseError(const Token *tok, const std::string &varname)
|
void CheckMemoryLeak::deallocuseError(const Token *tok, const std::string &varname)
|
||||||
{
|
{
|
||||||
errorLogger->reportErr(errmsg(tok, Severity::error, "deallocuse", "Using '" + varname + "' after it is deallocated / released"));
|
errorLogger->reportErr(errmsg(tok, Severity::error, "deallocuse", "Dereferencing '" + varname + "' after it is deallocated / released"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckMemoryLeak::mismatchSizeError(const Token *tok, const std::string &sz)
|
void CheckMemoryLeak::mismatchSizeError(const Token *tok, const std::string &sz)
|
||||||
|
@ -1515,7 +1515,7 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const char varname
|
||||||
while (Token::Match(tok2, "[;{}] ;"))
|
while (Token::Match(tok2, "[;{}] ;"))
|
||||||
Token::eraseTokens(tok2, tok2->tokAt(2));
|
Token::eraseTokens(tok2, tok2->tokAt(2));
|
||||||
}
|
}
|
||||||
if ((result = Token::findmatch(tok, "[;{}] dealloc [;{}] use|use_ ;")) != NULL)
|
if ((result = Token::findmatch(tok, "[;{}] dealloc ; use_ ;")) != NULL)
|
||||||
{
|
{
|
||||||
deallocuseError(result->tokAt(3), varname);
|
deallocuseError(result->tokAt(3), varname);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ private:
|
||||||
check(filedata);
|
check(filedata);
|
||||||
|
|
||||||
// Compare results..
|
// Compare results..
|
||||||
ASSERT_EQUALS("[file.cpp:5]: (error) Using 'foo' after it is deallocated / released\n", errout.str());
|
ASSERT_EQUALS("[file.cpp:5]: (error) Dereferencing 'foo' after it is deallocated / released\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void linenumbers2()
|
void linenumbers2()
|
||||||
|
|
|
@ -232,16 +232,10 @@ private:
|
||||||
TEST_CASE(cast2);
|
TEST_CASE(cast2);
|
||||||
TEST_CASE(cast3);
|
TEST_CASE(cast3);
|
||||||
|
|
||||||
|
// Using deallocated memory:
|
||||||
TEST_CASE(structmember1);
|
// * It is ok to take the address to deallocated memory
|
||||||
|
// * It is not ok to dereference a pointer to deallocated memory
|
||||||
TEST_CASE(dealloc_use_1); // Deallocate and then use memory
|
TEST_CASE(dealloc_use);
|
||||||
TEST_CASE(dealloc_use_2); // Deallocate and then use memory. No error if "use" is &var
|
|
||||||
TEST_CASE(dealloc_use_3); // Deallocate and then use memory. No error
|
|
||||||
TEST_CASE(dealloc_use_4);
|
|
||||||
TEST_CASE(dealloc_use_5);
|
|
||||||
TEST_CASE(dealloc_use_6);
|
|
||||||
TEST_CASE(dealloc_use_7);
|
|
||||||
|
|
||||||
// free a free'd pointer
|
// free a free'd pointer
|
||||||
TEST_CASE(freefree1);
|
TEST_CASE(freefree1);
|
||||||
|
@ -1771,34 +1765,26 @@ private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void structmember1()
|
void dealloc_use()
|
||||||
{
|
|
||||||
check("void f()\n"
|
|
||||||
"{\n"
|
|
||||||
" struct ABC *abc = new ABC;\n"
|
|
||||||
" abc->a = new char[100];\n"
|
|
||||||
" delete abc;\n"
|
|
||||||
"}\n");
|
|
||||||
|
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: abc.a\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void dealloc_use_1()
|
|
||||||
{
|
{
|
||||||
|
// It is ok to take the address..
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *s = new char[100];\n"
|
" char *s = new char[100];\n"
|
||||||
" delete [] s;\n"
|
" delete [] s;\n"
|
||||||
" p = s;\n"
|
" p = s;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Using 's' after it is deallocated / released\n", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
|
||||||
|
|
||||||
void dealloc_use_2()
|
check("void f()\n"
|
||||||
{
|
"{\n"
|
||||||
|
" char *s = new char[100];\n"
|
||||||
|
" delete [] s;\n"
|
||||||
|
" foo(s);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// The pointer to the pointer is valid..
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *str;\n"
|
" char *str;\n"
|
||||||
|
@ -1806,10 +1792,7 @@ private:
|
||||||
" foo(&str);\n"
|
" foo(&str);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
|
||||||
|
|
||||||
void dealloc_use_3()
|
|
||||||
{
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *str = 0;\n"
|
" char *str = 0;\n"
|
||||||
|
@ -1818,50 +1801,31 @@ private:
|
||||||
" f2(str);\n"
|
" f2(str);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
|
||||||
|
|
||||||
void dealloc_use_4()
|
// Dereferencing the freed pointer is not ok..
|
||||||
{
|
check("void foo()\n"
|
||||||
check("static void ReadDir(DIR *d)\n"
|
|
||||||
"{\n"
|
"{\n"
|
||||||
" DIR *subdir = OpenDir();\n"
|
" char *str = malloc(10);\n"
|
||||||
" ReadDir( subdir );\n"
|
" free(str);\n"
|
||||||
" closedir(subdir);\n"
|
" char c = *str;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Dereferencing 'str' after it is deallocated / released\n", errout.str());
|
||||||
}
|
|
||||||
|
|
||||||
void dealloc_use_5()
|
|
||||||
{
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *str = malloc(10);\n"
|
" char *str = malloc(10);\n"
|
||||||
" free(str);\n"
|
" free(str);\n"
|
||||||
" char c = str[10];\n"
|
" char c = str[10];\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Using 'str' after it is deallocated / released\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Dereferencing 'str' after it is deallocated / released\n", errout.str());
|
||||||
}
|
|
||||||
|
|
||||||
void dealloc_use_6()
|
|
||||||
{
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *str = 0;\n"
|
" char *str = malloc(10);\n"
|
||||||
" free(str);\n"
|
" free(str);\n"
|
||||||
" printf(\"free %x\", str);\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void dealloc_use_7()
|
|
||||||
{
|
|
||||||
check("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" char *str = new char[10];\n"
|
|
||||||
" delete [] str;\n"
|
|
||||||
" str[10] = 0;\n"
|
" str[10] = 0;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Using 'str' after it is deallocated / released\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Dereferencing 'str' after it is deallocated / released\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue