SymbolDatabase: Overload matching with boolean literals as argument and with arbitrary null-pointers

This commit is contained in:
PKEuS 2017-02-28 22:43:47 +01:00
parent 942644fde6
commit 85768f1829
2 changed files with 44 additions and 9 deletions

View File

@ -3897,7 +3897,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
else
same++;
else {
if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long"))
if (funcarg->isPointer() || Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long"))
fallback1++;
else if (Token::Match(funcarg->typeStartToken(), "float|double"))
fallback2++;
@ -3945,7 +3945,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
}
// check for a match with a char literal
else if (Token::Match(arguments[j], "%char% ,|)") && !funcarg->isArrayOrPointer()) {
else if (!funcarg->isArrayOrPointer() && Token::Match(arguments[j], "%char% ,|)")) {
if (arguments[j]->isLong() && funcarg->typeStartToken()->str() == "wchar_t")
same++;
else if (!arguments[j]->isLong() && funcarg->typeStartToken()->str() == "char")
@ -3954,6 +3954,19 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
fallback1++;
}
// check for a match with a boolean literal
else if (!funcarg->isArrayOrPointer() && Token::Match(arguments[j], "%bool% ,|)")) {
if (funcarg->typeStartToken()->str() == "bool")
same++;
else if (Token::Match(funcarg->typeStartToken(), "wchar_t|char|short|int|long"))
fallback1++;
}
// check for a match with nullptr
else if (funcarg->isPointer() && Token::Match(arguments[j], "nullptr|NULL ,|)")) {
same++;
}
// 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
@ -3963,17 +3976,16 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
}
}
size_t hasToBe = func->isVariadic() ? (func->argCount() - 1) : args;
// check if all arguments matched
if ((func->isVariadic() && same == (func->argCount() - 1)) ||
(!func->isVariadic() && same == args))
if (same == hasToBe)
return func;
if (!fallback1Func) {
if ((func->isVariadic() && same + fallback1 == (func->argCount() - 1)) ||
(!func->isVariadic() && same + fallback1 == args))
if (same + fallback1 == hasToBe)
fallback1Func = func;
else if (!fallback2Func && ((func->isVariadic() && same + fallback2 + fallback1 == (func->argCount() - 1)) ||
(!func->isVariadic() && same + fallback2 + fallback1 == args)))
else if (!fallback2Func && same + fallback2 + fallback1 == hasToBe)
fallback2Func = func;
}

View File

@ -3538,6 +3538,7 @@ private:
" foo(0);\n"
" foo(0L);\n"
" foo(0.f);\n"
" foo(false);\n"
" foo(bar());\n"
" foo(i);\n"
" foo(f);\n"
@ -3560,6 +3561,9 @@ private:
f = Token::findsimplematch(tokenizer.tokens(), "foo ( 0.f ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 2);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( false ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 3);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( bar ( ) ) ;");
ASSERT_EQUALS(true, f && f->function() == nullptr);
@ -3593,12 +3597,19 @@ private:
"void foo(const int* a) { }\n"
"void foo(void* a) { }\n"
"void foo(const float a) { }\n"
"void func(int* ip, const int* cip, const char* ccp, char* cp, float f) {\n"
"void foo(bool a) { }\n"
"void foo2(Foo* a) { }\n"
"void foo2(Foo a) { }\n"
"void func(int* ip, const int* cip, const char* ccp, char* cp, float f, bool b) {\n"
" foo(ip);\n"
" foo(cip);\n"
" foo(cp);\n"
" foo(ccp);\n"
" foo(f);\n"
" foo(b);\n"
" foo2(0);\n"
" foo2(nullptr);\n"
" foo2(NULL);\n"
"}");
ASSERT_EQUALS("", errout.str());
@ -3617,6 +3628,18 @@ private:
f = Token::findsimplematch(tokenizer.tokens(), "foo ( f ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 4);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( b ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 5);
f = Token::findsimplematch(tokenizer.tokens(), "foo2 ( 0 ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 6);
f = Token::findsimplematch(tokenizer.tokens(), "foo2 ( nullptr ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 6);
f = Token::findsimplematch(tokenizer.tokens(), "foo2 ( NULL ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 6);
}
void findFunction15() {