Fixed #3989 (false positive: memory leak (inline function))

This commit is contained in:
Daniel Marjamäki 2016-05-26 17:42:27 +02:00
parent 8b088a472f
commit 38741868b5
6 changed files with 51 additions and 3 deletions

View File

@ -140,6 +140,9 @@ void CheckLeakAutoVar::check()
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
if (scope->hasInlineFunction())
continue;
// Empty variable info // Empty variable info
VarInfo varInfo; VarInfo varInfo;

View File

@ -2177,8 +2177,8 @@ void CheckMemoryLeakInFunction::check()
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
if (!scope->hasInlineFunction())
checkScope(scope->classStart->next(), "", 0, scope->functionOf != nullptr, 1); checkScope(scope->classStart->next(), "", 0, scope->functionOf != nullptr, 1);
} }
// Check variables.. // Check variables..
@ -2197,6 +2197,9 @@ void CheckMemoryLeakInFunction::check()
if (var->isPointer() && var->type() && !var->typeScope()) if (var->isPointer() && var->type() && !var->typeScope())
continue; continue;
if (var->scope()->hasInlineFunction())
continue;
unsigned int sz = _tokenizer->sizeOfType(var->typeStartToken()); unsigned int sz = _tokenizer->sizeOfType(var->typeStartToken());
if (sz < 1) if (sz < 1)
sz = 1; sz = 1;

View File

@ -3493,7 +3493,16 @@ const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *ty
return nullptr; return nullptr;
} }
//--------------------------------------------------------------------------- bool Scope::hasInlineFunction() const
{
for (std::list<Scope*>::const_iterator it = nestedList.begin(); it != nestedList.end(); ++it) {
const Scope *s = *it;
// Inline function
if (s->type == Scope::eUnconditional && Token::Match(s->classStart->previous(), ") {"))
return true;
}
return false;
}
void Scope::findFunctionInBase(const std::string & name, size_t args, std::vector<const Function *> & matches) const void Scope::findFunctionInBase(const std::string & name, size_t args, std::vector<const Function *> & matches) const
{ {

View File

@ -898,6 +898,9 @@ public:
type == eTry || type == eCatch); type == eTry || type == eCatch);
} }
// Is there lambda/inline function(s) in this scope?
bool hasInlineFunction() const;
/** /**
* @brief find a function * @brief find a function
* @param tok token of function call * @param tok token of function call

View File

@ -121,6 +121,8 @@ private:
TEST_CASE(nestedAllocation); TEST_CASE(nestedAllocation);
TEST_CASE(testKeywords); // #6767 TEST_CASE(testKeywords); // #6767
TEST_CASE(inlineFunction); // #3989
} }
void check(const char code[], bool cpp = false) { void check(const char code[], bool cpp = false) {
@ -1223,6 +1225,19 @@ private:
"}", false); "}", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void inlineFunction() {
check("int test() {\n"
" char *c;\n"
" int ret() {\n"
" free(c);\n"
" return 0;\n"
" }\n"
" c = malloc(128);\n"
" return ret();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
}; };
REGISTER_TEST(TestLeakAutoVar) REGISTER_TEST(TestLeakAutoVar)

View File

@ -250,6 +250,8 @@ private:
TEST_CASE(allocfunc13); // Ticket #4494 and #4540 - class function TEST_CASE(allocfunc13); // Ticket #4494 and #4540 - class function
TEST_CASE(allocfunc14); // Use pointer before returning it TEST_CASE(allocfunc14); // Use pointer before returning it
TEST_CASE(inlineFunction); // #3989 - inline function
TEST_CASE(throw1); TEST_CASE(throw1);
TEST_CASE(throw2); TEST_CASE(throw2);
@ -2679,6 +2681,19 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void inlineFunction() { // #3989 - inline function
check("int test() {\n"
" char *c;\n"
" int ret() {\n"
" free(c);\n"
" return 0;\n"
" }\n"
" c = malloc(128);\n"
" return ret();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void throw1() { void throw1() {
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"