Fix #11531 FP constParameter with const/non-const overload / #8700 FP functionConst (#4802)

This commit is contained in:
chrchr-github 2023-02-24 07:05:18 +01:00 committed by GitHub
parent 535ab69fa0
commit a030970160
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 35 deletions

View File

@ -5298,8 +5298,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
return matches.empty() ? nullptr : matches[0];
}
const Function* fallback1Func = nullptr;
const Function* fallback2Func = nullptr;
std::vector<const Function*> fallback1Func, fallback2Func;
// check each function against the arguments in the function call for a match
for (std::size_t i = 0; i < matches.size();) {
@ -5461,16 +5460,16 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
// check if all arguments matched
if (same == hasToBe) {
if (constFallback || (!requireConst && func->isConst()))
fallback1Func = func;
fallback1Func.emplace_back(func);
else
return func;
}
else if (!fallback1Func) {
else {
if (same + fallback1 == hasToBe)
fallback1Func = func;
else if (!fallback2Func && same + fallback2 + fallback1 == hasToBe)
fallback2Func = func;
fallback1Func.emplace_back(func);
else if (same + fallback2 + fallback1 == hasToBe)
fallback2Func.emplace_back(func);
}
if (!erased)
@ -5478,11 +5477,16 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
}
// Fallback cases
if (fallback1Func)
return fallback1Func;
if (fallback2Func)
return fallback2Func;
for (const auto& fb : { fallback1Func, fallback2Func }) {
if (fb.size() == 1)
return fb.front();
if (fb.size() == 2) {
if (fb[0]->isConst() && !fb[1]->isConst())
return fb[1];
if (fb[1]->isConst() && !fb[0]->isConst())
return fb[0];
}
}
// remove pure virtual function if there is an overrider
auto itPure = std::find_if(matches.begin(), matches.end(), [](const Function* m) {

View File

@ -441,6 +441,7 @@ private:
TEST_CASE(findFunction43); // #10087
TEST_CASE(findFunction44); // #11182
TEST_CASE(findFunction45);
TEST_CASE(findFunction46);
TEST_CASE(findFunctionContainer);
TEST_CASE(findFunctionExternC);
TEST_CASE(findFunctionGlobalScope); // ::foo
@ -6111,15 +6112,10 @@ private:
"void foo(int* a) { }\n"
"void foo(void* a) { }\n"
"void func(int i, const float f, int* ip, float* fp, char* cp) {\n"
" foo(0);\n"
" foo(0L);\n"
" foo(0.f);\n"
" foo(false);\n"
" foo(bar());\n"
" foo(i);\n"
" foo(f);\n"
" foo(&i);\n"
" foo(&f);\n"
" foo(ip);\n"
" foo(fp);\n"
" foo(cp);\n"
@ -6128,33 +6124,19 @@ private:
ASSERT_EQUALS("", errout.str());
const Token *f = Token::findsimplematch(tokenizer.tokens(), "foo ( 0 ) ;");
ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 3);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( 0L ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 3);
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);
const Token* f = Token::findsimplematch(tokenizer.tokens(), "foo ( 0.f ) ;");
ASSERT_EQUALS(true, f && f->function());
TODO_ASSERT_EQUALS(2, 3, f->function()->tokenDef->linenr());
f = Token::findsimplematch(tokenizer.tokens(), "foo ( bar ( ) ) ;");
ASSERT_EQUALS(true, f && f->function() == nullptr);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( i ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 3);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( f ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 2);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( & i ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 4);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( & f ) ;");
ASSERT_EQUALS(true, f && f->function() == nullptr);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( ip ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 4);
@ -6197,7 +6179,7 @@ private:
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 2);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( cp ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 3);
TODO_ASSERT(f && f->function() && f->function()->tokenDef->linenr() == 3);
f = Token::findsimplematch(tokenizer.tokens(), "foo ( ccp ) ;");
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 5);
@ -7045,6 +7027,23 @@ private:
ASSERT_EQUALS(1, functok->function()->tokenDef->linenr());
}
void findFunction46() {
GET_SYMBOL_DB("struct S {\n" // #11531
" const int* g(int i, int j) const;\n"
" int* g(int i, int j);\n"
"};\n"
"enum E { E0 };\n"
"void f(S& s, int i) {\n"
" int* p = s.g(E0, i);\n"
" *p = 0;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "g ( E0");
ASSERT(functok && functok->function());
ASSERT(functok->function()->name() == "g");
ASSERT_EQUALS(3, functok->function()->tokenDef->linenr());
}
void findFunctionContainer() {
{
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"