Removed the UninitVar::analyseFunctions(). This was written for multifile checking however it did not work as it should => no multifile errors can be detected.
This commit is contained in:
parent
ed74a3dcc6
commit
234669b02b
2
Makefile
2
Makefile
|
@ -321,7 +321,7 @@ $(SRCDIR)/checkio.o: lib/checkio.cpp lib/cxx11emu.h lib/checkio.h lib/check.h li
|
|||
$(SRCDIR)/checkleakautovar.o: lib/checkleakautovar.cpp lib/cxx11emu.h lib/checkleakautovar.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h lib/checkmemoryleak.h lib/symboldatabase.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -std=c++0x -c -o $(SRCDIR)/checkleakautovar.o $(SRCDIR)/checkleakautovar.cpp
|
||||
|
||||
$(SRCDIR)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/cxx11emu.h lib/checkmemoryleak.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h lib/symboldatabase.h lib/utils.h lib/checkuninitvar.h
|
||||
$(SRCDIR)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/cxx11emu.h lib/checkmemoryleak.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h lib/symboldatabase.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -std=c++0x -c -o $(SRCDIR)/checkmemoryleak.o $(SRCDIR)/checkmemoryleak.cpp
|
||||
|
||||
$(SRCDIR)/checknonreentrantfunctions.o: lib/checknonreentrantfunctions.cpp lib/cxx11emu.h lib/checknonreentrantfunctions.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h lib/symboldatabase.h lib/utils.h
|
||||
|
|
|
@ -2675,16 +2675,8 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var
|
|||
|
||||
|
||||
|
||||
#include "checkuninitvar.h" // CheckUninitVar::analyse
|
||||
|
||||
void CheckMemoryLeakNoVar::check()
|
||||
{
|
||||
std::set<std::string> uvarFunctions;
|
||||
{
|
||||
const CheckUninitVar c(_tokenizer, _settings, _errorLogger);
|
||||
c.analyseFunctions(_tokenizer, uvarFunctions);
|
||||
}
|
||||
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
// only check functions
|
||||
|
@ -2723,10 +2715,6 @@ void CheckMemoryLeakNoVar::check()
|
|||
functionCallLeak(tok2, tok2->strAt(1), functionName);
|
||||
break;
|
||||
}
|
||||
if (uvarFunctions.find(functionName) != uvarFunctions.end()) {
|
||||
functionCallLeak(tok2, tok2->strAt(1), functionName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else if (tok3->str() == ")")
|
||||
|
|
|
@ -35,121 +35,6 @@ namespace {
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
namespace UninitVar {
|
||||
void analyseFunctions(const Token * const tokens, std::set<std::string> &func)
|
||||
{
|
||||
for (const Token *tok = tokens; tok; tok = tok->next()) {
|
||||
if (tok->str() == "{") {
|
||||
tok = tok->link();
|
||||
continue;
|
||||
}
|
||||
if (tok->str() != "::" && Token::Match(tok->next(), "%name% ( %type%")) {
|
||||
if (!Token::Match(tok->linkAt(2), ") [{;]"))
|
||||
continue;
|
||||
const Token *tok2 = tok->tokAt(3);
|
||||
while (tok2 && tok2->str() != ")") {
|
||||
if (tok2->str() == ",")
|
||||
tok2 = tok2->next();
|
||||
|
||||
if (Token::Match(tok2, "%type% %name% ,|)") && tok2->isStandardType()) {
|
||||
tok2 = tok2->tokAt(2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tok2->isStandardType() && Token::Match(tok2, "%type% & %name% ,|)")) {
|
||||
const unsigned int varid(tok2->tokAt(2)->varId());
|
||||
|
||||
// flags for read/write
|
||||
bool r = false, w = false;
|
||||
|
||||
// check how the variable is used in the function
|
||||
unsigned int indentlevel = 0;
|
||||
for (const Token *tok3 = tok2; tok3; tok3 = tok3->next()) {
|
||||
if (tok3->str() == "{")
|
||||
++indentlevel;
|
||||
else if (tok3->str() == "}") {
|
||||
if (indentlevel <= 1)
|
||||
break;
|
||||
--indentlevel;
|
||||
} else if (indentlevel == 0 && tok3->str() == ";")
|
||||
break;
|
||||
else if (indentlevel >= 1 && tok3->varId() == varid) {
|
||||
if (tok3->previous()->type() == Token::eIncDecOp ||
|
||||
tok3->next()->type() == Token::eIncDecOp) {
|
||||
r = true;
|
||||
}
|
||||
|
||||
else {
|
||||
w = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!r || w)
|
||||
break;
|
||||
|
||||
tok2 = tok2->tokAt(3);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "const %type% &|*| const| %name% ,|)") && tok2->next()->isStandardType()) {
|
||||
tok2 = tok2->tokAt(3);
|
||||
while (tok2->isName())
|
||||
tok2 = tok2->next();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "const %type% %name% [ ] ,|)") && tok2->next()->isStandardType()) {
|
||||
tok2 = tok2->tokAt(5);
|
||||
continue;
|
||||
}
|
||||
|
||||
/// @todo enable this code. if pointer is written in function then dead pointer is invalid but valid pointer is ok.
|
||||
/*
|
||||
if (Token::Match(tok2, "const| struct| %type% * %name% ,|)"))
|
||||
{
|
||||
while (tok2->isName())
|
||||
tok2 = tok2->next();
|
||||
tok2 = tok2->tokAt(2);
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// found simple function..
|
||||
if (tok2 && tok2->link() == tok->tokAt(2))
|
||||
func.insert(tok->next()->str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Check::FileInfo *CheckUninitVar::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
|
||||
{
|
||||
(void)settings;
|
||||
MyFileInfo * mfi = new MyFileInfo;
|
||||
analyseFunctions(tokenizer, mfi->uvarFunctions);
|
||||
// TODO: add suspicious function calls
|
||||
return mfi;
|
||||
}
|
||||
|
||||
void CheckUninitVar::analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings&, ErrorLogger &errorLogger)
|
||||
{
|
||||
(void)fileInfo;
|
||||
(void)errorLogger;
|
||||
}
|
||||
|
||||
void CheckUninitVar::analyseFunctions(const Tokenizer *tokenizer, std::set<std::string> &f) const
|
||||
{
|
||||
UninitVar::analyseFunctions(tokenizer->tokens(), f);
|
||||
}
|
||||
|
||||
|
||||
void CheckUninitVar::check()
|
||||
{
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
|
|
@ -80,14 +80,6 @@ public:
|
|||
std::set<std::string> functionCalls;
|
||||
};
|
||||
|
||||
/** @brief Parse current TU and extract file info */
|
||||
Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const;
|
||||
|
||||
/** @brief Analyse all file infos for all TU */
|
||||
void analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger);
|
||||
|
||||
void analyseFunctions(const Tokenizer *tokenizer, std::set<std::string> &f) const;
|
||||
|
||||
void uninitstringError(const Token *tok, const std::string &varname, bool strncpy_);
|
||||
void uninitdataError(const Token *tok, const std::string &varname);
|
||||
void uninitvarError(const Token *tok, const std::string &varname);
|
||||
|
|
|
@ -6259,14 +6259,14 @@ private:
|
|||
"void x() {\n"
|
||||
" set_error(strdup(p));\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Allocation with strdup, set_error doesn't release it.\n", errout.str());
|
||||
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Allocation with strdup, set_error doesn't release it.\n", "", errout.str());
|
||||
check("void set_error(const char *msg) {\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void x() {\n"
|
||||
" set_error(g_strdup(p));\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Allocation with g_strdup, set_error doesn't release it.\n", errout.str());
|
||||
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Allocation with g_strdup, set_error doesn't release it.\n", "", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
|
|
|
@ -1809,39 +1809,7 @@ private:
|
|||
ASSERT_EQUALS(errout.str(), "");
|
||||
}
|
||||
|
||||
std::string analyseFunctions(const char code[]) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
||||
std::set<std::string> f;
|
||||
const CheckUninitVar check((const Tokenizer *)0, (const Settings *)0, (ErrorLogger *)0);
|
||||
check.analyseFunctions(&tokenizer, f);
|
||||
|
||||
std::string ret;
|
||||
for (std::set<std::string>::const_iterator it = f.begin(); it != f.end(); ++it)
|
||||
ret += (ret.empty() ? "" : " ") + *it;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void uninitvar_func() {
|
||||
// function analysis..
|
||||
ASSERT_EQUALS("foo", analyseFunctions("void foo(int x) { }"));
|
||||
ASSERT_EQUALS("foo", analyseFunctions("void foo(int x);"));
|
||||
ASSERT_EQUALS("foo", analyseFunctions("void foo(const int &x) { }"));
|
||||
ASSERT_EQUALS("foo", analyseFunctions("void foo(int &x) { ++x; }"));
|
||||
ASSERT_EQUALS("rename", analyseFunctions("int rename (const char* oldname, const char* newname);")); // Ticket #914
|
||||
ASSERT_EQUALS("rename", analyseFunctions("int rename (const char oldname[], const char newname[]);"));
|
||||
ASSERT_EQUALS("", analyseFunctions("void foo(int &x) { x = 0; }"));
|
||||
ASSERT_EQUALS("", analyseFunctions("void foo(s x) { }"));
|
||||
// TODO: it's ok to pass a valid pointer to "foo". See #2775 and #2946
|
||||
TODO_ASSERT_EQUALS("foo", "", analyseFunctions("void foo(Fred *fred) { fred->x = 0; }"));
|
||||
ASSERT_EQUALS("", analyseFunctions("void foo(int *x) { x[0] = 0; }"));
|
||||
|
||||
// function calls..
|
||||
checkUninitVar("void assignOne(int &x)\n"
|
||||
"{ x = 1; }\n"
|
||||
|
|
Loading…
Reference in New Issue