Stronger testing for false positives in inconclusive checking in checknullpointer.cpp
This commit is contained in:
PKEuS 2012-04-30 12:36:41 +02:00
parent 5d6a257c86
commit 8e362ad5f7
2 changed files with 49 additions and 36 deletions

View File

@ -372,6 +372,10 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Sym
if (Token::Match(tok->previous(), "return|= %var% ;")) if (Token::Match(tok->previous(), "return|= %var% ;"))
return false; return false;
// (void)var
if (Token::Match(tok->previous(), "[{;}] %var% ;"))
return false;
// unknown if it's a dereference // unknown if it's a dereference
unknown = true; unknown = true;
} }

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(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
TEST_CASE(gcc_statement_expression); // Don't crash TEST_CASE(gcc_statement_expression); // Don't crash
@ -226,7 +227,7 @@ private:
" sizeof(*list);\n" " sizeof(*list);\n"
" if (!list)\n" " if (!list)\n"
" ;\n" " ;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// ticket #2245 - sizeof doesn't dereference // ticket #2245 - sizeof doesn't dereference
@ -234,7 +235,7 @@ private:
" if (!p) {\n" " if (!p) {\n"
" int sz = sizeof(p->x);\n" " int sz = sizeof(p->x);\n"
" }\n" " }\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -246,7 +247,7 @@ private:
" Fred fred;\n" " Fred fred;\n"
" while (fred);\n" " while (fred);\n"
" fred.hello();\n" " fred.hello();\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -322,13 +323,13 @@ private:
" abc = abc->next;\n" " abc = abc->next;\n"
" if (!abc)\n" " if (!abc)\n"
" ;\n" " ;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(struct ABC *abc) {\n" check("void f(struct ABC *abc) {\n"
" abc = (ABC *)(abc->_next);\n" " abc = (ABC *)(abc->_next);\n"
" if (abc) { }" " if (abc) { }"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// reassign struct.. // reassign struct..
@ -338,7 +339,7 @@ private:
" abc = abc->next;\n" " abc = abc->next;\n"
" if (!abc)\n" " if (!abc)\n"
" ;\n" " ;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(struct ABC *abc)\n" check("void foo(struct ABC *abc)\n"
@ -347,7 +348,7 @@ private:
" f(&abc);\n" " f(&abc);\n"
" if (!abc)\n" " if (!abc)\n"
" ;\n" " ;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// goto.. // goto..
@ -535,7 +536,7 @@ private:
" int **p = f();\n" " int **p = f();\n"
" if (!p)\n" " if (!p)\n"
" ;\n" " ;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(int *p)\n" check("void foo(int *p)\n"
@ -554,7 +555,7 @@ private:
" int a = 2 * x;" " int a = 2 * x;"
" if (x == 0)\n" " if (x == 0)\n"
" ;\n" " ;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(int *p)\n" check("void foo(int *p)\n"
@ -711,7 +712,7 @@ private:
" int c = sizeof(test[0]);\n" " int c = sizeof(test[0]);\n"
" if (!test)\n" " if (!test)\n"
" ;\n" " ;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #3023 - checked deref // #3023 - checked deref
@ -966,14 +967,14 @@ private:
" for (int i = 0; i < 3; i++) {\n" " for (int i = 0; i < 3; i++) {\n"
" if (a && (p[i] == '1'));\n" " if (a && (p[i] == '1'));\n"
" }\n" " }\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// ticket #2251: taking the address of member // ticket #2251: taking the address of member
check("void f() {\n" check("void f() {\n"
" Fred *fred = 0;\n" " Fred *fred = 0;\n"
" int x = &fred->x;\n" " int x = &fred->x;\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// ticket #3220: calling member function // ticket #3220: calling member function
@ -990,14 +991,14 @@ private:
" if (x)\n" " if (x)\n"
" p = q;\n" " p = q;\n"
" if (p && *p) { }\n" " if (p && *p) { }\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n" check("void f() {\n"
" int *p = NULL;\n" " int *p = NULL;\n"
" if (x)\n" " if (x)\n"
" p = q;\n" " p = q;\n"
" if (!p || *p) { }\n" " if (!p || *p) { }\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n" check("void f() {\n"
" int *p = NULL;\n" " int *p = NULL;\n"
@ -1063,7 +1064,7 @@ private:
"{\n" "{\n"
" wxLongLong x = 0;\n" " wxLongLong x = 0;\n"
" int y = x.GetValue();\n" " int y = x.GetValue();\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1152,7 +1153,7 @@ private:
"{\n" "{\n"
" int* i = nullptr;\n" " int* i = nullptr;\n"
" return *i;\n" " return *i;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1209,7 +1210,7 @@ private:
" int *p = 0;\n" " int *p = 0;\n"
" bar(&p);\n" " bar(&p);\n"
" *p = 0;\n" " *p = 0;\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1217,13 +1218,13 @@ private:
check("int foo() {\n" check("int foo() {\n"
" int *p = 0;\n" " int *p = 0;\n"
" return (!p || *p);\n" " return (!p || *p);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int foo() {\n" check("int foo() {\n"
" int *p = 0;\n" " int *p = 0;\n"
" return p && *p;\n" " return p && *p;\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1241,6 +1242,14 @@ 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 nullpointer_castToVoid() { // #3771
check("void f () {\n"
" int *buf = NULL;\n"
" (void)buf;\n"
"}", true);
ASSERT_EQUALS("", errout.str());
}
// Check if pointer is null and the dereference it // Check if pointer is null and the dereference it
void pointerCheckAndDeRef() { void pointerCheckAndDeRef() {
check("void foo(char *p) {\n" check("void foo(char *p) {\n"
@ -1351,14 +1360,14 @@ private:
" if (!p) {\n" " if (!p) {\n"
" switch (x) { }\n" " switch (x) { }\n"
" }\n" " }\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(char *p) {\n" check("void foo(char *p) {\n"
" if (!p) {\n" " if (!p) {\n"
" }\n" " }\n"
" return *x;\n" " return *x;\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int foo(int *p) {\n" check("int foo(int *p) {\n"
@ -1445,7 +1454,7 @@ private:
"\n" "\n"
"void Fred::b() {\n" "void Fred::b() {\n"
" wilma->Reload();\n" " wilma->Reload();\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void test(int *i) {\n" check("void test(int *i) {\n"
@ -1454,7 +1463,7 @@ private:
" } else {\n" " } else {\n"
" int b = *i;\n" " int b = *i;\n"
" }\n" " }\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #2696 - false positives nr 1 // #2696 - false positives nr 1
@ -1467,7 +1476,7 @@ private:
"\n" "\n"
" if (pFoo)\n" " if (pFoo)\n"
" bar();\n" " bar();\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #2696 - false positives nr 2 // #2696 - false positives nr 2
@ -1480,7 +1489,7 @@ private:
" pFoo = pFoo->next;\n" " pFoo = pFoo->next;\n"
"\n" "\n"
" len = sizeof(pFoo->data);\n" " len = sizeof(pFoo->data);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #2696 - false positives nr 3 // #2696 - false positives nr 3
@ -1493,7 +1502,7 @@ private:
" pFoo = pFoo->next;\n" " pFoo = pFoo->next;\n"
"\n" "\n"
" len = decltype(*pFoo);\n" " len = decltype(*pFoo);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int foo(struct Fred *fred) {\n" check("int foo(struct Fred *fred) {\n"
@ -1595,7 +1604,7 @@ private:
check("void f(struct fred_t *fred) {\n" check("void f(struct fred_t *fred) {\n"
" if (!fred)\n" " if (!fred)\n"
" int sz = sizeof fred->x;\n" " int sz = sizeof fred->x;\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// check in macro // check in macro
@ -1625,13 +1634,13 @@ private:
// Ticket #2413 - it's ok to pass NULL to fflush // Ticket #2413 - it's ok to pass NULL to fflush
check("void foo() {\n" check("void foo() {\n"
" fflush(NULL);\n" " fflush(NULL);\n"
"}\n"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// Ticket #3126 - don't confuse member function with standard function // Ticket #3126 - don't confuse member function with standard function
check("void f() {\n" check("void f() {\n"
" image1.fseek(0, SEEK_SET);\n" " image1.fseek(0, SEEK_SET);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n" check("void f() {\n"
@ -1653,7 +1662,7 @@ private:
// Ticket #2840 // Ticket #2840
check("void f() {\n" check("void f() {\n"
" int bytes = snprintf(0, 0, \"%u\", 1);\n" " int bytes = snprintf(0, 0, \"%u\", 1);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1804,7 +1813,7 @@ private:
check("int foo(int* iVal) {\n" check("int foo(int* iVal) {\n"
" return iVal[0];\n" " return iVal[0];\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1814,20 +1823,20 @@ private:
"bool foo() {\n" "bool foo() {\n"
" PolymorphicA* a = 0;\n" " PolymorphicA* a = 0;\n"
" return typeid(*a) == typeid(*a);\n" " return typeid(*a) == typeid(*a);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct NonPolymorphicA { ~A() {} };\n" check("struct NonPolymorphicA { ~A() {} };\n"
"bool foo() {\n" "bool foo() {\n"
" NonPolymorphicA* a = 0;\n" " NonPolymorphicA* a = 0;\n"
" return typeid(*a) == typeid(*a);\n" " return typeid(*a) == typeid(*a);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("bool foo() {\n" check("bool foo() {\n"
" char* c = 0;\n" " char* c = 0;\n"
" return typeid(*c) == typeid(*c);\n" " return typeid(*c) == typeid(*c);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1963,7 +1972,7 @@ private:
" char* p2 = 0;\n" " char* p2 = 0;\n"
" std::cin >> (int)p;\n" // result casted " std::cin >> (int)p;\n" // result casted
" std::cout << (int)p;\n" " std::cout << (int)p;\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(const std::string& str) {\n" check("void f(const std::string& str) {\n"
@ -1971,7 +1980,7 @@ private:
" std::istringstream istr(str);\n" " std::istringstream istr(str);\n"
" istr >> std::hex >> ret;\n" // Read integer " istr >> std::hex >> ret;\n" // Read integer
" return ret;\n" " return ret;\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }