Skip to content

Commit fa13e63

Browse files
Fix #12162 false negative: functionConst with container member functions (#7731)
1 parent 921d893 commit fa13e63

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

lib/checkclass.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2596,18 +2596,18 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member
25962596
if (!vt || !vt->container)
25972597
return false;
25982598
const auto yield = vt->container->getYield(end->str());
2599+
const Token* parent = tok1->astParent();
2600+
while (Token::Match(parent, "(|.|::"))
2601+
parent = parent->astParent();
25992602
if (contains({Library::Container::Yield::START_ITERATOR, Library::Container::Yield::END_ITERATOR, Library::Container::Yield::ITERATOR}, yield)) {
2600-
const Token* parent = tok1->astParent();
2601-
while (Token::Match(parent, "(|.|::"))
2602-
parent = parent->astParent();
26032603
if (parent && parent->isComparisonOp())
26042604
return true;
26052605
// TODO: use AST
26062606
if (parent && parent->isAssignmentOp() && tok1->tokAt(-2)->variable() && Token::Match(tok1->tokAt(-2)->variable()->typeEndToken(), "const_iterator|const_reverse_iterator"))
26072607
return true;
26082608
}
26092609
if ((yield == Library::Container::Yield::ITEM || yield == Library::Container::Yield::AT_INDEX) &&
2610-
(lhs->isComparisonOp() || lhs->isAssignmentOp() || (lhs->str() == "(" && Token::Match(lhs->astParent(), "%cop%"))))
2610+
((parent && parent->isComparisonOp()) || lhs->isAssignmentOp() || (lhs->str() == "(" && Token::Match(lhs->astParent(), "%cop%"))))
26112611
return true; // assume that these functions have const overloads
26122612
return false;
26132613
};

test/testclass.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6822,11 +6822,20 @@ class TestClass : public TestFixture {
68226822
ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'D::f' can be const. [functionConst]\n",
68236823
errout_str());
68246824

6825-
checkConst("struct S {\n" // #12162
6825+
checkConst("int g(int);\n" // #12162
6826+
"struct S {\n"
68266827
" bool has(int i) { return m.find(i) != m.end(); }\n"
6828+
" bool isZero(int i) { return m.at(i) == 0; }\n"
6829+
" bool isZero() { return v.front() == 0; }\n"
6830+
" void f() { g(v.front() + 1); }\n"
6831+
" void set(int i) { m.at(i) = 0; }\n"
68276832
" std::map<int, int> m;\n"
6833+
" std::vector<int> v;\n"
68286834
"};\n");
6829-
ASSERT_EQUALS("[test.cpp:2:10]: (style, inconclusive) Technically the member function 'S::has' can be const. [functionConst]\n",
6835+
ASSERT_EQUALS("[test.cpp:3:10]: (style, inconclusive) Technically the member function 'S::has' can be const. [functionConst]\n"
6836+
"[test.cpp:4:10]: (style, inconclusive) Technically the member function 'S::isZero' can be const. [functionConst]\n"
6837+
"[test.cpp:5:10]: (style, inconclusive) Technically the member function 'S::isZero' can be const. [functionConst]\n"
6838+
"[test.cpp:6:10]: (style, inconclusive) Technically the member function 'S::f' can be const. [functionConst]\n",
68306839
errout_str());
68316840
}
68326841

0 commit comments

Comments
 (0)