|
Cppcheck
|
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
1.7.6.1