SymbolDatabase: Overload matching with character literals as argument

This commit is contained in:
PKEuS 2017-02-28 22:08:18 +01:00
parent 841e0c2921
commit 942644fde6
2 changed files with 54 additions and 6 deletions

View File

@ -3765,9 +3765,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
const Function * func = matches[i]; const Function * func = matches[i];
size_t same = 0; size_t same = 0;
if (requireConst && func->isConst()) if (!requireConst || !func->isConst()) {
;
else {
// get the function this call is in // get the function this call is in
const Scope * scope = tok->scope(); const Scope * scope = tok->scope();
@ -3888,7 +3886,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
exactMatch = true; exactMatch = true;
} }
} else { } else {
if (Token::Match(funcarg->typeStartToken(), "char|short|int|long")) { if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long")) {
exactMatch = true; exactMatch = true;
} }
} }
@ -3899,7 +3897,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
else else
same++; same++;
else { else {
if (Token::Match(funcarg->typeStartToken(), "char|short|int|long")) if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long"))
fallback1++; fallback1++;
else if (Token::Match(funcarg->typeStartToken(), "float|double")) else if (Token::Match(funcarg->typeStartToken(), "float|double"))
fallback2++; fallback2++;
@ -3928,7 +3926,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
else { else {
if (Token::Match(funcarg->typeStartToken(), "float|double")) if (Token::Match(funcarg->typeStartToken(), "float|double"))
fallback1++; fallback1++;
else if (Token::Match(funcarg->typeStartToken(), "char|short|int|long")) else if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long"))
fallback2++; fallback2++;
} }
} }
@ -3946,6 +3944,16 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
fallback2++; 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 // check that function argument type is not mismatching
else if (arguments[j]->str() == "&" && funcarg && funcarg->isReference()) { else if (arguments[j]->str() == "&" && funcarg && funcarg->isReference()) {
// can't match so remove this function from possible matches // can't match so remove this function from possible matches

View File

@ -283,6 +283,7 @@ private:
TEST_CASE(findFunction12); TEST_CASE(findFunction12);
TEST_CASE(findFunction13); TEST_CASE(findFunction13);
TEST_CASE(findFunction14); TEST_CASE(findFunction14);
TEST_CASE(findFunction15);
TEST_CASE(noexceptFunction1); TEST_CASE(noexceptFunction1);
TEST_CASE(noexceptFunction2); TEST_CASE(noexceptFunction2);
@ -3618,6 +3619,45 @@ private:
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 4); 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()); \ #define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \
ASSERT_EQUALS(true, x != nullptr); \ ASSERT_EQUALS(true, x != nullptr); \
if (x) ASSERT_EQUALS(true, x->isNoExcept()); if (x) ASSERT_EQUALS(true, x->isNoExcept());