Skip to content

Commit 38dc3a9

Browse files
Fix #13464 FN functionConst with overloaded function call (regression) (danmar#7185)
1 parent 3dd800a commit 38dc3a9

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

lib/symboldatabase.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5753,7 +5753,8 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst, Referen
57535753
return matches.empty() ? nullptr : matches[0];
57545754
}
57555755

5756-
std::vector<const Function*> fallback1Func, fallback2Func;
5756+
// store function and number of matching arguments
5757+
std::vector<std::pair<const Function*, size_t>> fallback1Func, fallback2Func;
57575758

57585759
// check each function against the arguments in the function call for a match
57595760
for (std::size_t i = 0; i < matches.size();) {
@@ -5926,31 +5927,41 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst, Referen
59265927
// check if all arguments matched
59275928
if (same == hasToBe) {
59285929
if (constFallback || (!requireConst && func->isConst()))
5929-
fallback1Func.emplace_back(func);
5930+
fallback1Func.emplace_back(func, same);
59305931
else
59315932
return func;
59325933
}
59335934

59345935
else {
59355936
if (same + fallback1 == hasToBe)
5936-
fallback1Func.emplace_back(func);
5937+
fallback1Func.emplace_back(func, same);
59375938
else if (same + fallback2 + fallback1 == hasToBe)
5938-
fallback2Func.emplace_back(func);
5939+
fallback2Func.emplace_back(func, same);
59395940
}
59405941

59415942
if (!erased)
59425943
++i;
59435944
}
59445945

59455946
// Fallback cases
5947+
auto fb_pred = [](const std::pair<const Function*, size_t>& a, const std::pair<const Function*, size_t>& b) {
5948+
return a.second > b.second;
5949+
};
5950+
// sort according to matching arguments
5951+
std::sort(fallback1Func.begin(), fallback1Func.end(), fb_pred);
5952+
std::sort(fallback2Func.begin(), fallback2Func.end(), fb_pred);
59465953
for (const auto& fb : { fallback1Func, fallback2Func }) {
59475954
if (fb.size() == 1)
5948-
return fb.front();
5955+
return fb[0].first;
5956+
if (fb.size() >= 2) {
5957+
if (fb[0].second > fb[1].second)
5958+
return fb[0].first;
5959+
}
59495960
if (fb.size() == 2) {
5950-
if (fb[0]->isConst() && !fb[1]->isConst())
5951-
return fb[1];
5952-
if (fb[1]->isConst() && !fb[0]->isConst())
5953-
return fb[0];
5961+
if (fb[0].first->isConst() && !fb[1].first->isConst())
5962+
return fb[1].first;
5963+
if (fb[1].first->isConst() && !fb[0].first->isConst())
5964+
return fb[0].first;
59545965
}
59555966
}
59565967

@@ -5971,11 +5982,11 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst, Referen
59715982
for (const auto& fb : { fallback1Func, fallback2Func }) {
59725983
const Function* ret = nullptr;
59735984
for (std::size_t i = 0; i < fb.size(); ++i) {
5974-
if (std::find(matches.cbegin(), matches.cend(), fb[i]) == matches.cend())
5985+
if (std::find(matches.cbegin(), matches.cend(), fb[i].first) == matches.cend())
59755986
continue;
5976-
if (this == fb[i]->nestedIn) {
5987+
if (this == fb[i].first->nestedIn) {
59775988
if (!ret)
5978-
ret = fb[i];
5989+
ret = fb[i].first;
59795990
else {
59805991
ret = nullptr;
59815992
break;

test/testsymboldatabase.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ class TestSymbolDatabase : public TestFixture {
522522
TEST_CASE(findFunction56);
523523
TEST_CASE(findFunction57);
524524
TEST_CASE(findFunction58); // #13310
525+
TEST_CASE(findFunction59);
525526
TEST_CASE(findFunctionRef1);
526527
TEST_CASE(findFunctionRef2); // #13328
527528
TEST_CASE(findFunctionContainer);
@@ -8442,6 +8443,17 @@ class TestSymbolDatabase : public TestFixture {
84428443
ASSERT(a2 && a2->function());
84438444
}
84448445

8446+
void findFunction59() { // #13464
8447+
GET_SYMBOL_DB("void foo(const char[], const std::string&);\n"
8448+
"void foo(const std::string&, const std::string&);\n"
8449+
"void f() {\n"
8450+
" foo(\"\", \"\");\n"
8451+
"}\n");
8452+
const Token* foo = Token::findsimplematch(tokenizer.tokens(), "foo ( \"\"");
8453+
ASSERT(foo && foo->function());
8454+
ASSERT_EQUALS(foo->function()->tokenDef->linenr(), 1);
8455+
}
8456+
84458457
void findFunctionRef1() {
84468458
GET_SYMBOL_DB("struct X {\n"
84478459
" const std::vector<int> getInts() const & { return mInts; }\n"

0 commit comments

Comments
 (0)