Improved parsing of functions that accept nullpointers but no uninitialized data (Fixed #3811)

This commit is contained in:
PKEuS 2012-05-16 00:56:39 -07:00
parent 132a95b5f2
commit e8cd119ebd
3 changed files with 20 additions and 2 deletions

View File

@ -55,6 +55,7 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
// standard functions that dereference first parameter.. // standard functions that dereference first parameter..
static std::set<std::string> functionNames1_all; static std::set<std::string> functionNames1_all;
static std::set<std::string> functionNames1_nullptr; static std::set<std::string> functionNames1_nullptr;
static std::set<std::string> functionNames1_uninit;
if (functionNames1_all.empty()) { if (functionNames1_all.empty()) {
// cstdlib // cstdlib
functionNames1_all.insert("atoi"); functionNames1_all.insert("atoi");
@ -106,7 +107,6 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
functionNames1_all.insert("rename"); functionNames1_all.insert("rename");
functionNames1_all.insert("remove"); functionNames1_all.insert("remove");
functionNames1_all.insert("puts"); functionNames1_all.insert("puts");
functionNames1_all.insert("perror");
functionNames1_all.insert("getc"); functionNames1_all.insert("getc");
functionNames1_all.insert("clearerr"); functionNames1_all.insert("clearerr");
// ctime // ctime
@ -132,6 +132,9 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
functionNames1_nullptr.insert("gmtime"); functionNames1_nullptr.insert("gmtime");
functionNames1_nullptr.insert("localtime"); functionNames1_nullptr.insert("localtime");
functionNames1_nullptr.insert("strftime"); functionNames1_nullptr.insert("strftime");
functionNames1_uninit.insert("perror");
functionNames1_uninit.insert("fflush");
} }
// standard functions that dereference second parameter.. // standard functions that dereference second parameter..
@ -184,7 +187,7 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
var.push_back(firstParam); var.push_back(firstParam);
else if (value == 0 && functionNames1_nullptr.find(tok.str()) != functionNames1_nullptr.end()) else if (value == 0 && functionNames1_nullptr.find(tok.str()) != functionNames1_nullptr.end())
var.push_back(firstParam); var.push_back(firstParam);
else if (value != 0 && tok.str() == "fflush") else if (value != 0 && functionNames1_uninit.find(tok.str()) != functionNames1_uninit.end())
var.push_back(firstParam); var.push_back(firstParam);
else if (value == 0 && Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && secondParam && secondParam->str() != "0") // Only if length (second parameter) is not zero else if (value == 0 && Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && secondParam && secondParam->str() != "0") // Only if length (second parameter) is not zero
var.push_back(firstParam); var.push_back(firstParam);

View File

@ -52,6 +52,7 @@ private:
TEST_CASE(nullpointer16); // #3591 TEST_CASE(nullpointer16); // #3591
TEST_CASE(nullpointer17); // #3567 TEST_CASE(nullpointer17); // #3567
TEST_CASE(nullpointer18); // #1927 TEST_CASE(nullpointer18); // #1927
TEST_CASE(nullpointer19); // #3811
TEST_CASE(nullpointer_castToVoid); // #3771 TEST_CASE(nullpointer_castToVoid); // #3771
TEST_CASE(pointerCheckAndDeRef); // check if pointer is null and then dereference it TEST_CASE(pointerCheckAndDeRef); // check if pointer is null and then dereference it
TEST_CASE(nullConstantDereference); // Dereference NULL constant TEST_CASE(nullConstantDereference); // Dereference NULL constant
@ -1250,6 +1251,13 @@ private:
ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference\n", errout.str());
} }
void nullpointer19() { // #3811
check("int foo() {\n"
" perror(0);\n"
"}", true);
ASSERT_EQUALS("", errout.str());
}
void nullpointer_castToVoid() { // #3771 void nullpointer_castToVoid() { // #3771
check("void f () {\n" check("void f () {\n"
" int *buf = NULL;\n" " int *buf = NULL;\n"

View File

@ -1193,6 +1193,13 @@ private:
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Data is allocated but not initialized: s\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Data is allocated but not initialized: s\n", errout.str());
checkUninitVar("void f()\n"
"{\n"
" char *s = malloc(100);\n"
" perror(s);\n"
"};");
ASSERT_EQUALS("[test.cpp:4]: (error) Data is allocated but not initialized: s\n", errout.str());
checkUninitVar("void f()\n" checkUninitVar("void f()\n"
"{\n" "{\n"
" char *s1 = new char[10];\n" " char *s1 = new char[10];\n"