Fixed #5659 (False negative: mismatching allocation / deallocation whith using namespace)
This commit is contained in:
parent
c8ae1e4751
commit
4ae204e46b
|
@ -198,7 +198,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
Scope::UsingInfo using_info;
|
||||
|
||||
using_info.start = tok; // save location
|
||||
using_info.scope = 0; // fill in later
|
||||
using_info.scope = findNamespace(tok->tokAt(2), scope);
|
||||
|
||||
scope->usingList.push_back(using_info);
|
||||
|
||||
|
@ -669,6 +669,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
// fill in using info
|
||||
for (std::list<Scope>::iterator it = scopeList.begin(); it != scopeList.end(); ++it) {
|
||||
for (std::list<Scope::UsingInfo>::iterator i = it->usingList.begin(); i != it->usingList.end(); ++i) {
|
||||
// only find if not already found
|
||||
if (i->scope == nullptr) {
|
||||
// check scope for match
|
||||
scope = findScope(i->start->tokAt(2), &(*it));
|
||||
if (scope) {
|
||||
|
@ -678,6 +680,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill in variable info
|
||||
for (std::list<Scope>::iterator it = scopeList.begin(); it != scopeList.end(); ++it) {
|
||||
|
@ -1314,6 +1317,31 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To
|
|||
Scope *scope1 = &(*it1);
|
||||
|
||||
bool match = false;
|
||||
|
||||
// check in namespace if using found
|
||||
if (*scope == scope1 && !scope1->usingList.empty()) {
|
||||
std::list<Scope::UsingInfo>::const_iterator it2;
|
||||
for (it2 = scope1->usingList.begin(); it2 != scope1->usingList.end(); ++it2) {
|
||||
if (it2->scope) {
|
||||
Function * func = findFunctionInScope(tok1, it2->scope);
|
||||
if (func) {
|
||||
if (!func->hasBody) {
|
||||
func->hasBody = true;
|
||||
func->token = *tok;
|
||||
func->arg = argStart;
|
||||
addNewFunction(scope, tok);
|
||||
if (*scope) {
|
||||
(*scope)->functionOf = func->nestedIn;
|
||||
(*scope)->function = &*func;
|
||||
(*scope)->function->functionScope = *scope;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scope1->className == tok1->str() && (scope1->type != Scope::eFunction)) {
|
||||
// do the scopes match (same scope) or do their names match (multiple namespaces)
|
||||
if ((*scope == scope1->nestedIn) || (*scope &&
|
||||
|
@ -2794,6 +2822,7 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
|
|||
// not a valid path
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const Type* SymbolDatabase::findTypeInNested(const Token *startTok, const Scope *startScope) const
|
||||
|
@ -2846,3 +2875,34 @@ const Type* SymbolDatabase::findTypeInNested(const Token *startTok, const Scope
|
|||
// not a valid path
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const Scope * SymbolDatabase::findNamespace(const Token * tok, const Scope * scope) const
|
||||
{
|
||||
const Scope * s = findScope(tok, scope);
|
||||
|
||||
if (s)
|
||||
return s;
|
||||
else if (scope->nestedIn)
|
||||
return findNamespace(tok, scope->nestedIn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
Function * SymbolDatabase::findFunctionInScope(const Token *func, const Scope *ns)
|
||||
{
|
||||
const Function * function = ns->findFunction(func);
|
||||
|
||||
if (!function) {
|
||||
const Scope * scope = ns->findRecordInNestedList(func->str());
|
||||
if (scope && func->strAt(1) == "::") {
|
||||
function = findFunctionInScope(func->tokAt(2), scope);
|
||||
}
|
||||
}
|
||||
|
||||
return const_cast<Function *>(function);
|
||||
}
|
||||
|
||||
|
|
|
@ -828,6 +828,9 @@ private:
|
|||
void addNewFunction(Scope **info, const Token **tok);
|
||||
static bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart);
|
||||
const Type *findTypeInNested(const Token *tok, const Scope *startScope) const;
|
||||
const Scope *findNamespace(const Token * tok, const Scope * scope) const;
|
||||
Function *findFunctionInScope(const Token *func, const Scope *ns);
|
||||
|
||||
|
||||
const Tokenizer *_tokenizer;
|
||||
const Settings *_settings;
|
||||
|
|
|
@ -4108,8 +4108,7 @@ private:
|
|||
"}\n"
|
||||
"using namespace N;\n"
|
||||
"int Base::getResourceName() { return var; }");
|
||||
TODO_ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:6]: (style, inconclusive) Technically the member function 'N::Base::getResourceName' can be const.\n",
|
||||
"", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:6]: (style, inconclusive) Technically the member function 'N::Base::getResourceName' can be const.\n", errout.str());
|
||||
}
|
||||
|
||||
void const36() { // ticket #2003
|
||||
|
|
|
@ -4348,6 +4348,7 @@ private:
|
|||
TEST_CASE(free_member_in_sub_func);
|
||||
|
||||
TEST_CASE(mismatch1);
|
||||
TEST_CASE(mismatch2); // #5659
|
||||
|
||||
// allocating member variable in public function
|
||||
TEST_CASE(func1);
|
||||
|
@ -5418,6 +5419,31 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:14]: (error) Mismatching allocation and deallocation: A::pkt_buffer\n", errout.str());
|
||||
}
|
||||
|
||||
void mismatch2() { // #5659
|
||||
check("namespace NS\n"
|
||||
"{\n"
|
||||
"class Foo\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" void fct();\n"
|
||||
"\n"
|
||||
"private:\n"
|
||||
" char* data_;\n"
|
||||
"};\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"using namespace NS;\n"
|
||||
"\n"
|
||||
"void Foo::fct()\n"
|
||||
"{\n"
|
||||
" data_ = new char[42];\n"
|
||||
" delete data_;\n"
|
||||
" data_ = 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:16]: (warning) Possible leak in public function. The pointer 'data_' is not deallocated before it is allocated.\n"
|
||||
"[test.cpp:18]: (error) Mismatching allocation and deallocation: Foo::data_\n", errout.str());
|
||||
}
|
||||
|
||||
void func1() {
|
||||
check("class Fred\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue