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:
Daniel Marjamäki 2015-07-24 08:30:38 +02:00
parent ed74a3dcc6
commit 234669b02b
6 changed files with 3 additions and 170 deletions

View File

@ -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

View File

@ -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() == ")")

View File

@ -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();

View File

@ -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);

View File

@ -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"

View File

@ -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"