Cppcheck
checknullpointer.h
Go to the documentation of this file.
00001 /*
00002  * Cppcheck - A tool for static C/C++ code analysis
00003  * Copyright (C) 2007-2013 Daniel Marjamäki and Cppcheck team.
00004  *
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation, either version 3 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 
00020 //---------------------------------------------------------------------------
00021 #ifndef checknullpointerH
00022 #define checknullpointerH
00023 //---------------------------------------------------------------------------
00024 
00025 #include "config.h"
00026 #include "check.h"
00027 #include "settings.h"
00028 
00029 class Token;
00030 class SymbolDatabase;
00031 
00032 /// @addtogroup Checks
00033 /// @{
00034 
00035 
00036 /** @brief check for null pointer dereferencing */
00037 
00038 class CPPCHECKLIB CheckNullPointer : public Check {
00039 public:
00040     /** @brief This constructor is used when registering the CheckNullPointer */
00041     CheckNullPointer() : Check(myName())
00042     { }
00043 
00044     /** @brief This constructor is used when running checks. */
00045     CheckNullPointer(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
00046         : Check(myName(), tokenizer, settings, errorLogger)
00047     { }
00048 
00049     /** @brief Run checks against the normal token list */
00050     void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
00051         CheckNullPointer checkNullPointer(tokenizer, settings, errorLogger);
00052         checkNullPointer.nullPointer();
00053     }
00054 
00055     /** @brief Run checks against the simplified token list */
00056     void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
00057         CheckNullPointer checkNullPointer(tokenizer, settings, errorLogger);
00058         checkNullPointer.nullConstantDereference();
00059         checkNullPointer.executionPaths();
00060     }
00061 
00062     /**
00063      * @brief parse a function call and extract information about variable usage
00064      * @param tok first token
00065      * @param var variables that the function read / write.
00066      * @param value 0 => invalid with null pointers as parameter.
00067      *              non-zero => invalid with uninitialized data.
00068      */
00069     static void parseFunctionCall(const Token &tok,
00070                                   std::list<const Token *> &var,
00071                                   unsigned char value);
00072 
00073     /**
00074      * Is there a pointer dereference? Everything that should result in
00075      * a nullpointer dereference error message will result in a true
00076      * return value. If it's unknown if the pointer is dereferenced false
00077      * is returned.
00078      * @param tok token for the pointer
00079      * @param unknown it is not known if there is a pointer dereference (could be reported as a debug message)
00080      * @return true => there is a dereference
00081      */
00082     static bool isPointerDeRef(const Token *tok, bool &unknown);
00083 
00084     /** @brief possible null pointer dereference */
00085     void nullPointer();
00086 
00087     /**
00088      * @brief Does one part of the check for nullPointer().
00089      * Checking if pointer is NULL and then dereferencing it..
00090      */
00091     void nullPointerByCheckAndDeRef();
00092 
00093     /** @brief dereferencing null constant (after Tokenizer::simplifyKnownVariables) */
00094     void nullConstantDereference();
00095 
00096     /** @brief new type of check: check execution paths */
00097     void executionPaths();
00098 
00099     void nullPointerError(const Token *tok);  // variable name unknown / doesn't exist
00100     void nullPointerError(const Token *tok, const std::string &varname);
00101     void nullPointerError(const Token *tok, const std::string &varname, const Token* nullcheck, bool inconclusive = false);
00102     void nullPointerDefaultArgError(const Token *tok, const std::string &varname);
00103 private:
00104 
00105     /** Get error messages. Used by --errorlist */
00106     void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
00107         CheckNullPointer c(0, settings, errorLogger);
00108         c.nullPointerError(0, "pointer");
00109     }
00110 
00111     /** Name of check */
00112     static std::string myName() {
00113         return "Null pointer";
00114     }
00115 
00116     /** class info in WIKI format. Used by --doc */
00117     std::string classInfo() const {
00118         return "Null pointers\n"
00119                "* null pointer dereferencing\n";
00120     }
00121 
00122     /**
00123      * @brief Does one part of the check for nullPointer().
00124      * looping through items in a linked list in a inner loop..
00125      */
00126     void nullPointerLinkedList();
00127 
00128     /**
00129      * @brief Does one part of the check for nullPointer().
00130      * Dereferencing a struct pointer and then checking if it's NULL..
00131      */
00132     void nullPointerStructByDeRefAndChec();
00133 
00134     /**
00135      * @brief Does one part of the check for nullPointer().
00136      * Dereferencing a pointer and then checking if it's NULL..
00137      */
00138     void nullPointerByDeRefAndChec();
00139 
00140     /**
00141      * @brief Does one part of the check for nullPointer().
00142      * -# initialize pointer to 0
00143      * -# conditionally assign pointer
00144      * -# dereference pointer
00145      */
00146     void nullPointerConditionalAssignment();
00147 
00148     /**
00149      * @brief Does one part of the check for nullPointer().
00150      * -# default argument that sets a pointer to 0
00151      * -# dereference pointer
00152      */
00153     void nullPointerDefaultArgument();
00154 
00155     /**
00156      * @brief Investigate if function call can make pointer null. If
00157      * the pointer is passed by value it can't be made a null pointer.
00158      */
00159     static bool CanFunctionAssignPointer(const Token *functiontoken, unsigned int varid, bool& unknown);
00160 };
00161 /// @}
00162 //---------------------------------------------------------------------------
00163 #endif