From 29adee864c2499ff8dc19f6aab067e0aa8fe10c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 1 Jul 2024 08:35:38 +0200 Subject: [PATCH] Fix #12410 (GUI: show results customized for misra/cert/autosar) (#6556) --- gui/common.h | 4 + gui/erroritem.h | 2 + gui/mainwindow.cpp | 93 +- gui/mainwindow.h | 5 + gui/mainwindow.ui | 75 ++ gui/resultstree.cpp | 452 ++++++--- gui/resultstree.h | 18 + gui/resultsview.cpp | 4 + gui/resultsview.h | 3 + gui/test/resultstree/CMakeLists.txt | 1 + gui/test/resultstree/resultstree.pro | 7 +- gui/test/resultstree/testresultstree.cpp | 52 ++ gui/test/resultstree/testresultstree.h | 1 + lib/checkers.cpp | 1062 ++++++++++++++++++++++ lib/checkers.h | 27 + 15 files changed, 1672 insertions(+), 134 deletions(-) diff --git a/gui/common.h b/gui/common.h index e98d260e9cc..660ff13a14c 100644 --- a/gui/common.h +++ b/gui/common.h @@ -48,6 +48,10 @@ #define SETTINGS_TOOLBARS_VIEW_SHOW "Toolbars/ShowView" #define SETTINGS_TOOLBARS_FILTER_SHOW "Toolbars/ShowFilter" +// Report type +#define SETTINGS_REPORT_TYPE "Report type" +enum class ReportType : std::uint8_t { normal=0, autosar=1, certC=2, certCpp=3, misraC=4, misraCpp2008=5, misraCpp2023=6 }; + // Show * states #define SETTINGS_SHOW_STYLE "Show style" #define SETTINGS_SHOW_ERRORS "Show errors" diff --git a/gui/erroritem.h b/gui/erroritem.h index 21e76324598..e8c7a2a72d5 100644 --- a/gui/erroritem.h +++ b/gui/erroritem.h @@ -92,6 +92,8 @@ class ErrorItem { QList errorPath; QString symbolNames; QString remark; + QString classification; // misra/cert/etc: classification/level + QString guideline; // misra/cert/etc: guideline/rule // Special GUI properties QString sinceDate; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 07048c429f6..a510fbd1233 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -119,7 +119,8 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) : mPlatformActions(new QActionGroup(this)), mCStandardActions(new QActionGroup(this)), mCppStandardActions(new QActionGroup(this)), - mSelectLanguageActions(new QActionGroup(this)) + mSelectLanguageActions(new QActionGroup(this)), + mSelectReportActions(new QActionGroup(this)) { { Settings tempSettings; @@ -200,6 +201,15 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) : connect(mUI->mResults, &ResultsView::suppressIds, this, &MainWindow::suppressIds); connect(mUI->mMenuView, &QMenu::aboutToShow, this, &MainWindow::aboutToShowViewMenu); + // Change report type + connect(mUI->mActionReportNormal, &QAction::triggered, this, &MainWindow::changeReportType); + connect(mUI->mActionReportAutosar, &QAction::triggered, this, &MainWindow::changeReportType); + connect(mUI->mActionReportCertC, &QAction::triggered, this, &MainWindow::changeReportType); + connect(mUI->mActionReportCertCpp, &QAction::triggered, this, &MainWindow::changeReportType); + connect(mUI->mActionReportMisraC, &QAction::triggered, this, &MainWindow::changeReportType); + connect(mUI->mActionReportMisraCpp2008, &QAction::triggered, this, &MainWindow::changeReportType); + connect(mUI->mActionReportMisraCpp2023, &QAction::triggered, this, &MainWindow::changeReportType); + // File menu connect(mUI->mActionNewProjectFile, &QAction::triggered, this, &MainWindow::newProjectFile); connect(mUI->mActionOpenProjectFile, &QAction::triggered, this, &MainWindow::openProjectFile); @@ -261,6 +271,14 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) : connect(action, SIGNAL(triggered()), this, SLOT(selectPlatform())); } + mUI->mActionReportNormal->setActionGroup(mSelectReportActions); + mUI->mActionReportAutosar->setActionGroup(mSelectReportActions); + mUI->mActionReportCertC->setActionGroup(mSelectReportActions); + mUI->mActionReportCertCpp->setActionGroup(mSelectReportActions); + mUI->mActionReportMisraC->setActionGroup(mSelectReportActions); + mUI->mActionReportMisraCpp2008->setActionGroup(mSelectReportActions); + mUI->mActionReportMisraCpp2023->setActionGroup(mSelectReportActions); + mUI->mActionC89->setActionGroup(mCStandardActions); mUI->mActionC99->setActionGroup(mCStandardActions); mUI->mActionC11->setActionGroup(mCStandardActions); @@ -312,6 +330,8 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) : } else { delete mUI->mLayoutInformation; } + + changeReportType(); } MainWindow::~MainWindow() @@ -362,6 +382,15 @@ void MainWindow::loadSettings() mSettings->value(SETTINGS_WINDOW_HEIGHT, 600).toInt()); } + const ReportType reportType = (ReportType)mSettings->value(SETTINGS_REPORT_TYPE, (int)ReportType::normal).toInt(); + mUI->mActionReportNormal->setChecked(reportType <= ReportType::normal); + mUI->mActionReportAutosar->setChecked(reportType == ReportType::autosar); + mUI->mActionReportCertC->setChecked(reportType == ReportType::certC); + mUI->mActionReportCertCpp->setChecked(reportType == ReportType::certCpp); + mUI->mActionReportMisraC->setChecked(reportType == ReportType::misraC); + mUI->mActionReportMisraCpp2008->setChecked(reportType == ReportType::misraCpp2008); + mUI->mActionReportMisraCpp2023->setChecked(reportType == ReportType::misraCpp2023); + const ShowTypes &types = mUI->mResults->getShowTypes(); mUI->mActionShowStyle->setChecked(types.isShown(ShowTypes::ShowStyle)); mUI->mActionShowErrors->setChecked(types.isShown(ShowTypes::ShowErrors)); @@ -444,6 +473,15 @@ void MainWindow::saveSettings() const mSettings->setValue(SETTINGS_WINDOW_HEIGHT, size().height()); mSettings->setValue(SETTINGS_WINDOW_MAXIMIZED, isMaximized()); + const ReportType reportType = mUI->mActionReportAutosar->isChecked() ? ReportType::autosar : + mUI->mActionReportCertC->isChecked() ? ReportType::certC : + mUI->mActionReportCertCpp->isChecked() ? ReportType::certCpp : + mUI->mActionReportMisraC->isChecked() ? ReportType::misraC : + mUI->mActionReportMisraCpp2008->isChecked() ? ReportType::misraCpp2008 : + mUI->mActionReportMisraCpp2023->isChecked() ? ReportType::misraCpp2023 : + ReportType::normal; + mSettings->setValue(SETTINGS_REPORT_TYPE, (int)reportType); + // Show * states mSettings->setValue(SETTINGS_SHOW_STYLE, mUI->mActionShowStyle->isChecked()); mSettings->setValue(SETTINGS_SHOW_ERRORS, mUI->mActionShowErrors->isChecked()); @@ -2198,3 +2236,56 @@ bool MainWindow::isCppcheckPremium() const { return mCppcheckCfgProductName.startsWith("Cppcheck Premium "); } +void MainWindow::changeReportType() { + const ReportType reportType = mUI->mActionReportAutosar->isChecked() ? ReportType::autosar : + mUI->mActionReportCertC->isChecked() ? ReportType::certC : + mUI->mActionReportCertCpp->isChecked() ? ReportType::certCpp : + mUI->mActionReportMisraC->isChecked() ? ReportType::misraC : + mUI->mActionReportMisraCpp2008->isChecked() ? ReportType::misraCpp2008 : + mUI->mActionReportMisraCpp2023->isChecked() ? ReportType::misraCpp2023 : + ReportType::normal; + + mUI->mResults->setReportType(reportType); + + auto setTextAndHint = [](QAction* a, const QString& s) { + a->setVisible(!s.isEmpty()); + a->setText(s); + a->setToolTip(s); + }; + + const QString showMandatory = tr("Show Mandatory"); + const QString showRequired = tr("Show Required"); + const QString showAdvisory = tr("Show Advisory"); + const QString showDocument = tr("Show Document"); + + if (mUI->mActionReportAutosar->isChecked()) { + setTextAndHint(mUI->mActionShowErrors, ""); + setTextAndHint(mUI->mActionShowWarnings, showRequired); + setTextAndHint(mUI->mActionShowStyle, showAdvisory); + setTextAndHint(mUI->mActionShowPortability, ""); + setTextAndHint(mUI->mActionShowPerformance, ""); + setTextAndHint(mUI->mActionShowInformation, ""); + } else if (mUI->mActionReportMisraC->isChecked() || mUI->mActionReportMisraCpp2008->isChecked() || mUI->mActionReportMisraCpp2023->isChecked()) { + setTextAndHint(mUI->mActionShowErrors, mUI->mActionReportMisraCpp2008->isChecked() ? "" : showMandatory); + setTextAndHint(mUI->mActionShowWarnings, showRequired); + setTextAndHint(mUI->mActionShowStyle, showAdvisory); + setTextAndHint(mUI->mActionShowPortability, ""); + setTextAndHint(mUI->mActionShowPerformance, ""); + setTextAndHint(mUI->mActionShowInformation, mUI->mActionReportMisraCpp2008->isChecked() ? showDocument : QString()); + } else if (mUI->mActionReportCertC->isChecked() || mUI->mActionReportCertCpp->isChecked()) { + setTextAndHint(mUI->mActionShowErrors, tr("Show L1")); + setTextAndHint(mUI->mActionShowWarnings, tr("Show L2")); + setTextAndHint(mUI->mActionShowStyle, tr("Show L3")); + setTextAndHint(mUI->mActionShowPortability, ""); + setTextAndHint(mUI->mActionShowPerformance, ""); + setTextAndHint(mUI->mActionShowInformation, ""); + } else { + setTextAndHint(mUI->mActionShowErrors, tr("Show errors")); + setTextAndHint(mUI->mActionShowWarnings, tr("Show warnings")); + setTextAndHint(mUI->mActionShowStyle, tr("Show style")); + setTextAndHint(mUI->mActionShowPortability, tr("Show portability")); + setTextAndHint(mUI->mActionShowPerformance, tr("Show performance")); + setTextAndHint(mUI->mActionShowInformation, tr("Show information")); + } +} + diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 36785474839..608f8959b71 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -241,6 +241,8 @@ private slots: void replyFinished(QNetworkReply *reply); void hideInformation(); + + void changeReportType(); private: bool isCppcheckPremium() const; @@ -462,6 +464,9 @@ private slots: /** @brief GUI actions for selecting language. */ QActionGroup *mSelectLanguageActions; + /** @brief GUI actions for selecting report. */ + QActionGroup *mSelectReportActions; + /** * @brief Are we exiting the cppcheck? * If this is true then the cppcheck is waiting for check threads to exit diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index ac533599604..6fb74bc0cb2 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -159,8 +159,22 @@ + + + Report + + + + + + + + + + + @@ -950,6 +964,67 @@ Compliance report... + + + Report + + + + + true + + + Normal + + + + + true + + + Misra C + + + + + true + + + Misra C++ 2008 + + + + + true + + + Cert C + + + + + true + + + Cert C++ + + + + + true + + + Misra C++ 2023 + + + + + true + + + Autosar + + diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index e859108e2ef..e31388893f1 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -20,6 +20,7 @@ #include "application.h" #include "applicationlist.h" +#include "checkers.h" #include "common.h" #include "erroritem.h" #include "errorlogger.h" @@ -72,22 +73,176 @@ static constexpr char HIDE[] = "hide"; static constexpr char INCONCLUSIVE[] = "inconclusive"; static constexpr char LINE[] = "line"; static constexpr char MESSAGE[] = "message"; +static constexpr char REMARK[] = "remark"; static constexpr char SEVERITY[] = "severity"; static constexpr char SINCEDATE[] = "sinceDate"; static constexpr char SYMBOLNAMES[] = "symbolNames"; static constexpr char SUMMARY[] = "summary"; static constexpr char TAGS[] = "tags"; -static constexpr char REMARK[] = "remark"; // These must match column headers given in ResultsTree::translate() -static constexpr int COLUMN_SINCE_DATE = 6; -static constexpr int COLUMN_TAGS = 7; +static constexpr int COLUMN_FILE = 0; +static constexpr int COLUMN_LINE = 1; +static constexpr int COLUMN_SEVERITY = 2; +static constexpr int COLUMN_MISRA_CLASSIFICATION = 3; +static constexpr int COLUMN_CERT_LEVEL = 4; +static constexpr int COLUMN_INCONCLUSIVE = 5; +static constexpr int COLUMN_SUMMARY = 6; +static constexpr int COLUMN_ID = 7; +static constexpr int COLUMN_MISRA_GUIDELINE = 8; +static constexpr int COLUMN_CERT_RULE = 9; +static constexpr int COLUMN_SINCE_DATE = 10; +static constexpr int COLUMN_TAGS = 11; +static constexpr int COLUMN_CWE = 12; + +static QString getGuideline(ReportType reportType, const QMap& guidelines, const QString& errorId) { + if (reportType == ReportType::autosar) { + if (errorId.startsWith("premium-autosar-")) + return errorId.mid(16); + if (errorId.startsWith("premium-misra-cpp-2008-")) + return "M" + errorId.mid(23); + } + if (reportType == ReportType::certC || reportType == ReportType::certCpp) { + if (errorId.startsWith("premium-cert-")) + return errorId.mid(13).toUpper(); + } + if (errorId.startsWith("premium-")) + return getGuideline(reportType, guidelines, errorId.mid(8)); + if (reportType == ReportType::misraC && (errorId.startsWith("misra-c20") || errorId.startsWith("misra-c-20"))) + return errorId.mid(errorId.lastIndexOf("-") + 1); + if (reportType == ReportType::misraCpp2008 && errorId.startsWith("misra-cpp-2008-")) + return errorId.mid(15); + if (reportType == ReportType::misraCpp2023 && errorId.startsWith("misra-cpp-2023-")) + return errorId.mid(15); + return guidelines.value(errorId); +} + +static QString getClassification(ReportType reportType, const QString& guideline) { + if (guideline.isEmpty()) + return QString(); + if (reportType == ReportType::autosar) { + for (const checkers::Info& autosarInfo: checkers::autosarInfo) { + // cppcheck-suppress useStlAlgorithm + if (guideline.compare(autosarInfo.guideline, Qt::CaseInsensitive)) + return autosarInfo.classification; + } + } + else if (reportType == ReportType::certC || reportType == ReportType::certCpp) { + if (guideline.endsWith("-CPP")) { + for (const checkers::Info& info: checkers::certCppInfo) { + // cppcheck-suppress useStlAlgorithm + if (guideline.compare(info.guideline, Qt::CaseInsensitive)) + return info.classification; + } + } else if (guideline.endsWith("-C")) { + for (const checkers::Info& info: checkers::certCInfo) { + // cppcheck-suppress useStlAlgorithm + if (guideline.compare(info.guideline, Qt::CaseInsensitive)) + return info.classification; + } + } + } + else if (reportType == ReportType::misraC) { + QStringList list = guideline.split("."); + if (list.size() == 2) { + bool ok = true; + const int a = list[0].toInt(&ok); + if (!ok) + return QString(); + const int b = list[1].toInt(&ok); + if (!ok) + return QString(); + for (const auto& info: checkers::misraC2012Rules) { + // cppcheck-suppress useStlAlgorithm + if (info.a == a && info.b == b) + return info.str; + } + } + } + else if (reportType == ReportType::misraCpp2008) { + QStringList list = guideline.split("-"); + if (list.size() == 3) { + bool ok = true; + const int a = list[0].toInt(&ok); + if (!ok) + return QString(); + const int b = list[1].toInt(&ok); + if (!ok) + return QString(); + const int c = list[2].toInt(&ok); + if (!ok) + return QString(); + for (const auto& info: checkers::misraCpp2008Rules) { + // cppcheck-suppress useStlAlgorithm + if (info.a == a && info.b == b && info.c == c) + return info.classification; + } + } + } + else if (reportType == ReportType::misraCpp2023) { + QStringList list = guideline.split("."); + if (list.size() == 3) { + bool ok = true; + const int a = list[0].toInt(&ok); + if (!ok) + return QString(); + const int b = list[1].toInt(&ok); + if (!ok) + return QString(); + const int c = list[2].toInt(&ok); + if (!ok) + return QString(); + for (const auto& info: checkers::misraCpp2023Rules) { + // cppcheck-suppress useStlAlgorithm + if (info.a == a && info.b == b && info.c == c) + return info.classification; + } + } + } + return QString(); +} + +static Severity getSeverityFromClassification(const QString &c) { + if (c == checkers::Man) + return Severity::error; + if (c == checkers::Req) + return Severity::warning; + if (c == checkers::Adv) + return Severity::style; + if (c == checkers::Doc) + return Severity::information; + if (c == "L1") + return Severity::error; + if (c == "L2") + return Severity::warning; + if (c == "L3") + return Severity::style; + return Severity::none; +} + +static QStringList getLabels() { + return QStringList{ + QObject::tr("File"), + QObject::tr("Line"), + QObject::tr("Severity"), + QObject::tr("Classification"), + QObject::tr("Level"), + QObject::tr("Inconclusive"), + QObject::tr("Summary"), + QObject::tr("Id"), + QObject::tr("Guideline"), + QObject::tr("Rule"), + QObject::tr("Since date"), + QObject::tr("Tags"), + QObject::tr("CWE")}; +} ResultsTree::ResultsTree(QWidget * parent) : QTreeView(parent) { setModel(&mModel); translate(); // Adds columns to grid + clear(); setExpandsOnDoubleClick(false); setSortingEnabled(true); @@ -102,6 +257,77 @@ void ResultsTree::keyPressEvent(QKeyEvent *event) QTreeView::keyPressEvent(event); } +void ResultsTree::setReportType(ReportType reportType) { + mReportType = reportType; + + auto readIdMapping = [this](const std::vector& idMapping) { + for (const auto& i: idMapping) + for (const QString& cppcheckId: QString(i.cppcheckId).split(",")) + mGuideline[cppcheckId] = i.guideline; + }; + + if (reportType == ReportType::autosar) { + for (const auto& a: checkers::autosarInfo) { + mGuideline[a.cppcheckIds] = QString(a.guideline).toUpper(); + } + } + else if (reportType == ReportType::certC) { + for (const auto& a: checkers::certCInfo) + mGuideline[a.cppcheckIds] = QString(a.guideline).toUpper(); + } + else if (reportType == ReportType::certCpp) { + for (const auto& a: checkers::certCInfo) + mGuideline[a.cppcheckIds] = QString(a.guideline).toUpper(); + for (const auto& a: checkers::certCppInfo) + mGuideline[a.cppcheckIds] = QString(a.guideline).toUpper(); + } + else if (reportType == ReportType::misraC) + readIdMapping(checkers::idMappingMisraC); + else if (reportType == ReportType::misraCpp2008) + readIdMapping(checkers::idMappingMisraCpp2008); + else if (reportType == ReportType::misraCpp2023) + readIdMapping(checkers::idMappingMisraCpp2023); + + for (int i = 0; i < mModel.rowCount(); ++i) { + const QStandardItem *fileItem = mModel.item(i, COLUMN_FILE); + if (!fileItem) + continue; + for (int j = 0; j < fileItem->rowCount(); ++j) { + const QString& errorId = fileItem->child(j, COLUMN_ID)->text(); + const QString& guideline = getGuideline(mReportType, mGuideline, errorId); + const QString& classification = getClassification(mReportType, guideline); + fileItem->child(j, COLUMN_CERT_LEVEL)->setText(classification); + fileItem->child(j, COLUMN_CERT_RULE)->setText(guideline); + fileItem->child(j, COLUMN_MISRA_CLASSIFICATION)->setText(classification); + fileItem->child(j, COLUMN_MISRA_GUIDELINE)->setText(guideline); + } + } + + if (isAutosarMisraReport()) { + showColumn(COLUMN_MISRA_CLASSIFICATION); + showColumn(COLUMN_MISRA_GUIDELINE); + } else { + hideColumn(COLUMN_MISRA_CLASSIFICATION); + hideColumn(COLUMN_MISRA_GUIDELINE); + } + + if (isCertReport()) { + showColumn(COLUMN_CERT_LEVEL); + showColumn(COLUMN_CERT_RULE); + } else { + hideColumn(COLUMN_CERT_LEVEL); + hideColumn(COLUMN_CERT_RULE); + } + + if (mReportType == ReportType::normal) { + showColumn(COLUMN_SEVERITY); + } else { + hideColumn(COLUMN_SEVERITY); + } + + refreshTree(); +} + void ResultsTree::initialize(QSettings *settings, ApplicationList *list, ThreadHandler *checkThreadHandler) { mSettings = settings; @@ -151,27 +377,35 @@ bool ResultsTree::addErrorItem(const ErrorItem &item) realfile = tr("Undefined file"); } - bool hide = false; + bool showItem = true; // Ids that are temporarily hidden.. if (mHiddenMessageId.contains(item.errorId)) - hide = true; + showItem = false; //If specified, filter on summary, message, filename, and id - if (!hide && !mFilter.isEmpty()) { + if (showItem && !mFilter.isEmpty()) { if (!item.summary.contains(mFilter, Qt::CaseInsensitive) && !item.message.contains(mFilter, Qt::CaseInsensitive) && !item.errorPath.back().file.contains(mFilter, Qt::CaseInsensitive) && !item.errorId.contains(mFilter, Qt::CaseInsensitive)) { - hide = true; + showItem = false; } } - //if there is at least one error that is not hidden, we have a visible error - if (!hide) { - mVisibleErrors = true; + if (showItem) { + if (mReportType == ReportType::normal) + showItem = mShowSeverities.isShown(item.severity); + else { + const QString& guideline = getGuideline(mReportType, mGuideline, item.errorId); + const QString& classification = getClassification(mReportType, guideline); + showItem = !classification.isEmpty() && mShowSeverities.isShown(getSeverityFromClassification(classification)); + } } + // if there is at least one error that is not hidden, we have a visible error + mVisibleErrors |= showItem; + ErrorLine line; line.file = realfile; line.line = loc.line; @@ -189,10 +423,10 @@ bool ResultsTree::addErrorItem(const ErrorItem &item) line.remark = item.remark; //Create the base item for the error and ensure it has a proper //file item as a parent - QStandardItem* fileItem = ensureFileItem(loc.file, item.file0, hide); + QStandardItem* fileItem = ensureFileItem(loc.file, item.file0, !showItem); QStandardItem* stditem = addBacktraceFiles(fileItem, line, - hide, + !showItem, severityToIcon(line.severity), false); @@ -216,7 +450,7 @@ bool ResultsTree::addErrorItem(const ErrorItem &item) data[SYMBOLNAMES] = item.symbolNames; data[TAGS] = line.tags; data[REMARK] = line.remark; - data[HIDE] = hide; + data[HIDE] = false; stditem->setData(QVariant(data)); //Add backtrace files as children @@ -228,7 +462,7 @@ bool ResultsTree::addErrorItem(const ErrorItem &item) line.message = line.summary = e.info; QStandardItem *child_item = addBacktraceFiles(stditem, line, - hide, + false, ":images/go-down.png", true); if (!child_item) @@ -251,17 +485,6 @@ bool ResultsTree::addErrorItem(const ErrorItem &item) } } - // Partially refresh the tree: Unhide file item if necessary - setRowHidden(stditem->row(), fileItem->index(), hide || !mShowSeverities.isShown(item.severity)); - - bool hideFile = true; - for (int i = 0; i < fileItem->rowCount(); ++i) { - if (!isRowHidden(i, fileItem->index())) { - hideFile = false; - } - } - setRowHidden(fileItem->row(), QModelIndex(), hideFile); - return true; } @@ -271,34 +494,24 @@ QStandardItem *ResultsTree::addBacktraceFiles(QStandardItem *parent, const QString &icon, bool childOfMessage) { - if (!parent) { + if (!parent) return nullptr; - } - - QList list; - // Ensure shown path is with native separators - list << createNormalItem(QDir::toNativeSeparators(item.file)) - << createNormalItem(childOfMessage ? tr("note") : severityToTranslatedString(item.severity)) - << createLineNumberItem(QString::number(item.line)) - << createNormalItem(childOfMessage ? QString() : item.errorId) - << (childOfMessage ? createNormalItem(QString()) : createCheckboxItem(item.inconclusive)) - << createNormalItem(item.summary) - << createNormalItem(item.sinceDate) - << createNormalItem(item.tags); //TODO message has parameter names so we'll need changes to the core //cppcheck so we can get proper translations + const QString itemSeverity = childOfMessage ? tr("note") : severityToTranslatedString(item.severity); + // Check for duplicate rows and don't add them if found for (int i = 0; i < parent->rowCount(); i++) { // The first column is the file name and is always the same // the third column is the line number so check it first - if (parent->child(i, 2)->text() == list[2]->text()) { + if (parent->child(i, COLUMN_LINE)->text() == QString::number(item.line)) { // the second column is the severity so check it next - if (parent->child(i, 1)->text() == list[1]->text()) { + if (parent->child(i, COLUMN_SEVERITY)->text() == itemSeverity) { // the sixth column is the summary so check it last - if (parent->child(i, 5)->text() == list[5]->text()) { + if (parent->child(i, COLUMN_SUMMARY)->text() == item.summary) { // this row matches so don't add it return nullptr; } @@ -306,6 +519,28 @@ QStandardItem *ResultsTree::addBacktraceFiles(QStandardItem *parent, } } + QMap columns; + const QString guideline = getGuideline(mReportType, mGuideline, item.errorId); + const QString classification = getClassification(mReportType, guideline); + columns[COLUMN_CERT_LEVEL] = createNormalItem(classification); + columns[COLUMN_CERT_RULE] = createNormalItem(guideline); + columns[COLUMN_CWE] = createNormalItem(QString::number(item.cwe)); + columns[COLUMN_FILE] = createNormalItem(QDir::toNativeSeparators(item.file)); + columns[COLUMN_ID] = createNormalItem(childOfMessage ? QString() : item.errorId); + columns[COLUMN_INCONCLUSIVE] = childOfMessage ? createNormalItem(QString()) : createCheckboxItem(item.inconclusive); + columns[COLUMN_LINE] = createLineNumberItem(QString::number(item.line)); + columns[COLUMN_MISRA_CLASSIFICATION] = createNormalItem(classification); + columns[COLUMN_MISRA_GUIDELINE] = createNormalItem(guideline); + columns[COLUMN_SEVERITY] = createNormalItem(itemSeverity); + columns[COLUMN_SINCE_DATE] = createNormalItem(item.sinceDate); + columns[COLUMN_SUMMARY] = createNormalItem(item.summary); + columns[COLUMN_TAGS] = createNormalItem(item.tags); + + const int numberOfColumns = getLabels().size(); + QList list; + for (int i = 0; i < numberOfColumns; ++i) + list << columns[i]; + parent->appendRow(list); setRowHidden(parent->rowCount() - 1, parent->index(), hide); @@ -314,20 +549,6 @@ QStandardItem *ResultsTree::addBacktraceFiles(QStandardItem *parent, list[0]->setIcon(QIcon(icon)); } - /* TODO: the list items leak memory - Indirect leak of 80624 byte(s) in 5039 object(s) allocated from: - #0 0xa15a2d in operator new(unsigned long) (/mnt/s/GitHub/cppcheck-fw/cmake-build-debug-wsl-kali-clang-asan-ubsan/bin/cppcheck-gui+0xa15a2d) - #1 0xdda276 in ResultsTree::createNormalItem(QString const&) /mnt/s/GitHub/cppcheck-fw/gui/resultstree.cpp:122:27 - #2 0xde4290 in ResultsTree::addBacktraceFiles(QStandardItem*, ErrorLine const&, bool, QString const&, bool) /mnt/s/GitHub/cppcheck-fw/gui/resultstree.cpp:289:13 - #3 0xddd754 in ResultsTree::addErrorItem(ErrorItem const&) /mnt/s/GitHub/cppcheck-fw/gui/resultstree.cpp:199:30 - #4 0xe37046 in ResultsView::error(ErrorItem const&) /mnt/s/GitHub/cppcheck-fw/gui/resultsview.cpp:129:21 - #5 0xd2448d in QtPrivate::FunctorCall, QtPrivate::List, void, void (ResultsView::*)(ErrorItem const&)>::call(void (ResultsView::*)(ErrorItem const&), ResultsView*, void**) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:152:13 - #6 0xd2402c in void QtPrivate::FunctionPointer::call, void>(void (ResultsView::*)(ErrorItem const&), ResultsView*, void**) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:185:13 - #7 0xd23b45 in QtPrivate::QSlotObject, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:418:17 - #8 0x7fd2536cc0dd in QObject::event(QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2dc0dd) - #9 0x7fd2541836be in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1636be) - */ - return list[0]; } @@ -371,11 +592,11 @@ QStandardItem *ResultsTree::findFileItem(const QString &name) const for (int i = 0; i < mModel.rowCount(); i++) { #ifdef _WIN32 - if (QString::compare(mModel.item(i, 0)->text(), name, Qt::CaseInsensitive) == 0) + if (QString::compare(mModel.item(i, COLUMN_FILE)->text(), name, Qt::CaseInsensitive) == 0) #else - if (mModel.item(i, 0)->text() == name) + if (mModel.item(i, COLUMN_FILE)->text() == name) #endif - return mModel.item(i, 0); + return mModel.item(i, COLUMN_FILE); } return nullptr; } @@ -383,6 +604,17 @@ QStandardItem *ResultsTree::findFileItem(const QString &name) const void ResultsTree::clear() { mModel.removeRows(0, mModel.rowCount()); + + if (const ProjectFile *activeProject = ProjectFile::getActiveProject()) { + hideColumn(COLUMN_SINCE_DATE); + if (activeProject->getTags().isEmpty()) + hideColumn(COLUMN_TAGS); + else + showColumn(COLUMN_TAGS); + } else { + hideColumn(COLUMN_SINCE_DATE); + hideColumn(COLUMN_TAGS); + } } void ResultsTree::clear(const QString &filename) @@ -390,7 +622,7 @@ void ResultsTree::clear(const QString &filename) const QString stripped = stripPath(filename, false); for (int i = 0; i < mModel.rowCount(); ++i) { - const QStandardItem *fileItem = mModel.item(i, 0); + const QStandardItem *fileItem = mModel.item(i, COLUMN_FILE); if (!fileItem) continue; @@ -406,7 +638,7 @@ void ResultsTree::clear(const QString &filename) void ResultsTree::clearRecheckFile(const QString &filename) { for (int i = 0; i < mModel.rowCount(); ++i) { - const QStandardItem *fileItem = mModel.item(i, 0); + const QStandardItem *fileItem = mModel.item(i, COLUMN_FILE); if (!fileItem) continue; @@ -475,26 +707,6 @@ void ResultsTree::showHiddenResults() { //Clear the "hide" flag for each item mHiddenMessageId.clear(); - const int filecount = mModel.rowCount(); - for (int i = 0; i < filecount; i++) { - QStandardItem *fileItem = mModel.item(i, 0); - if (!fileItem) - continue; - - QVariantMap data = fileItem->data().toMap(); - data[HIDE] = false; - fileItem->setData(QVariant(data)); - - const int errorcount = fileItem->rowCount(); - for (int j = 0; j < errorcount; j++) { - QStandardItem *child = fileItem->child(j, 0); - if (child) { - data = child->data().toMap(); - data[HIDE] = false; - child->setData(QVariant(data)); - } - } - } refreshTree(); emit resultsHidden(false); } @@ -517,7 +729,7 @@ void ResultsTree::refreshTree() const int errorcount = fileItem->rowCount(); //By default it shouldn't be visible - bool show = false; + bool showFile = false; for (int j = 0; j < errorcount; j++) { //Get the error itself @@ -532,14 +744,24 @@ void ResultsTree::refreshTree() QVariantMap data = userdata.toMap(); //Check if this error should be hidden - bool hide = (data[HIDE].toBool() || !mShowSeverities.isShown(ShowTypes::VariantToShowType(data[SEVERITY]))); + bool hide = data[HIDE].toBool() || mHiddenMessageId.contains(data[ERRORID].toString()); - //If specified, filter on summary, message, filename, and id + if (!hide) { + if (mReportType == ReportType::normal) + hide = !mShowSeverities.isShown(ShowTypes::VariantToShowType(data[SEVERITY])); + else { + const QString& classification = fileItem->child(j, COLUMN_MISRA_CLASSIFICATION)->text(); + hide = classification.isEmpty() || !mShowSeverities.isShown(getSeverityFromClassification(classification)); + } + } + + // If specified, filter on summary, message, filename, and id if (!hide && !mFilter.isEmpty()) { if (!data[SUMMARY].toString().contains(mFilter, Qt::CaseInsensitive) && !data[MESSAGE].toString().contains(mFilter, Qt::CaseInsensitive) && !data[FILENAME].toString().contains(mFilter, Qt::CaseInsensitive) && - !data[ERRORID].toString().contains(mFilter, Qt::CaseInsensitive)) { + !data[ERRORID].toString().contains(mFilter, Qt::CaseInsensitive) && + !fileItem->child(j, COLUMN_MISRA_CLASSIFICATION)->text().contains(mFilter, Qt::CaseInsensitive)) { hide = true; } } @@ -553,25 +775,16 @@ void ResultsTree::refreshTree() } if (!hide) { + showFile = true; mVisibleErrors = true; } //Hide/show accordingly setRowHidden(j, fileItem->index(), hide); - - //If it was shown then the file itself has to be shown as well - if (!hide) { - show = true; - } } - //Hide the file if its "hide" attribute is set - if (fileItem->data().toMap()["hide"].toBool()) { - show = false; - } - - //Show the file if any of it's errors are visible - setRowHidden(i, QModelIndex(), !show); + // Show the file if any of it's errors are visible + setRowHidden(i, QModelIndex(), !showFile); } } @@ -583,6 +796,8 @@ QStandardItem *ResultsTree::ensureFileItem(const QString &fullpath, const QStrin QStandardItem *item = findFileItem(QDir::toNativeSeparators(name)); if (item) { + if (!hide) + setRowHidden(item->row(), QModelIndex(), hide); return item; } @@ -598,7 +813,7 @@ QStandardItem *ResultsTree::ensureFileItem(const QString &fullpath, const QStrin item->setData(QVariant(data)); mModel.appendRow(item); - setRowHidden(mModel.rowCount() - 1, QModelIndex(), hide); + setRowHidden(item->row(), QModelIndex(), hide); return item; } @@ -1001,33 +1216,6 @@ void ResultsTree::hideAllIdResult() mHiddenMessageId.append(messageId); - // hide all errors with that message Id - const int filecount = mModel.rowCount(); - for (int i = 0; i < filecount; i++) { - //Get file i - QStandardItem *file = mModel.item(i, 0); - if (!file) { - continue; - } - - //Get the amount of errors this file contains - const int errorcount = file->rowCount(); - - for (int j = 0; j < errorcount; j++) { - //Get the error itself - QStandardItem *child = file->child(j, 0); - if (!child) { - continue; - } - - QVariantMap userdata = child->data().toMap(); - if (userdata[ERRORID].toString() == messageId) { - userdata[HIDE] = true; - child->setData(QVariant(userdata)); - } - } - } - refreshTree(); emit resultsHidden(true); } @@ -1242,6 +1430,8 @@ static int indexOf(const QList &list, const ErrorItem &item) void ResultsTree::updateFromOldReport(const QString &filename) { + showColumn(COLUMN_SINCE_DATE); + QList oldErrors; XmlReportV2 oldReport(filename, QString()); if (oldReport.open()) { @@ -1299,6 +1489,8 @@ void ResultsTree::readErrorItem(const QStandardItem *error, ErrorItem *item) con item->sinceDate = data[SINCEDATE].toString(); item->tags = data[TAGS].toString(); item->remark = data[REMARK].toString(); + item->classification = error->parent()->child(error->row(), COLUMN_MISRA_CLASSIFICATION)->text(); + item->guideline = error->parent()->child(error->row(), COLUMN_MISRA_GUIDELINE)->text(); if (error->rowCount() == 0) { QErrorPathItem e; @@ -1443,9 +1635,7 @@ bool ResultsTree::hasResults() const void ResultsTree::translate() { - QStringList labels; - labels << tr("File") << tr("Severity") << tr("Line") << tr("Id") << tr("Inconclusive") << tr("Summary") << tr("Since date") << tr("Tag"); - mModel.setHorizontalHeaderLabels(labels); + mModel.setHorizontalHeaderLabels(getLabels()); //TODO go through all the errors in the tree and translate severity and message } @@ -1453,17 +1643,17 @@ void ResultsTree::showIdColumn(bool show) { mShowErrorId = show; if (show) - showColumn(3); + showColumn(COLUMN_ID); else - hideColumn(3); + hideColumn(COLUMN_ID); } void ResultsTree::showInconclusiveColumn(bool show) { if (show) - showColumn(4); + showColumn(COLUMN_INCONCLUSIVE); else - hideColumn(4); + hideColumn(COLUMN_INCONCLUSIVE); } void ResultsTree::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) diff --git a/gui/resultstree.h b/gui/resultstree.h index a69ee336a14..a360c7f8eb9 100644 --- a/gui/resultstree.h +++ b/gui/resultstree.h @@ -20,6 +20,7 @@ #ifndef RESULTSTREE_H #define RESULTSTREE_H +#include "common.h" #include "showtypes.h" #include @@ -186,6 +187,8 @@ class ResultsTree : public QTreeView { void keyPressEvent(QKeyEvent *event) override; + void setReportType(ReportType reportType); + signals: /** * @brief Signal that results have been hidden or shown @@ -518,6 +521,17 @@ protected slots: /** @brief Convert GUI error item into data error item */ void readErrorItem(const QStandardItem *error, ErrorItem *item) const; + bool isCertReport() const { + return mReportType == ReportType::certC || mReportType == ReportType::certCpp; + } + + bool isAutosarMisraReport() const { + return mReportType == ReportType::autosar || + mReportType == ReportType::misraC || + mReportType == ReportType::misraCpp2008 || + mReportType == ReportType::misraCpp2023; + } + QStringList mHiddenMessageId; QItemSelectionModel* mSelectionModel{}; @@ -525,6 +539,10 @@ protected slots: bool mShowCppcheck = true; bool mShowClang = true; + + ReportType mReportType = ReportType::normal; + + QMap mGuideline; }; /// @} #endif // RESULTSTREE_H diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index fd1bcf5855d..439d2560f3f 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -153,6 +153,10 @@ const ShowTypes & ResultsView::getShowTypes() const return mUI->mTree->mShowSeverities; } +void ResultsView::setReportType(ReportType reportType) { + mUI->mTree->setReportType(reportType); +} + void ResultsView::progress(int value, const QString& description) { mUI->mProgress->setValue(value); diff --git a/gui/resultsview.h b/gui/resultsview.h index ec97ccf74ff..d1249b80abf 100644 --- a/gui/resultsview.h +++ b/gui/resultsview.h @@ -20,6 +20,7 @@ #ifndef RESULTSVIEW_H #define RESULTSVIEW_H +#include "common.h" #include "report.h" #include "showtypes.h" @@ -217,6 +218,8 @@ class ResultsView : public QWidget { */ const ShowTypes & getShowTypes() const; + void setReportType(ReportType reportType); + signals: /** diff --git a/gui/test/resultstree/CMakeLists.txt b/gui/test/resultstree/CMakeLists.txt index 9c98e8dcf35..3e5cc0fe96f 100644 --- a/gui/test/resultstree/CMakeLists.txt +++ b/gui/test/resultstree/CMakeLists.txt @@ -9,6 +9,7 @@ add_executable(test-resultstree ${CMAKE_SOURCE_DIR}/gui/showtypes.cpp ${CMAKE_SOURCE_DIR}/gui/report.cpp ${CMAKE_SOURCE_DIR}/gui/xmlreportv2.cpp + ${CMAKE_SOURCE_DIR}/lib/checkers.cpp ) target_include_directories(test-resultstree PRIVATE ${CMAKE_SOURCE_DIR}/gui ${CMAKE_SOURCE_DIR}/lib) target_compile_definitions(test-resultstree PRIVATE SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/gui/test/resultstree/resultstree.pro b/gui/test/resultstree/resultstree.pro index d4677d13eea..27f2c0dda41 100644 --- a/gui/test/resultstree/resultstree.pro +++ b/gui/test/resultstree/resultstree.pro @@ -18,11 +18,14 @@ SOURCES += testresultstree.cpp \ ../../erroritem.cpp \ ../../showtypes.cpp \ ../../report.cpp \ - ../../xmlreportv2.cpp + ../../xmlreportv2.cpp \ + ../../../lib/checkers.cpp HEADERS += testresultstree.h \ ../../resultstree.h \ + ../../common.h \ ../../erroritem.h \ ../../showtypes.h \ ../../report.h \ - ../../xmlreportv2.h + ../../xmlreportv2.h \ + ../../../lib/checkers.h diff --git a/gui/test/resultstree/testresultstree.cpp b/gui/test/resultstree/testresultstree.cpp index b8fbb44b36f..b00b244cd73 100644 --- a/gui/test/resultstree/testresultstree.cpp +++ b/gui/test/resultstree/testresultstree.cpp @@ -33,6 +33,22 @@ #include +class TestReport: public Report { +public: + TestReport(QString format) : Report(QString()), format(format) {} + void writeHeader() override { output.clear(); } + void writeFooter() override {} + void writeError(const ErrorItem &error) override { + QString line = format; + line.replace("{id}", error.errorId); + line.replace("{classification}", error.classification); + line.replace("{guideline}", error.guideline); + output += (output.isEmpty() ? "" : "\n") + line; + } + QString format; + QString output; +}; + // Mock GUI... ProjectFile *ProjectFile::mActiveProject; void ProjectFile::addSuppression(const SuppressionList::Suppression & /*unused*/) {} @@ -104,5 +120,41 @@ void TestResultsTree::test1() const QCOMPARE(tree.isRowHidden(0,QModelIndex()), false); // Show item } +void TestResultsTree::testReportType() const +{ + TestReport report("{id},{classification},{guideline}"); + + int msgCount = 0; + auto createErrorItem = [&msgCount](const Severity severity, const QString& errorId) -> ErrorItem { + ++msgCount; + ErrorItem errorItem; + errorItem.errorPath << QErrorPathItem(ErrorMessage::FileLocation("file1.c", msgCount, 1)); + errorItem.severity = severity; + errorItem.errorId = errorId; + errorItem.summary = "test summary " + QString::number(msgCount); + return errorItem; + }; + + // normal report with 2 errors + ResultsTree tree(nullptr); + tree.updateSettings(false, false, false, false, false); + tree.addErrorItem(createErrorItem(Severity::style, "id1")); + tree.addErrorItem(createErrorItem(Severity::style, "unusedVariable")); // Misra C 2.8 + tree.saveResults(&report); + QCOMPARE(report.output, "id1,,\nunusedVariable,,"); + + // switch to Misra C report and check that "id1" is not shown + tree.setReportType(ReportType::misraC); + tree.saveResults(&report); + QCOMPARE(report.output, "unusedVariable,Advisory,2.8"); + + // add "missingReturn" and check that it is added properly + tree.addErrorItem(createErrorItem(Severity::warning, "missingReturn")); // Misra C 17.4 + tree.saveResults(&report); + QCOMPARE(report.output, + "unusedVariable,Advisory,2.8\n" + "missingReturn,Mandatory,17.4"); +} + QTEST_MAIN(TestResultsTree) diff --git a/gui/test/resultstree/testresultstree.h b/gui/test/resultstree/testresultstree.h index acea181ee5b..ddd68555e06 100644 --- a/gui/test/resultstree/testresultstree.h +++ b/gui/test/resultstree/testresultstree.h @@ -23,4 +23,5 @@ class TestResultsTree : public QObject { private slots: void test1() const; + void testReportType() const; }; diff --git a/lib/checkers.cpp b/lib/checkers.cpp index e54943302b7..9e7a69608a7 100644 --- a/lib/checkers.cpp +++ b/lib/checkers.cpp @@ -834,6 +834,7 @@ namespace checkers { const char Req[] = "Required"; const char Adv[] = "Advisory"; const char Man[] = "Mandatory"; + const char Doc[] = "Document"; const std::vector misraC2012Rules = { @@ -1070,4 +1071,1065 @@ namespace checkers { {"22.4", "error"}, //{"writeReadOnlyFile"}}, {"22.6", "error"}, //{"useClosedFile"}} }; + + const std::vector misraCpp2008Rules = + { + {0,1,1,Req}, + {0,1,2,Req}, + {0,1,3,Req}, + {0,1,4,Req}, + {0,1,5,Req}, + {0,1,6,Req}, + {0,1,7,Req}, + {0,1,8,Req}, + {0,1,9,Req}, + {0,1,10,Req}, + {0,1,11,Req}, + {0,1,12,Req}, + {0,2,1,Req}, + {0,3,1,Doc}, + {0,3,2,Req}, + {0,4,1,Doc}, + {0,4,2,Doc}, + {0,4,3,Doc}, + {1,0,1,Req}, + {1,0,2,Doc}, + {1,0,3,Doc}, + {2,2,1,Doc}, + {2,3,1,Req}, + {2,5,1,Adv}, + {2,7,1,Req}, + {2,7,2,Req}, + {2,7,3,Adv}, + {2,10,1,Req}, + {2,10,2,Req}, + {2,10,3,Req}, + {2,10,4,Req}, + {2,10,5,Adv}, + {2,10,6,Req}, + {2,13,1,Req}, + {2,13,2,Req}, + {2,13,3,Req}, + {2,13,4,Req}, + {2,13,5,Req}, + {3,1,1,Req}, + {3,1,2,Req}, + {3,1,3,Req}, + {3,2,1,Req}, + {3,2,2,Req}, + {3,2,3,Req}, + {3,2,4,Req}, + {3,3,1,Req}, + {3,3,2,Req}, + {3,4,1,Req}, + {3,9,1,Req}, + {3,9,2,Adv}, + {3,9,3,Req}, + {4,5,1,Req}, + {4,5,2,Req}, + {4,5,3,Req}, + {4,10,1,Req}, + {4,10,2,Req}, + {5,0,1,Req}, + {5,0,2,Adv}, + {5,0,3,Req}, + {5,0,4,Req}, + {5,0,5,Req}, + {5,0,6,Req}, + {5,0,7,Req}, + {5,0,8,Req}, + {5,0,9,Req}, + {5,0,10,Req}, + {5,0,11,Req}, + {5,0,12,Req}, + {5,0,13,Req}, + {5,0,14,Req}, + {5,0,15,Req}, + {5,0,16,Req}, + {5,0,17,Req}, + {5,0,18,Req}, + {5,0,19,Req}, + {5,0,20,Req}, + {5,0,21,Req}, + {5,2,1,Req}, + {5,2,2,Req}, + {5,2,3,Adv}, + {5,2,4,Req}, + {5,2,5,Req}, + {5,2,6,Req}, + {5,2,7,Req}, + {5,2,8,Req}, + {5,2,9,Adv}, + {5,2,10,Adv}, + {5,2,11,Req}, + {5,2,12,Req}, + {5,3,1,Req}, + {5,3,2,Req}, + {5,3,3,Req}, + {5,3,4,Req}, + {5,8,1,Req}, + {5,14,1,Req}, + {5,17,1,Req}, + {5,18,1,Req}, + {5,19,1,Adv}, + {6,2,1,Req}, + {6,2,2,Req}, + {6,2,3,Req}, + {6,3,1,Req}, + {6,4,1,Req}, + {6,4,2,Req}, + {6,4,3,Req}, + {6,4,4,Req}, + {6,4,5,Req}, + {6,4,6,Req}, + {6,4,7,Req}, + {6,4,8,Req}, + {6,5,1,Req}, + {6,5,2,Req}, + {6,5,3,Req}, + {6,5,4,Req}, + {6,5,5,Req}, + {6,5,6,Req}, + {6,6,1,Req}, + {6,6,2,Req}, + {6,6,3,Req}, + {6,6,4,Req}, + {6,6,5,Req}, + {7,1,1,Req}, + {7,1,2,Req}, + {7,2,1,Req}, + {7,3,1,Req}, + {7,3,2,Req}, + {7,3,3,Req}, + {7,3,4,Req}, + {7,3,5,Req}, + {7,3,6,Req}, + {7,4,1,Doc}, + {7,4,2,Req}, + {7,4,3,Req}, + {7,5,1,Req}, + {7,5,2,Req}, + {7,5,3,Req}, + {7,5,4,Adv}, + {8,4,1,Req}, + {8,4,2,Req}, + {8,4,3,Req}, + {8,4,4,Req}, + {8,5,1,Req}, + {8,5,2,Req}, + {8,5,3,Req}, + {9,3,1,Req}, + {9,3,2,Req}, + {9,3,3,Req}, + {9,5,1,Req}, + {9,6,1,Doc}, + {9,6,2,Req}, + {9,6,3,Req}, + {9,6,4,Req}, + {10,1,1,Adv}, + {10,1,2,Req}, + {10,1,3,Req}, + {10,2,1,Adv}, + {10,3,1,Req}, + {10,3,2,Req}, + {10,3,3,Req}, + {11,0,1,Req}, + {12,1,1,Req}, + {12,1,2,Adv}, + {12,1,3,Req}, + {12,8,1,Req}, + {12,8,2,Req}, + {14,5,1,Req}, + {14,5,2,Req}, + {14,5,3,Req}, + {14,6,1,Req}, + {14,6,2,Req}, + {14,7,1,Req}, + {14,7,2,Req}, + {14,7,3,Req}, + {14,8,1,Req}, + {14,8,2,Req}, + {15,0,1,Req}, + {15,0,2,Req}, + {15,0,3,Req}, + {15,1,1,Req}, + {15,1,2,Req}, + {15,1,3,Req}, + {15,3,1,Req}, + {15,3,2,Adv}, + {15,3,3,Req}, + {15,3,4,Req}, + {15,3,5,Req}, + {15,3,6,Req}, + {15,3,7,Req}, + {15,4,1,Req}, + {15,5,1,Req}, + {15,5,2,Req}, + {15,5,3,Req}, + {16,0,1,Req}, + {16,0,2,Req}, + {16,0,3,Req}, + {16,0,4,Req}, + {16,0,5,Req}, + {16,0,6,Req}, + {16,0,7,Req}, + {16,0,8,Req}, + {16,1,1,Req}, + {16,1,2,Req}, + {16,2,1,Req}, + {16,2,2,Req}, + {16,2,3,Req}, + {16,2,4,Req}, + {16,2,5,Adv}, + {16,2,6,Req}, + {16,3,1,Req}, + {16,3,2,Adv}, + {16,6,1,Doc}, + {17,0,1,Req}, + {17,0,2,Req}, + {17,0,3,Req}, + {17,0,4,Doc}, + {17,0,5,Req}, + {18,0,1,Req}, + {18,0,2,Req}, + {18,0,3,Req}, + {18,0,4,Req}, + {18,0,5,Req}, + {18,2,1,Req}, + {18,4,1,Req}, + {18,7,1,Req}, + {19,3,1,Req}, + {27,0,1,Req} + }; + + const std::vector misraCpp2023Rules = + { + {0,0,1,Req}, + {0,0,2,Adv}, + {0,1,1,Adv}, + {0,1,2,Req}, + {0,2,1,Adv}, + {0,2,2,Req}, + {0,2,3,Adv}, + {0,2,4,Adv}, + {0,3,1,Adv}, + {0,3,2,Req}, + {4,1,1,Req}, + {4,1,2,Adv}, + {4,1,3,Req}, + {4,6,1,Req}, + {5,0,1,Adv}, + {5,7,1,Req}, + {5,7,2,Adv}, + {5,7,3,Req}, + {5,10,1,Req}, + {5,13,1,Req}, + {5,13,2,Req}, + {5,13,3,Req}, + {5,13,4,Req}, + {5,13,5,Req}, + {5,13,6,Req}, + {5,13,7,Req}, + {6,0,1,Req}, + {6,0,2,Adv}, + {6,0,3,Adv}, + {6,0,4,Req}, + {6,2,1,Req}, + {6,2,2,Req}, + {6,2,3,Req}, + {6,2,4,Req}, + {6,4,1,Req}, + {6,4,2,Req}, + {6,4,3,Req}, + {6,5,1,Adv}, + {6,5,2,Adv}, + {6,7,1,Req}, + {6,7,2,Req}, + {6,8,1,Req}, + {6,8,2,Man}, + {6,8,3,Req}, + {6,8,4,Adv}, + {6,9,1,Req}, + {6,9,2,Adv}, + {7,0,1,Req}, + {7,0,2,Req}, + {7,0,3,Req}, + {7,0,4,Req}, + {7,0,5,Req}, + {7,0,6,Req}, + {7,11,1,Req}, + {7,11,2,Req}, + {7,11,3,Req}, + {8,0,1,Adv}, + {8,1,1,Req}, + {8,1,2,Adv}, + {8,2,1,Req}, + {8,2,2,Req}, + {8,2,3,Req}, + {8,2,4,Req}, + {8,2,5,Req}, + {8,2,6,Req}, + {8,2,7,Adv}, + {8,2,8,Req}, + {8,2,9,Req}, + {8,2,10,Req}, + {8,2,11,Req}, + {8,3,1,Adv}, + {8,3,2,Adv}, + {8,7,1,Req}, + {8,7,2,Req}, + {8,9,1,Req}, + {8,14,1,Adv}, + {8,18,1,Man}, + {8,18,2,Adv}, + {8,19,1,Adv}, + {8,20,1,Adv}, + {9,2,1,Req}, + {9,3,1,Req}, + {9,4,1,Req}, + {9,4,2,Req}, + {9,5,2,Adv}, + {9,5,3,Req}, + {9,6,1,Adv}, + {9,6,2,Req}, + {9,6,3,Req}, + {9,6,4,Req}, + {9,6,5,Req}, + {10,0,1,Adv}, + {10,1,1,Adv}, + {10,1,2,Req}, + {10,2,1,Req}, + {10,2,2,Adv}, + {10,2,3,Req}, + {10,3,1,Adv}, + {10,4,1,Req}, + {11,3,1,Adv}, + {11,3,2,Adv}, + {11,6,1,Adv}, + {11,6,2,Man}, + {11,6,3,Req}, + {12,2,1,Adv}, + {12,2,2,Req}, + {12,2,3,Req}, + {12,3,1,Req}, + {13,1,1,Adv}, + {13,1,2,Req}, + {13,3,1,Req}, + {13,3,2,Req}, + {13,3,3,Req}, + {13,3,4,Req}, + {14,1,1,Adv}, + {15,0,1,Req}, + {15,0,2,Adv}, + {15,1,1,Req}, + {15,1,2,Adv}, + {15,1,3,Req}, + {15,1,4,Adv}, + {15,1,5,Req}, + {15,8,1,Req}, + {16,5,2,Req}, + {16,6,1,Adv}, + {17,8,1,Req}, + {18,1,1,Req}, + {18,1,2,Req}, + {18,3,1,Adv}, + {18,3,2,Req}, + {18,3,3,Req}, + {18,4,1,Req}, + {18,5,1,Adv}, + {18,5,2,Adv}, + {19,0,1,Req}, + {19,0,2,Req}, + {19,0,3,Adv}, + {19,0,4,Adv}, + {19,1,1,Req}, + {19,1,2,Req}, + {19,1,3,Req}, + {19,2,1,Req}, + {19,2,2,Req}, + {19,2,3,Req}, + {19,3,1,Adv}, + {19,3,2,Req}, + {19,3,3,Req}, + {19,3,4,Req}, + {19,3,5,Req}, + {19,6,1,Adv}, + {21,2,1,Req}, + {21,2,2,Req}, + {21,2,3,Req}, + {21,2,4,Req}, + {21,6,1,Adv}, + {21,6,2,Req}, + {21,6,3,Req}, + {21,6,4,Req}, + {21,6,5,Req}, + {21,10,1,Req}, + {21,10,2,Req}, + {21,10,3,Req}, + {22,3,1,Req}, + {22,4,1,Req}, + {23,11,1,Adv}, + {24,5,1,Req}, + {24,5,2,Req}, + {25,5,1,Req}, + {25,5,2,Man}, + {25,5,3,Man}, + {26,3,1,Adv}, + {28,3,1,Req}, + {28,6,1,Req}, + {28,6,2,Req}, + {28,6,3,Req}, + {28,6,4,Req}, + {30,0,1,Req}, + {30,0,2,Req} + }; } + +// sed 's|", ".*", "|", "|' misrac2012.h +std::vector checkers::idMappingMisraC{ + {"1.1", "syntaxError"}, + {"1.3", "error"}, + {"2.1", "alwaysFalse,duplicateBreak,unreachableCode"}, + {"2.2", "alwaysTrue,redundantCondition,redundantAssignment,redundantAssignInSwitch,unreadVariable"}, + {"2.6", "unusedLabel"}, + {"2.8", "unusedVariable"}, + {"5.3", "shadowVariable"}, + {"8.3", "funcArgNamesDifferent"}, + {"8.13", "constParameterPointer"}, + {"9.1", "uninitvar"}, + {"12.3", "sizeofwithsilentarraypointer"}, + {"13.2", "unknownEvaluationOrder"}, + {"13.6", "sizeofCalculation"}, + {"14.3", "alwaysTrue,alwaysFalse,compareValueOutOfTypeRangeError,knownConditionTrueFalse"}, + {"17.4", "missingReturn"}, + {"17.5", "argumentSize"}, + {"18.1", "pointerOutOfBounds"}, + {"18.2", "comparePointers"}, + {"18.3", "comparePointers"}, + {"18.6", "danglingLifetime,danglingTemporaryLifetime,returnDanglingLifetime"}, + {"19.1", "overlappingWriteUnion,overlappingWriteFunction"}, + {"20.6", "preprocessorErrorDirective"}, + {"21.13", "invalidFunctionArg"}, + {"21.17", "bufferAccessOutOfBounds"}, + {"21.18", "bufferAccessOutOfBounds"}, + {"22.1", "memleak,resourceLeak,memleakOnRealloc,leakReturnValNotUsed,leakNoVarFunctionCall"}, + {"22.2", "autovarInvalidDeallocation"}, + {"22.3", "incompatibleFileOpen"}, + {"22.4", "writeReadOnlyFile"}, + {"22.6", "useClosedFile"}, +}; + +std::vector checkers::idMappingMisraCpp2008{ + {"0-1-1", "unreachableCode,duplicateBreak"}, + {"0-1-2", "unsignedLessThanZero"}, + {"0-1-3", "unusedVariable,unusedStructMember"}, + {"0-1-6", "redundantAssignment,unreadVariable,variableScope"}, + {"0-1-9", "redundantAssignment,redundantInitialization"}, + {"0-1-10", "unusedFunction"}, + {"0-2-1", "overlappingWriteUnion,overlappingWriteFunction"}, + {"2-10-2", "shadowVariable"}, + {"3-2-2", "ctuOneDefinitionRuleViolation"}, + {"3-4-1", "variableScope"}, + {"5-0-1", "unknownEvaluationOrder"}, + {"5-0-16", "pointerOutOfBounds"}, + {"5-0-17", "comparePointers"}, + {"5-0-18", "comparePointers"}, + {"5-2-4", "cstyleCast"}, + {"5-3-4", "sizeofFunctionCall"}, + {"5-8-1", "shiftTooManyBits"}, + {"6-6-5", "missingReturn"}, + {"7-1-1", "constVariable,constParameter"}, + {"7-1-2", "constParameter"}, + {"7-5-1", "autoVariables,returnReference,returnTempReference"}, + {"7-5-2", "danglingLifetime"}, + {"8-4-2", "funcArgNamesDifferent"}, + {"8-4-3", "missingReturn"}, + {"8-5-1", "uninitvar,uninitdata,uninitStructMember,uninitMemberVar,uninitMemberVarPrivate,uninitDerivedMemberVar,uninitDerivedMemberVarPrivate"}, + {"9-3-3", "functionConst,functionStatic"}, + {"10-2-1", "duplInheritedMember"}, + {"12-1-1", "virtualCallInConstructor"}, + {"12-1-3", "noExplicitConstructor"}, + {"15-3-1", "exceptThrowInDestructor"}, + {"15-5-1", "exceptThrowInDestructor"}, + {"15-5-3", "exceptThrowInDestructor"}, + {"16-0-5", "preprocessorErrorDirective"}, +}; + +std::vector checkers::idMappingMisraCpp2023{ + {"0.0.1", "unreachableCode"}, + {"0.0.2", "compareBoolExpressionWithInt,compareValueOutOfTypeRangeError,identicalConditionAfterEarlyExit,identicalInnerCondition,knownConditionTrueFalse"}, + {"0.1.1", "redundantAssignInSwitch,redundantAssignment,redundantCopy,redundantInitialization,unreadVariable"}, + {"Dir 0.3.2", "invalidFunctionArg,invalidFunctionArgBool,invalidFunctionArgStr"}, + {"4.1.3", "error"}, + {"4.6.1", "unknownEvaluationOrder"}, + {"5.10.1", "syntaxError"}, + {"6.2.1", "ctuOneDefinitionRuleViolation"}, + {"6.4.1", "shadowVariable"}, + {"6.8.1", "danglingLifetime"}, + {"6.8.2", "autoVariables"}, + {"8.7.1", "pointerOutOfBounds,pointerOutOfBoundsCond"}, + {"8.7.2", "subtractPointers"}, + {"8.9.1", "comparePointers"}, + {"8.18.1", "overlappingWriteUnion"}, + {"9.6.5", "missingReturn"}, + {"10.1.1", "constParameter,constParameterReference"}, + {"11.6.2", "uninitvar"}, + {"15.1.1", "virtualCallInConstructor"}, + {"15.1.3", "noExplicitConstructor"}, + {"15.1.4", "uninitMemberVar"}, + {"Dir 15.8.1", "operatorEqToSelf"}, + {"28.6.3", "accessForwarded,accessMoved"}, + {"28.6.4", "ignoredReturnValue"}, +}; + +std::vector checkers::autosarInfo{ + {"m0-1-1", checkers::Req, "unreachableCode,duplicateBreak"}, + {"m0-1-2", checkers::Req, "unsignedLessThanZero"}, + {"m0-1-3", checkers::Req, "unusedVariable,unusedStructMember"}, + {"m0-1-4", checkers::Req, ""}, + {"a0-1-1", checkers::Req, "unreadVariable,unusedValue,redundantAssignment"}, + {"a0-1-2", checkers::Req, "misra-c2012-17.7"}, + {"m0-1-8", checkers::Req, ""}, + {"m0-1-9", checkers::Req, "redundantAssignment,redundantInitialization"}, + {"m0-1-10", checkers::Adv, "unusedFunction"}, + {"a0-1-3", checkers::Req, ""}, + {"a0-1-4", checkers::Req, ""}, + {"a0-1-5", checkers::Req, ""}, + {"a0-1-6", checkers::Adv, ""}, + {"m0-2-1", checkers::Req, "overlappingWriteUnion,overlappingWriteFunction"}, + {"a0-4-2", checkers::Req, ""}, + {"a0-4-3", checkers::Req, "?"}, + {"a0-4-4", checkers::Req, ""}, + {"a1-1-1", checkers::Req, "g++ .."}, + {"a1-4-3", checkers::Adv, "?"}, + {"a2-3-1", checkers::Req, "The code contains unhandled character(s) (character code=195). Neither unicode nor extended ascii is supported. [syntaxError]"}, + {"a2-5-1", checkers::Req, ""}, + {"a2-5-2", checkers::Req, ""}, + {"m2-7-1", checkers::Req, ""}, + {"a2-7-1", checkers::Req, ""}, + {"a2-7-3", checkers::Req, "doxygen,clang -Wdocumentation"}, + {"a2-8-2", checkers::Adv, ""}, + {"m2-10-1", checkers::Req, ""}, + {"a2-10-1", checkers::Req, "shadowVariable,shadowFunction,shadowArgument"}, + {"a2-10-6", checkers::Req, ""}, + {"a2-10-4", checkers::Req, ""}, + {"a2-10-5", checkers::Adv, ""}, + {"a2-11-1", checkers::Req, ""}, + {"a2-13-1", checkers::Req, ""}, + {"a2-13-6", checkers::Req, ""}, + {"a2-13-5", checkers::Adv, ""}, + {"m2-13-2", checkers::Req, ""}, + {"m2-13-3", checkers::Req, ""}, + {"m2-13-4", checkers::Req, ""}, + {"a2-13-2", checkers::Req, "compile error"}, + {"a2-13-3", checkers::Req, ""}, + {"a2-13-4", checkers::Req, "compiler error"}, + {"a3-1-1", checkers::Req, ""}, + {"a3-1-2", checkers::Req, ""}, + {"a3-1-3", checkers::Adv, ""}, + {"m3-1-2", checkers::Req, ""}, + {"a3-1-4", checkers::Req, ""}, + {"a3-1-6", checkers::Adv, ""}, + {"m3-2-1", checkers::Req, ""}, + {"m3-2-2", checkers::Req, "ctuOneDefinitionRuleViolation"}, + {"m3-2-3", checkers::Req, ""}, + {"m3-2-4", checkers::Req, ""}, + {"a3-3-1", checkers::Req, ""}, + {"a3-3-2", checkers::Req, ""}, + {"m3-3-2", checkers::Req, ""}, + {"m3-4-1", checkers::Req, "variableScope"}, + {"m3-9-1", checkers::Req, ""}, + {"a3-9-1", checkers::Req, ""}, + {"m3-9-3", checkers::Req, ""}, + {"m4-5-1", checkers::Req, ""}, + {"a4-5-1", checkers::Req, ""}, + {"m4-5-3", checkers::Req, ""}, + {"a4-7-1", checkers::Req, ""}, + {"m4-10-1", checkers::Req, ""}, + {"a4-10-1", checkers::Req, ""}, + {"m4-10-2", checkers::Req, ""}, + {"a5-0-1", checkers::Req, "-Wsequence-point"}, + {"m5-0-2", checkers::Adv, ""}, + {"m5-0-3", checkers::Req, ""}, + {"m5-0-4", checkers::Req, ""}, + {"m5-0-5", checkers::Req, ""}, + {"m5-0-6", checkers::Req, ""}, + {"m5-0-7", checkers::Req, ""}, + {"m5-0-8", checkers::Req, ""}, + {"m5-0-9", checkers::Req, ""}, + {"m5-0-10", checkers::Req, ""}, + {"m5-0-11", checkers::Req, ""}, + {"m5-0-12", checkers::Req, ""}, + {"a5-0-2", checkers::Req, ""}, + {"m5-0-14", checkers::Req, ""}, + {"m5-0-15", checkers::Req, ""}, + {"m5-0-16", checkers::Req, "pointerOutOfBounds"}, + {"m5-0-17", checkers::Req, "comparePointers"}, + {"a5-0-4", checkers::Req, ""}, + {"m5-0-18", checkers::Req, "comparePointers"}, + {"a5-0-3", checkers::Req, ""}, + {"m5-0-20", checkers::Req, ""}, + {"m5-0-21", checkers::Req, ""}, + {"a5-1-1", checkers::Req, ""}, + {"a5-1-2", checkers::Req, ""}, + {"a5-1-3", checkers::Req, ""}, + {"a5-1-4", checkers::Req, "returnDanglingLifetime"}, + {"a5-1-6", checkers::Adv, ""}, + {"a5-1-7", checkers::Req, ""}, + {"a5-1-8", checkers::Adv, ""}, + {"a5-1-9", checkers::Adv, ""}, + {"m5-2-2", checkers::Req, ""}, + {"m5-2-3", checkers::Adv, ""}, + {"a5-2-1", checkers::Adv, ""}, + {"a5-2-2", checkers::Req, "cstyleCast"}, + {"a5-2-3", checkers::Req, ""}, + {"m5-2-6", checkers::Req, ""}, + {"a5-2-4", checkers::Req, ""}, + {"a5-2-6", checkers::Req, ""}, + {"m5-2-8", checkers::Req, ""}, + {"m5-2-9", checkers::Req, ""}, + {"m5-2-10", checkers::Req, ""}, + {"m5-2-11", checkers::Req, ""}, + {"a5-2-5", checkers::Req, "arrayIndexOutOfBounds,arrayIndexOutOfBoundsCond,pointerOutOfBounds,pointerOutOfBoundsCond,negativeIndex,arrayIndexThenCheck,bufferAccessOutOfBounds,objectIndex,argumentSize"}, + {"m5-2-12", checkers::Req, ""}, + {"m5-3-1", checkers::Req, ""}, + {"m5-3-2", checkers::Req, ""}, + {"m5-3-3", checkers::Req, ""}, + {"m5-3-4", checkers::Req, "sizeofFunctionCall"}, + {"a5-3-1", checkers::Req, ""}, + {"a5-3-2", checkers::Req, "nullPointer,nullPointerRedundantCheck,nullPointerArithmetic,nullPointerArithmeticRedundantCheck,nullPointerDefaultArg"}, + {"a5-3-3", checkers::Req, ""}, + {"a5-5-1", checkers::Req, ""}, + {"a5-6-1", checkers::Req, "zerodiv,zerodivcond"}, + {"m5-8-1", checkers::Req, "shiftTooManyBits"}, + {"a5-10-1", checkers::Req, ""}, + {"m5-14-1", checkers::Req, ""}, + {"a5-16-1", checkers::Req, ""}, + {"m5-18-1", checkers::Req, ""}, + {"m5-19-1", checkers::Req, ""}, + {"m6-2-1", checkers::Req, ""}, + {"a6-2-1", checkers::Req, ""}, + {"a6-2-2", checkers::Req, ""}, + {"m6-2-2", checkers::Req, ""}, + {"m6-2-3", checkers::Req, ""}, + {"m6-3-1", checkers::Req, ""}, + {"m6-4-1", checkers::Req, ""}, + {"m6-4-2", checkers::Req, ""}, + {"m6-4-3", checkers::Req, ""}, + {"m6-4-4", checkers::Req, ""}, + {"m6-4-5", checkers::Req, ""}, + {"m6-4-6", checkers::Req, ""}, + {"m6-4-7", checkers::Req, ""}, + {"a6-4-1", checkers::Req, ""}, + {"a6-5-1", checkers::Req, ""}, + {"a6-5-2", checkers::Req, ""}, + {"m6-5-2", checkers::Req, ""}, + {"m6-5-3", checkers::Req, ""}, + {"m6-5-4", checkers::Req, ""}, + {"m6-5-5", checkers::Req, ""}, + {"m6-5-6", checkers::Req, ""}, + {"a6-5-3", checkers::Adv, ""}, + {"a6-5-4", checkers::Adv, ""}, + {"a6-6-1", checkers::Req, "misra-c2012-15.1"}, + {"m6-6-1", checkers::Req, ""}, + {"m6-6-2", checkers::Req, ""}, + {"m6-6-3", checkers::Req, ""}, + {"a7-1-1", checkers::Req, ""}, + {"a7-1-2", checkers::Req, ""}, + {"m7-1-2", checkers::Req, "constParameter"}, + {"a7-1-3", checkers::Req, ""}, + {"a7-1-4", checkers::Req, ""}, + {"a7-1-5", checkers::Req, ""}, + {"a7-1-6", checkers::Req, ""}, + {"a7-1-7", checkers::Req, ""}, + {"a7-1-8", checkers::Req, ""}, + {"a7-1-9", checkers::Req, ""}, + {"a7-2-1", checkers::Req, ""}, + {"a7-2-2", checkers::Req, ""}, + {"a7-2-3", checkers::Req, ""}, + {"a7-2-4", checkers::Req, ""}, + {"m7-3-1", checkers::Req, ""}, + {"m7-3-2", checkers::Req, ""}, + {"m7-3-3", checkers::Req, ""}, + {"m7-3-4", checkers::Req, ""}, + {"a7-3-1", checkers::Req, ""}, + {"m7-3-6", checkers::Req, ""}, + {"a7-4-1", checkers::Req, ""}, + {"m7-4-2", checkers::Req, ""}, + {"m7-4-3", checkers::Req, ""}, + {"a7-5-1", checkers::Req, "returnDanglingLifetime"}, + {"a7-5-2", checkers::Req, "premium-misra-c2012-17.2"}, + {"a7-6-1", checkers::Req, ""}, + {"m8-0-1", checkers::Req, ""}, + {"a8-2-1", checkers::Req, ""}, + {"m8-3-1", checkers::Req, ""}, + {"a8-4-1", checkers::Req, ""}, + {"m8-4-2", checkers::Req, "funcArgNamesDifferent"}, + {"a8-4-2", checkers::Req, "missingReturn"}, + {"m8-4-4", checkers::Req, ""}, + {"a8-4-4", checkers::Adv, ""}, + {"a8-4-5", checkers::Req, ""}, + {"a8-4-6", checkers::Req, ""}, + {"a8-4-7", checkers::Req, ""}, + {"a8-4-8", checkers::Req, ""}, + {"a8-4-9", checkers::Req, ""}, + {"a8-4-10", checkers::Req, ""}, + {"a8-4-11", checkers::Req, ""}, + {"a8-4-12", checkers::Req, ""}, + {"a8-4-13", checkers::Req, ""}, + {"a8-4-14", checkers::Req, ""}, + {"a8-5-0", checkers::Req, "uninitData"}, + {"a8-5-1", checkers::Req, ""}, + {"m8-5-2", checkers::Req, ""}, + {"a8-5-2", checkers::Req, ""}, + {"a8-5-3", checkers::Req, ""}, + {"a8-5-4", checkers::Adv, ""}, + {"m9-3-1", checkers::Req, ""}, + {"a9-3-1", checkers::Req, ""}, + {"m9-3-3", checkers::Req, "functionConst,functionStatic"}, + {"a9-5-1", checkers::Req, "misra-c2012-19.2"}, + {"a9-6-1", checkers::Req, ""}, + {"m9-6-4", checkers::Req, ""}, + {"a10-1-1", checkers::Req, ""}, + {"m10-1-1", checkers::Adv, ""}, + {"m10-1-2", checkers::Req, ""}, + {"m10-1-3", checkers::Req, ""}, + {"m10-2-1", checkers::Adv, "duplInheritedMember,"}, + {"a10-2-1", checkers::Req, ""}, + {"a10-3-1", checkers::Req, ""}, + {"a10-3-2", checkers::Req, ""}, + {"a10-3-3", checkers::Req, ""}, + {"a10-3-5", checkers::Req, ""}, + {"m10-3-3", checkers::Req, ""}, + {"a10-4-1", checkers::Req, ""}, + {"m11-0-1", checkers::Req, ""}, + {"a11-0-1", checkers::Adv, ""}, + {"a11-0-2", checkers::Req, ""}, + {"a11-3-1", checkers::Req, ""}, + {"a12-0-1", checkers::Req, ""}, + {"a12-0-2", checkers::Req, ""}, + {"a12-1-1", checkers::Req, "uninitMember"}, + {"m12-1-1", checkers::Req, "virtualCallInConstructor"}, + {"a12-1-2", checkers::Req, ""}, + {"a12-1-3", checkers::Req, ""}, + {"a12-1-4", checkers::Req, "noExplicitConstructor"}, + {"a12-1-5", checkers::Req, ""}, + {"a12-1-6", checkers::Req, ""}, + {"a12-4-1", checkers::Req, ""}, + {"a12-4-2", checkers::Adv, ""}, + {"a12-6-1", checkers::Req, "useInitializationList"}, + {"a12-7-1", checkers::Req, ""}, + {"a12-8-1", checkers::Req, ""}, + {"a12-8-2", checkers::Adv, ""}, + {"a12-8-3", checkers::Req, "accessMoved"}, + {"a12-8-4", checkers::Req, ""}, + {"a12-8-5", checkers::Req, ""}, + {"a12-8-6", checkers::Req, ""}, + {"a12-8-7", checkers::Adv, ""}, + {"a13-1-2", checkers::Req, ""}, + {"a13-1-3", checkers::Req, ""}, + {"a13-2-1", checkers::Req, ""}, + {"a13-2-2", checkers::Req, ""}, + {"a13-2-3", checkers::Req, ""}, + {"a13-3-1", checkers::Req, ""}, + {"a13-5-1", checkers::Req, ""}, + {"a13-5-2", checkers::Req, ""}, + {"a13-5-3", checkers::Adv, ""}, + {"a13-5-4", checkers::Req, ""}, + {"a13-5-5", checkers::Req, ""}, + {"a13-6-1", checkers::Req, ""}, + {"a14-1-1", checkers::Adv, ""}, + {"a14-5-1", checkers::Req, ""}, + {"a14-5-2", checkers::Req, ""}, + {"a14-5-3", checkers::Req, ""}, + {"m14-5-3", checkers::Req, ""}, + {"m14-6-1", checkers::Req, ""}, + {"a14-7-1", checkers::Req, ""}, + {"a14-7-2", checkers::Req, ""}, + {"a14-8-2", checkers::Req, ""}, + {"a15-0-2", checkers::Req, ""}, + {"a15-1-2", checkers::Req, ""}, + {"m15-0-3", checkers::Req, ""}, + {"m15-1-1", checkers::Req, ""}, + {"m15-1-2", checkers::Req, ""}, + {"m15-1-3", checkers::Req, ""}, + {"a15-1-3", checkers::Adv, ""}, + {"a15-1-4", checkers::Req, "memleak"}, + {"a15-2-1", checkers::Req, ""}, + {"a15-2-2", checkers::Req, ""}, + {"m15-3-1", checkers::Req, "exceptThrowInDestructor"}, + {"a15-3-2", checkers::Req, ""}, + {"a15-3-3", checkers::Req, ""}, + {"m15-3-3", checkers::Req, ""}, + {"m15-3-4", checkers::Req, ""}, + {"a15-3-5", checkers::Req, ""}, + {"m15-3-6", checkers::Req, ""}, + {"m15-3-7", checkers::Req, ""}, + {"a15-4-1", checkers::Req, ""}, + {"a15-4-2", checkers::Req, "throwInNoexceptFunction"}, + {"a15-4-3", checkers::Req, ""}, + {"a15-4-4", checkers::Req, ""}, + {"a15-4-5", checkers::Req, ""}, + {"a15-5-1", checkers::Req, ""}, + {"a15-5-2", checkers::Req, ""}, + {"a15-5-3", checkers::Req, ""}, + {"a16-0-1", checkers::Req, ""}, + {"m16-0-1", checkers::Req, ""}, + {"m16-0-2", checkers::Req, ""}, + {"m16-0-5", checkers::Req, "preprocessorErrorDirective"}, + {"m16-0-6", checkers::Req, ""}, + {"m16-0-7", checkers::Req, ""}, + {"m16-0-8", checkers::Req, ""}, + {"m16-1-1", checkers::Req, ""}, + {"m16-1-2", checkers::Req, ""}, + {"m16-2-3", checkers::Req, ""}, + {"a16-2-1", checkers::Req, "misra-c2012-20.2"}, + {"a16-2-2", checkers::Req, "iwyu,check headers"}, + {"a16-2-3", checkers::Req, ""}, + {"m16-3-1", checkers::Req, ""}, + {"m16-3-2", checkers::Adv, ""}, + {"a16-6-1", checkers::Req, ""}, + {"a16-7-1", checkers::Req, ""}, + {"a17-0-1", checkers::Req, ""}, + {"m17-0-2", checkers::Req, ""}, + {"m17-0-3", checkers::Req, ""}, + {"m17-0-5", checkers::Req, ""}, + {"a17-1-1", checkers::Req, ""}, + {"a17-6-1", checkers::Req, ""}, + {"a18-0-1", checkers::Req, ""}, + {"a18-0-2", checkers::Req, ""}, + {"m18-0-3", checkers::Req, ""}, + {"m18-0-4", checkers::Req, ""}, + {"m18-0-5", checkers::Req, ""}, + {"a18-0-3", checkers::Req, ""}, + {"a18-1-1", checkers::Req, ""}, + {"a18-1-2", checkers::Req, ""}, + {"a18-1-3", checkers::Req, ""}, + {"a18-1-4", checkers::Req, ""}, + {"a18-1-6", checkers::Req, ""}, + {"m18-2-1", checkers::Req, ""}, + {"a18-5-1", checkers::Req, ""}, + {"a18-5-2", checkers::Req, ""}, + {"a18-5-3", checkers::Req, "mismatchAllocDealloc"}, + {"a18-5-4", checkers::Req, ""}, + {"a18-5-5", checkers::Req, ""}, + {"a18-5-6", checkers::Req, ""}, + {"a18-5-7", checkers::Req, ""}, + {"a18-5-8", checkers::Req, ""}, + {"a18-5-9", checkers::Req, ""}, + {"a18-5-10", checkers::Req, ""}, + {"a18-5-11", checkers::Req, ""}, + {"m18-7-1", checkers::Req, ""}, + {"a18-9-1", checkers::Req, ""}, + {"a18-9-2", checkers::Req, ""}, + {"a18-9-3", checkers::Req, ""}, + {"a18-9-4", checkers::Req, ""}, + {"m19-3-1", checkers::Req, ""}, + {"a20-8-1", checkers::Req, "doubleFree"}, + {"a20-8-2", checkers::Req, ""}, + {"a20-8-3", checkers::Req, ""}, + {"a20-8-4", checkers::Req, ""}, + {"a20-8-5", checkers::Req, ""}, + {"a20-8-6", checkers::Req, ""}, + {"a20-8-7", checkers::Req, ""}, + {"a21-8-1", checkers::Req, ""}, + {"a23-0-1", checkers::Req, ""}, + {"a23-0-2", checkers::Req, "invalidContainer"}, + {"a25-1-1", checkers::Req, ""}, + {"a25-4-1", checkers::Req, ""}, + {"a26-5-1", checkers::Req, ""}, + {"a26-5-2", checkers::Req, ""}, + {"m27-0-1", checkers::Req, ""}, + {"a27-0-1", checkers::Req, ""}, + {"a27-0-4", checkers::Req, ""}, + {"a27-0-2", checkers::Adv, ""}, + {"a27-0-3", checkers::Req, ""}, +}; + +std::vector checkers::certCInfo{ + {"PRE30-C", "L3", "preprocessorErrorDirective"}, + {"PRE31-C", "L3", ""}, + {"PRE32-C", "L3", "preprocessorErrorDirective"}, + {"DCL30-C", "L2", "danglingLifetime,autoVariables,invalidLifetime"}, + {"DCL31-C", "L3", ""}, + {"DCL36-C", "L2", ""}, + {"DCL37-C", "L3", ""}, + {"DCL38-C", "L3", ""}, + {"DCL39-C", "L3", ""}, + {"DCL40-C", "L3", ""}, + {"DCL41-C", "L3", ""}, + {"EXP30-C", "L2", "unknownEvaluationOrder"}, + {"EXP32-C", "L2", ""}, + {"EXP33-C", "L1", "uninitvar,uninitdata,uninitStructMember"}, + {"EXP34-C", "L1", "nullPointer,nullPointerDefaultArg,nullPointerRedundantCheck,nullPointerArithmetic,nullPointerArithmeticRedundantCheck"}, + {"EXP35-C", "L3", ""}, + {"EXP36-C", "L3", ""}, + {"EXP37-C", "L3", ""}, + {"EXP39-C", "L3", ""}, + {"EXP40-C", "L3", ""}, + {"EXP42-C", "L2", ""}, + {"EXP43-C", "L3", ""}, + {"EXP44-C", "L3", "sizeofCalculation"}, + {"EXP45-C", "L2", ""}, + {"EXP46-C", "L2", "bitwiseOnBoolean"}, + {"INT30-C", "L2", ""}, + {"INT31-C", "L2", ""}, + {"INT32-C", "L2", ""}, + {"INT33-C", "L2", ""}, + {"INT34-C", "L3", ""}, + {"INT35-C", "L3", ""}, + {"INT36-C", "L3", ""}, + {"FLP30-C", "L2", ""}, + {"FLP32-C", "L2", "invalidFunctionArg"}, + {"FLP34-C", "L3", "floatConversionOverflow"}, + {"FLP36-C", "L3", ""}, + {"FLP37-C", "L3", ""}, + {"ARR30-C", "L2", ""}, + {"ARR32-C", "L2", ""}, + {"ARR36-C", "L2", "comparePointers"}, + {"ARR37-C", "L2", ""}, + {"ARR38-C", "L1", ""}, + {"ARR39-C", "L2", ""}, + {"STR30-C", "L2", "stringLiteralWrite"}, + {"STR31-C", "L1", ""}, + {"STR32-C", "L1", ""}, + {"STR34-C", "L2", ""}, + {"STR37-C", "L3", "invalidFunctionArg"}, + {"STR38-C", "L1", ""}, + {"MEM30-C", "L1", "doubleFree,deallocret,deallocuse"}, + {"MEM31-C", "L2", "memleak,leakReturnValNotUsed,leakUnsafeArgAlloc,memleakOnRealloc"}, + {"MEM33-C", "L3", ""}, + {"MEM34-C", "L1", "autovarInvalidDeallocation,mismatchAllocDealloc"}, + {"MEM35-C", "L2", ""}, + {"MEM36-C", "L3", ""}, + {"FIO30-C", "L1", ""}, + {"FIO32-C", "L3", ""}, + {"FIO34-C", "L1", ""}, + {"FIO37-C", "L1", ""}, + {"FIO38-C", "L3", ""}, + {"FIO39-C", "L2", "IOWithoutPositioning"}, + {"FIO40-C", "L3", ""}, + {"FIO41-C", "L3", ""}, + {"FIO42-C", "L3", "resourceLeak"}, + {"FIO44-C", "L3", ""}, + {"FIO45-C", "L2", ""}, + {"FIO46-C", "L3", "useClosedFile"}, + {"FIO47-C", "L2", "invalidscanf,wrongPrintfScanfArgNum,invalidLengthModifierError,invalidScanfFormatWidth,wrongPrintfScanfParameterPositionError"}, + {"ENV30-C", "L3", ""}, + {"ENV31-C", "L3", ""}, + {"ENV32-C", "L1", ""}, + {"ENV33-C", "L1", ""}, + {"ENV34-C", "L3", ""}, + {"SIG30-C", "L1", ""}, + {"SIG31-C", "L2", ""}, + {"SIG34-C", "L3", ""}, + {"SIG35-C", "L3", ""}, + {"ERR30-C", "L2", ""}, + {"ERR32-C", "L3", ""}, + {"ERR33-C", "L1", ""}, + {"CON30-C", "L3", ""}, + {"CON31-C", "L3", ""}, + {"CON32-C", "L2", ""}, + {"CON33-C", "L3", ""}, + {"CON34-C", "L3", ""}, + {"CON35-C", "L3", ""}, + {"CON36-C", "L3", ""}, + {"CON37-C", "L2", ""}, + {"CON38-C", "L3", ""}, + {"CON39-C", "L2", ""}, + {"CON40-C", "L2", ""}, + {"CON41-C", "L3", ""}, + {"MSC30-C", "L2", ""}, + {"MSC32-C", "L1", ""}, + {"MSC33-C", "L1", ""}, + {"MSC37-C", "L2", "missingReturn"}, + {"MSC38-C", "L3", ""}, + {"MSC39-C", "L3", ""}, + {"MSC40-C", "L3", ""}, +}; + +std::vector checkers::certCppInfo{ + {"DCL50-CPP", "L1", ""}, + {"DCL51-CPP", "L3", ""}, + {"DCL52-CPP", "L3", ""}, + {"DCL53-CPP", "L3", ""}, + {"DCL54-CPP", "L2", ""}, + {"DCL55-CPP", "L3", "premium-cert-dcl39-c"}, + {"DCL56-CPP", "L3", ""}, + {"DCL57-CPP", "L3", "deallocThrow,exceptThrowInDestructor"}, + {"DCL58-CPP", "L3", ""}, + {"DCL59-CPP", "L3", ""}, + {"DCL60-CPP", "L3", "ctuOneDefinitionRuleViolation"}, + {"EXP50-CPP", "L2", ""}, + {"EXP51-CPP", "L3", ""}, + {"EXP52-CPP", "L3", "sizeofCalculation"}, + {"EXP53-CPP", "L1", "uninitvar"}, + {"EXP54-CPP", "L2", "uninitvar,danglingLifetime,danglingReference,danglingTemporaryLifetime,danglingTempReference,returnDanglingLifetime"}, + {"EXP55-CPP", "L2", ""}, + {"EXP56-CPP", "L3", ""}, + {"EXP57-CPP", "L3", ""}, + {"EXP58-CPP", "L3", ""}, + {"EXP59-CPP", "L3", ""}, + {"EXP60-CPP", "L1", ""}, + {"EXP61-CPP", "L2", "danglingLifetime,danglingReference,danglingTemporaryLifetime,danglingTempReference,returnDanglingLifetime"}, + {"EXP62-CPP", "L2", "premium-cert-exp42-c"}, + {"EXP63-CPP", "L2", "accessMoved"}, + {"INT50-CPP", "L3", ""}, + {"CTR50-CPP", "L2", ""}, + {"CTR51-CPP", "L2", "eraseDereference"}, + {"CTR52-CPP", "L1", ""}, + {"CTR53-CPP", "L2", ""}, + {"CTR54-CPP", "L2", "comparePointers"}, + {"CTR55-CPP", "L1", "containerOutOfBounds"}, + {"CTR56-CPP", "L2", ""}, + {"CTR57-CPP", "L3", ""}, + {"CTR58-CPP", "L3", ""}, + {"STR50-CPP", "L1", ""}, + {"STR51-CPP", "L1", "nullPointer"}, + {"STR52-CPP", "L2", "invalidContainer"}, + {"STR53-CPP", "L2", ""}, + {"MEM50-CPP", "L1", "deallocuse"}, + {"MEM51-CPP", "L1", "mismatchAllocDealloc"}, + {"MEM52-CPP", "L1", ""}, + {"MEM53-CPP", "L1", ""}, + {"MEM54-CPP", "L1", ""}, + {"MEM55-CPP", "L1", ""}, + {"MEM56-CPP", "L1", "doubleFree"}, + {"MEM57-CPP", "L2", ""}, + {"FIO50-CPP", "L2", "IOWithoutPositioning"}, + {"FIO51-CPP", "L3", ""}, + {"ERR50-CPP", "L3", ""}, + {"ERR51-CPP", "L3", ""}, + {"ERR52-CPP", "L3", ""}, + {"ERR53-CPP", "L3", ""}, + {"ERR54-CPP", "L1", ""}, + {"ERR55-CPP", "L2", ""}, + {"ERR56-CPP", "L2", ""}, + {"ERR57-CPP", "L3", "memleak"}, + {"ERR58-CPP", "L2", ""}, + {"ERR59-CPP", "L1", ""}, + {"ERR60-CPP", "L3", ""}, + {"ERR61-CPP", "L3", ""}, + {"ERR62-CPP", "L3", ""}, + {"OOP50-CPP", "L3", "virtualCallInConstructor"}, + {"OOP51-CPP", "L3", ""}, + {"OOP52-CPP", "L2", "virtualDestructor"}, + {"OOP53-CPP", "L3", "initializerList"}, + {"OOP54-CPP", "L3", "operatorEqToSelf"}, + {"OOP55-CPP", "L2", ""}, + {"OOP56-CPP", "L3", ""}, + {"OOP57-CPP", "L2", ""}, + {"OOP58-CPP", "L2", ""}, + {"CON50-CPP", "L3", ""}, + {"CON51-CPP", "L2", ""}, + {"CON52-CPP", "L2", ""}, + {"CON53-CPP", "L3", ""}, + {"CON54-CPP", "L3", ""}, + {"CON55-CPP", "L3", ""}, + {"CON56-CPP", "L3", ""}, + {"MSC50-CPP", "L2", ""}, + {"MSC51-CPP", "L1", ""}, + {"MSC52-CPP", "L3", "missingReturn"}, + {"MSC53-CPP", "L2", ""}, + {"MSC54-CPP", "L2", ""}, +}; diff --git a/lib/checkers.h b/lib/checkers.h index 4297665b01d..be885d9e791 100644 --- a/lib/checkers.h +++ b/lib/checkers.h @@ -36,13 +36,40 @@ namespace checkers { int amendment; }; + struct CPPCHECKLIB MisraCppInfo { + int a; + int b; + int c; + const char* classification; + }; + extern CPPCHECKLIB const char Req[]; // = "Required"; extern CPPCHECKLIB const char Adv[]; // = "Advisory"; extern CPPCHECKLIB const char Man[]; // = "Mandatory"; + extern CPPCHECKLIB const char Doc[]; // = "Document"; extern CPPCHECKLIB const std::vector misraC2012Rules; + extern CPPCHECKLIB const std::vector misraCpp2008Rules; + extern CPPCHECKLIB const std::vector misraCpp2023Rules; extern CPPCHECKLIB const std::map misraRuleSeverity; + + struct CPPCHECKLIB IdMapping { + const char* guideline; + const char* cppcheckId; + }; + extern std::vector idMappingMisraC; + extern std::vector idMappingMisraCpp2008; + extern std::vector idMappingMisraCpp2023; + + struct CPPCHECKLIB Info { + const char* guideline; + const char* classification; + const char* cppcheckIds; + }; + extern std::vector autosarInfo; + extern std::vector certCInfo; + extern std::vector certCppInfo; } #endif