fix #2664 (False negative: function can be const (using type from another namespace))

This commit is contained in:
Robert Reif 2011-03-20 12:53:37 -04:00
parent d54836822e
commit 41d80b5c8d
3 changed files with 58 additions and 17 deletions

View File

@ -555,28 +555,20 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// finish filling in base class info // finish filling in base class info
for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i)
{ {
std::list<Scope>::iterator it1; std::list<Scope>::const_iterator it1;
// check all scopes for match
for (it1 = scopeList.begin(); it1 != scopeList.end(); ++it1) 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 */ // found match?
if (scope1->type == Scope::eClass || scope1->type == Scope::eStruct) if (scope1)
{ {
// do class names match? // set found scope
if (scope1->className == scope->derivedFrom[i].name) scope->derivedFrom[i].scope = const_cast<Scope *>(scope1);
{ break;
// 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;
}
}
} }
} }
} }
@ -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<Scope *>::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 const Function *Scope::getDestructor() const
{ {
std::list<Function>::const_iterator it; std::list<Function>::const_iterator it;

View File

@ -430,6 +430,8 @@ public:
*/ */
Scope * findInNestedListRecursive(const std::string & name); Scope * findInNestedListRecursive(const std::string & name);
const Scope * findQualifiedScope(const std::string & name) const;
void addVariable(const Token *token_, const Token *start_, void addVariable(const Token *token_, const Token *start_,
const Token *end_, AccessControl access_, bool mutable_, const Token *end_, AccessControl access_, bool mutable_,
bool static_, bool const_, bool class_, const Scope *type_, bool static_, bool const_, bool class_, const Scope *type_,

View File

@ -165,6 +165,7 @@ private:
TEST_CASE(const42); // ticket #2282 TEST_CASE(const42); // ticket #2282
TEST_CASE(const43); // ticket #2377 TEST_CASE(const43); // ticket #2377
TEST_CASE(const44); // ticket #2595 TEST_CASE(const44); // ticket #2595
TEST_CASE(const45); // ticket #2664
TEST_CASE(assigningPointerToPointerIsNotAConstOperation); TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
TEST_CASE(assigningArrayElementIsNotAConstOperation); TEST_CASE(assigningArrayElementIsNotAConstOperation);
TEST_CASE(constoperator1); // operator< can often be const TEST_CASE(constoperator1); // operator< can often be const
@ -5191,6 +5192,24 @@ private:
ASSERT_EQUALS("", errout.str()); 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() void assigningPointerToPointerIsNotAConstOperation()
{ {
checkConst("struct s\n" checkConst("struct s\n"