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;
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue