Skip to content

Commit 23da5c9

Browse files
IOBYTERobert Reif
andauthored
fix #9885 (SymbolDatabase: function lookup fails calling variadic method) (#3002)
Co-authored-by: Robert Reif <reif@FX6840>
1 parent 76d5e6c commit 23da5c9

2 files changed

Lines changed: 126 additions & 1 deletion

File tree

lib/symboldatabase.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4617,7 +4617,8 @@ void Scope::findFunctionInBase(const std::string & name, nonneg int args, std::v
46174617

46184618
for (std::multimap<std::string, const Function *>::const_iterator it = base->classScope->functionMap.find(name); it != base->classScope->functionMap.end() && it->first == name; ++it) {
46194619
const Function *func = it->second;
4620-
if (args == func->argCount() || (args < func->argCount() && args >= func->minArgCount())) {
4620+
if ((func->isVariadic() && args >= (func->argCount() - 1)) ||
4621+
(args == func->argCount() || (args < func->argCount() && args >= func->minArgCount()))) {
46214622
matches.push_back(func);
46224623
}
46234624
}

test/testsymboldatabase.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ class TestSymbolDatabase: public TestFixture {
395395
TEST_CASE(findFunction30);
396396
TEST_CASE(findFunction31);
397397
TEST_CASE(findFunction32); // C: relax type matching
398+
TEST_CASE(findFunction33); // #9885 variadic function
398399
TEST_CASE(findFunctionContainer);
399400
TEST_CASE(findFunctionExternC);
400401
TEST_CASE(findFunctionGlobalScope); // ::foo
@@ -6065,6 +6066,129 @@ class TestSymbolDatabase: public TestFixture {
60656066
ASSERT_EQUALS(1, foo->function()->tokenDef->linenr());
60666067
}
60676068

6069+
void findFunction33() {
6070+
{
6071+
GET_SYMBOL_DB("class Base {\n"
6072+
" int i{};\n"
6073+
"public:\n"
6074+
" void foo(...) const { bar(); }\n"
6075+
" int bar() const { return i; }\n"
6076+
"};\n"
6077+
"class Derived : public Base {\n"
6078+
"public:\n"
6079+
" void doIt() const {\n"
6080+
" foo();\n"
6081+
" }\n"
6082+
"};");
6083+
(void)db;
6084+
const Token *foo = Token::findsimplematch(tokenizer.tokens(), "foo ( ) ;");
6085+
ASSERT(foo);
6086+
ASSERT(foo->function());
6087+
ASSERT(foo->function()->tokenDef);
6088+
ASSERT_EQUALS(4, foo->function()->tokenDef->linenr());
6089+
}
6090+
{
6091+
GET_SYMBOL_DB("class Base {\n"
6092+
" int i{};\n"
6093+
"public:\n"
6094+
" void foo(...) const { bar(); }\n"
6095+
" int bar() const { return i; }\n"
6096+
"};\n"
6097+
"class Derived : public Base {\n"
6098+
"public:\n"
6099+
" void doIt() const {\n"
6100+
" foo(1);\n"
6101+
" }\n"
6102+
"};");
6103+
(void)db;
6104+
const Token *foo = Token::findsimplematch(tokenizer.tokens(), "foo ( 1 ) ;");
6105+
ASSERT(foo);
6106+
ASSERT(foo->function());
6107+
ASSERT(foo->function()->tokenDef);
6108+
ASSERT_EQUALS(4, foo->function()->tokenDef->linenr());
6109+
}
6110+
{
6111+
GET_SYMBOL_DB("class Base {\n"
6112+
" int i{};\n"
6113+
"public:\n"
6114+
" void foo(...) const { bar(); }\n"
6115+
" int bar() const { return i; }\n"
6116+
"};\n"
6117+
"class Derived : public Base {\n"
6118+
"public:\n"
6119+
" void doIt() const {\n"
6120+
" foo(1,2);\n"
6121+
" }\n"
6122+
"};");
6123+
(void)db;
6124+
const Token *foo = Token::findsimplematch(tokenizer.tokens(), "foo ( 1 , 2 ) ;");
6125+
ASSERT(foo);
6126+
ASSERT(foo->function());
6127+
ASSERT(foo->function()->tokenDef);
6128+
ASSERT_EQUALS(4, foo->function()->tokenDef->linenr());
6129+
}
6130+
{
6131+
GET_SYMBOL_DB("class Base {\n"
6132+
" int i{};\n"
6133+
"public:\n"
6134+
" void foo(int, ...) const { bar(); }\n"
6135+
" int bar() const { return i; }\n"
6136+
"};\n"
6137+
"class Derived : public Base {\n"
6138+
"public:\n"
6139+
" void doIt() const {\n"
6140+
" foo(1);\n"
6141+
" }\n"
6142+
"};");
6143+
(void)db;
6144+
const Token *foo = Token::findsimplematch(tokenizer.tokens(), "foo ( 1 ) ;");
6145+
ASSERT(foo);
6146+
ASSERT(foo->function());
6147+
ASSERT(foo->function()->tokenDef);
6148+
ASSERT_EQUALS(4, foo->function()->tokenDef->linenr());
6149+
}
6150+
{
6151+
GET_SYMBOL_DB("class Base {\n"
6152+
" int i{};\n"
6153+
"public:\n"
6154+
" void foo(int,...) const { bar(); }\n"
6155+
" int bar() const { return i; }\n"
6156+
"};\n"
6157+
"class Derived : public Base {\n"
6158+
"public:\n"
6159+
" void doIt() const {\n"
6160+
" foo(1,2);\n"
6161+
" }\n"
6162+
"};");
6163+
(void)db;
6164+
const Token *foo = Token::findsimplematch(tokenizer.tokens(), "foo ( 1 , 2 ) ;");
6165+
ASSERT(foo);
6166+
ASSERT(foo->function());
6167+
ASSERT(foo->function()->tokenDef);
6168+
ASSERT_EQUALS(4, foo->function()->tokenDef->linenr());
6169+
}
6170+
{
6171+
GET_SYMBOL_DB("class Base {\n"
6172+
" int i{};\n"
6173+
"public:\n"
6174+
" void foo(int,...) const { bar(); }\n"
6175+
" int bar() const { return i; }\n"
6176+
"};\n"
6177+
"class Derived : public Base {\n"
6178+
"public:\n"
6179+
" void doIt() const {\n"
6180+
" foo(1, 2, 3);\n"
6181+
" }\n"
6182+
"};");
6183+
(void)db;
6184+
const Token *foo = Token::findsimplematch(tokenizer.tokens(), "foo ( 1 , 2 , 3 ) ;");
6185+
ASSERT(foo);
6186+
ASSERT(foo->function());
6187+
ASSERT(foo->function()->tokenDef);
6188+
ASSERT_EQUALS(4, foo->function()->tokenDef->linenr());
6189+
}
6190+
}
6191+
60686192
void findFunctionContainer() {
60696193
{
60706194
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"

0 commit comments

Comments
 (0)