From 41d80b5c8d589a0175523fc1d7072a653389b9b0 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 20 Mar 2011 12:53:37 -0400 Subject: [PATCH] fix #2664 (False negative: function can be const (using type from another namespace)) --- lib/symboldatabase.cpp | 54 +++++++++++++++++++++++++++++------------- lib/symboldatabase.h | 2 ++ test/testclass.cpp | 19 +++++++++++++++ 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 6c94c572e..b95dc1371 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -555,28 +555,20 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // finish filling in base class info for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) { - std::list::iterator it1; + std::list::const_iterator it1; + // check all scopes for match for (it1 = scopeList.begin(); it1 != scopeList.end(); ++it1) { - Scope *scope1 = &(*it1); + // check scope for match + const Scope *scope1 = it1->findQualifiedScope(scope->derivedFrom[i].name); - /** @todo handle derived base classes and namespaces */ - if (scope1->type == Scope::eClass || scope1->type == Scope::eStruct) + // found match? + if (scope1) { - // do class names match? - if (scope1->className == scope->derivedFrom[i].name) - { - // are they in the same namespace or different namespaces with same name? - if ((scope1->nestedIn == scope->nestedIn) || - ((scope1->nestedIn && scope1->nestedIn->type == Scope::eNamespace) && - (scope->nestedIn && scope->nestedIn->type == Scope::eNamespace) && - (scope1->nestedIn->className == scope->nestedIn->className))) - { - scope->derivedFrom[i].scope = scope1; - break; - } - } + // set found scope + scope->derivedFrom[i].scope = const_cast(scope1); + break; } } } @@ -1760,6 +1752,34 @@ Scope * Scope::findInNestedListRecursive(const std::string & name) //--------------------------------------------------------------------------- +const Scope * Scope::findQualifiedScope(const std::string & name) const +{ + if (type == Scope::eClass || type == Scope::eStruct || type == Scope::eNamespace) + { + if (name.compare(0, className.size(), className) == 0) + { + std::string path = name; + path.erase(0, className.size()); + if (path.compare(0, 4, " :: ") == 0) + path.erase(0, 4); + else if (path.empty()) + return this; + + std::list::const_iterator it; + + for (it = nestedList.begin() ; it != nestedList.end(); ++it) + { + const Scope *scope1 = (*it)->findQualifiedScope(path); + if (scope1) + return scope1; + } + } + } + return 0; +} + +//--------------------------------------------------------------------------- + const Function *Scope::getDestructor() const { std::list::const_iterator it; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 2d8c733e4..a4814106c 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -430,6 +430,8 @@ public: */ Scope * findInNestedListRecursive(const std::string & name); + const Scope * findQualifiedScope(const std::string & name) const; + void addVariable(const Token *token_, const Token *start_, const Token *end_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const Scope *type_, diff --git a/test/testclass.cpp b/test/testclass.cpp index 8dd0d4d8e..2524e6b9f 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -165,6 +165,7 @@ private: TEST_CASE(const42); // ticket #2282 TEST_CASE(const43); // ticket #2377 TEST_CASE(const44); // ticket #2595 + TEST_CASE(const45); // ticket #2664 TEST_CASE(assigningPointerToPointerIsNotAConstOperation); TEST_CASE(assigningArrayElementIsNotAConstOperation); TEST_CASE(constoperator1); // operator< can often be const @@ -5191,6 +5192,24 @@ private: ASSERT_EQUALS("", errout.str()); } + void const45() // ticket 2664 + { + checkConst("namespace wraps {\n" + " class BaseLayout {};\n" + "}\n" + "namespace tools {\n" + " class WorkspaceControl :\n" + " public wraps::BaseLayout\n" + " {\n" + " int toGrid(int _value)\n" + " {\n" + " }\n" + " };\n" + "}\n"); + + ASSERT_EQUALS("[test.cpp:8]: (information) Technically the member function 'tools::WorkspaceControl::toGrid' can be const.\n", errout.str()); + } + void assigningPointerToPointerIsNotAConstOperation() { checkConst("struct s\n"