Skip to content

Commit 4d8eab3

Browse files
Fix #14390 Inconsistent functionConst with pointers in container member (#8248)
1 parent afc317e commit 4d8eab3

2 files changed

Lines changed: 17 additions & 2 deletions

File tree

lib/checkclass.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,8 +2545,10 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member
25452545
}
25462546
}
25472547
} else if (lhs->str() == ":" && lhs->astParent() && lhs->astParent()->str() == "(") { // range-based for-loop (C++11)
2548-
// TODO: We could additionally check what is done with the elements to avoid false negatives. Here we just rely on "const" keyword being used.
2549-
if (lhs->astParent()->strAt(1) != "const")
2548+
const Variable* loopVar = lhs->astOperand1()->variable();
2549+
if (!loopVar || !loopVar->valueType())
2550+
return false;
2551+
if (!loopVar->valueType()->isConst(loopVar->valueType()->pointer))
25502552
return false;
25512553
} else {
25522554
if (lhs->isAssignmentOp()) {

test/testclass.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7741,6 +7741,19 @@ class TestClass : public TestFixture {
77417741
" }\n"
77427742
"};");
77437743
ASSERT_EQUALS("[test.cpp:8:10]: (style, inconclusive) Technically the member function 'Fred::f2' can be const. [functionConst]\n", errout_str());
7744+
7745+
checkConst("struct T {\n" // #14390
7746+
" std::vector<int*> v;\n"
7747+
" void f() {\n"
7748+
" for (const auto& p : v)\n"
7749+
" *p = 0;\n"
7750+
" }\n"
7751+
" void g() {\n"
7752+
" for (auto* p : v)\n"
7753+
" *p = 0;\n"
7754+
" }\n"
7755+
"};\n");
7756+
ASSERT_EQUALS("", errout_str());
77447757
}
77457758

77467759
void const_shared_ptr() { // #8674

0 commit comments

Comments
 (0)