diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 067e587d8..17bfbf9c0 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -367,6 +367,9 @@ void CheckClass::initializeVarList(const Function &func, std::list if (level == 0 && Token::Match(ftok, "%var% (")) { if (ftok->strAt(2) != ")") initVar(ftok->str(), scope, usage); + } else if (level == 0 && Token::Match(ftok, "%var% {")) { + initVar(ftok->str(), scope, usage); + ftok = ftok->linkAt(1); } else if (level != 0 && Token::Match(ftok, "%var% =")) // assignment in the initializer: var(value = x) assignVar(ftok->str(), scope, usage); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index ff7952544..ac56a7cd6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -916,7 +916,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const tok->strAt(-1) == "::" || tok->strAt(-1) == "~" || // or a scope qualifier in front of tok outerScope->isClassOrStruct()) && // or a ctor/dtor (Token::Match(tok->next()->link(), ") const| ;|{|=") || - Token::Match(tok->next()->link(), ") : ::| %var% (|::"))) { + Token::Match(tok->next()->link(), ") : ::| %var% (|::|<|{"))) { *funcStart = tok; *argStart = tok->next(); return true; @@ -1251,8 +1251,8 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok) Scope *new_scope = &scopeList.back(); // skip to start of function - while (tok1 && tok1->str() != "{") { - if (tok1->str() == "(") + while (tok1 && ((tok1->str() != "{") || (tok1->previous() && tok1->previous()->isName() && tok1->strAt(-1) != "const"))) { + if (tok1->str() == "(" || tok1->str() == "{") tok1 = tok1->link(); tok1 = tok1->next(); } diff --git a/test/testclass.cpp b/test/testclass.cpp index aa02a1cb1..338694b87 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -53,6 +53,7 @@ private: TEST_CASE(noConstructor6); // ticket #4386 TEST_CASE(noConstructor7); // ticket #4391 TEST_CASE(noConstructor8); // ticket #4404 + TEST_CASE(noConstructor9); // ticket #4419 TEST_CASE(operatorEq1); TEST_CASE(operatorEq2); @@ -1913,6 +1914,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void noConstructor9() { + // ticket #4419 + checkNoConstructor("class CGreeting : public CGreetingBase {\n" + "public:\n" + " CGreeting() : CGreetingBase(), MessageSet(false) {}\n" + "private:\n" + " bool MessageSet;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + } + void checkNoMemset(const char code[]) { // Clear the error log errout.str(""); diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 17988607b..5c12a860c 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -124,7 +124,8 @@ private: TEST_CASE(uninitVarArray8); TEST_CASE(uninitVarArray2D); TEST_CASE(uninitVarArray3D); - TEST_CASE(uninitVarCpp11Init); + TEST_CASE(uninitVarCpp11Init1); + TEST_CASE(uninitVarCpp11Init2); TEST_CASE(uninitVarStruct1); // ticket #2172 TEST_CASE(uninitVarStruct2); // ticket #838 TEST_CASE(uninitVarUnion1); // ticket #3196 @@ -1814,7 +1815,7 @@ private: ASSERT_EQUALS("", errout.str()); } - void uninitVarCpp11Init() { + void uninitVarCpp11Init1() { check("class Foo {\n" " std::vector bar;\n" "public:\n" @@ -1825,6 +1826,20 @@ private: ASSERT_EQUALS("", errout.str()); } + void uninitVarCpp11Init2() { + check("class Fred {\n" + " struct Foo {\n" + " int a;\n" + " bool b;\n" + " };\n" + " Foo f;\n" + " float g;\n" + "public:\n" + " Fred() : f{0, true} { }\n" + "};"); + ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'Fred::g' is not initialized in the constructor.\n", errout.str()); + } + void uninitVarStruct1() { // ticket #2172 check("class A\n" "{\n"