From a58094e827197bcac7cba5a376d6289e79bf3fb8 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Wed, 13 Oct 2010 07:26:41 +0200 Subject: [PATCH] Fixed #2089 (False negative: Function can be const (calling const function)) --- lib/checkclass.cpp | 44 +++++++++++++++++++++++++++++++++++++++++--- lib/checkclass.h | 1 + test/testclass.cpp | 2 +- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 44b4afc3f..892a78dfd 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2139,6 +2139,37 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok) return false; } +bool CheckClass::isConstMemberFunc(const SpaceInfo *info, const Token *tok) +{ + std::list::const_iterator func; + + for (func = info->functionList.begin(); func != info->functionList.end(); ++func) + { + if (func->tokenDef->str() == tok->str() && func->isConst) + return true; + } + + // not found in this class + if (!info->derivedFrom.empty()) + { + // check each base class + for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) + { + // find the base class + const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; + + // find the function in the base class + if (spaceInfo) + { + if (isConstMemberFunc(spaceInfo, tok)) + return true; + } + } + } + + return false; +} + bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok) { // if the function doesn't have any assignment nor function call, @@ -2200,9 +2231,16 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok) } // function call.. - else if ((Token::Match(tok1, "%var% (") && - !(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType())) || - Token::Match(tok1, "%var% < %any% > (")) + else if (Token::Match(tok1, "%var% (") && + !(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType())) + { + if (!isConstMemberFunc(info, tok1)) + { + isconst = false; + break; + } + } + else if (Token::Match(tok1, "%var% < %any% > (")) { isconst = false; break; diff --git a/lib/checkclass.h b/lib/checkclass.h index eb86322a9..279b2cacf 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -305,6 +305,7 @@ private: bool argsMatch(const Token *first, const Token *second, const std::string &path, unsigned int depth) const; bool isMemberVar(const SpaceInfo *info, const Token *tok); + bool isConstMemberFunc(const SpaceInfo *info, const Token *tok); bool checkConstFunc(const SpaceInfo *info, const Token *tok); const Token *initBaseInfo(SpaceInfo *info, const Token *tok); diff --git a/test/testclass.cpp b/test/testclass.cpp index 34e9dbae2..a40d130d9 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -4130,7 +4130,7 @@ private: " void f() const { };\n" " void a() { f(); };\n" "};\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (style) The function 'Fred::a' can be const\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (style) The function 'Fred::a' can be const\n", errout.str()); // ticket #1593 checkConst("#include \n"