Warn about memset(this, 0, sizeof(*this)); (#1285)
This commit is contained in:
parent
167e11b645
commit
711d0d7a33
|
@ -797,6 +797,16 @@ void CheckClass::unusedPrivateFunctionError(const Token *tok, const std::string
|
||||||
// ClassCheck: Check that memset is not used on classes
|
// ClassCheck: Check that memset is not used on classes
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Scope* findFunctionOf(const Scope* scope)
|
||||||
|
{
|
||||||
|
while (scope) {
|
||||||
|
if (scope->type == Scope::eFunction)
|
||||||
|
return scope->functionOf;
|
||||||
|
scope = scope->nestedIn;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CheckClass::noMemset()
|
void CheckClass::noMemset()
|
||||||
{
|
{
|
||||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||||
|
@ -813,27 +823,30 @@ void CheckClass::noMemset()
|
||||||
arg3 = arg3->nextArgument();
|
arg3 = arg3->nextArgument();
|
||||||
|
|
||||||
const Token *typeTok = 0;
|
const Token *typeTok = 0;
|
||||||
|
const Scope *type = 0;
|
||||||
if (Token::Match(arg3, "sizeof ( %type% ) )"))
|
if (Token::Match(arg3, "sizeof ( %type% ) )"))
|
||||||
typeTok = arg3->tokAt(2);
|
typeTok = arg3->tokAt(2);
|
||||||
else if (Token::Match(arg3, "sizeof ( %type% :: %type% ) )"))
|
else if (Token::Match(arg3, "sizeof ( %type% :: %type% ) )"))
|
||||||
typeTok = arg3->tokAt(4);
|
typeTok = arg3->tokAt(4);
|
||||||
else if (Token::Match(arg3, "sizeof ( struct %type% ) )"))
|
else if (Token::Match(arg3, "sizeof ( struct %type% ) )"))
|
||||||
typeTok = arg3->tokAt(3);
|
typeTok = arg3->tokAt(3);
|
||||||
else if (Token::Match(arg1, "&| %var% ,")) {
|
else if (Token::simpleMatch(arg3, "sizeof ( * this ) )") || Token::simpleMatch(arg1, "this ,")) {
|
||||||
|
type = findFunctionOf(arg3->scope());
|
||||||
|
} else if (Token::Match(arg1, "&| %var% ,")) {
|
||||||
const Variable *var = arg1->str() == "&" ? arg1->next()->variable() : arg1->variable();
|
const Variable *var = arg1->str() == "&" ? arg1->next()->variable() : arg1->variable();
|
||||||
if (var && (var->typeStartToken() == var->typeEndToken() || Token::Match(var->typeStartToken(), "%type% :: %type%"))
|
if (var && (arg1->str() == "&" || var->isPointer() || var->isArray()))
|
||||||
&& (arg1->str() == "&" || var->isPointer() || var->isArray()))
|
type = var->type();
|
||||||
typeTok = var->typeEndToken();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No type defined => The tokens didn't match
|
// No type defined => The tokens didn't match
|
||||||
if (!typeTok)
|
if (!typeTok && !type)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (typeTok->str() == "(")
|
if (typeTok && typeTok->str() == "(")
|
||||||
typeTok = typeTok->next();
|
typeTok = typeTok->next();
|
||||||
|
|
||||||
const Scope *type = symbolDatabase->findVariableType(&(*scope), typeTok);
|
if (!type)
|
||||||
|
type = symbolDatabase->findVariableType(&(*scope), typeTok);
|
||||||
|
|
||||||
if (type)
|
if (type)
|
||||||
checkMemsetType(&(*scope), tok, type);
|
checkMemsetType(&(*scope), tok, type);
|
||||||
|
|
|
@ -2014,6 +2014,15 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:8]: (error) Using 'memset' on class that contains a 'std::string'.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:8]: (error) Using 'memset' on class that contains a 'std::string'.\n", errout.str());
|
||||||
|
|
||||||
|
checkNoMemset("class Fred {\n"
|
||||||
|
" std::string b;\n"
|
||||||
|
" void f();\n"
|
||||||
|
"};\n"
|
||||||
|
"void Fred::f() {\n"
|
||||||
|
" memset(this, 0, sizeof(*this));\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:6]: (error) Using 'memset' on class that contains a 'std::string'.\n", errout.str());
|
||||||
|
|
||||||
checkNoMemset("class Fred\n"
|
checkNoMemset("class Fred\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
|
|
Loading…
Reference in New Issue