diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index ad4d3acf312..a510064048a 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -361,21 +361,11 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con supprlist.addSuppression(std::move(s)); } - const auto reportErrorsFn = [&](const std::string& sourcefile, std::size_t fsFileId, const std::vector& errors) -> bool { + const auto reportErrorsFn = [&](const std::vector& errors) -> bool { if (errors.empty()) return false; - // TODO: what if sourcefile is empty? - - AnalyzerInformation analyzerInfo; - // FIXME: this is a horrible hack - // we need to "re-open" the file so we can add the unmatchedSuppression findings. - // we cannot keep it open conditionally because the whole program analysis reads the XML. - // re-ordering the code is also not an option because the unmatched suppression reporting needs to be run after all other checks. - analyzerInfo.reopen(settings.buildDir, sourcefile, /*cfgname*/ "", fsFileId); - for (const auto& errmsg : errors) { - analyzerInfo.reportErr(errmsg); errorLogger.reportErr(errmsg); } return true; @@ -385,30 +375,24 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con for (auto i = files.cbegin(); i != files.cend(); ++i) { const std::vector errors = getUnmatchedSuppressions(supprlist.getUnmatchedLocalSuppressions(*i), settings.unmatchedSuppressionFilters); - err |= reportErrorsFn(i->spath(), i->fsFileId(), errors); + err |= reportErrorsFn(errors); } for (auto i = fileSettings.cbegin(); i != fileSettings.cend(); ++i) { const std::vector errors = getUnmatchedSuppressions(supprlist.getUnmatchedLocalSuppressions(i->file), settings.unmatchedSuppressionFilters); - err |= reportErrorsFn(i->file.spath(), i->file.fsFileId(), errors); + err |= reportErrorsFn(errors); } if (settings.inlineSuppressions) { const std::vector errors = getUnmatchedSuppressions(supprlist.getUnmatchedInlineSuppressions(), settings.unmatchedSuppressionFilters); for (const auto& errmsg : errors) { - std::string sourcefile; - if (!errmsg.callStack.empty()) - sourcefile = errmsg.callStack.cbegin()->getfile(false); // TODO: simplify path? - err |= reportErrorsFn(sourcefile, 0, {errmsg}); + err |= reportErrorsFn({errmsg}); } } const std::vector errors = getUnmatchedSuppressions(supprlist.getUnmatchedGlobalSuppressions(), settings.unmatchedSuppressionFilters); for (const auto& errmsg : errors) { - std::string sourcefile; - if (!errmsg.callStack.empty()) - sourcefile = errmsg.callStack.cbegin()->getfile(false); // TODO: simplify path? - err |= reportErrorsFn(sourcefile, 0, {errmsg}); + err |= reportErrorsFn({errmsg}); } return err; } @@ -469,6 +453,39 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup // TODO: is this run again instead of using previously cached results? returnValue |= cppcheck.analyseWholeProgram(settings.buildDir, mFiles, mFileSettings, stdLogger.getCtuInfo()); + if (settings.inlineSuppressions && !settings.buildDir.empty()) + { + auto s = supprs.nomsg.getSuppressions(); + if (!s.empty()) { + std::ofstream fout(Path::join(settings.buildDir, "supprstate.xml")); + + /* + { + const char * const supprStr = e->Attribute("str"); + const char * const supprChecked = e->Attribute("checked"); + const char * const supprMatched = e->Attribute("matched"); + SuppressionList::Suppression s = SuppressionList::parseLine(supprStr); + s.checked = supprChecked == "true"; + s.matched = supprMatched == "true"; + mSuppressions.nomsg.updateSuppressionState(s); // TODO: check result + } + */ + + fout << ""; + + for (const auto& suppr : s) + { + if (!suppr.isInline) + continue; + if (!suppr.checked) + continue; + fout << ""; + } + + fout << ""; + } + } + if ((settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) && !supprs.nomsg.getSuppressions().empty()) { const bool err = reportUnmatchedSuppressions(settings, supprs.nomsg, mFiles, mFileSettings, stdLogger); if (err && returnValue == 0) diff --git a/lib/analyzerinfo.cpp b/lib/analyzerinfo.cpp index 6f919ec3651..16eccb8aba1 100644 --- a/lib/analyzerinfo.cpp +++ b/lib/analyzerinfo.cpp @@ -293,24 +293,3 @@ std::string AnalyzerInformation::processFilesTxt(const std::string& buildDir, co // TODO: error on empty file? return ""; } - -void AnalyzerInformation::reopen(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t fsFileId) -{ - if (buildDir.empty() || sourcefile.empty()) - return; - - const std::string analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile(buildDir,sourcefile,cfg,fsFileId); - std::ifstream ifs(analyzerInfoFile); - if (!ifs.is_open()) - return; - - std::ostringstream iss; - iss << ifs.rdbuf(); - ifs.close(); - - std::string content = iss.str(); - content.resize(content.find("")); - - mOutputStream.open(analyzerInfoFile, std::ios::trunc); - mOutputStream << content; -} diff --git a/lib/analyzerinfo.h b/lib/analyzerinfo.h index d8a220a5c55..2460f7204e6 100644 --- a/lib/analyzerinfo.h +++ b/lib/analyzerinfo.h @@ -69,8 +69,6 @@ class CPPCHECKLIB AnalyzerInformation { 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, std::size_t fsFileId); - void reopen(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t fsFileId); - static const char sep = ':'; class CPPCHECKLIB Info { diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 5023a5e258e..3f50f45124b 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -874,6 +874,7 @@ std::size_t CppCheck::calculateHash(const Preprocessor& preprocessor, const std: toolinfo << a.args; } toolinfo << mSettings.premiumArgs; + toolinfo << mSettings.inlineSuppressions; // TODO: do we need to add more options? mSuppressions.nomsg.dump(toolinfo, filePath); return preprocessor.calculateHash(toolinfo.str());