Uninitialized variables: Detect reading uninitialized data through array/pointer variable
This commit is contained in:
parent
6db663f6de
commit
d26a2cfc16
|
@ -1810,6 +1810,10 @@ private:
|
||||||
if (mode == 3 && (!c->pointer || c->alloc))
|
if (mode == 3 && (!c->pointer || c->alloc))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// mode 4 : reading uninitialized array or pointer is invalid.
|
||||||
|
if (mode == 4 && (!c->array && !c->pointer))
|
||||||
|
continue;
|
||||||
|
|
||||||
CheckOther *checkOther = dynamic_cast<CheckOther *>(c->owner);
|
CheckOther *checkOther = dynamic_cast<CheckOther *>(c->owner);
|
||||||
if (checkOther)
|
if (checkOther)
|
||||||
{
|
{
|
||||||
|
@ -1855,9 +1859,9 @@ private:
|
||||||
* @param checks all available checks
|
* @param checks all available checks
|
||||||
* @param tok variable token
|
* @param tok variable token
|
||||||
*/
|
*/
|
||||||
static void use_pointer(std::list<ExecutionPath *> &checks, const Token *tok)
|
static bool use_pointer(std::list<ExecutionPath *> &checks, const Token *tok)
|
||||||
{
|
{
|
||||||
use(checks, tok, 2);
|
return use(checks, tok, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1865,11 +1869,23 @@ private:
|
||||||
* @param checks all available checks
|
* @param checks all available checks
|
||||||
* @param tok variable token
|
* @param tok variable token
|
||||||
*/
|
*/
|
||||||
static void use_dead_pointer(std::list<ExecutionPath *> &checks, const Token *tok)
|
static bool use_dead_pointer(std::list<ExecutionPath *> &checks, const Token *tok)
|
||||||
{
|
{
|
||||||
use(checks, tok, 3);
|
return use(checks, tok, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using variable.. reading from uninitialized array or pointer data is invalid.
|
||||||
|
* Example: = x[0];
|
||||||
|
* @param checks all available checks
|
||||||
|
* @param tok variable token
|
||||||
|
*/
|
||||||
|
static bool use_array_or_pointer_data(std::list<ExecutionPath *> &checks, const Token *tok)
|
||||||
|
{
|
||||||
|
return use(checks, tok, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** declaring a variable */
|
/** declaring a variable */
|
||||||
void declare(std::list<ExecutionPath *> &checks, const Token *vartok, const Token &tok, const bool p, const bool a) const
|
void declare(std::list<ExecutionPath *> &checks, const Token *vartok, const Token &tok, const bool p, const bool a) const
|
||||||
{
|
{
|
||||||
|
@ -1918,7 +1934,7 @@ private:
|
||||||
const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const
|
const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const
|
||||||
{
|
{
|
||||||
// Variable declaration..
|
// Variable declaration..
|
||||||
if (tok.str() != "return")
|
if (tok.isName() && tok.str() != "return")
|
||||||
{
|
{
|
||||||
if (Token::Match(&tok, "enum %type% {"))
|
if (Token::Match(&tok, "enum %type% {"))
|
||||||
return tok.tokAt(2)->link();
|
return tok.tokAt(2)->link();
|
||||||
|
@ -1989,7 +2005,13 @@ private:
|
||||||
!Token::Match(tok2->previous(), "&|::") &&
|
!Token::Match(tok2->previous(), "&|::") &&
|
||||||
!Token::simpleMatch(tok2->next(), "="))
|
!Token::simpleMatch(tok2->next(), "="))
|
||||||
{
|
{
|
||||||
bool foundError = use(checks, tok2);
|
bool foundError;
|
||||||
|
if (tok2->next()->str() == "[")
|
||||||
|
foundError = use_array_or_pointer_data(checks, tok2);
|
||||||
|
else
|
||||||
|
foundError = use(checks, tok2);
|
||||||
|
|
||||||
|
// prevent duplicate error messages
|
||||||
if (foundError)
|
if (foundError)
|
||||||
{
|
{
|
||||||
bailOutVar(checks, tok2->varId());
|
bailOutVar(checks, tok2->varId());
|
||||||
|
|
|
@ -1671,6 +1671,13 @@ private:
|
||||||
"};\n");
|
"};\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Data is allocated but not initialized: s1\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Data is allocated but not initialized: s1\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" char *p = malloc(64);\n"
|
||||||
|
" int x = p[0];\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (error) Data is allocated but not initialized: p\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" Fred *fred = new Fred;\n"
|
" Fred *fred = new Fred;\n"
|
||||||
|
|
Loading…
Reference in New Issue