Improved fix for #2698 and added test case

This commit is contained in:
PKEuS 2012-05-16 12:36:05 -07:00
parent 77df633904
commit 6a05ad1cf8
2 changed files with 37 additions and 4 deletions

View File

@ -1415,7 +1415,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func)
// function call..
else if (Token::Match(tok1, "%var% (") && !tok1->isStandardType() &&
!Token::Match(tok1, "return|if|string|switch|while|catch|for")) {
if (isMemberFunc(scope, tok1) && !isConstMemberFunc(scope, tok1)) {
if (isMemberFunc(scope, tok1) && !isConstMemberFunc(scope, tok1) && tok1->strAt(-1) != ".") {
return(false);
}
// Member variable given as parameter
@ -1428,7 +1428,9 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func)
} else if (Token::Match(tok1, "> (") && (!tok1->link() || !Token::Match(tok1->link()->previous(), "static_cast|const_cast|dynamic_cast|reinterpret_cast"))) {
return(false);
} else if (Token::Match(tok1, "%var% . %var% (")) {
if (tok1->varId() && (Token::Match(tok1->tokAt(2), "size|empty|cend|crend|cbegin|crbegin|max_size|length|count|capacity|get_allocator|c_str|str ( )") || Token::Match(tok1->tokAt(2), "rfind|copy"))) {
if (!isMemberVar(scope, tok1))
tok1 = tok1->tokAt(2);
else if (tok1->varId() && (Token::Match(tok1->tokAt(2), "size|empty|cend|crend|cbegin|crbegin|max_size|length|count|capacity|get_allocator|c_str|str ( )") || Token::Match(tok1->tokAt(2), "rfind|copy"))) {
const Variable *var = symbolDatabase->getVariableFromVarId(tok1->varId());
// assume all std::*::size() and std::*::empty() are const
@ -1436,8 +1438,6 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func)
tok1 = tok1->next();
else // TODO: Check if the function is const (#2477)
return(false);
} else if (!isMemberVar(scope, tok1)) {
tok1 = tok1->tokAt(2);
} else
return(false);
}

View File

@ -133,6 +133,7 @@ private:
TEST_CASE(const55);
TEST_CASE(const56); // ticket #3149
TEST_CASE(const57); // ticket #2669
TEST_CASE(const58); // ticket #2698
TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
TEST_CASE(assigningArrayElementIsNotAConstOperation);
TEST_CASE(constoperator1); // operator< can often be const
@ -4285,6 +4286,38 @@ private:
}
void const58() {
checkConst("struct MyObject {\n"
" void foo(Foo f) {\n"
" f.clear();\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Technically the member function 'MyObject::foo' can be const.\n", errout.str());
checkConst("struct MyObject {\n"
" int foo(Foo f) {\n"
" return f.length();\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Technically the member function 'MyObject::foo' can be const.\n", errout.str());
checkConst("struct MyObject {\n"
" Foo f;\n"
" int foo() {\n"
" return f.length();\n"
" }\n"
"};");
ASSERT_EQUALS("", errout.str());
checkConst("struct MyObject {\n"
" std::string f;\n"
" int foo() {\n"
" return f.length();\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Technically the member function 'MyObject::foo' can be const.\n", errout.str());
}
void assigningPointerToPointerIsNotAConstOperation() {
checkConst("struct s\n"
"{\n"