Cppcheck
checkleakautovar.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 checkleakautovarH
00022 #define checkleakautovarH
00023 //---------------------------------------------------------------------------
00024 
00025 #include "config.h"
00026 #include "check.h"
00027 
00028 
00029 class CPPCHECKLIB VarInfo {
00030 public:
00031     std::map<unsigned int, std::string> alloctype;
00032     std::map<unsigned int, std::string> possibleUsage;
00033     std::set<unsigned int> conditionalAlloc;
00034     std::set<unsigned int> referenced;
00035 
00036     void clear() {
00037         alloctype.clear();
00038         possibleUsage.clear();
00039         conditionalAlloc.clear();
00040         referenced.clear();
00041     }
00042 
00043     void erase(unsigned int varid) {
00044         alloctype.erase(varid);
00045         possibleUsage.erase(varid);
00046         conditionalAlloc.erase(varid);
00047     }
00048 
00049     void swap(VarInfo &other) {
00050         alloctype.swap(other.alloctype);
00051         possibleUsage.swap(other.possibleUsage);
00052         conditionalAlloc.swap(other.conditionalAlloc);
00053         referenced.swap(other.referenced);
00054     }
00055 
00056     /** set possible usage for all variables */
00057     void possibleUsageAll(const std::string &functionName);
00058 
00059     void print();
00060 };
00061 
00062 
00063 /// @addtogroup Checks
00064 /// @{
00065 
00066 /**
00067  * @brief Check for leaks
00068  */
00069 
00070 class CPPCHECKLIB CheckLeakAutoVar : public Check {
00071 public:
00072     /** This constructor is used when registering the CheckLeakAutoVar */
00073     CheckLeakAutoVar() : Check(myName()) {
00074     }
00075 
00076     /** This constructor is used when running checks. */
00077     CheckLeakAutoVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
00078         : Check(myName(), tokenizer, settings, errorLogger) {
00079     }
00080 
00081     /** @brief Run checks against the simplified token list */
00082     void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
00083         CheckLeakAutoVar checkLeakAutoVar(tokenizer, settings, errorLogger);
00084         checkLeakAutoVar.parseConfigurationFile("cppcheck.cfg");
00085         checkLeakAutoVar.check();
00086     }
00087 
00088 private:
00089 
00090     std::map<std::string,std::string> cfgalloc;
00091     std::map<std::string,std::string> cfgdealloc;
00092     std::set<std::string> cfgignore;
00093     std::set<std::string> cfguse;
00094     std::set<std::string> cfgnoreturn;
00095 
00096     void parseConfigurationFile(const std::string &filename);
00097 
00098     /** check for leaks in all scopes */
00099     void check();
00100 
00101     /** check for leaks in a function scope */
00102     void checkScope(const Token * const startToken,
00103                     VarInfo *varInfo,
00104                     std::set<unsigned int> notzero);
00105 
00106     /** parse function call */
00107     void functionCall(const Token *tok, VarInfo *varInfo, const std::string &dealloc);
00108 
00109     /** return. either "return" or end of variable scope is seen */
00110     void ret(const Token *tok, const VarInfo &varInfo);
00111 
00112     /** if variable is allocated then there is a leak */
00113     void leakIfAllocated(const Token *vartok, const VarInfo &varInfo);
00114 
00115     void leakError(const Token* tok, const std::string &varname, const std::string &type);
00116     void mismatchError(const Token* tok, const std::string &varname);
00117     void deallocUseError(const Token *tok, const std::string &varname);
00118     void deallocReturnError(const Token *tok, const std::string &varname);
00119 
00120     /** message: user configuration is needed to complete analysis */
00121     void configurationInfo(const Token* tok, const std::string &functionName);
00122 
00123     void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
00124         CheckLeakAutoVar c(0, settings, errorLogger);
00125         c.deallocReturnError(0, "p");
00126         c.configurationInfo(0, "f");  // user configuration is needed to complete analysis
00127     }
00128 
00129     static std::string myName() {
00130         return "Leaks (auto variables)";
00131     }
00132 
00133     std::string classInfo() const {
00134         return "Detect when a auto variable is allocated but not deallocated.\n";
00135     }
00136 };
00137 /// @}
00138 //---------------------------------------------------------------------------
00139 #endif