Class: Show inconclusive warnings about unknown types that are not initialized in copy constructors. Ticket: #3611
This commit is contained in:
parent
07db469c06
commit
de8e592d00
|
@ -107,6 +107,8 @@ void CheckClass::constructors()
|
|||
std::list<Variable>::const_iterator var;
|
||||
unsigned int count = 0;
|
||||
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count) {
|
||||
bool inconclusive = false;
|
||||
|
||||
if (usage[count].assign || usage[count].init || var->isStatic())
|
||||
continue;
|
||||
|
||||
|
@ -131,12 +133,18 @@ void CheckClass::constructors()
|
|||
|
||||
// Don't warn about unknown types in copy constructors since we
|
||||
// don't know if they can be copied or not..
|
||||
if (!var->isPointer() && !var->isClass() && (func->type == Function::eCopyConstructor || func->type == Function::eOperatorEqual)) {
|
||||
if (!var->isPointer() &&
|
||||
!(var->type() && var->type()->needInitialization != Scope::True) &&
|
||||
(func->type == Function::eCopyConstructor || func->type == Function::eOperatorEqual)) {
|
||||
bool stdtype = false;
|
||||
for (const Token *type = var->typeStartToken(); type && type->isName(); type = type->next())
|
||||
stdtype |= type->isStandardType();
|
||||
if (!stdtype)
|
||||
continue;
|
||||
if (!stdtype) {
|
||||
if (_settings->inconclusive)
|
||||
inconclusive = true;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// It's non-static and it's not initialized => error
|
||||
|
@ -152,11 +160,11 @@ void CheckClass::constructors()
|
|||
}
|
||||
|
||||
if (classNameUsed)
|
||||
operatorEqVarError(func->token, scope->className, var->name());
|
||||
operatorEqVarError(func->token, scope->className, var->name(), inconclusive);
|
||||
} else if (func->access != Private) {
|
||||
const Scope *varType = var->type();
|
||||
if (!varType || varType->type != Scope::eUnion)
|
||||
uninitVarError(func->token, scope->className, var->name());
|
||||
uninitVarError(func->token, scope->className, var->name(), inconclusive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -593,14 +601,14 @@ void CheckClass::noConstructorError(const Token *tok, const std::string &classna
|
|||
"instanciated. That may cause bugs or undefined behavior.");
|
||||
}
|
||||
|
||||
void CheckClass::uninitVarError(const Token *tok, const std::string &classname, const std::string &varname)
|
||||
void CheckClass::uninitVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive)
|
||||
{
|
||||
reportError(tok, Severity::warning, "uninitMemberVar", "Member variable '" + classname + "::" + varname + "' is not initialized in the constructor.");
|
||||
reportError(tok, Severity::warning, "uninitMemberVar", "Member variable '" + classname + "::" + varname + "' is not initialized in the constructor.", inconclusive);
|
||||
}
|
||||
|
||||
void CheckClass::operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname)
|
||||
void CheckClass::operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive)
|
||||
{
|
||||
reportError(tok, Severity::warning, "operatorEqVarError", "Member variable '" + classname + "::" + varname + "' is not assigned a value in '" + classname + "::operator='.");
|
||||
reportError(tok, Severity::warning, "operatorEqVarError", "Member variable '" + classname + "::" + varname + "' is not assigned a value in '" + classname + "::operator='.", inconclusive);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -126,8 +126,8 @@ private:
|
|||
//void copyConstructorMallocError(const Token *cctor, const Token *alloc, const std::string& var_name);
|
||||
void copyConstructorShallowCopyError(const Token *tok, const std::string& varname);
|
||||
void noCopyConstructorError(const Token *tok, const std::string &classname, bool isStruct);
|
||||
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 uninitVarError(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 memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type);
|
||||
void operatorEqReturnError(const Token *tok, const std::string &className);
|
||||
|
@ -146,8 +146,8 @@ private:
|
|||
//c.copyConstructorMallocError(0, 0, "var");
|
||||
c.copyConstructorShallowCopyError(0, "var");
|
||||
c.noCopyConstructorError(0, "class", false);
|
||||
c.uninitVarError(0, "classname", "varname");
|
||||
c.operatorEqVarError(0, "classname", "");
|
||||
c.uninitVarError(0, "classname", "varname", false);
|
||||
c.operatorEqVarError(0, "classname", "", false);
|
||||
c.unusedPrivateFunctionError(0, "classname", "funcname");
|
||||
c.memsetError(0, "memfunc", "classname", "class");
|
||||
c.operatorEqReturnError(0, "class");
|
||||
|
|
|
@ -77,6 +77,7 @@ private:
|
|||
TEST_CASE(initvar_nested_constructor); // ticket #1375
|
||||
TEST_CASE(initvar_nocopy1); // ticket #2474
|
||||
TEST_CASE(initvar_nocopy2); // ticket #2484
|
||||
TEST_CASE(initvar_nocopy3); // ticket #3611
|
||||
|
||||
TEST_CASE(initvar_destructor); // No variables need to be initialized in a destructor
|
||||
|
||||
|
@ -677,7 +678,7 @@ private:
|
|||
" Fred() { };\n"
|
||||
" Fred(const Fred &) { };\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (warning) Member variable 'Fred::var' is not initialized in the constructor.\n", errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("class Fred\n"
|
||||
"{\n"
|
||||
|
@ -689,7 +690,29 @@ private:
|
|||
"};\n"
|
||||
"Fred::Fred() { };\n"
|
||||
"Fred::Fred(const Fred &) { };\n");
|
||||
ASSERT_EQUALS("[test.cpp:10]: (warning) Member variable 'Fred::var' is not initialized in the constructor.\n", errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("class Fred\n"
|
||||
"{\n"
|
||||
"private:\n"
|
||||
" std::string var;\n"
|
||||
"public:\n"
|
||||
" Fred() { };\n"
|
||||
" Fred(const Fred &) { };\n"
|
||||
"};", true);
|
||||
ASSERT_EQUALS("[test.cpp:7]: (warning, inconclusive) Member variable 'Fred::var' is not initialized in the constructor.\n", errout.str());
|
||||
|
||||
check("class Fred\n"
|
||||
"{\n"
|
||||
"private:\n"
|
||||
" std::string var;\n"
|
||||
"public:\n"
|
||||
" Fred();\n"
|
||||
" Fred(const Fred &);\n"
|
||||
"};\n"
|
||||
"Fred::Fred() { };\n"
|
||||
"Fred::Fred(const Fred &) { };\n", true);
|
||||
ASSERT_EQUALS("[test.cpp:10]: (warning, inconclusive) Member variable 'Fred::var' is not initialized in the constructor.\n", errout.str());
|
||||
}
|
||||
|
||||
void initvar_nested_constructor() { // ticket #1375
|
||||
|
@ -823,8 +846,7 @@ private:
|
|||
" A(const A&){}\n"
|
||||
" const A& operator=(const A&){return *this;}\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (warning) Member variable 'A::m_SemVar' is not initialized in the constructor.\n"
|
||||
"[test.cpp:7]: (warning) Member variable 'A::m_SemVar' is not assigned a value in 'A::operator='.\n", errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void initvar_nocopy2() { // ticket #2484
|
||||
|
@ -868,6 +890,13 @@ private:
|
|||
" A(const A& rhs) {}\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("struct A {\n"
|
||||
" B b;\n"
|
||||
" A() {}\n"
|
||||
" A(const A& rhs) {}\n"
|
||||
"};", true);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) Member variable 'A::b' is not initialized in the constructor.\n", errout.str());
|
||||
}
|
||||
|
||||
void initvar_destructor() {
|
||||
|
@ -897,7 +926,7 @@ private:
|
|||
"\n"
|
||||
"void Fred::operator=(const Fred &f)\n"
|
||||
"{ }", true);
|
||||
ASSERT_EQUALS("[test.cpp:13]: (warning) Member variable 'Fred::ints' is not assigned a value in 'Fred::operator='.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:13]: (warning, inconclusive) Member variable 'Fred::ints' is not assigned a value in 'Fred::operator='.\n", errout.str());
|
||||
}
|
||||
|
||||
void uninitVar1() {
|
||||
|
|
Loading…
Reference in New Issue