diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 5d2bdad5c..7bd18ab8a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -598,28 +598,31 @@ void CheckClass::initializeVarList(const Function &func, std::listvarId(), 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) diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 165d1b553..1d3c37a53 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -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;