Compare commits

...

14 Commits

Author SHA1 Message Date
Daniel Marjamäki 70b3cc7638 Set version 2.8.2 2022-07-12 23:11:29 +02:00
Daniel Marjamäki 220effee6a Fixed #11172 (Unmatched suppression for inline suppression even though --suppress=unmatchedSuppression is used) 2022-07-12 23:07:57 +02:00
Daniel Marjamäki f28be6494c Fixed whole program analysis 2022-07-12 23:03:03 +02:00
Daniel Marjamäki ac38e9fdb3 misra.py: strip error message so it does not end with \r 2022-07-08 16:12:21 +02:00
Daniel Marjamäki 48738c22eb misra.py: better handling of --get-rule-text 2022-07-08 14:07:23 +02:00
Daniel Marjamäki c6f7b7db02 Fix syntax error 2022-07-07 19:46:20 +02:00
Daniel Marjamäki 731928a3b6 Catch internal error during whole program analysis 2022-07-07 19:14:58 +02:00
Daniel Marjamäki 32a0641365 Set version 2.8.1 2022-07-07 19:05:21 +02:00
Daniel Marjamäki a626c2d171 Cppcheck: Write product name if provided in xml output 2022-07-07 17:36:21 +02:00
Daniel Marjamäki 4719e725a1 ErrorLogger: do not allocate huge std::string when column is -1 2022-07-07 16:10:47 +02:00
Daniel Marjamäki b44a38bf7f cppcheckdata.py: fix cmd_output() function, handle errors better 2022-07-07 16:07:49 +02:00
Daniel Marjamäki 61f846073d 2.8: Updated Makefile 2022-05-21 12:54:19 +02:00
Daniel Marjamäki f998703a50 2.8: Set version 2022-05-21 12:48:12 +02:00
Daniel Marjamäki 05102aa06e createrelease: tweak sed command to update version 2022-05-21 12:47:30 +02:00
21 changed files with 140 additions and 49 deletions

View File

@ -96,7 +96,7 @@ ifeq (clang++, $(findstring clang++,$(CXX)))
CPPCHK_GLIBCXX_DEBUG=
endif
ifndef CXXFLAGS
CXXFLAGS=-pedantic -Wall -Wextra -Wcast-qual -Wno-deprecated-declarations -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wno-long-long -Wpacked -Wredundant-decls -Wundef -Wno-shadow -Wno-missing-field-initializers -Wno-missing-braces -Wno-sign-compare -Wno-multichar $(CPPCHK_GLIBCXX_DEBUG) -g
CXXFLAGS=-std=c++0x -O2 -DNDEBUG -Wall -Wno-sign-compare
endif
ifeq (g++, $(findstring g++,$(CXX)))
@ -213,6 +213,7 @@ CLIOBJ = cli/cmdlineparser.o \
TESTOBJ = test/options.o \
test/test64bit.o \
test/testanalyzerinformation.o \
test/testassert.o \
test/testastutils.o \
test/testautovariables.o \
@ -582,6 +583,9 @@ test/options.o: test/options.cpp test/options.h
test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/test64bit.o test/test64bit.cpp
test/testanalyzerinformation.o: test/testanalyzerinformation.cpp lib/analyzerinfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/platform.h lib/suppressions.h lib/utils.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testanalyzerinformation.o test/testanalyzerinformation.cpp
test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testassert.o test/testassert.cpp

View File

@ -1391,7 +1391,10 @@ def get_path_premium_addon():
def cmd_output(cmd):
try:
return subprocess.check_output(cmd).strip().decode('ascii')
except subprocess.CalledProcessError as e:
return e.output
with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as p:
comm = p.communicate()
out = comm[0]
if p.returncode == 1 and len(comm[1]) > 2:
out = comm[1]
return out.decode(encoding='utf-8', errors='ignore')

View File

@ -4062,8 +4062,9 @@ class MisraChecker:
errmsg = 'misra violation (use --rule-texts=<file> to get proper output)'
if self.path_premium_addon:
for line in cppcheckdata.cmd_output([self.path_premium_addon, '--cli', '--get-rule-text=' + errorId]).split('\n'):
if not line.startswith('{'):
errmsg = line
if len(line) > 1 and not line.startswith('{'):
errmsg = line.strip()
break
else:
errmsg = 'misra violation %s with no text in the supplied rule-texts-file' % (ruleNum)

View File

@ -122,7 +122,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
if (parser.getShowErrorMessages()) {
mShowAllErrors = true;
std::cout << ErrorMessage::getXMLHeader();
std::cout << ErrorMessage::getXMLHeader(settings.cppcheckCfgProductName);
cppcheck->getErrorMessages();
std::cout << ErrorMessage::getXMLFooter() << std::endl;
}
@ -908,7 +908,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
}
if (settings.xml) {
reportErr(ErrorMessage::getXMLHeader());
reportErr(ErrorMessage::getXMLHeader(settings.cppcheckCfgProductName));
}
if (!settings.buildDir.empty()) {
@ -979,7 +979,12 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
cppcheck.analyseWholeProgram(mSettings->buildDir, mFiles);
if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) {
bool suppressUnmatchedSuppressions = false;
for (const Suppressions::Suppression& suppression: settings.nomsg.getSuppressions()) {
if (suppression.errorId == "unmatchedSuppression" && suppression.fileName.empty() && suppression.lineNumber == Suppressions::Suppression::NO_LINE)
suppressUnmatchedSuppressions = true;
}
if (!suppressUnmatchedSuppressions && (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration)) {
const bool enableUnusedFunctionCheck = cppcheck.isUnusedFunctionCheckEnabled();
if (settings.jointSuppressionReport) {

View File

@ -20,7 +20,7 @@
/**
*
* @mainpage Cppcheck
* @version 2.7
* @version 2.8
*
* @section overview_sec Overview
* Cppcheck is a simple tool for static analysis of C/C++ code.

View File

@ -1,9 +1,10 @@
# Version for libraries CPP
SET(VERSION "2.7")
SET(VERSION "2.8.2")
STRING(REGEX MATCHALL "[0-9]" VERSION_PARTS "${VERSION}")
LIST(GET VERSION_PARTS 0 VERSION_MAJOR)
LIST(GET VERSION_PARTS 1 VERSION_MINOR)
SET(SOVERSION "${VERSION_MAJOR}.${VERSION_MINOR}")
LIST(GET VERSION_PARTS 2 VERSION_BUILD)
SET(SOVERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_BUILD}")
# Postfix of so's:
SET(DLLVERSION "")

View File

@ -30,7 +30,7 @@
# git checkout -b 2.6.x ; git push -u origin 2.6.x
#
# Update version numbers in:
# sed -i -r "s/version 2[.][0-9]+([.]99)*/2.7/" cli/main.cpp
# sed -i -r "s/version 2[.][0-9]+([.]99)*/version 2.7/" cli/main.cpp
# sed -i -r "s|2[.][0-9]+([.]99)*|2.7|" cmake/versions.cmake
# sed -i -r "s/MINOR [0-9]+/MINOR 7/" lib/version.h
# sed -i -r "s/2[.][0-9]+([.]99)*/2.7/" win_installer/productInfo.wxi

View File

@ -95,34 +95,36 @@ static bool skipAnalysis(const std::string &analyzerInfoFile, unsigned long long
return true;
}
std::string AnalyzerInformation::getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg)
{
std::string line;
const std::string end(':' + cfg + ':' + Path::simplifyPath(sourcefile));
while (std::getline(filesTxt,line)) {
if (line.size() <= end.size() + 2U)
continue;
if (!endsWith(line, end.c_str(), end.size()))
continue;
return line.substr(0,line.find(':'));
}
return "";
}
std::string AnalyzerInformation::getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg)
{
const std::string files(buildDir + "/files.txt");
std::ifstream fin(files);
std::ifstream fin(Path::join(buildDir, "files.txt"));
if (fin.is_open()) {
std::string line;
const std::string end(':' + cfg + ':' + sourcefile);
while (std::getline(fin,line)) {
if (line.size() <= end.size() + 2U)
continue;
if (!endsWith(line, end.c_str(), end.size()))
continue;
std::ostringstream ostr;
ostr << buildDir << '/' << line.substr(0,line.find(':'));
return ostr.str();
}
const std::string& ret = getAnalyzerInfoFileFromFilesTxt(fin, sourcefile, cfg);
if (!ret.empty())
return Path::join(buildDir, ret);
}
std::string filename = Path::fromNativeSeparators(buildDir);
if (!endsWith(filename, '/'))
filename += '/';
const std::string::size_type pos = sourcefile.rfind('/');
if (pos == std::string::npos)
filename += sourcefile;
std::string filename;
if (pos != std::string::npos)
filename = sourcefile;
else
filename += sourcefile.substr(pos+1);
filename += ".analyzerinfo";
return filename;
filename = sourcefile.substr(pos + 1);
return Path::join(buildDir, filename) + ".analyzerinfo";
}
bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, unsigned long long checksum, std::list<ErrorMessage> *errors)

View File

@ -58,6 +58,8 @@ public:
void reportErr(const ErrorMessage &msg, bool verbose);
void setFileInfo(const std::string &check, const std::string &fileInfo);
static std::string getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg);
protected:
static std::string getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg);
private:
std::ofstream mOutputStream;
std::string mAnalyzerInfoFile;

View File

@ -1435,7 +1435,12 @@ void CppCheck::executeAddonsWholeProgram(const std::map<std::string, std::size_t
ctuInfoFiles.push_back(getCtuInfoFileName(dumpFileName));
}
executeAddons(ctuInfoFiles);
try {
executeAddons(ctuInfoFiles);
} catch (const InternalError& e) {
internalError("", "Internal error during whole program analysis: " + e.errorMessage);
mExitCode = 1;
}
for (const std::string &f: ctuInfoFiles) {
std::remove(f.c_str());

View File

@ -368,7 +368,7 @@ bool ErrorMessage::deserialize(const std::string &data)
return true;
}
std::string ErrorMessage::getXMLHeader()
std::string ErrorMessage::getXMLHeader(const std::string& productName)
{
tinyxml2::XMLPrinter printer;
@ -380,6 +380,8 @@ std::string ErrorMessage::getXMLHeader()
printer.PushAttribute("version", 2);
printer.OpenElement("cppcheck", false);
if (!productName.empty())
printer.PushAttribute("product-name", productName.c_str());
printer.PushAttribute("version", CppCheck::version());
printer.CloseElement(false);
printer.OpenElement("errors", false);
@ -489,7 +491,7 @@ static std::string readCode(const std::string &file, int linenr, int column, con
std::string::size_type pos = 0;
while ((pos = line.find('\t', pos)) != std::string::npos)
line[pos] = ' ';
return line + endl + std::string((column>0 ? column-1 : column), ' ') + '^';
return line + endl + std::string((column>0 ? column-1 : 0), ' ') + '^';
}
static void replaceColors(std::string& source)

View File

@ -160,7 +160,7 @@ public:
*/
std::string toXML() const;
static std::string getXMLHeader();
static std::string getXMLHeader(const std::string& productName);
static std::string getXMLFooter();
/**

View File

@ -242,3 +242,11 @@ bool Path::fileExists(const std::string &file)
std::ifstream f(file.c_str());
return f.is_open();
}
std::string Path::join(std::string path1, std::string path2) {
if (path1.empty() || path2.empty())
return path1 + path2;
if (path2.front() == '/')
return path2;
return ((path1.back() == '/') ? path1 : (path1 + "/")) + path2;
}

View File

@ -179,6 +179,11 @@ public:
* @return true if given path is a File
*/
static bool fileExists(const std::string &file);
/**
* join 2 paths with '/' separators
*/
static std::string join(std::string path1, std::string path2);
};
/// @}

View File

@ -2,14 +2,14 @@
// After a release the DEVMINOR is incremented. MAJOR=x MINOR=y, DEVMINOR=y+1
#define CPPCHECK_MAJOR 2
#define CPPCHECK_MINOR 7
#define CPPCHECK_DEVMINOR 7
#define CPPCHECK_MINOR 8
#define CPPCHECK_DEVMINOR 8
#define STRINGIFY(x) STRING(x)
#define STRING(VER) #VER
#if CPPCHECK_MINOR == CPPCHECK_DEVMINOR
#define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_DEVMINOR)
#define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,0,0
#define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_DEVMINOR) ".2"
#define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,1,0
#else
#define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_DEVMINOR) " dev"
#define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,99,0

View File

@ -1,6 +1,6 @@
---
title: Cppcheck manual
subtitle: Version 2.7
subtitle: Version 2.8
author: Cppcheck team
lang: en
documentclass: report

View File

@ -0,0 +1,43 @@
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2022 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 "testsuite.h"
#include <sstream>
class TestAnalyzerInformation : public TestFixture, private AnalyzerInformation {
public:
TestAnalyzerInformation() : TestFixture("TestAnalyzerInformation") {}
private:
void run() override {
TEST_CASE(getAnalyzerInfoFile);
}
void getAnalyzerInfoFile() const {
const char filesTxt[] = "file1.a4::file1.c\n";
std::istringstream f1(filesTxt);
ASSERT_EQUALS("file1.a4", getAnalyzerInfoFileFromFilesTxt(f1, "file1.c", ""));
std::istringstream f2(filesTxt);
ASSERT_EQUALS("file1.a4", getAnalyzerInfoFileFromFilesTxt(f2, "./file1.c", ""));
}
};
REGISTER_TEST(TestAnalyzerInformation)

View File

@ -192,7 +192,7 @@ private:
header += " <cppcheck version=\"";
header += CppCheck::version();
header += "\"/>\n <errors>";
ASSERT_EQUALS(header, ErrorMessage::getXMLHeader());
ASSERT_EQUALS(header, ErrorMessage::getXMLHeader(""));
ASSERT_EQUALS(" </errors>\n</results>", ErrorMessage::getXMLFooter());
std::string message(" <error id=\"errorId\" severity=\"error\"");
message += " msg=\"Programming error.\" verbose=\"Verbose error\">\n";
@ -208,7 +208,7 @@ private:
header += " <cppcheck version=\"";
header += CppCheck::version();
header += "\"/>\n <errors>";
ASSERT_EQUALS(header, ErrorMessage::getXMLHeader());
ASSERT_EQUALS(header, ErrorMessage::getXMLHeader(""));
ASSERT_EQUALS(" </errors>\n</results>", ErrorMessage::getXMLFooter());
std::string message(" <error id=\"errorId\" severity=\"error\"");
message += " msg=\"Programming error.\" verbose=\"Verbose error\">\n";

View File

@ -37,6 +37,7 @@ private:
TEST_CASE(is_c);
TEST_CASE(is_cpp);
TEST_CASE(get_path_from_filename);
TEST_CASE(join);
}
void removeQuotationMarks() const {
@ -141,6 +142,14 @@ private:
ASSERT_EQUALS("a/b/c/", Path::getPathFromFilename("a/b/c/index.h"));
ASSERT_EQUALS("a/b/c/", Path::getPathFromFilename("a/b/c/"));
}
void join() const {
ASSERT_EQUALS("a", Path::join("a", ""));
ASSERT_EQUALS("a", Path::join("", "a"));
ASSERT_EQUALS("a/b", Path::join("a", "b"));
ASSERT_EQUALS("a/b", Path::join("a/", "b"));
ASSERT_EQUALS("/b", Path::join("a", "/b"));
}
};
REGISTER_TEST(TestPath)

View File

@ -31,6 +31,7 @@
<ClCompile Include="..\lib\astutils.cpp" />
<ClCompile Include="options.cpp" />
<ClCompile Include="test64bit.cpp" />
<ClCompile Include="testanalyzerinformation.cpp" />
<ClCompile Include="testassert.cpp" />
<ClCompile Include="testastutils.cpp" />
<ClCompile Include="testautovariables.cpp" />
@ -313,4 +314,4 @@
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
</Project>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?define ProductName = "Cppcheck $(var.Platform) 2.7" ?>
<?define ProductName = "Cppcheck $(var.Platform) 2.8" ?>
<?define ProductNameShort = "Cppcheck" ?>
<?define ProductVersion = "2.7" ?>
<?define ProductVersion = "2.8" ?>
<?define ProductManufacturer = "The Cppcheck team" ?>
<?define ProductDescription = "Cppcheck is a tool for static analysis of C/C++ code" ?>