errmsg: Added "uninitialized member variable"

This commit is contained in:
Daniel Marjamäki 2009-01-10 17:11:47 +00:00
parent 5570f06075
commit dc6317878e
5 changed files with 49 additions and 14 deletions

View File

@ -446,10 +446,7 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const
continue; continue;
// It's non-static and it's not initialized => error // It's non-static and it's not initialized => error
std::ostringstream ostr; _errorLogger->reportErr(ErrorMessage::uninitVar(_tokenizer, constructor_token, className, var->name));
ostr << _tokenizer->fileLine(constructor_token);
ostr << " Uninitialized member variable '" << className << "::" << var->name << "'";
_errorLogger->reportErr(ostr.str());
} }
for (struct VAR *var = varlist; var; var = var->next) for (struct VAR *var = varlist; var; var = var->next)

View File

@ -271,7 +271,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
checkMemoryLeak.CheckMemoryLeak(); checkMemoryLeak.CheckMemoryLeak();
// Check that all class constructors are ok. // Check that all class constructors are ok.
if (ErrorMessage::noConstructor(_settings)) if (ErrorMessage::noConstructor(_settings) || ErrorMessage::uninitVar(_settings))
checkClass.constructors(); checkClass.constructors();
// Check that all base classes have virtual destructors // Check that all base classes have virtual destructors

View File

@ -39,6 +39,15 @@ public:
return s._checkCodingStyle; 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) static std::string memleak(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{ {
return msg1(tokenizer, Location) + "Memory leak: " + varname + ""; return msg1(tokenizer, Location) + "Memory leak: " + varname + "";

View File

@ -96,7 +96,7 @@ private:
" Fred() { }\n" " Fred() { }\n"
" int i;\n" " int i;\n"
"};\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" "};\n"
"Fred::Fred()\n" "Fred::Fred()\n"
"{ }\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" "{\n"
" i = _i;\n" " i = _i;\n"
"}\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" " void operator=() { }\n"
" int i;\n" " int i;\n"
"};\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() void initvar_operator_eq3()

View File

@ -27,12 +27,15 @@ private:
std::string _funcname; std::string _funcname;
std::string _msg; std::string _msg;
std::string _par1; std::string _par1;
std::string _par2;
unsigned int _settings; unsigned int _settings;
std::string msg(bool code) const; std::string msg(bool code) const;
public: 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);
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 ALL = 1;
static const unsigned int STYLE = 2; static const unsigned int STYLE = 2;
@ -52,16 +55,17 @@ int main()
// checkclass.cpp.. // checkclass.cpp..
err.push_back(Message("noConstructor", Message::STYLE, "The class '%1' has no constructor", "classname")); 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.. // checkmemoryleak.cpp..
err.push_back(Message("memleak", 0, "Memory leak: %1", "varname")); err.push_back(Message("memleak", 0, "Memory leak: %1", "varname"));
err.push_back(Message("resourceLeak", 0, "Resource leak: %1", "varname")); err.push_back(Message("resourceLeak", 0, "Resource leak: %1", "varname"));
// checkother.cpp.. // checkother.cpp..
err.push_back(Message("cstyleCast", Message::STYLE, "C-style pointer casting", "")); 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("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("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("dangerousUsageStrtol", 0, "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36"));
// Generate code.. // Generate code..
std::cout << "Generate code.." << std::endl; 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) 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 std::string Message::msg(bool code) const
{ {
const char *str = code ? "\"" : ""; const char *str = code ? "\"" : "";
std::string ret(str + _msg + str); std::string ret(str + _msg + str);
if (! _par1.empty()) if (! _par1.empty())
{ {
std::string::size_type pos = 0; std::string::size_type pos = 0;
@ -141,6 +154,20 @@ std::string Message::msg(bool code) const
ret.insert(pos, _par1); 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; return ret;
} }
@ -150,6 +177,8 @@ void Message::generateCode(std::ostream &ostr) const
ostr << " static std::string " << _funcname << "(const Tokenizer *tokenizer, const Token *Location"; ostr << " static std::string " << _funcname << "(const Tokenizer *tokenizer, const Token *Location";
if (! _par1.empty()) if (! _par1.empty())
ostr << ", const std::string &" << _par1; ostr << ", const std::string &" << _par1;
if (! _par2.empty())
ostr << ", const std::string &" << _par2;
ostr << ")\n"; ostr << ")\n";
ostr << " {\n"; ostr << " {\n";
ostr << " return msg1(tokenizer, Location) + " << msg(true) << ";\n"; ostr << " return msg1(tokenizer, Location) + " << msg(true) << ";\n";