Fixed false positives in CheckClass::checkConst() due to unmatched function overloads
Fixed function matching if constness mismatches
This commit is contained in:
parent
4d6cb8d43d
commit
ea215c3b7b
|
@ -1832,7 +1832,23 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const
|
||||||
|
|
||||||
bool CheckClass::isMemberFunc(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();
|
return !tok->function()->isStatic();
|
||||||
|
|
||||||
// not found in this class
|
// 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
|
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();
|
return tok->function()->isConst();
|
||||||
|
|
||||||
// not found in this class
|
// not found in this class
|
||||||
|
|
|
@ -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
|
// check each function against the arguments in the function call for a match
|
||||||
for (std::size_t i = 0; i < matches.size();) {
|
for (std::size_t i = 0; i < matches.size();) {
|
||||||
bool erased = false;
|
bool erased = false;
|
||||||
|
bool constFallback = false;
|
||||||
const Function * func = matches[i];
|
const Function * func = matches[i];
|
||||||
size_t same = 0;
|
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()) {
|
if (scope && scope->functionOf && scope->functionOf->isClassOrStruct()) {
|
||||||
// check if isConst mismatches
|
// check if isConst mismatches
|
||||||
if (!(scope->function && scope->function->isConst() == func->isConst())) {
|
if (!(scope->function && scope->function->isConst() == func->isConst())) {
|
||||||
if (!erased)
|
if (scope->function->isConst()) {
|
||||||
++i;
|
if (!erased)
|
||||||
continue;
|
++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;
|
size_t hasToBe = func->isVariadic() ? (func->argCount() - 1) : args;
|
||||||
|
|
||||||
// check if all arguments matched
|
// check if all arguments matched
|
||||||
if (same == hasToBe)
|
if (same == hasToBe) {
|
||||||
return func;
|
if (constFallback)
|
||||||
|
fallback1Func = func;
|
||||||
|
else
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
if (!fallback1Func) {
|
else if (!fallback1Func) {
|
||||||
if (same + fallback1 == hasToBe)
|
if (same + fallback1 == hasToBe)
|
||||||
fallback1Func = func;
|
fallback1Func = func;
|
||||||
else if (!fallback2Func && same + fallback2 + fallback1 == hasToBe)
|
else if (!fallback2Func && same + fallback2 + fallback1 == hasToBe)
|
||||||
|
|
|
@ -287,6 +287,7 @@ private:
|
||||||
TEST_CASE(findFunction15);
|
TEST_CASE(findFunction15);
|
||||||
TEST_CASE(findFunction16);
|
TEST_CASE(findFunction16);
|
||||||
TEST_CASE(findFunction17);
|
TEST_CASE(findFunction17);
|
||||||
|
TEST_CASE(findFunction18);
|
||||||
|
|
||||||
TEST_CASE(noexceptFunction1);
|
TEST_CASE(noexceptFunction1);
|
||||||
TEST_CASE(noexceptFunction2);
|
TEST_CASE(noexceptFunction2);
|
||||||
|
@ -3785,6 +3786,22 @@ private:
|
||||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 2);
|
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()); \
|
#define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \
|
||||||
ASSERT_EQUALS(true, x != nullptr); \
|
ASSERT_EQUALS(true, x != nullptr); \
|
||||||
|
|
Loading…
Reference in New Issue