From 9f386d305adbe140c9716b05b5a351b40def10de Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Fri, 6 Apr 2018 01:53:05 -0400 Subject: [PATCH] Fixed #8280 (False positive uninitMemberVar - initialized from nested overloaded function) (#1151) --- lib/symboldatabase.cpp | 19 +++++++++++++++++++ test/testsymboldatabase.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index e0178d139..14b7318b6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4078,6 +4078,25 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const checkVariableCallMatch(callarg, funcarg, same, fallback1, fallback2); } + // check for a match with refrence of a variable + else if (Token::Match(arguments[j], "* %var% ,|)")) { + const Variable * callarg = check->getVariableFromVarId(arguments[j]->next()->varId()); + if (callarg) { + const bool funcargref = (funcarg->typeEndToken()->str() == "&"); + if (funcargref && + (callarg->typeStartToken()->str() == funcarg->typeStartToken()->str() && + callarg->typeStartToken()->isUnsigned() == funcarg->typeStartToken()->isUnsigned() && + callarg->typeStartToken()->isLong() == funcarg->typeStartToken()->isLong())) { + same++; + } else { + // can't match so remove this function from possible matches + matches.erase(matches.begin() + i); + erased = true; + break; + } + } + } + // check for a match with address of a variable else if (Token::Match(arguments[j], "& %var% ,|)")) { const Variable * callarg = check->getVariableFromVarId(arguments[j]->next()->varId()); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index efef3df51..cd047b991 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -306,6 +306,7 @@ private: TEST_CASE(findFunction17); TEST_CASE(findFunction18); TEST_CASE(findFunction19); + TEST_CASE(findFunction20); // #8280 TEST_CASE(noexceptFunction1); TEST_CASE(noexceptFunction2); @@ -4015,6 +4016,35 @@ private: ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 16); } + void findFunction20() { // # 8280 + GET_SYMBOL_DB("class Foo {\n" + "public:\n" + " Foo() : _x(0), _y(0) {}\n" + " Foo(const Foo& f) {\n" + " copy(&f);\n" + " }\n" + " void copy(const Foo* f) {\n" + " _x=f->_x;\n" + " copy(*f);\n" + " }\n" + "private:\n" + " void copy(const Foo& f) {\n" + " _y=f._y;\n" + " }\n" + " int _x;\n" + " int _y;\n" + "};"); + + ASSERT_EQUALS("", errout.str()); + + const Token *f = Token::findsimplematch(tokenizer.tokens(), "copy ( & f ) ;"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 7); + + f = Token::findsimplematch(tokenizer.tokens(), "copy ( * f ) ;"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 12); + + } + #define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \ ASSERT_EQUALS(true, x != nullptr); \ if (x) ASSERT_EQUALS(true, x->isNoExcept());