Skip to content

Commit 44c149e

Browse files
authored
Fix #11897 (Safety: show what checks are enabled/disabled) (#5378)
This primarily adds the corresponding report in the GUI that we have in the command line already
1 parent 22547be commit 44c149e

22 files changed

Lines changed: 562 additions & 304 deletions

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ LIBOBJ = $(libcppdir)/analyzerinfo.o \
200200
$(libcppdir)/checkbufferoverrun.o \
201201
$(libcppdir)/checkclass.o \
202202
$(libcppdir)/checkcondition.o \
203+
$(libcppdir)/checkersreport.o \
203204
$(libcppdir)/checkexceptionsafety.o \
204205
$(libcppdir)/checkfunctions.o \
205206
$(libcppdir)/checkinternal.o \
@@ -488,6 +489,9 @@ $(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/
488489
$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/astutils.h lib/check.h lib/checkcondition.h lib/checkother.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
489490
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp
490491

492+
$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/checkers.h lib/checkersreport.h lib/config.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/utils.h
493+
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp
494+
491495
$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/check.h lib/checkexceptionsafety.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
492496
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp
493497

@@ -638,7 +642,7 @@ $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathli
638642
cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h
639643
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp
640644

641-
cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/cppcheckexecutorsig.h cli/executor.h cli/filelister.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
645+
cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/cppcheckexecutorsig.h cli/executor.h cli/filelister.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
642646
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp
643647

644648
cli/cppcheckexecutorseh.o: cli/cppcheckexecutorseh.cpp cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/utils.h

cli/cli.vcxproj.filters

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
</Filter>
1515
</ItemGroup>
1616
<ItemGroup Label="HeaderFiles">
17-
<ClInclude Include="..\lib\config.h">
18-
<Filter>Header Files</Filter>
19-
</ClInclude>
2017
<ClInclude Include="cmdlineparser.h">
2118
<Filter>Header Files</Filter>
2219
</ClInclude>
@@ -44,6 +41,9 @@
4441
<ClInclude Include="stacktrace.h">
4542
<Filter>Header Files</Filter>
4643
</ClInclude>
44+
<ClInclude Include="singleexecutor.h">
45+
<Filter>Header Files</Filter>
46+
</ClInclude>
4747
</ItemGroup>
4848
<ItemGroup Label="SourceFiles">
4949
<ClCompile Include="main.cpp">
@@ -76,6 +76,9 @@
7676
<ClCompile Include="stacktrace.cpp">
7777
<Filter>Source Files</Filter>
7878
</ClCompile>
79+
<ClCompile Include="singleexecutor.cpp">
80+
<Filter>Source Files</Filter>
81+
</ClCompile>
7982
</ItemGroup>
8083
<ItemGroup>
8184
<ResourceCompile Include="version.rc">

cli/cppcheckexecutor.cpp

Lines changed: 8 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "analyzerinfo.h"
2222
#include "checkers.h"
23+
#include "checkersreport.h"
2324
#include "cmdlineparser.h"
2425
#include "color.h"
2526
#include "config.h"
@@ -337,60 +338,13 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
337338
return 0;
338339
}
339340

340-
static bool isCppcheckPremium(const Settings& settings) {
341-
return (settings.cppcheckCfgProductName.compare(0, 16, "Cppcheck Premium") == 0);
342-
}
343-
344-
static std::string getMisraRuleSeverity(const std::string& rule) {
345-
if (checkers::misraRuleSeverity.count(rule) > 0)
346-
return checkers::misraRuleSeverity.at(rule);
347-
return "style";
348-
}
349-
350-
static bool isMisraRuleInconclusive(const std::string& rule) {
351-
return rule == "8.3";
352-
}
353-
354-
static bool isMisraRuleActive(const std::string& rule, int amendment, const std::string& severity, const Settings& settings) {
355-
if (!isCppcheckPremium(settings) && amendment >= 3)
356-
return false;
357-
const bool inconclusive = isMisraRuleInconclusive(rule);
358-
if (inconclusive && !settings.certainty.isEnabled(Certainty::inconclusive))
359-
return false;
360-
if (severity == "warning")
361-
return settings.severity.isEnabled(Severity::warning);
362-
if (severity == "style")
363-
return settings.severity.isEnabled(Severity::style);
364-
return true; // error severity
365-
}
366-
367341
void CppCheckExecutor::writeCheckersReport(const Settings& settings) const
368342
{
343+
CheckersReport checkersReport(settings, mActiveCheckers);
344+
369345
if (!settings.quiet) {
370-
int activeCheckers = 0;
371-
int totalCheckers = 0;
372-
for (const auto& checkReq: checkers::allCheckers) {
373-
if (mActiveCheckers.count(checkReq.first) > 0)
374-
++activeCheckers;
375-
++totalCheckers;
376-
}
377-
if (isCppcheckPremium(settings)) {
378-
for (const auto& checkReq: checkers::premiumCheckers) {
379-
if (mActiveCheckers.count(checkReq.first) > 0)
380-
++activeCheckers;
381-
++totalCheckers;
382-
}
383-
}
384-
if (mSettings->premiumArgs.find("misra-c-") != std::string::npos || mSettings->addons.count("misra")) {
385-
for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
386-
const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b);
387-
const std::string severity = getMisraRuleSeverity(rule);
388-
const bool active = isMisraRuleActive(rule, info.amendment, severity, settings);
389-
if (active)
390-
++activeCheckers;
391-
++totalCheckers;
392-
}
393-
}
346+
const int activeCheckers = checkersReport.getActiveCheckersCount();
347+
const int totalCheckers = checkersReport.getAllCheckersCount();
394348

395349
const std::string extra = settings.verbose ? " (use --checkers-report=<filename> to see details)" : "";
396350
if (mCriticalErrors.empty())
@@ -403,111 +357,9 @@ void CppCheckExecutor::writeCheckersReport(const Settings& settings) const
403357
return;
404358

405359
std::ofstream fout(settings.checkersReportFilename);
406-
if (!fout.is_open())
407-
return;
360+
if (fout.is_open())
361+
fout << checkersReport.getReport(mCriticalErrors);
408362

409-
fout << "Critical errors" << std::endl;
410-
fout << "---------------" << std::endl;
411-
if (!mCriticalErrors.empty()) {
412-
fout << "There was critical errors (" << mCriticalErrors << ")" << std::endl;
413-
fout << "All checking is skipped for a file with such error" << std::endl;
414-
} else {
415-
fout << "No critical errors, all files were checked." << std::endl;
416-
fout << "Important: Analysis is still not guaranteed to be 'complete' it is possible there are false negatives." << std::endl;
417-
}
418-
419-
fout << std::endl << std::endl;
420-
fout << "Open source checkers" << std::endl;
421-
fout << "--------------------" << std::endl;
422-
423-
int maxCheckerSize = 0;
424-
for (const auto& checkReq: checkers::allCheckers) {
425-
const std::string& checker = checkReq.first;
426-
if (checker.size() > maxCheckerSize)
427-
maxCheckerSize = checker.size();
428-
}
429-
for (const auto& checkReq: checkers::allCheckers) {
430-
const std::string& checker = checkReq.first;
431-
const bool active = mActiveCheckers.count(checkReq.first) > 0;
432-
const std::string& req = checkReq.second;
433-
fout << (active ? "Yes " : "No ") << checker;
434-
if (!active && !req.empty())
435-
fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" + req;
436-
fout << std::endl;
437-
}
438-
439-
const bool cppcheckPremium = isCppcheckPremium(settings);
440-
441-
if (cppcheckPremium) {
442-
fout << std::endl << std::endl;
443-
fout << "Premium checkers" << std::endl;
444-
fout << "----------------" << std::endl;
445-
446-
maxCheckerSize = 0;
447-
for (const auto& checkReq: checkers::premiumCheckers) {
448-
const std::string& checker = checkReq.first;
449-
if (checker.size() > maxCheckerSize)
450-
maxCheckerSize = checker.size();
451-
}
452-
for (const auto& checkReq: checkers::premiumCheckers) {
453-
const std::string& checker = checkReq.first;
454-
std::string req = checkReq.second;
455-
bool active = cppcheckPremium;
456-
if (req == "warning")
457-
active &= mSettings->severity.isEnabled(Severity::warning);
458-
else if (req == "style")
459-
active &= mSettings->severity.isEnabled(Severity::style);
460-
fout << (active ? "Yes " : "No ") << checker;
461-
if (!req.empty())
462-
req = "premium," + req;
463-
else
464-
req = "premium";
465-
if (!active)
466-
fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" + req;
467-
fout << std::endl;
468-
}
469-
}
470-
471-
int misra = 0;
472-
if (mSettings->premiumArgs.find("misra-c-2012") != std::string::npos)
473-
misra = 2012;
474-
else if (mSettings->premiumArgs.find("misra-c-2023") != std::string::npos)
475-
misra = 2023;
476-
else if (mSettings->addons.count("misra"))
477-
misra = 2012;
478-
479-
if (misra == 0) {
480-
fout << std::endl << std::endl;
481-
fout << "Misra C" << std::endl;
482-
fout << "-------" << std::endl;
483-
fout << "Misra is not enabled" << std::endl;
484-
} else {
485-
fout << std::endl << std::endl;
486-
fout << "Misra C " << misra << std::endl;
487-
fout << "------------" << std::endl;
488-
for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
489-
const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b);
490-
const std::string severity = getMisraRuleSeverity(rule);
491-
const bool active = isMisraRuleActive(rule, info.amendment, severity, settings);
492-
const bool inconclusive = isMisraRuleInconclusive(rule);
493-
fout << (active ? "Yes " : "No ") << rule;
494-
std::string extra;
495-
if (misra == 2012 && info.amendment >= 1)
496-
extra = " amendment:" + std::to_string(info.amendment);
497-
std::string reqs;
498-
if (info.amendment >= 3)
499-
reqs += ",premium";
500-
if (severity != "error")
501-
reqs += "," + severity;
502-
if (inconclusive)
503-
reqs += ",inconclusive";
504-
if (!active && !reqs.empty())
505-
extra += " require:" + reqs.substr(1);
506-
if (!extra.empty())
507-
fout << std::string(7 - rule.size(), ' ') << extra;
508-
fout << '\n';
509-
}
510-
}
511363
}
512364

513365
bool CppCheckExecutor::loadLibraries(Settings& settings)
@@ -607,7 +459,7 @@ void CppCheckExecutor::reportErr(const ErrorMessage &msg)
607459
{
608460
assert(mSettings != nullptr);
609461

610-
if (msg.severity == Severity::none && msg.id == "logChecker") {
462+
if (msg.severity == Severity::none && (msg.id == "logChecker" || endsWith(msg.id, "-logChecker"))) {
611463
const std::string& checker = msg.shortMessage();
612464
mActiveCheckers.emplace(checker);
613465
return;

gui/checkstatistics.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ void CheckStatistics::addItem(const QString &tool, ShowTypes::ShowType type)
6565
}
6666
}
6767

68+
void CheckStatistics::addChecker(const QString &checker)
69+
{
70+
mActiveCheckers.insert(checker.toStdString());
71+
}
72+
6873
void CheckStatistics::clear()
6974
{
7075
mStyle.clear();
@@ -73,6 +78,8 @@ void CheckStatistics::clear()
7378
mPortability.clear();
7479
mInformation.clear();
7580
mError.clear();
81+
mActiveCheckers.clear();
82+
mCheckersReport.clear();
7683
}
7784

7885
unsigned CheckStatistics::getCount(const QString &tool, ShowTypes::ShowType type) const

gui/checkstatistics.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@
2323

2424
#include <QMap>
2525
#include <QObject>
26+
#include <QSet>
2627
#include <QString>
2728
#include <QStringList>
2829

30+
#include <set>
31+
#include <string>
32+
2933
/// @addtogroup GUI
3034
/// @{
3135

@@ -44,6 +48,11 @@ class CheckStatistics : public QObject {
4448
*/
4549
void addItem(const QString &tool, ShowTypes::ShowType type);
4650

51+
/**
52+
* @brief Add checker to statistics
53+
*/
54+
void addChecker(const QString& checker);
55+
4756
/**
4857
* @brief Clear the statistics.
4958
*
@@ -59,16 +68,33 @@ class CheckStatistics : public QObject {
5968
*/
6069
unsigned getCount(const QString &tool, ShowTypes::ShowType type) const;
6170

71+
std::set<std::string> getActiveCheckers() const {
72+
return mActiveCheckers;
73+
}
74+
75+
int getNumberOfActiveCheckers() const {
76+
return mActiveCheckers.size();
77+
}
78+
6279
/** Get tools with results */
6380
QStringList getTools() const;
6481

82+
void setCheckersReport(QString report) {
83+
mCheckersReport = std::move(report);
84+
}
85+
QString getCheckersReport() const {
86+
return mCheckersReport;
87+
}
88+
6589
private:
6690
QMap<QString, unsigned> mStyle;
6791
QMap<QString, unsigned> mWarning;
6892
QMap<QString, unsigned> mPerformance;
6993
QMap<QString, unsigned> mPortability;
7094
QMap<QString, unsigned> mInformation;
7195
QMap<QString, unsigned> mError;
96+
std::set<std::string> mActiveCheckers;
97+
QString mCheckersReport;
7298
};
7399

74100
/// @}

gui/mainwindow.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons
540540
}
541541
mThread->setProject(p);
542542
mThread->check(checkSettings);
543+
mUI->mResults->setCheckSettings(checkSettings);
543544
}
544545

545546
void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrary, const bool checkConfiguration)
@@ -603,6 +604,7 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrar
603604

604605
mThread->setCheckFiles(true);
605606
mThread->check(checkSettings);
607+
mUI->mResults->setCheckSettings(checkSettings);
606608
}
607609

608610
void MainWindow::analyzeCode(const QString& code, const QString& filename)
@@ -1208,7 +1210,9 @@ void MainWindow::reAnalyzeSelected(const QStringList& files)
12081210
// considered in "Modified Files Check" performed after "Selected Files Check"
12091211
// TODO: Should we store per file CheckStartTime?
12101212
QDateTime saveCheckStartTime = mThread->getCheckStartTime();
1211-
mThread->check(getCppcheckSettings());
1213+
const Settings& checkSettings = getCppcheckSettings();
1214+
mThread->check(checkSettings);
1215+
mUI->mResults->setCheckSettings(checkSettings);
12121216
mThread->setCheckStartTime(saveCheckStartTime);
12131217
}
12141218

@@ -1232,7 +1236,9 @@ void MainWindow::reAnalyze(bool all)
12321236
qDebug() << "Rechecking project file" << mProjectFile->getFilename();
12331237

12341238
mThread->setCheckFiles(all);
1235-
mThread->check(getCppcheckSettings());
1239+
const Settings& checkSettings = getCppcheckSettings();
1240+
mThread->check(checkSettings);
1241+
mUI->mResults->setCheckSettings(checkSettings);
12361242
}
12371243

12381244
void MainWindow::clearResults()

gui/mainwindow.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public slots:
193193
/** @brief Slot for showing the library editor */
194194
void showLibraryEditor();
195195

196-
protected slots:
196+
private slots:
197197

198198
/** @brief Slot for checkthread's done signal */
199199
void analysisDone();

0 commit comments

Comments
 (0)