Skip to content

Commit 5721e1d

Browse files
committed
CheckNullPointer: Removed some of the old checking that doesn't use ValueFlow
1 parent 311059f commit 5721e1d

1 file changed

Lines changed: 40 additions & 218 deletions

File tree

lib/checknullpointer.cpp

Lines changed: 40 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -753,233 +753,55 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
753753
{
754754
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
755755

756-
if (_settings->valueFlow) {
757-
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
758-
if (!tok->isName() || tok->values.empty())
759-
continue;
760-
761-
const Variable *var = tok->variable();
762-
if (!var || !var->isPointer() || tok == var->nameToken())
763-
continue;
756+
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
757+
if (!tok->isName() || tok->values.empty())
758+
continue;
764759

765-
// Can pointer be NULL?
766-
const ValueFlow::Value *value = 0;
767-
for (std::list<ValueFlow::Value>::const_iterator it = tok->values.begin(); it != tok->values.end(); ++it) {
768-
if (it->intvalue == 0) {
769-
value = &(*it);
770-
break;
771-
}
772-
}
773-
if (!value)
774-
continue;
760+
const Variable *var = tok->variable();
761+
if (!var || !var->isPointer() || tok == var->nameToken())
762+
continue;
775763

776-
// Is pointer used as function parameter?
777-
if (Token::Match(tok->previous(), "[(,] %var% [,)]")) {
778-
const Token *ftok = tok->previous();
779-
while (ftok && ftok->str() != "(") {
780-
if (ftok->str() == ")")
781-
ftok = ftok->link();
782-
ftok = ftok->previous();
783-
}
784-
if (!ftok || !ftok->previous())
785-
continue;
786-
std::list<const Token *> varlist;
787-
parseFunctionCall(*ftok->previous(), varlist, &_settings->library, 0);
788-
if (std::find(varlist.begin(), varlist.end(), tok) != varlist.end()) {
789-
if (value->condition == NULL)
790-
nullPointerError(tok);
791-
else if (_settings->isEnabled("warning"))
792-
nullPointerError(tok, tok->str(), value->condition, value->inconclusive);
793-
}
794-
continue;
764+
// Can pointer be NULL?
765+
const ValueFlow::Value *value = 0;
766+
for (std::list<ValueFlow::Value>::const_iterator it = tok->values.begin(); it != tok->values.end(); ++it) {
767+
if (it->intvalue == 0) {
768+
value = &(*it);
769+
break;
795770
}
796-
797-
// Pointer dereference.
798-
bool unknown = false;
799-
if (!isPointerDeRef(tok,unknown))
800-
continue;
801-
802-
if (value->condition == NULL)
803-
nullPointerError(tok);
804-
else if (_settings->isEnabled("warning"))
805-
nullPointerError(tok, tok->str(), value->condition, value->inconclusive);
806771
}
807-
return;
808-
}
809-
810-
// Dereferencing a pointer and then checking if it's NULL..
811-
// This check will first scan for the check. And then scan backwards
812-
// from the check, searching for dereferencing.
813-
for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) {
814-
// TODO: false negatives.
815-
// - logical operators
816-
const Token* tok = i->classDef;
817-
if ((i->type == Scope::eIf || i->type == Scope::eElseIf || i->type == Scope::eWhile) &&
818-
tok && Token::Match(tok, "else| %var% ( !| %var% )|%oror%|&&") && !tok->tokAt(tok->str()=="else"?1:0)->isExpandedMacro()) {
819-
820-
if (tok->str() == "else")
821-
tok = tok->next();
822-
823-
const Token * vartok = tok->tokAt(2);
824-
if (vartok->str() == "!")
825-
vartok = vartok->next();
772+
if (!value)
773+
continue;
826774

827-
const Variable *var = vartok->variable();
828-
// Check that variable is a pointer..
829-
if (!var || !var->isPointer())
775+
// Is pointer used as function parameter?
776+
if (Token::Match(tok->previous(), "[(,] %var% [,)]")) {
777+
const Token *ftok = tok->previous();
778+
while (ftok && ftok->str() != "(") {
779+
if (ftok->str() == ")")
780+
ftok = ftok->link();
781+
ftok = ftok->previous();
782+
}
783+
if (!ftok || !ftok->previous())
830784
continue;
831-
832-
// Variable id for pointer
833-
const unsigned int varid(vartok->varId());
834-
835-
// bailout for while scope if pointer is assigned inside the loop
836-
if (i->type == Scope::eWhile) {
837-
bool assign = false;
838-
for (const Token *tok2 = i->classStart; tok2 && tok2 != i->classEnd; tok2 = tok2->next()) {
839-
if (Token::Match(tok2, "%varid% =", varid)) {
840-
assign = true;
841-
break;
842-
}
843-
}
844-
if (assign)
845-
continue;
785+
std::list<const Token *> varlist;
786+
parseFunctionCall(*ftok->previous(), varlist, &_settings->library, 0);
787+
if (std::find(varlist.begin(), varlist.end(), tok) != varlist.end()) {
788+
if (value->condition == NULL)
789+
nullPointerError(tok);
790+
else if (_settings->isEnabled("warning"))
791+
nullPointerError(tok, tok->str(), value->condition, value->inconclusive);
846792
}
793+
continue;
794+
}
847795

848-
// Name of pointer
849-
const std::string& varname(vartok->str());
850-
851-
const Token * const decltok = var->nameToken();
852-
bool inconclusive = false;
853-
854-
for (const Token *tok1 = tok->previous(); tok1 && tok1 != decltok; tok1 = tok1->previous()) {
855-
if (tok1->str() == ")" && Token::Match(tok1->link()->previous(), "%var% (")) {
856-
const Token *tok2 = tok1->link();
857-
while (tok2 && !Token::Match(tok2, "[;{}?:]"))
858-
tok2 = tok2->previous();
859-
if (Token::Match(tok2, "[?:]"))
860-
break;
861-
if (Token::Match(tok2->next(), "%varid% = %var%", varid))
862-
break;
863-
864-
if (Token::Match(tok2->next(), "while ( %varid%", varid))
865-
break;
866-
867-
if (Token::Match(tok1->link(), "( ! %varid% %oror%", varid) ||
868-
Token::Match(tok1->link(), "( %varid% &&", varid)) {
869-
tok1 = tok1->link();
870-
continue;
871-
}
872-
873-
if (Token::simpleMatch(tok1->link()->previous(), "sizeof (")) {
874-
tok1 = tok1->link()->previous();
875-
continue;
876-
}
877-
878-
if (Token::Match(tok2->next(), "%var% ( %varid% ,", varid)) {
879-
std::list<const Token *> varlist;
880-
parseFunctionCall(*(tok2->next()), varlist, &_settings->library, 0);
881-
if (!varlist.empty() && varlist.front() == tok2->tokAt(3)) {
882-
nullPointerError(tok2->tokAt(3), varname, tok, inconclusive);
883-
break;
884-
}
885-
}
886-
887-
// Passing pointer as parameter..
888-
if (Token::Match(tok2->next(), "%type% (")) {
889-
bool unknown = false;
890-
if (CanFunctionAssignPointer(tok2->next(), varid, unknown)) {
891-
if (!_settings->inconclusive || !unknown)
892-
break;
893-
inconclusive = true;
894-
}
895-
}
896-
897-
// calling unknown function => it might initialize the pointer
898-
if (!(var->isLocal() || var->isArgument()))
899-
break;
900-
}
901-
902-
if (tok1->str() == "break")
903-
break;
904-
905-
if (tok1->varId() == varid) {
906-
// Don't write warning if the dereferencing is
907-
// guarded by ?: or &&
908-
const Token *tok2 = tok1->previous();
909-
if (tok2 && (tok2->isArithmeticalOp() || Token::Match(tok2, "[(,]"))) {
910-
while (tok2 && !Token::Match(tok2, "[;{}?:]")) {
911-
if (tok2->str() == ")") {
912-
tok2 = tok2->link();
913-
if (Token::Match(tok2, "( %varid% =", varid)) {
914-
tok2 = tok2->next();
915-
break;
916-
}
917-
}
918-
// guarded by && or ||
919-
if (Token::Match(tok2, "%varid% &&|%oror%",varid))
920-
break;
921-
tok2 = tok2->previous();
922-
}
923-
}
924-
if (!tok2 || Token::Match(tok2, "[?:]") || tok2->varId() == varid)
925-
continue;
926-
927-
// unknown : this is set by isPointerDeRef if it is
928-
// uncertain
929-
bool unknown = _settings->inconclusive;
930-
931-
// reassign : is the pointer reassigned like this:
932-
// tok = tok->next();
933-
bool reassign = false;
934-
if (Token::Match(tok1->previous(), "= %varid% .", varid)) {
935-
const Token *back = tok1->tokAt(-2);
936-
while (back) {
937-
if (back->varId() == varid) {
938-
reassign = true;
939-
break;
940-
}
941-
if (Token::Match(back, "[{};,(]")) {
942-
break;
943-
}
944-
back = back->previous();
945-
}
946-
} else if (Token::Match(tok1->tokAt(-4), "%varid% = ( * %varid%", varid)) {
947-
reassign = true;
948-
} else if (Token::Match(tok1->tokAt(-3), "%varid% = * %varid%", varid)) {
949-
reassign = true;
950-
}
951-
952-
if (reassign) {
953-
break;
954-
} else if (Token::simpleMatch(tok1->tokAt(-2), "* )") &&
955-
Token::Match(tok1->linkAt(-1)->tokAt(-2), "%varid% = (", tok1->varId())) {
956-
break;
957-
} else if (Token::simpleMatch(tok1->tokAt(-3), "* ) (") &&
958-
Token::Match(tok1->linkAt(-2)->tokAt(-2), "%varid% = (", tok1->varId())) {
959-
break;
960-
} else if (Token::Match(tok1->previous(), "&&|%oror%")) {
961-
break;
962-
} else if (Token::Match(tok1->tokAt(-2), "&&|%oror% !")) {
963-
break;
964-
} else if (CheckNullPointer::isPointerDeRef(tok1, unknown)) {
965-
nullPointerError(tok1, varname, tok, inconclusive);
966-
break;
967-
} else if (tok1->strAt(-1) == "&") {
968-
break;
969-
} else if (tok1->strAt(1) == "=") {
970-
break;
971-
}
972-
}
973-
974-
else if (tok1->str() == "{" ||
975-
tok1->str() == "}")
976-
break;
796+
// Pointer dereference.
797+
bool unknown = false;
798+
if (!isPointerDeRef(tok,unknown))
799+
continue;
977800

978-
// label..
979-
else if (Token::Match(tok1, "%type% :"))
980-
break;
981-
}
982-
}
801+
if (value->condition == NULL)
802+
nullPointerError(tok);
803+
else if (_settings->isEnabled("warning"))
804+
nullPointerError(tok, tok->str(), value->condition, value->inconclusive);
983805
}
984806
}
985807

0 commit comments

Comments
 (0)