From b40edca62f985c9e74510b52d72429996ec182c8 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Tue, 2 Aug 2016 23:34:11 +0200 Subject: [PATCH] Fixed #7387 (SymbolDatabase: Wrong overloaded function is picked) --- lib/symboldatabase.cpp | 19 +++++++++++++++++++ test/testsymboldatabase.cpp | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4014d885e..d8369171c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3630,6 +3630,25 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const } } + // 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()); + if (callarg) { + if (funcarg->typeEndToken()->str() == "*" && + (funcarg->typeStartToken()->str() == "void" || + (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 a numeric literal else if (Token::Match(arguments[j], "%num% ,|)")) { if (MathLib::isInt(arguments[j]->str())) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 4bb8cc9f5..e9d28dd43 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -296,8 +296,9 @@ private: TEST_CASE(valuetype); - TEST_CASE(variadic); // # 7453 - TEST_CASE(variadic2); + TEST_CASE(variadic1); // #7453 + TEST_CASE(variadic2); // #7649 + TEST_CASE(variadic3); // #7387 } void array() { @@ -3720,7 +3721,7 @@ private: } } - void variadic() { // #7453 + void variadic1() { // #7453 { GET_SYMBOL_DB("CBase* create(const char *c1, ...);\n" "int create(COther& ot, const char *c1, ...);\n" @@ -3751,7 +3752,7 @@ private: } } - void variadic2() { + void variadic2() { // #7649 { GET_SYMBOL_DB("CBase* create(const char *c1, ...);\n" "CBase* create(const wchar_t *c1, ...);\n" @@ -3781,6 +3782,33 @@ private: ASSERT_EQUALS(true, db && f && f->tokAt(2) && f->tokAt(2)->function() && f->tokAt(2)->function()->tokenDef->linenr() == 1); } } + + void variadic3() { // #7387 + { + GET_SYMBOL_DB("int zdcalc(const XYZ & per, short rs = 0);\n" + "double zdcalc(long& length, const XYZ * per);\n" + "long mycalc( ) {\n" + " long length;\n" + " XYZ per;\n" + " zdcalc(length, &per);\n" + "}"); + + const Token *f = Token::findsimplematch(tokenizer.tokens(), "zdcalc ( length"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 2); + } + { + GET_SYMBOL_DB("double zdcalc(long& length, const XYZ * per);\n" + "int zdcalc(const XYZ & per, short rs = 0);\n" + "long mycalc( ) {\n" + " long length;\n" + " XYZ per;\n" + " zdcalc(length, &per);\n" + "}"); + + const Token *f = Token::findsimplematch(tokenizer.tokens(), "zdcalc ( length"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 1); + } + } }; REGISTER_TEST(TestSymbolDatabase)