CheckClass: made warnings about uninitialized members in default constructors inconclusive. Ticket: #4639

This commit is contained in:
Robert Reif 2013-03-09 09:20:48 +01:00 committed by Daniel Marjamäki
parent 1fbef0e4e6
commit 25c36b56fa
4 changed files with 26 additions and 10 deletions

View File

@ -170,8 +170,18 @@ void CheckClass::constructors()
operatorEqVarError(func->token, scope->className, var->name(), inconclusive); operatorEqVarError(func->token, scope->className, var->name(), inconclusive);
} else if (func->access != Private) { } else if (func->access != Private) {
const Scope *varType = var->typeScope(); const Scope *varType = var->typeScope();
if (!varType || varType->type != Scope::eUnion) if (!varType || varType->type != Scope::eUnion) {
uninitVarError(func->token, scope->className, var->name(), inconclusive); if (func->type == Function::eConstructor &&
func->nestedIn && (func->nestedIn->numConstructors - func->nestedIn->numCopyConstructors) > 1 &&
func->argCount() == 0 && func->functionScope &&
func->arg && func->arg->link()->next() == func->functionScope->classStart &&
func->functionScope->classStart->link() == func->functionScope->classStart->next()) {
// don't warn about user defined default constructor when there are other constructors
if (_settings->inconclusive)
uninitVarError(func->token, scope->className, var->name(), true);
} else
uninitVarError(func->token, scope->className, var->name(), inconclusive);
}
} }
} }
} }

View File

@ -421,9 +421,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
function.isConst = true; function.isConst = true;
// count the number of constructors // count the number of constructors
if (function.type == Function::eConstructor || if (function.type == Function::eConstructor)
function.type == Function::eCopyConstructor)
scope->numConstructors++; scope->numConstructors++;
else if (function.type == Function::eCopyConstructor) {
scope->numConstructors++;
scope->numCopyConstructors++;
}
// assume implementation is inline (definition and implementation same) // assume implementation is inline (definition and implementation same)
function.token = function.tokenDef; function.token = function.tokenDef;
@ -1943,6 +1946,7 @@ Scope::Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *
classEnd(start_->link()), classEnd(start_->link()),
nestedIn(nestedIn_), nestedIn(nestedIn_),
numConstructors(0), numConstructors(0),
numCopyConstructors(0),
type(type_), type(type_),
definedType(NULL), definedType(NULL),
functionOf(NULL), functionOf(NULL),
@ -1957,6 +1961,7 @@ Scope::Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *
classEnd(NULL), classEnd(NULL),
nestedIn(nestedIn_), nestedIn(nestedIn_),
numConstructors(0), numConstructors(0),
numCopyConstructors(0),
definedType(NULL), definedType(NULL),
functionOf(NULL), functionOf(NULL),
function(NULL) function(NULL)

View File

@ -519,6 +519,7 @@ public:
const Scope *nestedIn; const Scope *nestedIn;
std::list<Scope *> nestedList; std::list<Scope *> nestedList;
unsigned int numConstructors; unsigned int numConstructors;
unsigned int numCopyConstructors;
std::list<UsingInfo> usingList; std::list<UsingInfo> usingList;
ScopeType type; ScopeType type;
Type* definedType; Type* definedType;

View File

@ -261,8 +261,8 @@ private:
"Fred::Fred(int _i)\n" "Fred::Fred(int _i)\n"
"{\n" "{\n"
" i = _i;\n" " i = _i;\n"
"}\n"); "}\n", true);
ASSERT_EQUALS("[test.cpp:7]: (warning) Member variable 'Fred::i' is not initialized in the constructor.\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (warning, inconclusive) Member variable 'Fred::i' is not initialized in the constructor.\n", errout.str());
} }
void simple5() { // ticket #2560 void simple5() { // ticket #2560
@ -835,9 +835,9 @@ private:
"public:\n" "public:\n"
" A(int n) : A() { }\n" " A(int n) : A() { }\n"
" A() {}\n" " A() {}\n"
"};"); "};", true);
ASSERT_EQUALS("[test.cpp:4]: (warning) Member variable 'A::number' is not initialized in the constructor.\n" ASSERT_EQUALS("[test.cpp:4]: (warning) Member variable 'A::number' is not initialized in the constructor.\n"
"[test.cpp:5]: (warning) Member variable 'A::number' is not initialized in the constructor.\n", errout.str()); "[test.cpp:5]: (warning, inconclusive) Member variable 'A::number' is not initialized in the constructor.\n", errout.str());
check("class A {\n" check("class A {\n"
" int number;\n" " int number;\n"
@ -1781,9 +1781,9 @@ private:
"::Foo::Sub::Sub() { }\n" "::Foo::Sub::Sub() { }\n"
"class Foo;\n" "class Foo;\n"
"class Bar;\n" "class Bar;\n"
"class Sub;\n"); "class Sub;\n", true);
ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'Sub::b' is not initialized in the constructor.\n" ASSERT_EQUALS("[test.cpp:9]: (warning, inconclusive) Member variable 'Sub::b' is not initialized in the constructor.\n"
"[test.cpp:12]: (warning) Member variable 'Sub::b' is not initialized in the constructor.\n" "[test.cpp:12]: (warning) Member variable 'Sub::b' is not initialized in the constructor.\n"
"[test.cpp:20]: (warning) Member variable 'Sub::f' is not initialized in the constructor.\n", errout.str()); "[test.cpp:20]: (warning) Member variable 'Sub::f' is not initialized in the constructor.\n", errout.str());
} }