Skip to content

Commit 7bd1711

Browse files
autoantwortclaude
andcommitted
Skip references to functions in checkConstVariable
A reference to a function returning a reference was no longer skipped because isRValueReference() is now false for it. A function reference can't be const-qualified, so it is never reported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 440310e commit 7bd1711

3 files changed

Lines changed: 30 additions & 0 deletions

File tree

‎lib/checkother.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,8 @@ void CheckOtherImpl::checkConstVariable()
17681768
continue;
17691769
if (var->isConst())
17701770
continue;
1771+
if (Token::Match(var->nameToken(), "%name% ) (")) // reference to function
1772+
continue;
17711773
const Scope* scope = var->scope();
17721774
if (!scope)
17731775
continue;

‎test/testother.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4213,6 +4213,17 @@ class TestOther : public TestFixture {
42134213
" }\n"
42144214
"}\n");
42154215
ASSERT_EQUALS("", errout_str());
4216+
4217+
check("int& g();\n" // reference to function
4218+
"int k();\n"
4219+
"int f1() { int& (&r)() = g; return r(); }\n"
4220+
"int f2() { int (&r)() = k; return r(); }\n"
4221+
"int& f3(int& (&f)()) { return f(); }\n"
4222+
"int f4(int&& (&f)()) { return f(); }\n"
4223+
"int f5(int (&f)()) { return f(); }\n"
4224+
"using FR = int&(&)();\n"
4225+
"void f6(FR f) { f(); }\n");
4226+
ASSERT_EQUALS("", errout_str());
42164227
}
42174228

42184229
void constParameterCallback() {

‎test/testsymboldatabase.cpp‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,18 @@ class TestSymbolDatabase : public TestFixture {
16531653
ASSERT(p->valueType());
16541654
ASSERT(p->valueType()->reference == Reference::LValue);
16551655
}
1656+
{ // reference to function returning a reference
1657+
GET_SYMBOL_DB("void foo(int& (&f)()) {}\n");
1658+
const Variable* const p = db->getVariableFromVarId(1);
1659+
ASSERT(p->isReference());
1660+
ASSERT(!p->isRValueReference());
1661+
}
1662+
{
1663+
GET_SYMBOL_DB("void foo(int&& (&f)()) {}\n");
1664+
const Variable* const p = db->getVariableFromVarId(1);
1665+
ASSERT(p->isReference());
1666+
ASSERT(!p->isRValueReference());
1667+
}
16561668
}
16571669

16581670
void VariableValueTypeTemplate() {
@@ -2461,6 +2473,11 @@ class TestSymbolDatabase : public TestFixture {
24612473
ASSERT(db && ctor && ctor->type == FunctionType::eMoveConstructor);
24622474
ASSERT(ctor && ctor->retDef == nullptr);
24632475
}
2476+
{
2477+
GET_SYMBOL_DB("class Foo { Foo(Foo&& (*f)()); };\n");
2478+
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
2479+
ASSERT(db && ctor && ctor->type == FunctionType::eConstructor);
2480+
}
24642481
{
24652482
GET_SYMBOL_DB("void f() { extern void f(); }\n");
24662483
ASSERT(db && db->scopeList.size() == 2);

0 commit comments

Comments
 (0)