Fixed #4461 (Warn about memset/memcpy on class with references as members)

This commit is contained in:
Alexander Mai 2014-03-15 18:22:29 +01:00 committed by Daniel Marjamäki
parent 894a65b0b1
commit 40ddcabab6
3 changed files with 38 additions and 9 deletions

View File

@ -1044,8 +1044,12 @@ void CheckClass::checkMemsetType(const Scope *start, const Token *tok, const Sco
std::list<Variable>::const_iterator var; std::list<Variable>::const_iterator var;
for (var = type->varlist.begin(); var != type->varlist.end(); ++var) { for (var = type->varlist.begin(); var != type->varlist.end(); ++var) {
if (var->isReference()) {
memsetErrorReference(tok, tok->str(), type->classDef->str());
continue;
}
// don't warn if variable static or const, pointer or reference // don't warn if variable static or const, pointer or reference
if (!var->isStatic() && !var->isConst() && !var->isPointer() && !var->isReference()) { if (!var->isStatic() && !var->isConst() && !var->isPointer()) {
const Token *tok1 = var->typeStartToken(); const Token *tok1 = var->typeStartToken();
const Scope *typeScope = var->typeScope(); const Scope *typeScope = var->typeScope();
@ -1090,6 +1094,12 @@ void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const
reportError(tok, Severity::error, "memsetClass", "Using '" + memfunc + "' on " + type + " that contains a " + classname + "."); reportError(tok, Severity::error, "memsetClass", "Using '" + memfunc + "' on " + type + " that contains a " + classname + ".");
} }
void CheckClass::memsetErrorReference(const Token *tok, const std::string &memfunc, const std::string &type)
{
reportError(tok, Severity::error, "memsetClass", "Using '" + memfunc + "' on " + type + " that contains a reference.");
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// ClassCheck: "void operator=(" and "const type & operator=(" // ClassCheck: "void operator=(" and "const type & operator=("
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1266,7 +1276,7 @@ void CheckClass::operatorEqToSelf()
} }
} }
bool CheckClass::hasAllocation(const Function *func, const Scope* scope) bool CheckClass::hasAllocation(const Function *func, const Scope* scope) const
{ {
// This function is called when no simple check was found for assignment // This function is called when no simple check was found for assignment
// to self. We are currently looking for: // to self. We are currently looking for:
@ -1573,7 +1583,7 @@ void CheckClass::checkConst()
} }
} }
bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const
{ {
bool again = false; bool again = false;
@ -1661,7 +1671,7 @@ static unsigned int countMinArgs(const Token* argList)
return count; return count;
} }
bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const
{ {
unsigned int args = countParameters(tok); unsigned int args = countParameters(tok);
@ -1691,7 +1701,7 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok)
return false; return false;
} }
bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) const
{ {
unsigned int args = countParameters(tok); unsigned int args = countParameters(tok);

View File

@ -139,6 +139,7 @@ private:
void operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive); void operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive);
void unusedPrivateFunctionError(const Token *tok, const std::string &classname, const std::string &funcname); void unusedPrivateFunctionError(const Token *tok, const std::string &classname, const std::string &funcname);
void memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type); void memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type);
void memsetErrorReference(const Token *tok, const std::string &memfunc, const std::string &type);
void mallocOnClassError(const Token* tok, const std::string &memfunc, const Token* classTok, const std::string &classname); void mallocOnClassError(const Token* tok, const std::string &memfunc, const Token* classTok, const std::string &classname);
void mallocOnClassWarning(const Token* tok, const std::string &memfunc, const Token* classTok); void mallocOnClassWarning(const Token* tok, const std::string &memfunc, const Token* classTok);
void operatorEqReturnError(const Token *tok, const std::string &className); void operatorEqReturnError(const Token *tok, const std::string &className);
@ -205,13 +206,13 @@ private:
void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last); void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last);
// operatorEqToSelf helper functions // operatorEqToSelf helper functions
bool hasAllocation(const Function *func, const Scope* scope); bool hasAllocation(const Function *func, const Scope* scope) const;
static bool hasAssignSelf(const Function *func, const Token *rhs); static bool hasAssignSelf(const Function *func, const Token *rhs);
// checkConst helper functions // checkConst helper functions
bool isMemberVar(const Scope *scope, const Token *tok); bool isMemberVar(const Scope *scope, const Token *tok) const;
bool isMemberFunc(const Scope *scope, const Token *tok); bool isMemberFunc(const Scope *scope, const Token *tok) const;
bool isConstMemberFunc(const Scope *scope, const Token *tok); bool isConstMemberFunc(const Scope *scope, const Token *tok) const;
bool checkConstFunc(const Scope *scope, const Function *func, bool& memberAccessed); bool checkConstFunc(const Scope *scope, const Function *func, bool& memberAccessed);
// constructors helper function // constructors helper function

View File

@ -2284,6 +2284,24 @@ private:
" memset(b,0,4);\n" " memset(b,0,4);\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #4461 Warn about memset/memcpy on class with references as members
checkNoMemset("class A {\n"
" std::string &s;\n"
"};\n"
"void f() {\n"
" A a;\n"
" memset(&a, 0, sizeof(a)); \n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (error) Using 'memset' on class that contains a reference.\n", errout.str());
checkNoMemset("class A {\n"
" const B&b;\n"
"};\n"
"void f() {\n"
" A a;\n"
" memset(&a, 0, sizeof(a)); \n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (error) Using 'memset' on class that contains a reference.\n", errout.str());
} }
void memsetOnInvalid() { // Ticket #5425 void memsetOnInvalid() { // Ticket #5425