Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/che
test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp

test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp

test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h
Expand Down
31 changes: 18 additions & 13 deletions lib/cppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,19 +850,24 @@ static simplecpp::TokenList createTokenList(const std::string& filename, std::ve
return {filename, files, outputList};
}

static std::size_t calculateHash(const Preprocessor& preprocessor, const simplecpp::TokenList& tokens, const Settings& settings, const Suppressions& supprs)
std::size_t CppCheck::calculateHash(const Preprocessor& preprocessor, const simplecpp::TokenList& tokens)
{
std::ostringstream toolinfo;
toolinfo << (settings.cppcheckCfgProductName.empty() ? CPPCHECK_VERSION_STRING : settings.cppcheckCfgProductName);
toolinfo << (settings.severity.isEnabled(Severity::warning) ? 'w' : ' ');
toolinfo << (settings.severity.isEnabled(Severity::style) ? 's' : ' ');
toolinfo << (settings.severity.isEnabled(Severity::performance) ? 'p' : ' ');
toolinfo << (settings.severity.isEnabled(Severity::portability) ? 'p' : ' ');
toolinfo << (settings.severity.isEnabled(Severity::information) ? 'i' : ' ');
toolinfo << settings.userDefines;
toolinfo << std::to_string(static_cast<std::uint8_t>(settings.checkLevel));
toolinfo << (mSettings.cppcheckCfgProductName.empty() ? CPPCHECK_VERSION_STRING : mSettings.cppcheckCfgProductName);
toolinfo << (mSettings.severity.isEnabled(Severity::warning) ? 'w' : ' ');
toolinfo << (mSettings.severity.isEnabled(Severity::style) ? 's' : ' ');
toolinfo << (mSettings.severity.isEnabled(Severity::performance) ? 'p' : ' ');
toolinfo << (mSettings.severity.isEnabled(Severity::portability) ? 'p' : ' ');
toolinfo << (mSettings.severity.isEnabled(Severity::information) ? 'i' : ' ');
toolinfo << mSettings.userDefines;
toolinfo << std::to_string(static_cast<std::uint8_t>(mSettings.checkLevel));
for (const auto &a : mSettings.addonInfos) {
toolinfo << a.name;
toolinfo << a.args;
}
toolinfo << mSettings.premiumArgs;
// TODO: do we need to add more options?
supprs.nomsg.dump(toolinfo);
mSuppressions.nomsg.dump(toolinfo);
return preprocessor.calculateHash(tokens, toolinfo.str());
}

Expand Down Expand Up @@ -922,7 +927,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
simplecpp::TokenList tokens(*fileStream, files, file.spath());
if (analyzerInformation) {
const Preprocessor preprocessor(mSettings, mErrorLogger, Standards::Language::C);
hash = calculateHash(preprocessor, tokens, mSettings, mSuppressions);
hash = calculateHash(preprocessor, tokens);
}
tokenlist.createTokens(std::move(tokens));
}
Expand All @@ -931,7 +936,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
simplecpp::TokenList tokens(file.spath(), files);
if (analyzerInformation) {
const Preprocessor preprocessor(mSettings, mErrorLogger, file.lang());
hash = calculateHash(preprocessor, tokens, mSettings, mSuppressions);
hash = calculateHash(preprocessor, tokens);
}
tokenlist.createTokens(std::move(tokens));
}
Expand Down Expand Up @@ -1015,7 +1020,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string

if (analyzerInformation) {
// Calculate hash so it can be compared with old hash / future hashes
const std::size_t hash = calculateHash(preprocessor, tokens1, mSettings, mSuppressions);
const std::size_t hash = calculateHash(preprocessor, tokens1);
std::list<ErrorMessage> errors;
if (!analyzerInformation->analyzeFile(mSettings.buildDir, file.spath(), cfgname, fileIndex, hash, errors)) {
while (!errors.empty()) {
Expand Down
11 changes: 10 additions & 1 deletion lib/cppcheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <string>
#include <vector>

class TokenList;
enum class SHOWTIME_MODES : std::uint8_t;
struct FileSettings;
class CheckUnusedFunctions;
Expand All @@ -42,6 +41,7 @@ class AnalyzerInformation;
class ErrorLogger;
class Settings;
struct Suppressions;
class Preprocessor;

namespace simplecpp { class TokenList; }

Expand Down Expand Up @@ -162,6 +162,15 @@ class CPPCHECKLIB CppCheck {
/** @brief There has been an internal error => Report information message */
void internalError(const std::string &filename, const std::string &msg);

/**
* @brief Calculate hash used to detect when a file needs to be reanalyzed.
*
* @param preprocessor Preprocessor used to calculate the hash.
* @param tokens Token list from preprocessed file.
* @return hash
*/
std::size_t calculateHash(const Preprocessor &preprocessor, const simplecpp::TokenList &tokens);

/**
* @brief Check a file using stream
* @param file the file
Expand Down
35 changes: 35 additions & 0 deletions test/testcppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "fixture.h"
#include "helpers.h"
#include "path.h"
#include "preprocessor.h"
#include "settings.h"
#include "suppressions.h"

Expand Down Expand Up @@ -68,6 +69,7 @@ class TestCppcheck : public TestFixture {
TEST_CASE(isPremiumCodingStandardId);
TEST_CASE(getDumpFileContentsRawTokens);
TEST_CASE(getDumpFileContentsLibrary);
TEST_CASE(premiumResultsCache);
}

void getErrorMessages() const {
Expand Down Expand Up @@ -324,6 +326,39 @@ class TestCppcheck : public TestFixture {
}
}

void premiumResultsCache() const {
// Trac #13889 - cached misra results are shown after removing --premium=misra-c-2012 option

Settings settings;
Suppressions supprs;
ErrorLogger2 errorLogger;

std::vector<std::string> files;

std::istringstream istr("void f();\nint x;\n");
simplecpp::TokenList tokens(istr, files, "m1.c");

Preprocessor preprocessor(settings, errorLogger, Standards::Language::C);
ASSERT(preprocessor.loadFiles(tokens, files));

AddonInfo premiumaddon;
premiumaddon.name = "premiumaddon.json";
premiumaddon.executable = "premiumaddon";

settings.cppcheckCfgProductName = "Cppcheck Premium 0.0.0";
settings.addons.insert(premiumaddon.name);
settings.addonInfos.push_back(premiumaddon);

settings.premiumArgs = "misra-c-2012";
CppCheck check(settings, supprs, errorLogger, false, {});
size_t hash1 = check.calculateHash(preprocessor, tokens);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use const when possible.


settings.premiumArgs = "";
size_t hash2 = check.calculateHash(preprocessor, tokens);

ASSERT(hash1 != hash2);
}

// TODO: test suppressions
// TODO: test all with FS
};
Expand Down
Loading