diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index e2efc7f79..3e9088dda 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1682,53 +1682,10 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const return false; } -static unsigned int countParameters(const Token *tok) -{ - tok = tok->tokAt(2); - if (tok->str() == ")") - return 0; - - unsigned int numpar = 1; - while (nullptr != (tok = tok->nextArgument())) - numpar++; - - return numpar; -} - -static unsigned int countMinArgs(const Token* argList) -{ - if (!argList) - return 0; - - argList = argList->next(); - if (argList->str() == ")") - return 0; - - unsigned int count = 1; - for (; argList; argList = argList->next()) { - if (argList->link() && Token::Match(argList, "(|[|{|<")) - argList = argList->link(); - else if (argList->str() == ",") - count++; - else if (argList->str() == "=") - return count-1; - else if (argList->str() == ")") - break; - } - return count; -} - bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const { - unsigned int args = countParameters(tok); - - for (std::list::const_iterator func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { - /** @todo we need to look at the argument types when there are overloaded functions - * with the same number of arguments */ - if (func->tokenDef->str() == tok->str() && (func->argCount() == args || (func->argCount() > args && countMinArgs(func->argDef) <= args))) { - return !func->isStatic; - } - } + if (tok->function() && tok->function()->nestedIn == scope) + return !tok->function()->isStatic; // not found in this class if (!scope->definedType->derivedFrom.empty()) { @@ -1750,25 +1707,8 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) const { - unsigned int args = countParameters(tok); - - std::list::const_iterator func; - unsigned int matches = 0; - unsigned int consts = 0; - - for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { - /** @todo we need to look at the argument types when there are overloaded functions - * with the same number of arguments */ - if (func->tokenDef->str() == tok->str() && (func->argCount() == args || (func->argCount() > args && countMinArgs(func->argDef) <= args))) { - matches++; - if (func->isConst) - consts++; - } - } - - // if there are multiple matches that are all const, return const - if (matches > 0 && matches == consts) - return true; + if (tok->function() && tok->function()->nestedIn == scope) + return tok->function()->isConst; // not found in this class if (!scope->definedType->derivedFrom.empty()) { diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 43678633f..729195b1f 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2961,9 +2961,9 @@ void Scope::findFunctionInBase(const Token * tok, size_t args, std::vectorstr() == "&" && funcarg && funcarg->isReference()) { // can't match so remove this function from possible matches - matches.erase(matches.begin() + i--); + matches.erase(matches.begin() + i); + erased = true; break; } } // check if all arguments matched if (same == args) { - // found a match - return func; + // get the function this call is in + const Scope * scope = tok->scope(); + + // check if this function is a member function + if (scope && scope->functionOf && scope->functionOf->isClassOrStruct()) { + // check if isConst match + if (scope->function && scope->function->isConst == func->isConst) + return func; + } else + return func; } + + if (!erased) + ++i; } // no exact match so just return first function found diff --git a/test/testclass.cpp b/test/testclass.cpp index b8efb9f8d..a38cbd4c8 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -4825,7 +4825,7 @@ private: " void set(const Key& key) {\n" " inherited::set(inherited::Key(key));\n" " }\n" - "};\n"); + "};\n", 0, false); ASSERT_EQUALS("", errout.str()); } diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 33fc8bcc7..eb08d9c02 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -136,6 +136,7 @@ private: TEST_CASE(uninitVar26); TEST_CASE(uninitVar27); // ticket #5170 - rtl::math::setNan(&d) TEST_CASE(uninitVar28); // ticket #6258 + TEST_CASE(uninitVar29); TEST_CASE(uninitVarEnum); TEST_CASE(uninitVarStream); TEST_CASE(uninitVarTypedef); @@ -2126,6 +2127,39 @@ private: ASSERT_EQUALS("", errout.str()); } + void uninitVar29() { + check("class A {\n" + " int i;\n" + "public:\n" + " A() { foo(); }\n" + " void foo() const { };\n" + " void foo() { i = 0; }\n" + "};\n" + "class B {\n" + " int i;\n" + "public:\n" + " B() { foo(); }\n" + " void foo() { i = 0; }\n" + " void foo() const { }\n" + "};\n" + "class C {\n" + " int i;\n" + "public:\n" + " C() { foo(); }\n" + " void foo() const { i = 0; }\n" + " void foo() { }\n" + "};\n" + "class D {\n" + " int i;\n" + "public:\n" + " D() { foo(); }\n" + " void foo() { }\n" + " void foo() const { i = 0; }\n" + "};"); + ASSERT_EQUALS("[test.cpp:18]: (warning) Member variable 'C::i' is not initialized in the constructor.\n" + "[test.cpp:25]: (warning) Member variable 'D::i' is not initialized in the constructor.\n", errout.str()); + } + void uninitVarArray1() { check("class John\n" "{\n"