From 942644fde6df15fc5de94789ba2626e8e21699d0 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Tue, 28 Feb 2017 22:08:18 +0100 Subject: [PATCH] SymbolDatabase: Overload matching with character literals as argument --- lib/symboldatabase.cpp | 20 +++++++++++++------ test/testsymboldatabase.cpp | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d2318b353..4a681c630 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3765,9 +3765,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const const Function * func = matches[i]; size_t same = 0; - if (requireConst && func->isConst()) - ; - else { + if (!requireConst || !func->isConst()) { // get the function this call is in const Scope * scope = tok->scope(); @@ -3888,7 +3886,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const exactMatch = true; } } else { - if (Token::Match(funcarg->typeStartToken(), "char|short|int|long")) { + if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long")) { exactMatch = true; } } @@ -3899,7 +3897,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const else same++; else { - if (Token::Match(funcarg->typeStartToken(), "char|short|int|long")) + if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long")) fallback1++; else if (Token::Match(funcarg->typeStartToken(), "float|double")) fallback2++; @@ -3928,7 +3926,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const else { if (Token::Match(funcarg->typeStartToken(), "float|double")) fallback1++; - else if (Token::Match(funcarg->typeStartToken(), "char|short|int|long")) + else if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long")) fallback2++; } } @@ -3946,6 +3944,16 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const fallback2++; } + // check for a match with a char literal + else if (Token::Match(arguments[j], "%char% ,|)") && !funcarg->isArrayOrPointer()) { + if (arguments[j]->isLong() && funcarg->typeStartToken()->str() == "wchar_t") + same++; + else if (!arguments[j]->isLong() && funcarg->typeStartToken()->str() == "char") + same++; + else if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long")) + fallback1++; + } + // check that function argument type is not mismatching else if (arguments[j]->str() == "&" && funcarg && funcarg->isReference()) { // can't match so remove this function from possible matches diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 19843ba56..c01575fb3 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -283,6 +283,7 @@ private: TEST_CASE(findFunction12); TEST_CASE(findFunction13); TEST_CASE(findFunction14); + TEST_CASE(findFunction15); TEST_CASE(noexceptFunction1); TEST_CASE(noexceptFunction2); @@ -3618,6 +3619,45 @@ private: ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 4); } + void findFunction15() { + GET_SYMBOL_DB("void foo1(int, char* a) { }\n" + "void foo1(int, char a) { }\n" + "void foo1(int, wchar_t a) { }\n" + "void foo2(int, float a) { }\n" + "void foo2(int, wchar_t a) { }\n" + "void foo3(int, float a) { }\n" + "void foo3(int, char a) { }\n" + "void func() {\n" + " foo1(1, 'c');\n" + " foo1(2, L'c');\n" + " foo2(3, 'c');\n" + " foo2(4, L'c');\n" + " foo3(5, 'c');\n" + " foo3(6, L'c');\n" + "}"); + + ASSERT_EQUALS("", errout.str()); + + const Token *f = Token::findsimplematch(tokenizer.tokens(), "foo1 ( 1"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 2); + + f = Token::findsimplematch(tokenizer.tokens(), "foo1 ( 2"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 3); + + f = Token::findsimplematch(tokenizer.tokens(), "foo2 ( 3"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 5); + + f = Token::findsimplematch(tokenizer.tokens(), "foo2 ( 4"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 5); + + f = Token::findsimplematch(tokenizer.tokens(), "foo3 ( 5"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 7); + + f = Token::findsimplematch(tokenizer.tokens(), "foo3 ( 6"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 7); + } + + #define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \ ASSERT_EQUALS(true, x != nullptr); \ if (x) ASSERT_EQUALS(true, x->isNoExcept());