Fixed #5983: Support storing pointers/references to member variables in CheckClass::checkConst()

This commit is contained in:
PKEuS 2014-11-02 13:38:03 +01:00
parent df6855c216
commit e5d63195cb
2 changed files with 63 additions and 0 deletions

View File

@ -1802,6 +1802,21 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
if (tok1->str() == "this" && tok1->previous()->isAssignmentOp())
return (false);
const Token* lhs = tok1->tokAt(-1);
if (lhs->str() == "&") {
lhs = lhs->previous();
if (lhs->type() == Token::eAssignmentOp && lhs->previous()->variable()) {
if (lhs->previous()->variable()->typeStartToken()->strAt(-1) != "const" && lhs->previous()->variable()->isPointer())
return false;
}
} else {
const Variable* v2 = lhs->previous()->variable();
if (lhs->type() == Token::eAssignmentOp && v2)
if (!v2->isConst() && v2->isReference() && lhs == v2->nameToken()->next())
return false;
}
const Token* jumpBackToken = 0;
const Token *lastVarTok = tok1;
const Token *end = tok1;

View File

@ -143,6 +143,7 @@ private:
TEST_CASE(const60); // ticket #3322
TEST_CASE(const61); // ticket #5606
TEST_CASE(const62); // ticket #5701
TEST_CASE(const63); // ticket #5983
TEST_CASE(const_handleDefaultParameters);
TEST_CASE(const_passThisToMemberOfOtherClass);
TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
@ -4842,6 +4843,53 @@ private:
ASSERT_EQUALS("", errout.str());
}
void const63() {
checkConst("struct A {\n"
" std::string s;\n"
" void clear() {\n"
" std::string* p = &s;\n"
" p->clear();\n"
" }\n"
"};");
ASSERT_EQUALS("", errout.str());
checkConst("struct A {\n"
" std::string s;\n"
" void clear() {\n"
" std::string& r = s;\n"
" r.clear();\n"
" }\n"
"};");
ASSERT_EQUALS("", errout.str());
checkConst("struct A {\n"
" std::string s;\n"
" void clear() {\n"
" std::string& r = sth; r = s;\n"
" r.clear();\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Technically the member function 'A::clear' can be const.\n", errout.str());
checkConst("struct A {\n"
" std::string s;\n"
" void clear() {\n"
" const std::string* p = &s;\n"
" p->somefunction();\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Technically the member function 'A::clear' can be const.\n", errout.str());
checkConst("struct A {\n"
" std::string s;\n"
" void clear() {\n"
" const std::string& r = s;\n"
" r.somefunction();\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Technically the member function 'A::clear' can be const.\n", errout.str());
}
void const_handleDefaultParameters() {
checkConst("struct Foo {\n"
" void foo1(int i, int j = 0) {\n"