Skip to content

Commit 5aa1710

Browse files
authored
Fix #12071 (Add safety mode that makes cppcheck more strict about critical errors) (#5777)
1 parent aa7629d commit 5aa1710

18 files changed

Lines changed: 131 additions & 16 deletions

cli/cmdlineparser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,10 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
10661066
#endif
10671067
}
10681068

1069+
// Safety certified behavior
1070+
else if (std::strcmp(argv[i], "--safety") == 0)
1071+
mSettings.safety = true;
1072+
10691073
// show timing information..
10701074
else if (std::strncmp(argv[i], "--showtime=", 11) == 0) {
10711075
const std::string showtimeMode = argv[i] + 11;

cli/cppcheckexecutor.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ class CppCheckExecutor::StdLogger : public ErrorLogger
118118
*/
119119
void writeCheckersReport() const;
120120

121+
bool hasCriticalErrors() const {
122+
return !mCriticalErrors.empty();
123+
}
124+
121125
private:
122126
/**
123127
* Information about progress is directed here. This should be
@@ -288,9 +292,12 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) const
288292

289293
mStdLogger->writeCheckersReport();
290294

295+
if (settings.safety && mStdLogger->hasCriticalErrors())
296+
return EXIT_FAILURE;
297+
291298
if (returnValue)
292299
return settings.exitCode;
293-
return 0;
300+
return EXIT_SUCCESS;
294301
}
295302

296303
void CppCheckExecutor::StdLogger::writeCheckersReport() const
@@ -385,24 +392,29 @@ void CppCheckExecutor::StdLogger::reportProgress(const std::string &filename, co
385392

386393
void CppCheckExecutor::StdLogger::reportErr(const ErrorMessage &msg)
387394
{
388-
if (msg.severity == Severity::none && (msg.id == "logChecker" || endsWith(msg.id, "-logChecker"))) {
395+
if (msg.severity == Severity::internal && (msg.id == "logChecker" || endsWith(msg.id, "-logChecker"))) {
389396
const std::string& checker = msg.shortMessage();
390397
mActiveCheckers.emplace(checker);
391398
return;
392399
}
393400

394-
// TODO: we generate a different message here then we log below
395-
// TODO: there should be no need for verbose and default messages here
396-
// Alert only about unique errors
397-
if (!mShownErrors.insert(msg.toString(mSettings.verbose)).second)
398-
return;
399-
400401
if (ErrorLogger::isCriticalErrorId(msg.id) && mCriticalErrors.find(msg.id) == std::string::npos) {
401402
if (!mCriticalErrors.empty())
402403
mCriticalErrors += ", ";
403404
mCriticalErrors += msg.id;
405+
if (msg.severity == Severity::internal)
406+
mCriticalErrors += " (suppressed)";
404407
}
405408

409+
if (msg.severity == Severity::internal)
410+
return;
411+
412+
// TODO: we generate a different message here then we log below
413+
// TODO: there should be no need for verbose and default messages here
414+
// Alert only about unique errors
415+
if (!mShownErrors.insert(msg.toString(mSettings.verbose)).second)
416+
return;
417+
406418
if (mSettings.xml)
407419
reportErr(msg.toXML());
408420
else

gui/resultstree.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ QString ResultsTree::severityToTranslatedString(Severity severity)
343343
case Severity::debug:
344344
return tr("debug");
345345

346+
case Severity::internal:
347+
return tr("internal");
348+
346349
case Severity::none:
347350
default:
348351
return QString();
@@ -666,6 +669,11 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
666669
menu.addAction(hideallid);
667670

668671
QAction *suppress = new QAction(tr("Suppress selected id(s)"), &menu);
672+
{
673+
QVariantMap data = mContextItem->data().toMap();
674+
const QString messageId = data[ERRORID].toString();
675+
suppress->setEnabled(!ErrorLogger::isCriticalErrorId(messageId.toStdString()));
676+
}
669677
menu.addAction(suppress);
670678
connect(suppress, &QAction::triggered, this, &ResultsTree::suppressSelectedIds);
671679

gui/resultsview.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,16 @@ void ResultsView::progress(int value, const QString& description)
161161

162162
void ResultsView::error(const ErrorItem &item)
163163
{
164-
if (item.severity == Severity::none && (item.errorId == "logChecker" || item.errorId.endsWith("-logChecker"))) {
164+
if (item.severity == Severity::internal && (item.errorId == "logChecker" || item.errorId.endsWith("-logChecker"))) {
165165
mStatistics->addChecker(item.message);
166166
return;
167167
}
168168

169169
handleCriticalError(item);
170170

171+
if (item.severity == Severity::internal)
172+
return;
173+
171174
if (mUI->mTree->addErrorItem(item)) {
172175
emit gotResults();
173176
mStatistics->addItem(item.tool(), ShowTypes::SeverityToShowType(item.severity));
@@ -562,10 +565,14 @@ void ResultsView::handleCriticalError(const ErrorItem &item)
562565
if (!mCriticalErrors.isEmpty())
563566
mCriticalErrors += ",";
564567
mCriticalErrors += item.errorId;
568+
if (item.severity == Severity::internal)
569+
mCriticalErrors += " (suppressed)";
565570
}
566571
QString msg = tr("There was a critical error with id '%1'").arg(item.errorId);
567572
if (!item.file0.isEmpty())
568573
msg += ", " + tr("when checking %1").arg(item.file0);
574+
else
575+
msg += ", " + tr("when checking a file");
569576
msg += ". " + tr("Analysis was aborted.");
570577
mUI->mLabelCriticalErrors->setText(msg);
571578
mUI->mLabelCriticalErrors->setVisible(true);

gui/showtypes.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ ShowTypes::ShowType ShowTypes::SeverityToShowType(Severity severity)
3737
{
3838
switch (severity) {
3939
case Severity::none:
40+
case Severity::internal:
4041
return ShowTypes::ShowNone;
4142
case Severity::error:
4243
return ShowTypes::ShowErrors;

lib/check.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,6 @@ ErrorPath Check::getErrorPath(const Token* errtok, const ValueFlow::Value* value
128128

129129
void Check::logChecker(const char id[])
130130
{
131-
reportError(nullptr, Severity::none, "logChecker", id);
131+
reportError(nullptr, Severity::internal, "logChecker", id);
132132
}
133133

lib/cppcheck.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,9 +1460,10 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
14601460
errmsg.setmsg(text);
14611461
const std::string severity = obj["severity"].get<std::string>();
14621462
errmsg.severity = severityFromString(severity);
1463-
if (errmsg.severity == Severity::none) {
1463+
if (errmsg.severity == Severity::none || errmsg.severity == Severity::internal) {
14641464
if (!endsWith(errmsg.id, "-logChecker"))
14651465
continue;
1466+
errmsg.severity = Severity::internal;
14661467
}
14671468
else if (!mSettings.severity.isEnabled(errmsg.severity))
14681469
continue;
@@ -1568,7 +1569,7 @@ void CppCheck::purgedConfigurationMessage(const std::string &file, const std::st
15681569
// TODO: part of this logic is duplicated in Executor::hasToLog()
15691570
void CppCheck::reportErr(const ErrorMessage &msg)
15701571
{
1571-
if (msg.severity == Severity::none && (msg.id == "logChecker" || endsWith(msg.id, "-logChecker"))) {
1572+
if (msg.severity == Severity::internal) {
15721573
mErrorLogger.reportErr(msg);
15731574
return;
15741575
}
@@ -1589,6 +1590,21 @@ void CppCheck::reportErr(const ErrorMessage &msg)
15891590
const auto errorMessage = Suppressions::ErrorMessage::fromErrorMessage(msg, macroNames);
15901591

15911592
if (mSettings.nomsg.isSuppressed(errorMessage, mUseGlobalSuppressions)) {
1593+
// Safety: Report critical errors to ErrorLogger
1594+
if (mSettings.safety && ErrorLogger::isCriticalErrorId(msg.id)) {
1595+
mExitCode = 1;
1596+
1597+
if (mSettings.nomsg.isSuppressedExplicitly(errorMessage, mUseGlobalSuppressions)) {
1598+
// Report with internal severity to signal that there is this critical error but
1599+
// it is suppressed
1600+
ErrorMessage temp(msg);
1601+
temp.severity = Severity::internal;
1602+
mErrorLogger.reportErr(temp);
1603+
} else {
1604+
// Report critical error that is not explicitly suppressed
1605+
mErrorLogger.reportErr(msg);
1606+
}
1607+
}
15921608
return;
15931609
}
15941610

lib/errortypes.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ std::string severityToString(Severity severity)
6666
return "information";
6767
case Severity::debug:
6868
return "debug";
69+
case Severity::internal:
70+
return "internal";
6971
}
7072
throw InternalError(nullptr, "Unknown severity");
7173
}
@@ -90,5 +92,7 @@ Severity severityFromString(const std::string& severity)
9092
return Severity::information;
9193
if (severity == "debug")
9294
return Severity::debug;
95+
if (severity == "internal")
96+
return Severity::internal;
9397
return Severity::none;
9498
}

lib/errortypes.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,13 @@ enum class Severity {
109109
* Debug message.
110110
* Debug-mode message useful for the developers.
111111
*/
112-
debug
112+
debug,
113+
/**
114+
* Internal message.
115+
* Message will not be shown to the user.
116+
* Tracking what checkers is executed, tracking suppressed critical errors, etc.
117+
*/
118+
internal
113119
};
114120

115121
CPPCHECKLIB std::string severityToString(Severity severity);

lib/settings.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ std::string Settings::loadCppcheckCfg()
119119
}
120120
}
121121
}
122+
{
123+
const picojson::object::const_iterator it = obj.find("safety");
124+
if (it != obj.cend()) {
125+
const auto& v = it->second;
126+
if (!v.is<bool>())
127+
return "'safety' is not a bool";
128+
safety = v.get<bool>();
129+
}
130+
}
122131

123132
return "";
124133
}

0 commit comments

Comments
 (0)