You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
ASSERT_EQUALS("[test.cpp:3:12] -> [test.cpp:4:11]: (warning) Either the condition 'tok' is redundant or there is possible null pointer dereference: tok. [nullPointerRedundantCheck]\n", errout_str());
// #2681
{
constchar code[] = "void foo(const Token *tok)\n"
"{\n"
" while (tok && tok->str() == \"=\")\n"
" tok = tok->next();\n"
"\n"
" if (tok->str() != \";\")\n"
" ;\n"
"}\n";
check(code);
ASSERT_EQUALS("[test.cpp:3:12] -> [test.cpp:6:9]: (warning) Either the condition 'tok' is redundant or there is possible null pointer dereference: tok. [nullPointerRedundantCheck]\n", errout_str());
}
check("void foo()\n"
"{\n"
" for (const Token *tok = tokens; tok; tok = tok->next())\n"
" {\n"
" while (tok && tok->str() != \";\")\n"
" tok = tok->next();\n"
" }\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:3]: (warning) Either the condition 'while' is redundant or there is possible null pointer dereference: tok.\n", "", errout_str());
check("void foo(Token &tok)\n"
"{\n"
" for (int i = 0; i < tok.size(); i++ )\n"
" {\n"
" while (!tok)\n"
" char c = tok.read();\n"
" }\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo()\n"
"{\n"
" for (const Token *tok = tokens; tok; tok = tok->next())\n"
" {\n"
" while (tok && tok->str() != \";\")\n"
" tok = tok->next();\n"
" if( !tok ) break;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo()\n"
"{\n"
" for (const Token *tok = tokens; tok; tok = tok ? tok->next() : NULL)\n"
" {\n"
" while (tok && tok->str() != \";\")\n"
" tok = tok->next();\n"
" }\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo(A*a)\n"
"{\n"
" switch (a->b()) {\n"
" case 1:\n"
" while( a ){\n"
" a = a->next;\n"
" }\n"
" break;\n"
" case 2:\n"
" a->b();\n"
" break;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout_str());
// dereference in outer scope..
check("void foo(int x, const Token *tok) {\n"
" if (x == 123) {\n"
" while (tok) tok = tok->next();\n"
" }\n"
" tok->str();\n"
"}");
ASSERT_EQUALS("[test.cpp:3:16] -> [test.cpp:5:5]: (warning) Either the condition 'tok' is redundant or there is possible null pointer dereference: tok. [nullPointerRedundantCheck]\n", errout_str());
ASSERT_EQUALS("[test.cpp:7:13] -> [test.cpp:6:40]: (warning) Either the condition 'd' is redundant or there is possible null pointer dereference: d. [nullPointerRedundantCheck]\n", errout_str());
}
voidnullpointer1() {
// ticket #1923 - no false positive when using else if
check("void f(A *a)\n"
"{\n"
" if (a->x == 1)\n"
" {\n"
" a = a->next;\n"
" }\n"
" else if (a->x == 2) { }\n"
" if (a) { }\n"
"}");
ASSERT_EQUALS("", errout_str());
// ticket #2134 - sizeof doesn't dereference
check("void f() {\n"
" int c = 1;\n"
" int *list = NULL;\n"
" sizeof(*list);\n"
" if (!list)\n"
" ;\n"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
// ticket #2245 - sizeof doesn't dereference
check("void f(Bar *p) {\n"
" if (!p) {\n"
" int sz = sizeof(p->x);\n"
" }\n"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
}
voidnullpointer2() {
// Null pointer dereference can only happen with pointers
check("void foo()\n"
"{\n"
" Fred fred;\n"
" while (fred);\n"
" fred.hello();\n"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
}
// Dereferencing a struct and then checking if it is null
// This is checked by this function:
// CheckOther::nullPointerStructByDeRefAndCheck
voidstructDerefAndCheck() {
// extracttests.start: struct ABC { int a; int b; int x; };
// errors..
check("void foo(struct ABC *abc)\n"
"{\n"
" int a = abc->a;\n"
" if (!abc)\n"
" ;\n"
"}");
ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:13]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str());
check("void foo(struct ABC *abc) {\n"
" bar(abc->a);\n"
" bar(x, abc->a);\n"
" bar(x, y, abc->a);\n"
" if (!abc)\n"
" ;\n"
"}");
ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:2:9]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n"
"[test.cpp:5:9] -> [test.cpp:3:12]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n"
"[test.cpp:5:9] -> [test.cpp:4:15]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str());
check("void foo(ABC *abc) {\n"
" if (abc->a == 3) {\n"
" return;\n"
" }\n"
" if (abc) {}\n"
"}");
ASSERT_EQUALS(
"[test.cpp:5:9] -> [test.cpp:2:9]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n",
errout_str());
check("void f(ABC *abc) {\n"
" if (abc->x == 0) {\n"
" return;\n"
" }\n"
" if (!abc);\n"
"}");
ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:2:9]: (warning) Either the condition '!abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n", errout_str());
// TODO: False negative if member of member is dereferenced
check("void foo(ABC *abc) {\n"
" abc->next->a = 0;\n"
" if (abc->next)\n"
" ;\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Possible null pointer dereference: abc - otherwise it is redundant to check it against null.\n", "", errout_str());
check("void foo(ABC *abc) {\n"
" abc->a = 0;\n"
" if (abc && abc->b == 0)\n"
" ;\n"
"}");
ASSERT_EQUALS(
"[test.cpp:3:9] -> [test.cpp:2:5]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n",
errout_str());
// ok dereferencing in a condition
check("void foo(struct ABC *abc)\n"
"{\n"
" if (abc && abc->a);\n"
" if (!abc)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void f(struct ABC *abc) {\n"
" int x = abc && a(abc->x);\n"
" if (abc) { }\n"
"}");
ASSERT_EQUALS("", errout_str());
// ok to use a linked list..
check("void foo(struct ABC *abc)\n"
"{\n"
" abc = abc->next;\n"
" if (!abc)\n"
" ;\n"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
check("void f(struct ABC *abc) {\n"
" abc = (ABC *)(abc->_next);\n"
" if (abc) { }"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
// reassign struct..
check("void foo(struct ABC *abc)\n"
"{\n"
" int a = abc->a;\n"
" abc = abc->next;\n"
" if (!abc)\n"
" ;\n"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
check("void foo(struct ABC *abc)\n"
"{\n"
" int a = abc->a;\n"
" f(&abc);\n"
" if (!abc)\n"
" ;\n"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
// goto..
check("void foo(struct ABC *abc)\n"
"{\n"
" int a;\n"
" if (!abc)\n"
" goto out;"
" a = abc->a;\n"
" return;\n"
"out:\n"
" if (!abc)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
// loops..
check("void foo(struct ABC *abc)\n"
"{\n"
" int a = abc->a;"
" do\n"
" {\n"
" if (abc)\n"
" abc = abc->next;\n"
" --a;\n"
" }\n"
" while (a > 0);\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void f()\n"
"{\n"
" for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())\n"
" {\n"
" while (tok && tok->str() != \"{\")\n"
" tok = tok->next();\n"
" if (!tok)\n"
" return;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout_str());
// dynamic_cast..
check("void foo(ABC *abc)\n"
"{\n"
" int a = abc->a;\n"
" if (!dynamic_cast<DEF *>(abc))\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
// #2641 - global pointer, function call
check("ABC *abc;\n"
"void f() {\n"
" abc->a = 0;\n"
" do_stuff();\n"
" if (abc) { }\n"
"}");
ASSERT_EQUALS("",errout_str());
check("Fred *fred;\n"
"void f() {\n"
" fred->foo();\n"
" if (fred) { }\n"
"}");
ASSERT_EQUALS("",errout_str());
// #2641 - local pointer, function call
check("void f() {\n"
" ABC *abc = abc1;\n"
" abc->a = 0;\n"
" do_stuff();\n"
" if (abc) { }\n"
"}");
ASSERT_EQUALS(
"[test.cpp:5:9] -> [test.cpp:3:5]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n",
errout_str());
// #2641 - local pointer, function call
check("void f(ABC *abc) {\n"
" abc->a = 0;\n"
" do_stuff();\n"
" if (abc) { }\n"
"}");
ASSERT_EQUALS(
"[test.cpp:4:9] -> [test.cpp:2:5]: (warning) Either the condition 'abc' is redundant or there is possible null pointer dereference: abc. [nullPointerRedundantCheck]\n",
errout_str());
// #2691 - switch/break
check("void f(ABC *abc) {\n"
" switch ( x ) {\n"
" case 14:\n"
" sprintf(buf, \"%d\", abc->a);\n"
" break;\n"
" case 15:\n"
" if ( abc ) {}\n"
" break;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout_str());
// #3128
check("void f(ABC *abc) {\n"
" x(!abc || y(abc->a));\n"
" if (abc) {}\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void f(ABC *abc) {\n"
" x(def || !abc || y(def, abc->a));\n"
" if (abc) {}\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void f(ABC *abc) {\n"
" x(abc && y(def, abc->a));\n"
" if (abc) {}\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void f(ABC *abc) {\n"
" x(def && abc && y(def, abc->a));\n"
" if (abc) {}\n"
"}");
ASSERT_EQUALS("", errout_str());
// #3228 - calling function with null object
{
constchar code[] = "void f(Fred *fred) {\n"
" fred->x();\n"
" if (fred) { }\n"
"}";
check(code);
ASSERT_EQUALS(
"[test.cpp:3:9] -> [test.cpp:2:5]: (warning) Either the condition 'fred' is redundant or there is possible null pointer dereference: fred. [nullPointerRedundantCheck]\n",
errout_str());
}
// #3425 - false positives when there are macros
checkP("#define IF if\n"
"void f(struct FRED *fred) {\n"
" fred->x = 0;\n"
" IF(!fred){}\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo() {\n"
" BUFFER *buffer = get_buffer();\n"
" if (!buffer)\n"
" uv_fatal_error();\n"
" buffer->x = 11;\n"
"}");
ASSERT_EQUALS("", errout_str());
}
// Dereferencing a pointer and then checking if it is null
voidpointerDerefAndCheck() {
// extracttests.start: void bar(int);
// errors..
check("void foo(int *p)\n"
"{\n"
" *p = 0;\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:6]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str());
check("void foo(int *p)\n"
"{\n"
" *p = 0;\n"
" if (p) { }\n"
"}");
ASSERT_EQUALS(
"[test.cpp:4:9] -> [test.cpp:3:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n",
errout_str());
check("void foo(int *p)\n"
"{\n"
" *p = 0;\n"
" if (p || q) { }\n"
"}");
ASSERT_EQUALS(
"[test.cpp:4:9] -> [test.cpp:3:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n",
errout_str());
check("void foo(int *p)\n"
"{\n"
" bar(*p);\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:10]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str());
check("void foo(char *p)\n"
"{\n"
" strcpy(p, \"abc\");\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:12]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str());
check("void foo(char *p)\n"
"{\n"
" if (*p == 0) { }\n"
" if (!p) { }\n"
"}");
ASSERT_EQUALS("[test.cpp:4:9] -> [test.cpp:3:10]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n", errout_str());
// no error
check("void foo()\n"
"{\n"
" int *p;\n"
" f(&p);\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo()\n"
"{\n"
" int **p = f();\n"
" if (!p)\n"
" ;\n"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
check("void foo(int *p)\n"
"{\n"
" if (x)\n"
" p = 0;\n"
" else\n"
" *p = 0;\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo(int x)\n"
"{\n"
" int a = 2 * x;"
" if (x == 0)\n"
" ;\n"
"}", dinit(CheckOptions, $.inconclusive = true));
ASSERT_EQUALS("", errout_str());
check("void foo(int *p)\n"
"{\n"
" int var1 = p ? *p : 0;\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo(int *p, bool x)\n"
"{\n"
" int var1 = x ? *p : 5;\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS(
"[test.cpp:4:9] -> [test.cpp:3:21]: (warning) Either the condition '!p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n",
errout_str());
// while
check("void f(int *p) {\n"
" *p = 0;\n"
" while (p) { p = 0; }\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void f(int *p) {\n"
" *p = 0;\n"
" while (p) { }\n"
"}");
ASSERT_EQUALS(
"[test.cpp:3:12] -> [test.cpp:2:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n",
"[test.cpp:3:12] -> [test.cpp:2:6]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n",
errout_str());
check("void foo(x *p)\n"
"{\n"
" p = p->next;\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo(x *p)\n"
"{\n"
" p = bar(p->next);\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo(x *p)\n"
"{\n"
" p = aa->bar(p->next);\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo(x *p)\n"
"{\n"
" p = *p2 = p->next;\n"
" if (!p)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void foo(struct ABC *abc)\n"
"{\n"
" abc = abc ? abc->next : 0;\n"
" if (!abc)\n"
" ;\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void f(struct ABC *abc) {\n"// #4523
" abc = (*abc).next;\n"
" if (abc) { }\n"
"}");
ASSERT_EQUALS("", errout_str());
check("void f(struct ABC *abc) {\n"// #4523
" abc = (*abc->ptr);\n"
" if (abc) { }\n"
"}");
ASSERT_EQUALS("", errout_str());
check("int f(Item *item) {\n"
" x = item ? ab(item->x) : 0;\n"
" if (item) { }\n"
"}");
ASSERT_EQUALS("", errout_str());
check("int f(Item *item) {\n"
" item->x = 0;\n"
" a = b ? c : d;\n"
" if (item) { }\n"
"}");
ASSERT_EQUALS(
"[test.cpp:4:9] -> [test.cpp:2:5]: (warning) Either the condition 'item' is redundant or there is possible null pointer dereference: item. [nullPointerRedundantCheck]\n",