Skip to content

Commit

Permalink
Fix #11892 (Safety: status message when cppcheck analysis fails)
Browse files Browse the repository at this point in the history
  • Loading branch information
danmar committed Aug 24, 2023
1 parent 3949965 commit c429d3e
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 21 deletions.
14 changes: 14 additions & 0 deletions cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,20 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
}
}

if (!mSettings.severity.isEnabled(Severity::style)) {
std::string std;
if (mSettings.premiumArgs.find("misra") != std::string::npos || mSettings.addons.count("misra"))
std = "misra";
else if (mSettings.premiumArgs.find("autosar") != std::string::npos)
std = "autosar";
else if (mSettings.premiumArgs.find("cert") != std::string::npos)
std = "cert";
if (!std.empty()) {
printError("When " + std + " is used, you must enable style messages: --enable=style");
return false;
}
}

mSettings.loadCppcheckCfg();

// Default template format..
Expand Down
27 changes: 27 additions & 0 deletions cli/cppcheckexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@
#include <windows.h>
#endif

static const std::set<std::string> criticalErrors{
"cppcheckError",
"cppcheckLimit",
"internalAstError",
"instantiationError",
"internalError",
"preprocessorErrorDirective",
"syntaxError",
"unknownMacro"
};


class XMLErrorMessagesLogger : public ErrorLogger
{
void reportOut(const std::string & outmsg, Color /*c*/ = Color::Reset) override
Expand Down Expand Up @@ -296,6 +308,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
AnalyzerInformation::writeFilesTxt(settings.buildDir, fileNames, settings.userDefines, settings.project.fileSettings);
}

std::set<std::string> criticalErrors;
unsigned int returnValue = 0;
if (settings.useSingleJob()) {
// Single process
Expand Down Expand Up @@ -326,6 +339,17 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
reportErr(ErrorMessage::getXMLFooter());
}

if (!mCriticalErrors.empty()) {
std::string err;
for (const std::string& id: mCriticalErrors)
err += "," + id;
reportOut("Checking was not successful. Checking was aborted because of critical errors (" + err.substr(1) + ").", Color::FgRed);
}

if (settings.terminated()) {
reportOut("Checking was not successful. Checking was stopped.", Color::FgRed);
}

if (returnValue)
return settings.exitCode;
return 0;
Expand Down Expand Up @@ -428,6 +452,9 @@ void CppCheckExecutor::reportErr(const ErrorMessage &msg)
{
assert(mSettings != nullptr);

if (criticalErrors.count(msg.id))
mCriticalErrors.insert(msg.id);

// Alert only about unique errors
if (!mShownErrors.insert(msg.toString(mSettings->verbose)).second)
return;
Expand Down
5 changes: 5 additions & 0 deletions cli/cppcheckexecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ class CppCheckExecutor : public ErrorLogger {
*/
std::set<std::string> mShownErrors;

/**
* @brief Critical errors that has been reported.
*/
std::set<std::string> mCriticalErrors;

/**
* Filename associated with size of file
*/
Expand Down
8 changes: 1 addition & 7 deletions gui/compliancereportdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,7 @@ void ComplianceReportDialog::save()
"--project-version=" + projectVersion,
"--output-file=" + outFile};

if (std.startsWith("misra-c-")) {
args << "--misra-c"
<< "--compliant=misra-c2012-1.1"
<< "--compliant=misra-c2012-1.2";
} else {
args << ("--" + std);
}
args << ("--" + std);

if (files)
args << "--files=" + tempFiles.fileName();
Expand Down
2 changes: 1 addition & 1 deletion gui/compliancereportdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<widget class="QComboBox" name="mCodingStandard">
<item>
<property name="text">
<string>Misra C 2023</string>
<string>Misra C</string>
</property>
</item>
<item>
Expand Down
32 changes: 20 additions & 12 deletions gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1020,11 +1020,10 @@ Settings MainWindow::getCppcheckSettings()
premiumArgs += " --bughunting";
if (mProjectFile->getCertIntPrecision() > 0)
premiumArgs += " --cert-c-int-precision=" + QString::number(mProjectFile->getCertIntPrecision());
if (mProjectFile->getAddons().contains("misra"))
premiumArgs += " --misra-c-2012";
for (const QString& c: mProjectFile->getCodingStandards()) {
for (const QString& c: mProjectFile->getCodingStandards())
premiumArgs += " --" + c;
}
if (!premiumArgs.contains("misra") && mProjectFile->getAddons().contains("misra"))
premiumArgs += " --misra-c-2012";
result.premiumArgs = premiumArgs.mid(1).toStdString();
}
}
Expand Down Expand Up @@ -1495,16 +1494,24 @@ void MainWindow::save()

void MainWindow::complianceReport()
{
if (isCppcheckPremium() && mProjectFile && mProjectFile->getAddons().contains("misra")) {
QTemporaryFile tempResults;
tempResults.open();
tempResults.close();
if (!mUI->mResults->isSuccess()) {
QMessageBox m(QMessageBox::Critical,
tr("Cppcheck"),
tr("Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors."),
QMessageBox::Ok,
this);
m.exec();
return;
}

mUI->mResults->save(tempResults.fileName(), Report::XMLV2);
QTemporaryFile tempResults;
tempResults.open();
tempResults.close();

ComplianceReportDialog dlg(mProjectFile, tempResults.fileName());
dlg.exec();
}
mUI->mResults->save(tempResults.fileName(), Report::XMLV2);

ComplianceReportDialog dlg(mProjectFile, tempResults.fileName());
dlg.exec();
}

void MainWindow::resultsAdded()
Expand Down Expand Up @@ -1574,6 +1581,7 @@ void MainWindow::aboutToShowViewMenu()
void MainWindow::stopAnalysis()
{
mThread->stop();
mUI->mResults->stopAnalysis();
mUI->mResults->disableProgressbar();
const QString &lastResults = getLastResults();
if (!lastResults.isEmpty()) {
Expand Down
41 changes: 41 additions & 0 deletions gui/resultsview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void ResultsView::initialize(QSettings *settings, ApplicationList *list, ThreadH
{
mUI->mProgress->setMinimum(0);
mUI->mProgress->setVisible(false);
mUI->mLabelCriticalErrors->setVisible(false);

CodeEditorStyle theStyle(CodeEditorStyle::loadSettings(settings));
mUI->mCode->setStyle(theStyle);
Expand Down Expand Up @@ -120,6 +121,8 @@ void ResultsView::clear(bool results)
mUI->mProgress->setMaximum(PROGRESS_MAX);
mUI->mProgress->setValue(0);
mUI->mProgress->setFormat("%p%");

mUI->mLabelCriticalErrors->setVisible(false);
}

void ResultsView::clear(const QString &filename)
Expand All @@ -145,6 +148,8 @@ void ResultsView::progress(int value, const QString& description)

void ResultsView::error(const ErrorItem &item)
{
handleCriticalError(item);

if (mUI->mTree->addErrorItem(item)) {
emit gotResults();
mStatistics->addItem(item.tool(), ShowTypes::SeverityToShowType(item.severity));
Expand Down Expand Up @@ -285,6 +290,8 @@ void ResultsView::checkingStarted(int count)

void ResultsView::checkingFinished()
{
mSuccess = !mUI->mLabelCriticalErrors->isVisible();

mUI->mProgress->setVisible(false);
mUI->mProgress->setFormat("%p%");

Expand Down Expand Up @@ -377,6 +384,7 @@ void ResultsView::readErrorsXml(const QString &filename)
}

for (const ErrorItem& item : errors) {
handleCriticalError(item);
mUI->mTree->addErrorItem(item);
}

Expand Down Expand Up @@ -506,3 +514,36 @@ void ResultsView::on_mListLog_customContextMenuRequested(const QPoint &pos)

contextMenu.exec(globalPos);
}

void ResultsView::stopAnalysis()
{
mUI->mLabelCriticalErrors->setText(tr("Analysis was stopped"));
mUI->mLabelCriticalErrors->setVisible(true);
}

void ResultsView::handleCriticalError(const ErrorItem &item)
{
const QSet<QString> criticalErrors{
"cppcheckError",
"cppcheckLimit",
"internalAstError",
"instantiationError",
"internalError",
"preprocessorErrorDirective",
"syntaxError",
"unknownMacro"
};

if (criticalErrors.contains(item.errorId)) {
QString msg = tr("There was a critical error with id '%1'").arg(item.errorId);
if (!item.file0.isEmpty())
msg += ", " + tr("when checking %1").arg(item.file0);
msg += ". " + tr("Analysis was aborted.");
mUI->mLabelCriticalErrors->setText(msg);
mUI->mLabelCriticalErrors->setVisible(true);
}
}

bool ResultsView::isSuccess() const {
return mSuccess && !mUI->mLabelCriticalErrors->isVisible();
}
22 changes: 21 additions & 1 deletion gui/resultsview.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,17 @@ class ResultsView : public QWidget {
*/
void translate();

/**
* @brief This function should be called when analysis is stopped
*/
void stopAnalysis();

/**
* @brief Are there successful results?
* @return true if analysis finished without critical errors etc
*/
bool isSuccess() const;

void disableProgressbar();

/**
Expand Down Expand Up @@ -340,7 +351,11 @@ public slots:
*/
void logCopyComplete();

protected:
private:

void handleCriticalError(const ErrorItem& item);
bool mHasCriticalError = false;

/**
* @brief Should we show a "No errors found dialog" every time no errors were found?
*/
Expand All @@ -350,6 +365,11 @@ public slots:

CheckStatistics *mStatistics;

/**
* Set to true when checking finish successfully. Set to false whenever analysis starts.
*/
bool mSuccess = false;

private slots:
/**
* @brief Custom context menu for Analysis Log
Expand Down
10 changes: 10 additions & 0 deletions gui/resultsview.ui
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="mLabelCriticalErrors">
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
<property name="text">
<string>Critical errors</string>
</property>
</widget>
</item>
<item>
<widget class="QSplitter" name="mVerticalSplitter">
<property name="orientation">
Expand Down

0 comments on commit c429d3e

Please sign in to comment.