From d8c7a856f98f05ef7b68254f6de722be49f2083c Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 Aug 2025 09:58:41 +0200 Subject: [PATCH 1/6] Update testclass.cpp --- test/testclass.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/testclass.cpp b/test/testclass.cpp index a1bd19f9850..2cac353babc 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -6824,9 +6824,15 @@ class TestClass : public TestFixture { checkConst("struct S {\n" // #12162 " bool has(int i) { return m.find(i) != m.end(); }\n" + " bool isZero(int i) { return m.at(i) == 0; }\n" + " bool isZero() { return v.front() == 0; }\n" + " void set(int i) { m.at(i) = 0; }\n" " std::map m;\n" + " std::vector v;\n" "};\n"); - ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Technically the member function 'S::has' can be const. [functionConst]\n", + ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Technically the member function 'S::has' can be const. [functionConst]\n" + "[test.cpp:3:10]: (style, inconclusive) Technically the member function 'S::isZero' can be const. [functionConst]\n" + "[test.cpp:4:10]: (style, inconclusive) Technically the member function 'S::isZero' can be const. [functionConst]\n", errout_str()); } From 0220dbebe59909dc74248e05547b8741adb5b0c9 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 Aug 2025 10:00:27 +0200 Subject: [PATCH 2/6] Update checkclass.cpp --- lib/checkclass.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 3c7816a9479..d15b578b0fa 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2594,12 +2594,12 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member auto isConstContainerUsage = [&](const ValueType* vt) -> bool { if (!vt || !vt->container) - return false; + return false; const auto yield = vt->container->getYield(end->str()); - if (contains({Library::Container::Yield::START_ITERATOR, Library::Container::Yield::END_ITERATOR, Library::Container::Yield::ITERATOR}, yield)) { - const Token* parent = tok1->astParent(); + const Token* parent = tok1->astParent(); while (Token::Match(parent, "(|.|::")) parent = parent->astParent(); + if (contains({Library::Container::Yield::START_ITERATOR, Library::Container::Yield::END_ITERATOR, Library::Container::Yield::ITERATOR}, yield)) { if (parent && parent->isComparisonOp()) return true; // TODO: use AST @@ -2607,7 +2607,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member return true; } if ((yield == Library::Container::Yield::ITEM || yield == Library::Container::Yield::AT_INDEX) && - (lhs->isComparisonOp() || lhs->isAssignmentOp() || (lhs->str() == "(" && Token::Match(lhs->astParent(), "%cop%")))) + ((parent && parent->isComparisonOp()) || lhs->isAssignmentOp())) return true; // assume that these functions have const overloads return false; }; From 94ff4d359cbe88359243c88b072faba60bd31bb7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 Aug 2025 10:04:50 +0200 Subject: [PATCH 3/6] Update checkclass.cpp --- lib/checkclass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index d15b578b0fa..5e4a794a79a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2594,7 +2594,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member auto isConstContainerUsage = [&](const ValueType* vt) -> bool { if (!vt || !vt->container) - return false; + return false; const auto yield = vt->container->getYield(end->str()); const Token* parent = tok1->astParent(); while (Token::Match(parent, "(|.|::")) From c8f80dbf6122caab8cc2f4bfe6205303a10f00d2 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 Aug 2025 10:12:17 +0200 Subject: [PATCH 4/6] Update checkclass.cpp --- lib/checkclass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 5e4a794a79a..a5a85106558 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2597,8 +2597,8 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member return false; const auto yield = vt->container->getYield(end->str()); const Token* parent = tok1->astParent(); - while (Token::Match(parent, "(|.|::")) - parent = parent->astParent(); + while (Token::Match(parent, "(|.|::")) + parent = parent->astParent(); if (contains({Library::Container::Yield::START_ITERATOR, Library::Container::Yield::END_ITERATOR, Library::Container::Yield::ITERATOR}, yield)) { if (parent && parent->isComparisonOp()) return true; From 26dccda4e7232a6b86a4de6355a4312f48ea89f0 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 Aug 2025 16:51:47 +0200 Subject: [PATCH 5/6] Update checkclass.cpp --- lib/checkclass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index a5a85106558..b3976175e2f 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2607,7 +2607,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member return true; } if ((yield == Library::Container::Yield::ITEM || yield == Library::Container::Yield::AT_INDEX) && - ((parent && parent->isComparisonOp()) || lhs->isAssignmentOp())) + ((parent && parent->isComparisonOp()) || lhs->isAssignmentOp() || (lhs->str() == "(" && Token::Match(lhs->astParent(), "%cop%")))) return true; // assume that these functions have const overloads return false; }; From 36be61bb13610d6ad894ac988062e2d32b9e269d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 12 Aug 2025 16:58:32 +0200 Subject: [PATCH 6/6] Update testclass.cpp --- test/testclass.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/testclass.cpp b/test/testclass.cpp index 2cac353babc..05f863189c5 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -6822,17 +6822,20 @@ class TestClass : public TestFixture { ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'D::f' can be const. [functionConst]\n", errout_str()); - checkConst("struct S {\n" // #12162 + checkConst("int g(int);\n" // #12162 + "struct S {\n" " bool has(int i) { return m.find(i) != m.end(); }\n" " bool isZero(int i) { return m.at(i) == 0; }\n" " bool isZero() { return v.front() == 0; }\n" + " void f() { g(v.front() + 1); }\n" " void set(int i) { m.at(i) = 0; }\n" " std::map m;\n" " std::vector v;\n" "};\n"); - ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Technically the member function 'S::has' can be const. [functionConst]\n" - "[test.cpp:3:10]: (style, inconclusive) Technically the member function 'S::isZero' can be const. [functionConst]\n" - "[test.cpp:4:10]: (style, inconclusive) Technically the member function 'S::isZero' can be const. [functionConst]\n", + ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'S::has' can be const. [functionConst]\n" + "[test.cpp:4:10]: (style, inconclusive) Technically the member function 'S::isZero' can be const. [functionConst]\n" + "[test.cpp:5:10]: (style, inconclusive) Technically the member function 'S::isZero' can be const. [functionConst]\n" + "[test.cpp:6:10]: (style, inconclusive) Technically the member function 'S::f' can be const. [functionConst]\n", errout_str()); }