fix #2664 (False negative: function can be const (using type from another namespace))
This commit is contained in:
parent
d54836822e
commit
41d80b5c8d
|
@ -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;
|
||||||
|
|
|
@ -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_,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue