Null pointers: Detect code where the assignment is conditional
This commit is contained in:
parent
0e56e4cd37
commit
857c95e7b5
|
@ -1106,12 +1106,54 @@ void CheckOther::nullPointerByDeRefAndChec()
|
|||
}
|
||||
}
|
||||
|
||||
void CheckOther::nullPointerConditionalAssignment()
|
||||
{
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||
{
|
||||
// 1. Initialize..
|
||||
if (!tok->Match(tok, "; %var% = 0 ;"))
|
||||
continue;
|
||||
|
||||
const unsigned int varid(tok->next()->varId());
|
||||
if (!varid)
|
||||
continue;
|
||||
|
||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
|
||||
{
|
||||
if (tok2->str() == "{" || tok2->str() == "}")
|
||||
break;
|
||||
|
||||
if (Token::simpleMatch(tok2, "if ("))
|
||||
{
|
||||
const Token *tok3 = tok2;
|
||||
tok3 = tok3->next()->link();
|
||||
if (!tok3)
|
||||
break;
|
||||
if (tok3->next()->str() == "{")
|
||||
{
|
||||
tok2 = tok3->next()->link();
|
||||
if (!tok2)
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "else !!if"))
|
||||
break;
|
||||
|
||||
if (Token::Match(tok2, "%varid% . %var% (", varid))
|
||||
nullPointerError(tok2, tok->next()->str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::nullPointer()
|
||||
{
|
||||
nullPointerAfterLoop();
|
||||
nullPointerLinkedList();
|
||||
nullPointerStructByDeRefAndChec();
|
||||
nullPointerByDeRefAndChec();
|
||||
nullPointerConditionalAssignment();
|
||||
}
|
||||
|
||||
void CheckOther::checkZeroDivision()
|
||||
|
|
|
@ -228,6 +228,14 @@ private:
|
|||
* Dereferencing a pointer and then checking if it's NULL..
|
||||
*/
|
||||
void nullPointerByDeRefAndChec();
|
||||
|
||||
/**
|
||||
* Does one part of the check for nullPointer().
|
||||
* 1. initialize pointer to 0
|
||||
* 2. conditionally assign pointer
|
||||
* 3. dereference pointer
|
||||
*/
|
||||
void nullPointerConditionalAssignment();
|
||||
};
|
||||
/// @}
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -65,7 +65,8 @@ private:
|
|||
TEST_CASE(nullpointer2);
|
||||
TEST_CASE(nullpointer3); // dereferencing struct and then checking if it's null
|
||||
TEST_CASE(nullpointer4);
|
||||
TEST_CASE(nullpointer5); // References should not be checked
|
||||
TEST_CASE(nullpointer5); // References should not be checked
|
||||
TEST_CASE(nullpointer6);
|
||||
|
||||
TEST_CASE(oldStylePointerCast);
|
||||
|
||||
|
@ -885,6 +886,21 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void nullpointer6()
|
||||
{
|
||||
// errors..
|
||||
checkNullPointer("static void foo()\n"
|
||||
"{\n"
|
||||
" Foo *p = 0;\n"
|
||||
" if (a == 1)\n"
|
||||
" p = new FooBar;\n"
|
||||
" else if (a == 2)\n"
|
||||
" p = new FooCar;\n"
|
||||
" p->abcd();\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (error) Possible null pointer dereference: p\n", errout.str());
|
||||
}
|
||||
|
||||
void checkOldStylePointerCast(const char code[])
|
||||
{
|
||||
// Tokenize..
|
||||
|
|
Loading…
Reference in New Issue