diff --git a/src/checkclass.cpp b/src/checkclass.cpp index 07c4ed585..bbc0390f3 100644 --- a/src/checkclass.cpp +++ b/src/checkclass.cpp @@ -446,10 +446,7 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const continue; // It's non-static and it's not initialized => error - std::ostringstream ostr; - ostr << _tokenizer->fileLine(constructor_token); - ostr << " Uninitialized member variable '" << className << "::" << var->name << "'"; - _errorLogger->reportErr(ostr.str()); + _errorLogger->reportErr(ErrorMessage::uninitVar(_tokenizer, constructor_token, className, var->name)); } for (struct VAR *var = varlist; var; var = var->next) diff --git a/src/cppcheck.cpp b/src/cppcheck.cpp index 3d1cfafac..502b2c6b2 100644 --- a/src/cppcheck.cpp +++ b/src/cppcheck.cpp @@ -271,7 +271,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[]) checkMemoryLeak.CheckMemoryLeak(); // Check that all class constructors are ok. - if (ErrorMessage::noConstructor(_settings)) + if (ErrorMessage::noConstructor(_settings) || ErrorMessage::uninitVar(_settings)) checkClass.constructors(); // Check that all base classes have virtual destructors diff --git a/src/errormessage.h b/src/errormessage.h index 32f602336..7b5af16c9 100644 --- a/src/errormessage.h +++ b/src/errormessage.h @@ -39,6 +39,15 @@ public: return s._checkCodingStyle; } + static std::string uninitVar(const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &varname) + { + return msg1(tokenizer, Location) + "Uninitialized member variable '" + classname + "::" + varname + "'"; + } + static bool uninitVar(const Settings &s) + { + return true; + } + static std::string memleak(const Tokenizer *tokenizer, const Token *Location, const std::string &varname) { return msg1(tokenizer, Location) + "Memory leak: " + varname + ""; diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index e804275f3..5ce4b720c 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -96,7 +96,7 @@ private: " Fred() { }\n" " int i;\n" "};\n"); - ASSERT_EQUALS(std::string("[test.cpp:4] Uninitialized member variable 'Fred::i'\n"), errout.str()); + ASSERT_EQUALS(std::string("[test.cpp:4]: Uninitialized member variable 'Fred::i'\n"), errout.str()); } @@ -110,7 +110,7 @@ private: "};\n" "Fred::Fred()\n" "{ }\n"); - ASSERT_EQUALS(std::string("[test.cpp:7] Uninitialized member variable 'Fred::i'\n"), errout.str()); + ASSERT_EQUALS(std::string("[test.cpp:7]: Uninitialized member variable 'Fred::i'\n"), errout.str()); } @@ -129,7 +129,7 @@ private: "{\n" " i = _i;\n" "}\n"); - ASSERT_EQUALS(std::string("[test.cpp:8] Uninitialized member variable 'Fred::i'\n"), errout.str()); + ASSERT_EQUALS(std::string("[test.cpp:8]: Uninitialized member variable 'Fred::i'\n"), errout.str()); } @@ -196,7 +196,7 @@ private: " void operator=() { }\n" " int i;\n" "};\n"); - ASSERT_EQUALS(std::string("[test.cpp:5] Uninitialized member variable 'Fred::i'\n"), errout.str()); + ASSERT_EQUALS(std::string("[test.cpp:5]: Uninitialized member variable 'Fred::i'\n"), errout.str()); } void initvar_operator_eq3() diff --git a/tools/errmsg.cpp b/tools/errmsg.cpp index afa84db9d..3208b1952 100644 --- a/tools/errmsg.cpp +++ b/tools/errmsg.cpp @@ -27,12 +27,15 @@ private: std::string _funcname; std::string _msg; std::string _par1; + std::string _par2; unsigned int _settings; std::string msg(bool code) const; public: + Message(std::string funcname, unsigned int settings, std::string msg); Message(std::string funcname, unsigned int settings, std::string msg, std::string par1); + Message(std::string funcname, unsigned int settings, std::string msg, std::string par1, std::string par2); static const unsigned int ALL = 1; static const unsigned int STYLE = 2; @@ -52,16 +55,17 @@ int main() // checkclass.cpp.. err.push_back(Message("noConstructor", Message::STYLE, "The class '%1' has no constructor", "classname")); + err.push_back(Message("uninitVar", 0, "Uninitialized member variable '%1::%2'", "classname", "varname")); // checkmemoryleak.cpp.. err.push_back(Message("memleak", 0, "Memory leak: %1", "varname")); err.push_back(Message("resourceLeak", 0, "Resource leak: %1", "varname")); // checkother.cpp.. - err.push_back(Message("cstyleCast", Message::STYLE, "C-style pointer casting", "")); - err.push_back(Message("redundantIfDelete0", Message::STYLE, "Redundant condition. It is safe to deallocate a NULL pointer", "")); - err.push_back(Message("redundantIfRemove", Message::STYLE, "Redundant condition. The remove function in the STL will not do anything if element doesn't exist", "")); - err.push_back(Message("dangerousUsageStrtol", 0, "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36", "")); + err.push_back(Message("cstyleCast", Message::STYLE, "C-style pointer casting")); + err.push_back(Message("redundantIfDelete0", Message::STYLE, "Redundant condition. It is safe to deallocate a NULL pointer")); + err.push_back(Message("redundantIfRemove", Message::STYLE, "Redundant condition. The remove function in the STL will not do anything if element doesn't exist")); + err.push_back(Message("dangerousUsageStrtol", 0, "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36")); // Generate code.. std::cout << "Generate code.." << std::endl; @@ -121,14 +125,23 @@ int main() +Message::Message(std::string funcname, unsigned int settings, std::string msg) + : _funcname(funcname), _msg(msg), _par1(""), _par2(""), _settings(settings) +{ } + Message::Message(std::string funcname, unsigned int settings, std::string msg, std::string par1) - : _funcname(funcname), _msg(msg), _par1(par1), _settings(settings) + : _funcname(funcname), _msg(msg), _par1(par1), _par2(""), _settings(settings) +{ } + +Message::Message(std::string funcname, unsigned int settings, std::string msg, std::string par1, std::string par2) + : _funcname(funcname), _msg(msg), _par1(par1), _par2(par2), _settings(settings) { } std::string Message::msg(bool code) const { const char *str = code ? "\"" : ""; std::string ret(str + _msg + str); + if (! _par1.empty()) { std::string::size_type pos = 0; @@ -141,6 +154,20 @@ std::string Message::msg(bool code) const ret.insert(pos, _par1); } } + + if (! _par2.empty()) + { + std::string::size_type pos = 0; + while ((pos = ret.find("%2", pos)) != std::string::npos) + { + ret.erase(pos, 2); + if (code) + ret.insert(pos, "\" + " + _par2 + " + \""); + else + ret.insert(pos, _par2); + } + } + return ret; } @@ -150,6 +177,8 @@ void Message::generateCode(std::ostream &ostr) const ostr << " static std::string " << _funcname << "(const Tokenizer *tokenizer, const Token *Location"; if (! _par1.empty()) ostr << ", const std::string &" << _par1; + if (! _par2.empty()) + ostr << ", const std::string &" << _par2; ostr << ")\n"; ostr << " {\n"; ostr << " return msg1(tokenizer, Location) + " << msg(true) << ";\n";