Added --cppcheck-build-dir flag

This commit is contained in:
Daniel Marjamäki 2016-10-29 12:18:11 +02:00
parent 324f68ca36
commit 9ff3e85899
17 changed files with 299 additions and 15 deletions

View File

@ -128,7 +128,8 @@ MAN_SOURCE=man/cppcheck.1.xml
###### Object Files
LIBOBJ = $(SRCDIR)/astutils.o \
LIBOBJ = $(SRCDIR)/analyzerinfo.o \
$(SRCDIR)/astutils.o \
$(SRCDIR)/check.o \
$(SRCDIR)/check64bit.o \
$(SRCDIR)/checkassert.o \
@ -299,6 +300,9 @@ endif
###### Build
$(SRCDIR)/analyzerinfo.o: lib/analyzerinfo.cpp lib/cxx11emu.h lib/analyzerinfo.h lib/config.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/analyzerinfo.o $(SRCDIR)/analyzerinfo.cpp
$(SRCDIR)/astutils.o: lib/astutils.cpp lib/cxx11emu.h lib/astutils.h lib/symboldatabase.h lib/config.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/astutils.o $(SRCDIR)/astutils.cpp
@ -380,10 +384,10 @@ $(SRCDIR)/checkunusedvar.o: lib/checkunusedvar.cpp lib/cxx11emu.h lib/checkunuse
$(SRCDIR)/checkvaarg.o: lib/checkvaarg.cpp lib/cxx11emu.h lib/checkvaarg.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/platform.h lib/importproject.h lib/timer.h lib/symboldatabase.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/checkvaarg.o $(SRCDIR)/checkvaarg.cpp
$(SRCDIR)/cppcheck.o: lib/cppcheck.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/preprocessor.h lib/path.h lib/version.h
$(SRCDIR)/cppcheck.o: lib/cppcheck.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h lib/preprocessor.h lib/path.h lib/version.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/cppcheck.o $(SRCDIR)/cppcheck.cpp
$(SRCDIR)/errorlogger.o: lib/errorlogger.cpp lib/cxx11emu.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/path.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/utils.h
$(SRCDIR)/errorlogger.o: lib/errorlogger.cpp lib/cxx11emu.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/path.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h lib/utils.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/errorlogger.o $(SRCDIR)/errorlogger.cpp
$(SRCDIR)/importproject.o: lib/importproject.cpp lib/cxx11emu.h lib/importproject.h lib/config.h lib/platform.h lib/path.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/token.h lib/valueflow.h
@ -434,10 +438,10 @@ $(SRCDIR)/tokenlist.o: lib/tokenlist.cpp lib/cxx11emu.h lib/tokenlist.h lib/conf
$(SRCDIR)/valueflow.o: lib/valueflow.cpp lib/cxx11emu.h lib/valueflow.h lib/config.h lib/astutils.h lib/errorlogger.h lib/suppressions.h lib/mathlib.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/symboldatabase.h lib/token.h lib/tokenlist.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(SRCDIR)/valueflow.o $(SRCDIR)/valueflow.cpp
cli/cmdlineparser.o: cli/cmdlineparser.cpp lib/cxx11emu.h cli/cmdlineparser.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h cli/cppcheckexecutor.h cli/filelister.h lib/path.h cli/threadexecutor.h
cli/cmdlineparser.o: cli/cmdlineparser.cpp lib/cxx11emu.h cli/cmdlineparser.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h cli/cppcheckexecutor.h cli/filelister.h lib/path.h cli/threadexecutor.h
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o cli/cmdlineparser.o cli/cmdlineparser.cpp
cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp lib/cxx11emu.h cli/cppcheckexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h cli/cmdlineparser.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h cli/filelister.h lib/path.h lib/pathmatch.h lib/preprocessor.h cli/threadexecutor.h lib/utils.h
cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp lib/cxx11emu.h cli/cppcheckexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h cli/cmdlineparser.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h cli/filelister.h lib/path.h lib/pathmatch.h lib/preprocessor.h cli/threadexecutor.h lib/utils.h
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o cli/cppcheckexecutor.o cli/cppcheckexecutor.cpp
cli/filelister.o: cli/filelister.cpp lib/cxx11emu.h cli/filelister.h lib/path.h lib/config.h lib/pathmatch.h
@ -446,7 +450,7 @@ cli/filelister.o: cli/filelister.cpp lib/cxx11emu.h cli/filelister.h lib/path.h
cli/main.o: cli/main.cpp lib/cxx11emu.h cli/cppcheckexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o cli/main.o cli/main.cpp
cli/threadexecutor.o: cli/threadexecutor.cpp lib/cxx11emu.h cli/threadexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/importproject.h lib/platform.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h cli/cppcheckexecutor.h
cli/threadexecutor.o: cli/threadexecutor.cpp lib/cxx11emu.h cli/threadexecutor.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/importproject.h lib/platform.h lib/cppcheck.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h cli/cppcheckexecutor.h
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o cli/threadexecutor.o cli/threadexecutor.cpp
test/options.o: test/options.cpp lib/cxx11emu.h test/options.h
@ -488,10 +492,10 @@ test/testcondition.o: test/testcondition.cpp lib/cxx11emu.h lib/tokenize.h lib/e
test/testconstructors.o: test/testconstructors.cpp lib/cxx11emu.h lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checkclass.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testconstructors.o test/testconstructors.cpp
test/testcppcheck.o: test/testcppcheck.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h test/testsuite.h lib/path.h
test/testcppcheck.o: test/testcppcheck.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h test/testsuite.h lib/path.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testcppcheck.o test/testcppcheck.cpp
test/testerrorlogger.o: test/testerrorlogger.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h test/testsuite.h
test/testerrorlogger.o: test/testerrorlogger.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testerrorlogger.o test/testerrorlogger.cpp
test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/cxx11emu.h lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checkexceptionsafety.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/utils.h test/testsuite.h
@ -578,13 +582,13 @@ test/teststring.o: test/teststring.cpp lib/cxx11emu.h lib/tokenize.h lib/errorlo
test/testsuite.o: test/testsuite.cpp lib/cxx11emu.h test/testsuite.h lib/errorlogger.h lib/config.h lib/suppressions.h test/options.h test/redirect.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testsuite.o test/testsuite.cpp
test/testsuppressions.o: test/testsuppressions.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h test/testsuite.h
test/testsuppressions.o: test/testsuppressions.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testsuppressions.o test/testsuppressions.cpp
test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/cxx11emu.h test/testsuite.h lib/errorlogger.h lib/config.h lib/suppressions.h test/testutils.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/platform.h lib/importproject.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/symboldatabase.h lib/token.h lib/valueflow.h lib/utils.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testsymboldatabase.o test/testsymboldatabase.cpp
test/testthreadexecutor.o: test/testthreadexecutor.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h test/testsuite.h
test/testthreadexecutor.o: test/testthreadexecutor.cpp lib/cxx11emu.h lib/cppcheck.h lib/config.h lib/settings.h lib/library.h lib/mathlib.h lib/standards.h lib/errorlogger.h lib/suppressions.h lib/platform.h lib/importproject.h lib/timer.h lib/check.h lib/token.h lib/valueflow.h lib/tokenize.h lib/tokenlist.h lib/analyzerinfo.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testthreadexecutor.o test/testthreadexecutor.cpp
test/testtimer.o: test/testtimer.cpp lib/cxx11emu.h lib/timer.h lib/config.h test/testsuite.h lib/errorlogger.h lib/suppressions.h

View File

@ -120,6 +120,9 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
return true;
}
else if (std::strncmp(argv[i], "--cppcheck-build-dir=", 21) == 0)
_settings->buildDir = argv[i] + 21;
// Flag used for various purposes during debugging
else if (std::strcmp(argv[i], "--debug") == 0)
_settings->debug = _settings->debugwarnings = true;
@ -797,6 +800,9 @@ void CmdLineParser::PrintHelp()
"If a directory is given instead of a filename, *.cpp, *.cxx, *.cc, *.c++, *.c,\n"
"*.tpp, and *.txx files are checked recursively from the given directory.\n\n"
"Options:\n"
" --analyze-dir=<dir> Analysis output directory. Useful for various data.\n"
" Some possible usages are; whole program analysis,\n"
" incremental analysis, distributed analysis.\n"
" --check-config Check cppcheck configuration. The normal code\n"
" analysis is disabled by this flag.\n"
" --check-library Show information messages when library files have\n"

104
lib/analyzerinfo.cpp Normal file
View File

@ -0,0 +1,104 @@
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2016 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "analyzerinfo.h"
#include "path.h"
#include <tinyxml2.h>
AnalyzerInformation::AnalyzerInformation() {}
AnalyzerInformation::~AnalyzerInformation()
{
close();
}
void AnalyzerInformation::close()
{
analyzerInfoFile.clear();
if (fout.is_open()) {
fout << "</analyzerinfo>\n";
fout.close();
}
}
static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t checksum, std::list<ErrorLogger::ErrorMessage> *errors)
{
tinyxml2::XMLDocument doc;
tinyxml2::XMLError error = doc.LoadFile(analyzerInfoFile.c_str());
if (error != tinyxml2::XML_SUCCESS)
return false;
const tinyxml2::XMLElement * const rootNode = doc.FirstChildElement();
if (rootNode == nullptr)
return false;
const char *attr = rootNode->Attribute("checksum");
if (!attr || attr != std::to_string(checksum))
return false;
for (const tinyxml2::XMLElement *e = rootNode->FirstChildElement(); e; e = e->NextSiblingElement()) {
if (std::strcmp(e->Name(), "error") == 0)
errors->push_back(ErrorLogger::ErrorMessage(e));
}
return true;
}
bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, std::size_t checksum, std::list<ErrorLogger::ErrorMessage> *errors)
{
if (buildDir.empty() || sourcefile.empty())
return true;
close();
analyzerInfoFile = Path::fromNativeSeparators(buildDir);
if (analyzerInfoFile.back() != '/')
analyzerInfoFile += '/';
const std::string::size_type pos = sourcefile.rfind("/");
if (pos == std::string::npos)
analyzerInfoFile += sourcefile;
else
analyzerInfoFile += sourcefile.substr(pos+1);
analyzerInfoFile += ".analyzerinfo";
const std::string start = "<analyzerinfo checksum=\"" + std::to_string(checksum) + "\">";
if (skipAnalysis(analyzerInfoFile, checksum, errors)) {
return false;
}
fout.open(analyzerInfoFile);
if (fout.is_open()) {
fout << "<?xml version=\"1.0\"?>\n";
fout << start << '\n';
} else {
analyzerInfoFile.clear();
}
return true;
}
void AnalyzerInformation::reportErr(const ErrorLogger::ErrorMessage &msg, bool verbose)
{
if (fout.is_open())
fout << msg.toXML(verbose,2) << '\n';
}
void AnalyzerInformation::setFileInfo(const std::string &check, const std::string &fileInfo)
{
if (fout.is_open() && !fileInfo.empty())
fout << " <FileInfo check=\"" << check << "\">\n" << fileInfo << " </FileInfo>\n";
}

63
lib/analyzerinfo.h Normal file
View File

@ -0,0 +1,63 @@
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2016 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
#ifndef analyzerinfoH
#define analyzerinfoH
//---------------------------------------------------------------------------
#include "config.h"
#include "errorlogger.h"
#include <string>
#include <fstream>
/// @addtogroup Core
/// @{
/**
* @brief Analyzer information
*
* Store various analysis information:
* - checksum
* - error messages
* - whole program analysis data
*
* The information can be used for various purposes. It allows:
* - 'make' - only analyze TUs that are changed and generate full report
* - should be possible to add distributed analysis later
* - multi-threaded whole program analysis
*/
class CPPCHECKLIB AnalyzerInformation {
public:
AnalyzerInformation();
~AnalyzerInformation();
/** Close current TU.analyzerinfo file */
void close();
bool analyzeFile(const std::string &buildDir, const std::string &sourcefile, std::size_t checksum, std::list<ErrorLogger::ErrorMessage> *errors);
void reportErr(const ErrorLogger::ErrorMessage &msg, bool verbose);
void setFileInfo(const std::string &check, const std::string &fileInfo);
private:
std::ofstream fout;
std::string analyzerInfoFile;
};
/// @}
//---------------------------------------------------------------------------
#endif // analyzerinfoH

View File

@ -90,6 +90,9 @@ public:
public:
FileInfo() {}
virtual ~FileInfo() {}
virtual std::string toString() const {
return std::string();
}
};
virtual FileInfo * getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const {

View File

@ -1896,6 +1896,24 @@ void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::s
"not be accessed if the index is out of limits.", CWE398, false);
}
std::string CheckBufferOverrun::MyFileInfo::toString() const
{
std::ostringstream ret;
for (std::map<std::string, struct CheckBufferOverrun::MyFileInfo::ArrayUsage>::const_iterator it = arrayUsage.begin(); it != arrayUsage.end(); ++it) {
ret << " <ArrayUsage"
<< " array=\"" << ErrorLogger::toxml(it->first) << '\"'
<< " index=\"" << it->second.index << '\"'
<< " fileName=\"" << ErrorLogger::toxml(it->second.fileName) << '\"'
<< " linenr=\"" << it->second.linenr << "\"/>\n";
}
for (std::map<std::string, MathLib::bigint>::const_iterator it = arraySize.begin(); it != arraySize.end(); ++it) {
ret << " <ArraySize"
<< " array=\"" << ErrorLogger::toxml(it->first) << '\"'
<< " size=\"" << it->second << "\"/>\n";
}
return ret.str();
}
Check::FileInfo* CheckBufferOverrun::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
{
(void)settings;

View File

@ -209,6 +209,8 @@ public:
/* data for multifile checking */
class MyFileInfo : public Check::FileInfo {
public:
std::string toString() const;
struct ArrayUsage {
MathLib::bigint index;
std::string fileName;

View File

@ -272,3 +272,19 @@ void CheckUnusedFunctions::analyseWholeProgram(const std::list<Check::FileInfo*>
(void)fileInfo;
check(&errorLogger, settings);
}
std::string CheckUnusedFunctions::analyzerInfo(const std::string &filename) const
{
std::ostringstream ret;
for (std::map<std::string, FunctionUsage>::const_iterator it = _functions.begin(); it != _functions.end(); ++it) {
if (it->second.filename != filename)
continue;
ret << " <functionusage"
<< " function=\"" << ErrorLogger::toxml(it->first) << '\"'
<< " lineNumber=\"" << it->second.lineNumber << '\"'
<< " usedSameFile=\"" << (it->second.usedSameFile?1:0) << '\"'
<< " usedOtherFile=\"" << (it->second.usedOtherFile?1:0) << "\"/>\n";
}
return ret.str();
}

View File

@ -55,6 +55,8 @@ public:
static CheckUnusedFunctions instance;
std::string analyzerInfo(const std::string &filename) const;
private:
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
@ -72,9 +74,7 @@ private:
/**
* Dummy implementation, just to provide error for --errorlist
*/
void runSimplifiedChecks(const Tokenizer *, const Settings *, ErrorLogger *) {
}
void runSimplifiedChecks(const Tokenizer *, const Settings *, ErrorLogger *) {}
static std::string myName() {
return "Unused functions";

View File

@ -24,6 +24,8 @@
#include "check.h"
#include "path.h"
#include "checkunusedfunctions.h"
#include <algorithm>
#include <fstream>
#include <sstream>
@ -135,6 +137,18 @@ unsigned int CppCheck::processFile(const std::string& filename, const std::strin
tokens1.removeComments();
preprocessor.removeComments();
if (!_settings.buildDir.empty()) {
std::list<ErrorLogger::ErrorMessage> errors;
unsigned int checksum = preprocessor.calculateChecksum(tokens1);
if (!analyzerInformation.analyzeFile(_settings.buildDir, filename, checksum, &errors)) {
while (!errors.empty()) {
reportErr(errors.front());
errors.pop_front();
}
return exitcode; // known results => no need to reanalyze file
}
}
// Get directives
preprocessor.setDirectives(tokens1);
@ -343,6 +357,9 @@ unsigned int CppCheck::processFile(const std::string& filename, const std::strin
exitcode=1; // e.g. reflect a syntax error
}
analyzerInformation.setFileInfo("CheckUnusedFunctions", CheckUnusedFunctions::instance.analyzerInfo(filename));
analyzerInformation.close();
// In jointSuppressionReport mode, unmatched suppressions are
// collected after all files are processed
if (!_settings.jointSuppressionReport && (_settings.isEnabled("information") || _settings.checkConfiguration)) {
@ -411,8 +428,10 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer)
// Analyse the tokens..
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
Check::FileInfo *fi = (*it)->getFileInfo(&tokenizer, &_settings);
if (fi != nullptr)
if (fi != nullptr) {
fileInfo.push_back(fi);
analyzerInformation.setFileInfo((*it)->name(), fi->toString());
}
}
executeRules("normal", tokenizer);
@ -635,6 +654,7 @@ void CppCheck::reportErr(const ErrorLogger::ErrorMessage &msg)
_errorList.push_back(errmsg);
_errorLogger.reportErr(msg);
analyzerInformation.reportErr(msg, _settings.verbose);
}
void CppCheck::reportOut(const std::string &outmsg)

View File

@ -25,6 +25,7 @@
#include "settings.h"
#include "errorlogger.h"
#include "check.h"
#include "analyzerinfo.h"
#include <string>
#include <list>
@ -214,6 +215,8 @@ private:
/** File info used for whole program analysis */
std::list<Check::FileInfo*> fileInfo;
AnalyzerInformation analyzerInformation;
};
/// @}

View File

@ -111,6 +111,23 @@ ErrorLogger::ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack
setmsg(msg);
}
ErrorLogger::ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg) : _cwe(0U)
{
_id = errmsg->Attribute("id");
_severity = Severity::fromString(errmsg->Attribute("severity"));
const char *attr = errmsg->Attribute("cwe");
std::istringstream(attr ? attr : "0") >> _cwe.id;
attr = errmsg->Attribute("inconclusive");
_inconclusive = attr && (std::strcmp(attr, "true") == 0);
_shortMessage = errmsg->Attribute("msg");
_verboseMessage = errmsg->Attribute("verbose");
for (const tinyxml2::XMLElement *e = errmsg->FirstChildElement(); e; e = e->NextSiblingElement()) {
if (std::strcmp(e->Name(),"location")==0) {
_callStack.push_back(ErrorLogger::ErrorMessage::FileLocation(e->Attribute("file"), std::atoi(e->Attribute("line"))));
}
}
}
void ErrorLogger::ErrorMessage::setmsg(const std::string &msg)
{
// If a message ends to a '\n' and contains only a one '\n'

View File

@ -40,6 +40,9 @@ struct CWE {
class Token;
class TokenList;
namespace tinyxml2 {
class XMLElement;
}
/// @addtogroup Core
/// @{
@ -213,6 +216,7 @@ public:
ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive);
ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, bool inconclusive);
ErrorMessage();
ErrorMessage(const tinyxml2::XMLElement * const errmsg);
/**
* Format the error message in XML format

View File

@ -4,6 +4,7 @@ include($$PWD/pcrerules.pri)
include($$PWD/../externals/externals.pri)
INCLUDEPATH += $$PWD
HEADERS += $${PWD}/check.h \
$${PWD}/analyzerinfo.h \
$${PWD}/astutils.h \
$${PWD}/check.h \
$${PWD}/check64bit.h \
@ -51,7 +52,8 @@ HEADERS += $${PWD}/check.h \
$${PWD}/valueflow.h \
SOURCES += $${PWD}/astutils.cpp \
SOURCES += $${PWD}/analyzerinfo.cpp \
$${PWD}/astutils.cpp \
$${PWD}/check.cpp \
$${PWD}/check64bit.cpp \
$${PWD}/checkassert.cpp \

View File

@ -24,6 +24,7 @@
#include "simplecpp.h"
#include <algorithm>
#include <functional>
#include <sstream>
#include <cstdlib>
#include <cctype>
@ -806,3 +807,19 @@ void Preprocessor::dump(std::ostream &out) const
}
out << " </directivelist>" << std::endl;
}
std::size_t Preprocessor::calculateChecksum(const simplecpp::TokenList &tokens1) const
{
std::ostringstream ostr;
for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
if (!tok->comment)
ostr << tok->str;
}
for (std::map<std::string, simplecpp::TokenList *>::const_iterator it = tokenlists.begin(); it != tokenlists.end(); ++it) {
for (const simplecpp::Token *tok = it->second->cfront(); tok; tok = tok->next) {
if (!tok->comment)
ostr << tok->str;
}
}
return std::hash<std::string> {}(ostr.str());
}

View File

@ -160,6 +160,8 @@ public:
bool validateCfg(const std::string &cfg, const std::list<simplecpp::MacroUsage> &macroUsageList);
void validateCfgError(const std::string &file, const unsigned int line, const std::string &cfg, const std::string &macro);
std::size_t calculateChecksum(const simplecpp::TokenList &tokens1) const;
private:
/**

View File

@ -56,6 +56,9 @@ private:
public:
Settings();
/** @brief --cppcheck-build-dir */
std::string buildDir;
/** @brief Is --debug given? */
bool debug;