Fixed #2662 (Segfault: overloaded function call function with same name)
This commit is contained in:
parent
3259239dfe
commit
5f36ede4f5
@ -104,7 +104,7 @@ bool CheckMemoryLeak::isclass(const Tokenizer *_tokenizer, const Token *tok) con
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, unsigned int varid) const
|
CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, unsigned int varid, std::list<const Token *> *callstack) const
|
||||||
{
|
{
|
||||||
// What we may have...
|
// What we may have...
|
||||||
// * var = (char *)malloc(10);
|
// * var = (char *)malloc(10);
|
||||||
@ -190,7 +190,19 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
|
|||||||
|
|
||||||
// User function
|
// User function
|
||||||
const Token *ftok = tokenizer->getFunctionTokenByName(tok2->str().c_str());
|
const Token *ftok = tokenizer->getFunctionTokenByName(tok2->str().c_str());
|
||||||
return functionReturnType(ftok);
|
if (ftok == NULL)
|
||||||
|
return No;
|
||||||
|
|
||||||
|
// Prevent recursion
|
||||||
|
if (callstack && std::find(callstack->begin(), callstack->end(), ftok) != callstack->end())
|
||||||
|
return No;
|
||||||
|
|
||||||
|
std::list<const Token *> cs;
|
||||||
|
if (!callstack)
|
||||||
|
callstack = &cs;
|
||||||
|
|
||||||
|
callstack->push_back(ftok);
|
||||||
|
return functionReturnType(ftok, callstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -386,13 +398,11 @@ void CheckMemoryLeak::mismatchAllocDealloc(const std::list<const Token *> &calls
|
|||||||
reportErr(callstack, Severity::error, "mismatchAllocDealloc", "Mismatching allocation and deallocation: " + varname);
|
reportErr(callstack, Severity::error, "mismatchAllocDealloc", "Mismatching allocation and deallocation: " + varname);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok) const
|
CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok, std::list<const Token *> *callstack) const
|
||||||
{
|
{
|
||||||
if (!tok)
|
if (!tok)
|
||||||
return No;
|
return No;
|
||||||
|
|
||||||
const std::string functionName = tok->str();
|
|
||||||
|
|
||||||
// Locate start of function
|
// Locate start of function
|
||||||
while (tok)
|
while (tok)
|
||||||
{
|
{
|
||||||
@ -437,11 +447,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok)
|
|||||||
}
|
}
|
||||||
else if (tok2->str() == "return")
|
else if (tok2->str() == "return")
|
||||||
{
|
{
|
||||||
// recursion => bail out
|
AllocType allocType = getAllocationType(tok2->next(), 0, callstack);
|
||||||
if (tok2->strAt(1) == functionName)
|
|
||||||
return No;
|
|
||||||
|
|
||||||
AllocType allocType = getAllocationType(tok2->next(), 0);
|
|
||||||
if (allocType != No)
|
if (allocType != No)
|
||||||
return allocType;
|
return allocType;
|
||||||
}
|
}
|
||||||
@ -457,11 +463,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok)
|
|||||||
{
|
{
|
||||||
if (Token::Match(tok, "%varid% =", varid))
|
if (Token::Match(tok, "%varid% =", varid))
|
||||||
{
|
{
|
||||||
// recursion => bail out
|
allocType = getAllocationType(tok->tokAt(2), varid, callstack);
|
||||||
if (tok->strAt(2) == functionName)
|
|
||||||
return No;
|
|
||||||
|
|
||||||
allocType = getAllocationType(tok->tokAt(2), varid);
|
|
||||||
}
|
}
|
||||||
if (Token::Match(tok, "= %varid% ;", varid))
|
if (Token::Match(tok, "= %varid% ;", varid))
|
||||||
{
|
{
|
||||||
|
@ -114,7 +114,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Get type of allocation at given position
|
* @brief Get type of allocation at given position
|
||||||
*/
|
*/
|
||||||
AllocType getAllocationType(const Token *tok2, unsigned int varid) const;
|
AllocType getAllocationType(const Token *tok2, unsigned int varid, std::list<const Token *> *callstack = NULL) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get type of reallocation at given position
|
* @brief Get type of reallocation at given position
|
||||||
@ -144,7 +144,7 @@ public:
|
|||||||
void memleakUponReallocFailureError(const Token *tok, const std::string &varname);
|
void memleakUponReallocFailureError(const Token *tok, const std::string &varname);
|
||||||
|
|
||||||
/** What type of allocated memory does the given function return? */
|
/** What type of allocated memory does the given function return? */
|
||||||
AllocType functionReturnType(const Token *tok) const;
|
AllocType functionReturnType(const Token *tok, std::list<const Token *> *callstack = NULL) const;
|
||||||
|
|
||||||
/** Function allocates pointed-to argument (a la asprintf)? */
|
/** Function allocates pointed-to argument (a la asprintf)? */
|
||||||
const char *functionArgAlloc(const Token *tok, unsigned int targetpar, AllocType &allocType) const;
|
const char *functionArgAlloc(const Token *tok, unsigned int targetpar, AllocType &allocType) const;
|
||||||
|
@ -3631,6 +3631,18 @@ private:
|
|||||||
" char *s = foo();\n"
|
" char *s = foo();\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("int shl()\n"
|
||||||
|
"{\n"
|
||||||
|
" int a = shr();\n"
|
||||||
|
" return a;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"int shr()\n"
|
||||||
|
"{\n"
|
||||||
|
" return shl();\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user