Fixed false positives in CheckClass::checkConst() due to unmatched function overloads

Fixed function matching if constness mismatches
This commit is contained in:
PKEuS 2017-04-01 10:18:53 +02:00
parent 4d6cb8d43d
commit ea215c3b7b
3 changed files with 51 additions and 8 deletions

View File

@ -1832,7 +1832,23 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const
bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const
{
if (tok->function() && tok->function()->nestedIn == scope)
if (!tok->function()) {
for (std::list<Function>::const_iterator i = scope->functionList.cbegin(); i != scope->functionList.cend(); ++i) {
if (i->name() == tok->str()) {
const Token* tok2 = tok->tokAt(2);
size_t argsPassed = tok2->str() == ")" ? 0 : 1;
for (;;) {
tok2 = tok2->nextArgument();
if (tok2)
argsPassed++;
else
break;
}
if (argsPassed == i->argCount() || (argsPassed < i->argCount() && argsPassed >= i->minArgCount()))
return true;
}
}
} else if (tok->function()->nestedIn == scope)
return !tok->function()->isStatic();
// not found in this class
@ -1855,7 +1871,9 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const
bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) const
{
if (tok->function() && tok->function()->nestedIn == scope)
if (!tok->function())
return false;
else if (tok->function()->nestedIn == scope)
return tok->function()->isConst();
// not found in this class

View File

@ -3846,6 +3846,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
// check each function against the arguments in the function call for a match
for (std::size_t i = 0; i < matches.size();) {
bool erased = false;
bool constFallback = false;
const Function * func = matches[i];
size_t same = 0;
@ -3857,9 +3858,12 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
if (scope && scope->functionOf && scope->functionOf->isClassOrStruct()) {
// check if isConst mismatches
if (!(scope->function && scope->function->isConst() == func->isConst())) {
if (!erased)
++i;
continue;
if (scope->function->isConst()) {
if (!erased)
++i;
continue;
}
constFallback = true;
}
}
}
@ -4072,10 +4076,14 @@ 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 (same == hasToBe)
return func;
if (same == hasToBe) {
if (constFallback)
fallback1Func = func;
else
return func;
}
if (!fallback1Func) {
else if (!fallback1Func) {
if (same + fallback1 == hasToBe)
fallback1Func = func;
else if (!fallback2Func && same + fallback2 + fallback1 == hasToBe)

View File

@ -287,6 +287,7 @@ private:
TEST_CASE(findFunction15);
TEST_CASE(findFunction16);
TEST_CASE(findFunction17);
TEST_CASE(findFunction18);
TEST_CASE(noexceptFunction1);
TEST_CASE(noexceptFunction2);
@ -3785,6 +3786,22 @@ private:
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 2);
}
void findFunction18() {
GET_SYMBOL_DB("class Fred {\n"
" void f(int i) { }\n"
" void f(float f) const { }\n"
" void a() { f(1); }\n"
" void b() { f(1.f); }\n"
"};");
ASSERT_EQUALS("", errout.str());
const Token *f = Token::findsimplematch(tokenizer.tokens(), "f ( 1 ) ;");
ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 2);
f = Token::findsimplematch(tokenizer.tokens(), "f ( 1.f ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 3);
}
#define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \
ASSERT_EQUALS(true, x != nullptr); \