code cleanup and add more tests to CheckClass::noMemset()

This commit is contained in:
Robert Reif 2011-02-24 19:59:50 -05:00
parent 51eee5f3a7
commit f596a6959e
3 changed files with 125 additions and 29 deletions

View File

@ -717,7 +717,7 @@ void CheckClass::noMemset()
unsigned int varid = tok->tokAt(3)->varId();
for (const Token *lookback = tok->previous(); lookback; lookback = lookback->previous())
{
if (Token::Match(lookback, "%type% %varid%",varid))
if (Token::Match(lookback, "%type% %varid%", varid))
{
type = lookback->str();
break;
@ -731,7 +731,14 @@ void CheckClass::noMemset()
// Warn if type is a class or struct that contains any std::* variables
const std::string pattern2(std::string("struct|class ") + type + " {");
for (const Token *tstruct = Token::findmatch(_tokenizer->tokens(), pattern2.c_str()); tstruct; tstruct = tstruct->next())
const Token *tstruct = Token::findmatch(_tokenizer->tokens(), pattern2.c_str());
if (!tstruct)
continue;
const std::string &typeName = tstruct->str();
for (; tstruct; tstruct = tstruct->next())
{
if (tstruct->str() == "}")
break;
@ -751,7 +758,7 @@ void CheckClass::noMemset()
tstruct->str().find(":") != std::string::npos)
{
if (Token::Match(tstruct->next(), "std :: %type% %var% ;"))
memsetStructError(tok, tok->str(), tstruct->strAt(3));
memsetError(tok, tok->str(), tstruct->strAt(3), typeName);
else if (Token::Match(tstruct->next(), "std :: %type% <"))
{
@ -779,21 +786,16 @@ void CheckClass::noMemset()
// found error => report
if (Token::Match(tstruct, "> %var% ;"))
memsetStructError(tok, tok->str(), typestr);
memsetError(tok, tok->str(), typestr, typeName);
}
}
}
}
}
void CheckClass::memsetClassError(const Token *tok, const std::string &memfunc)
void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type)
{
reportError(tok, Severity::error, "memsetClass", "Using '" + memfunc + "' on class");
}
void CheckClass::memsetStructError(const Token *tok, const std::string &memfunc, const std::string &classname)
{
reportError(tok, Severity::error, "memsetStruct", "Using '" + memfunc + "' on struct that contains a 'std::" + classname + "'");
reportError(tok, Severity::error, "memsetClass", "Using '" + memfunc + "' on " + type + " that contains a 'std::" + classname + "'");
}
//---------------------------------------------------------------------------

View File

@ -117,8 +117,7 @@ private:
void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname);
void operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname);
void unusedPrivateFunctionError(const Token *tok, const std::string &classname, const std::string &funcname);
void memsetClassError(const Token *tok, const std::string &memfunc);
void memsetStructError(const Token *tok, const std::string &memfunc, const std::string &classname);
void memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type);
void operatorEqReturnError(const Token *tok);
void virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived);
void thisSubtractionError(const Token *tok);
@ -134,8 +133,7 @@ private:
c.uninitVarError(0, "classname", "varname");
c.operatorEqVarError(0, "classname", "");
c.unusedPrivateFunctionError(0, "classname", "funcname");
c.memsetClassError(0, "memfunc");
c.memsetStructError(0, "memfunc", "classname");
c.memsetError(0, "memfunc", "classname", "class");
c.operatorEqReturnError(0);
//c.virtualDestructorError(0, "Base", "Derived");
c.thisSubtractionError(0);

View File

@ -2908,7 +2908,52 @@ private:
void memsetOnClass()
{
checkNoMemset("class A\n"
checkNoMemset("class Fred\n"
"{\n"
"};\n"
"void f()\n"
"{\n"
" Fred fred;\n"
" memset(&fred, 0, sizeof(Fred));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
checkNoMemset("class Fred\n"
"{\n"
" std::string b; \n"
"};\n"
"void f()\n"
"{\n"
" Fred fred;\n"
" memset(&fred, 0, sizeof(Fred));\n"
"}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Using 'memset' on class that contains a 'std::string'\n", errout.str());
checkNoMemset("class Fred\n"
"{\n"
"};\n"
"void f()\n"
"{\n"
" Fred fred;\n"
" memset(&fred, 0, sizeof(fred));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
checkNoMemset("class Fred\n"
"{\n"
" std::string s;\n"
"};\n"
"void f()\n"
"{\n"
" Fred fred;\n"
" memset(&fred, 0, sizeof(fred));\n"
"}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Using 'memset' on class that contains a 'std::string'\n", errout.str());
}
void memsetOnStruct()
{
checkNoMemset("struct A\n"
"{\n"
"};\n"
"void f()\n"
@ -2918,6 +2963,16 @@ private:
"}\n");
ASSERT_EQUALS("", errout.str());
checkNoMemset("struct A\n"
"{\n"
"};\n"
"void f()\n"
"{\n"
" struct A a;\n"
" memset(&a, 0, sizeof(struct A));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
checkNoMemset("struct A\n"
"{\n"
"};\n"
@ -2927,17 +2982,8 @@ private:
" memset(&a, 0, sizeof(A));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void memsetOnStruct()
{
checkNoMemset("class A\n"
"{\n"
" void g( struct sockaddr_in6& a);\n"
"private:\n"
" std::string b; \n"
"};\n"
"void f()\n"
checkNoMemset("void f()\n"
"{\n"
" struct sockaddr_in6 fail;\n"
" memset(&fail, 0, sizeof(struct sockaddr_in6));\n"
@ -2971,13 +3017,63 @@ private:
void memsetVector()
{
checkNoMemset("class A\n"
"{ std::vector<int> ints; }\n"
"\n"
"void f()\n"
"{\n"
" A a;\n"
" memset(&a, 0, sizeof(A));\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on class that contains a 'std::vector'\n", errout.str());
checkNoMemset("struct A\n"
"{ std::vector<int> ints; }\n"
"\n"
"void f()\n"
"{\n"
" A a;\n"
" memset(a, 0, sizeof(A));\n"
" memset(&a, 0, sizeof(A));\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'\n", errout.str());
checkNoMemset("struct A\n"
"{ std::vector<int> ints; }\n"
"\n"
"void f()\n"
"{\n"
" A a;\n"
" memset(&a, 0, sizeof(struct A));\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'\n", errout.str());
checkNoMemset("struct A\n"
"{ std::vector<int> ints; }\n"
"\n"
"void f()\n"
"{\n"
" A a;\n"
" memset(&a, 0, sizeof(a));\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'\n", errout.str());
checkNoMemset("class A\n"
"{ std::vector< std::vector<int> > ints; }\n"
"\n"
"void f()\n"
"{\n"
" A a;\n"
" memset(&a, 0, sizeof(A));\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on class that contains a 'std::vector'\n", errout.str());
checkNoMemset("struct A\n"
"{ std::vector< std::vector<int> > ints; }\n"
"\n"
"void f()\n"
"{\n"
" A a;\n"
" memset(&a, 0, sizeof(A));\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'\n", errout.str());
@ -2987,7 +3083,7 @@ private:
"void f()\n"
"{\n"
" A a;\n"
" memset(a, 0, sizeof(A));\n"
" memset(&a, 0, sizeof(a));\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'\n", errout.str());
@ -2997,7 +3093,7 @@ private:
"void f()\n"
"{\n"
" A a;\n"
" memset(a, 0, sizeof(A));\n"
" memset(&a, 0, sizeof(A));\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'\n", errout.str());
}