Fixed #7502 (Correct exit code if never used function is found) (#1026)

This commit is contained in:
Ivan Maidanski 2018-01-12 10:24:01 +03:00 committed by Daniel Marjamäki
parent 03603c85cf
commit 97ffec85c0
10 changed files with 34 additions and 15 deletions

View File

@ -888,7 +888,8 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
c++;
}
}
cppcheck.analyseWholeProgram();
if (cppcheck.analyseWholeProgram())
returnValue++;
} else if (!ThreadExecutor::isEnabled()) {
std::cout << "No thread support yet implemented for this platform." << std::endl;
} else {

View File

@ -109,10 +109,12 @@ public:
return nullptr;
}
virtual void analyseWholeProgram(const std::list<FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger) {
// Return true if an error is reported.
virtual bool analyseWholeProgram(const std::list<FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger) {
(void)fileInfo;
(void)settings;
(void)errorLogger;
return false;
}
protected:

View File

@ -2022,8 +2022,9 @@ Check::FileInfo * CheckBufferOverrun::loadFileInfoFromXml(const tinyxml2::XMLEle
}
void CheckBufferOverrun::analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings&, ErrorLogger &errorLogger)
bool CheckBufferOverrun::analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings&, ErrorLogger &errorLogger)
{
bool errors = false;
// Merge all fileInfo
MyFileInfo all;
for (std::list<Check::FileInfo*>::const_iterator it = fileInfo.begin(); it != fileInfo.end(); ++it) {
@ -2069,8 +2070,10 @@ void CheckBufferOverrun::analyseWholeProgram(const std::list<Check::FileInfo*> &
"arrayIndexOutOfBounds",
CWE788, false);
errorLogger.reportErr(errmsg);
errors = true;
}
}
return errors;
}
unsigned int CheckBufferOverrun::sizeOfType(const Token *type) const

View File

@ -244,7 +244,7 @@ public:
Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const;
/** @brief Analyse all file infos for all TU */
void analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger);
bool analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger);
/**
* Calculates sizeof value for given type.

View File

@ -237,8 +237,9 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi
void CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings& settings)
bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings& settings)
{
bool errors = false;
for (std::map<std::string, FunctionUsage>::const_iterator it = _functions.begin(); it != _functions.end(); ++it) {
const FunctionUsage &func = it->second;
if (func.usedOtherFile || func.filename.empty())
@ -252,15 +253,18 @@ void CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings
if (func.filename != "+")
filename = func.filename;
unusedFunctionError(errorLogger, filename, func.lineNumber, it->first);
errors = true;
} else if (! func.usedOtherFile) {
/** @todo add error message "function is only used in <file> it can be static" */
/*
std::ostringstream errmsg;
errmsg << "The function '" << it->first << "' is only used in the file it was declared in so it should have local linkage.";
_errorLogger->reportErr( errmsg.str() );
errors = true;
*/
}
}
return errors;
}
void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger,
@ -291,10 +295,10 @@ Check::FileInfo *CheckUnusedFunctions::getFileInfo(const Tokenizer *tokenizer, c
return nullptr;
}
void CheckUnusedFunctions::analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger)
bool CheckUnusedFunctions::analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger)
{
(void)fileInfo;
check(&errorLogger, settings);
return check(&errorLogger, settings);
}
CheckUnusedFunctions::FunctionDecl::FunctionDecl(const Function *f)

View File

@ -55,13 +55,14 @@ public:
// * What functions are declared
void parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings *settings, bool clear=true);
void check(ErrorLogger * const errorLogger, const Settings& settings);
// Return true if an error is reported.
bool check(ErrorLogger * const errorLogger, const Settings& settings);
/** @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);
bool analyseWholeProgram(const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger);
static CheckUnusedFunctions instance;

View File

@ -809,11 +809,13 @@ void CppCheck::getErrorMessages()
Preprocessor::getErrorMessages(this, &s);
}
void CppCheck::analyseWholeProgram()
bool CppCheck::analyseWholeProgram()
{
bool errors = false;
// Analyse the tokens
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it)
(*it)->analyseWholeProgram(fileInfo, _settings, *this);
errors |= (*it)->analyseWholeProgram(fileInfo, _settings, *this);
return errors;
}
void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map<std::string, std::size_t> &files)

View File

@ -131,9 +131,10 @@ public:
/** Analyse whole program, run this after all TUs has been scanned.
* This is deprecated and the plan is to remove this when
* .analyzeinfo is good enough
* .analyzeinfo is good enough.
* Return true if an error is reported.
*/
void analyseWholeProgram();
bool analyseWholeProgram();
/** analyse whole program use .analyzeinfo files */
void analyseWholeProgram(const std::string &buildDir, const std::map<std::string, std::size_t> &files);

View File

@ -161,7 +161,8 @@ private:
for (std::map<std::string, std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
exitCode |= cppCheck.check(file->first, file->second);
}
cppCheck.analyseWholeProgram();
if (cppCheck.analyseWholeProgram())
exitCode |= settings.exitCode;
reportSuppressions(settings, files);

View File

@ -77,7 +77,11 @@ private:
// Check for unused functions..
CheckUnusedFunctions checkUnusedFunctions(&tokenizer, &settings, this);
checkUnusedFunctions.parseTokens(tokenizer, "someFile.c", &settings);
checkUnusedFunctions.check(this, settings);
// check() returns error if and only if errout is not empty.
if (checkUnusedFunctions.check(this, settings))
ASSERT(errout.str() != "");
else
ASSERT_EQUALS("", errout.str());
}
void incondition() {