Fixed #440 (NULL referencing not detected)
This commit is contained in:
parent
e1ed22aa2b
commit
fa535ff3ae
|
@ -1252,6 +1252,29 @@ private:
|
|||
return vartok->next();
|
||||
}
|
||||
|
||||
// Template pointer variable..
|
||||
if (Token::Match(tok.previous(), "[;{}] %type% ::|<"))
|
||||
{
|
||||
const Token * vartok = &tok;
|
||||
while (Token::Match(vartok, "%type% ::"))
|
||||
vartok = vartok->tokAt(2);
|
||||
if (Token::Match(vartok, "%type% < %type%"))
|
||||
{
|
||||
vartok = vartok->tokAt(3);
|
||||
while (vartok && (vartok->str() == "*" || vartok->isName()))
|
||||
vartok = vartok->next();
|
||||
if (Token::Match(vartok, "> * %var% ;|="))
|
||||
{
|
||||
vartok = vartok->tokAt(2);
|
||||
checks.push_back(new CheckNullpointer(owner, vartok->varId(), vartok->str()));
|
||||
if (Token::simpleMatch(vartok->next(), "= 0 ;"))
|
||||
setnull(checks, vartok->varId());
|
||||
return vartok->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Token::Match(&tok, "%var% ("))
|
||||
{
|
||||
// parse usage..
|
||||
|
@ -1554,6 +1577,25 @@ private:
|
|||
declare(checks, vartok, tok, false, true);
|
||||
return vartok->next()->link()->next();
|
||||
}
|
||||
|
||||
// Template pointer variable..
|
||||
if (Token::Match(tok.previous(), "[;{}] %type% ::|<"))
|
||||
{
|
||||
const Token * vartok = &tok;
|
||||
while (Token::Match(vartok, "%type% ::"))
|
||||
vartok = vartok->tokAt(2);
|
||||
if (Token::Match(vartok, "%type% < %type%"))
|
||||
{
|
||||
vartok = vartok->tokAt(3);
|
||||
while (vartok && (vartok->str() == "*" || vartok->isName()))
|
||||
vartok = vartok->next();
|
||||
if (Token::Match(vartok, "> * %var% ;"))
|
||||
{
|
||||
declare(checks, vartok->tokAt(2), tok, true, false);
|
||||
return vartok->tokAt(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tok.varId())
|
||||
|
@ -1646,6 +1688,7 @@ private:
|
|||
|
||||
// is the variable passed as a parameter to some function?
|
||||
unsigned int parlevel = 0;
|
||||
std::set<unsigned int> bailouts;
|
||||
for (const Token *tok2 = tok.next(); tok2; tok2 = tok2->next())
|
||||
{
|
||||
if (tok2->str() == "(")
|
||||
|
@ -1667,13 +1710,16 @@ private:
|
|||
|
||||
else if (tok2->varId())
|
||||
{
|
||||
if (Token::Match(tok2->tokAt(-2), "[(,] *"))
|
||||
if (Token::Match(tok2->tokAt(-2), "[(,] *") || Token::Match(tok2->next(), ". %var%"))
|
||||
use_dead_pointer(foundError, checks, tok2);
|
||||
|
||||
// it is possible that the variable is initialized here
|
||||
ExecutionPath::bailOutVar(checks, tok2->varId());
|
||||
bailouts.insert(tok2->varId());
|
||||
}
|
||||
}
|
||||
|
||||
for (std::set<unsigned int>::const_iterator it = bailouts.begin(); it != bailouts.end(); ++it)
|
||||
ExecutionPath::bailOutVar(checks, *it);
|
||||
}
|
||||
|
||||
// function call via function pointer
|
||||
|
|
|
@ -65,6 +65,29 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
|
|||
if (tok->str() == "}")
|
||||
return 0;
|
||||
|
||||
if (Token::simpleMatch(tok, "while ("))
|
||||
{
|
||||
// parse condition
|
||||
if (checks.size() > 10 || check->parseCondition(*tok->tokAt(2), checks))
|
||||
{
|
||||
ExecutionPath::bailOut(checks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// skip "while (fgets()!=NULL)"
|
||||
if (Token::simpleMatch(tok, "while ( fgets ("))
|
||||
{
|
||||
const Token *tok2 = tok->tokAt(3)->link();
|
||||
if (Token::simpleMatch(tok2, ") ) {"))
|
||||
{
|
||||
tok = tok2->tokAt(2)->link();
|
||||
if (!tok)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo: handle for/while
|
||||
if (Token::Match(tok, "for|while|switch|do"))
|
||||
{
|
||||
|
|
|
@ -929,6 +929,13 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
|
||||
|
||||
checkNullPointer("static void foo(int x)\n"
|
||||
"{\n"
|
||||
" Foo<int> *abc = 0;\n"
|
||||
" abc->a();\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: abc\n", errout.str());
|
||||
|
||||
// no false positive..
|
||||
checkNullPointer("static void foo()\n"
|
||||
"{\n"
|
||||
|
@ -992,6 +999,13 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
|
||||
|
||||
checkUninitVar("static void foo()\n"
|
||||
"{\n"
|
||||
" Foo<int> *p;\n"
|
||||
" p->abcd();\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
|
||||
|
||||
checkUninitVar("static void foo()\n"
|
||||
"{\n"
|
||||
" int *p;\n"
|
||||
|
@ -1308,6 +1322,15 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// while..
|
||||
checkUninitVar("int f()\n"
|
||||
"{\n"
|
||||
" int i;\n"
|
||||
" while (fgets())\n"
|
||||
" i = 1;\n"
|
||||
" return i;"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: i\n", errout.str());
|
||||
|
||||
// member variables..
|
||||
checkUninitVar("class Fred\n"
|
||||
|
@ -1365,6 +1388,13 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkUninitVar("void foo()\n"
|
||||
"{\n"
|
||||
" Foo *p;\n"
|
||||
" x = bar(p->begin());\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
|
||||
|
||||
// arrays..
|
||||
checkUninitVar("void f()\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue