Fixed #4461 (Warn about memset/memcpy on class with references as members)
This commit is contained in:
parent
894a65b0b1
commit
40ddcabab6
|
@ -1044,8 +1044,12 @@ void CheckClass::checkMemsetType(const Scope *start, const Token *tok, const Sco
|
|||
std::list<Variable>::const_iterator 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
|
||||
if (!var->isStatic() && !var->isConst() && !var->isPointer() && !var->isReference()) {
|
||||
if (!var->isStatic() && !var->isConst() && !var->isPointer()) {
|
||||
const Token *tok1 = var->typeStartToken();
|
||||
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 + ".");
|
||||
}
|
||||
|
||||
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=("
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
// 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;
|
||||
|
||||
|
@ -1661,7 +1671,7 @@ static unsigned int countMinArgs(const Token* argList)
|
|||
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);
|
||||
|
||||
|
@ -1691,7 +1701,7 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok)
|
|||
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);
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ private:
|
|||
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 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 mallocOnClassWarning(const Token* tok, const std::string &memfunc, const Token* classTok);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
// checkConst helper functions
|
||||
bool isMemberVar(const Scope *scope, const Token *tok);
|
||||
bool isMemberFunc(const Scope *scope, const Token *tok);
|
||||
bool isConstMemberFunc(const Scope *scope, const Token *tok);
|
||||
bool isMemberVar(const Scope *scope, const Token *tok) const;
|
||||
bool isMemberFunc(const Scope *scope, const Token *tok) const;
|
||||
bool isConstMemberFunc(const Scope *scope, const Token *tok) const;
|
||||
bool checkConstFunc(const Scope *scope, const Function *func, bool& memberAccessed);
|
||||
|
||||
// constructors helper function
|
||||
|
|
|
@ -2284,6 +2284,24 @@ private:
|
|||
" memset(b,0,4);\n"
|
||||
"}");
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue