Uninitialized Member variable: Fixed FP when delegate constructor is used

This commit is contained in:
Daniel Marjamäki 2019-01-10 20:13:37 +01:00
parent fd9ca16e51
commit 8509159d1a
2 changed files with 47 additions and 20 deletions

View File

@ -598,28 +598,31 @@ void CheckClass::initializeVarList(const Function &func, std::list<const Functio
initVar(ftok->varId(), scope, usage);
} else { // c++11 delegate constructor
const Function *member = ftok->function();
// member function found
if (member) {
// recursive call
// assume that all variables are initialized
if (std::find(callstack.begin(), callstack.end(), member) != callstack.end()) {
/** @todo false negative: just bail */
assignAllVar(usage);
return;
}
// member function not found => assume it initializes all members
if (!member) {
assignAllVar(usage);
return;
}
// member function has implementation
if (member->hasBody()) {
// initialize variable use list using member function
callstack.push_back(member);
initializeVarList(*member, callstack, scope, usage);
callstack.pop_back();
}
// recursive call
// assume that all variables are initialized
if (std::find(callstack.begin(), callstack.end(), member) != callstack.end()) {
/** @todo false negative: just bail */
assignAllVar(usage);
return;
}
// there is a called member function, but it has no implementation, so we assume it initializes everything
else {
assignAllVar(usage);
}
// member function has implementation
if (member->hasBody()) {
// initialize variable use list using member function
callstack.push_back(member);
initializeVarList(*member, callstack, scope, usage);
callstack.pop_back();
}
// there is a called member function, but it has no implementation, so we assume it initializes everything
else {
assignAllVar(usage);
}
}
} else if (level != 0 && Token::Match(ftok, "%name% =")) // assignment in the initializer: var(value = x)

View File

@ -96,6 +96,7 @@ private:
TEST_CASE(initvar_staticvar);
TEST_CASE(initvar_union);
TEST_CASE(initvar_delegate); // ticket #4302
TEST_CASE(initvar_delegate2);
TEST_CASE(initvar_private_constructor); // BUG 2354171 - private constructor
TEST_CASE(initvar_copy_constructor); // ticket #1611
@ -1138,6 +1139,29 @@ private:
ASSERT_EQUALS("", errout.str());
}
void initvar_delegate2() {
check("class Foo {\n"
"public:\n"
" explicit Foo(const Bar bar);\n"
" Foo(const std::string& id);\n"
" virtual ~RtpSession() { }\n"
"protected:\n"
" bool a;\n"
" uint16_t b;\n"
"};\n"
"\n"
"Foo::Foo(const Bar var)\n"
" : Foo(bar->getId())\n"
"{\n"
"}\n"
"\n"
"Foo::Foo(const std::string& id)\n"
" : a(true)\n"
" , b(0)\n"
"{\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void initvar_private_constructor() {
settings.standards.cpp = Standards::CPP11;