@@ -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