Skip to content

Commit d071066

Browse files
authored
fix #13730: Report type: cppcheck severity is shown for misra directive even though --report-type=misra-c-2023 is used (#7595)
1 parent fef5812 commit d071066

File tree

11 files changed

+106
-31
lines changed

11 files changed

+106
-31
lines changed

cli/cmdlineparser.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,8 +1309,12 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
13091309
mSettings.reportType = ReportType::certC;
13101310
} else if (typeStr == "cert-cpp-2016") {
13111311
mSettings.reportType = ReportType::certCpp;
1312-
} else if (typeStr == "misra-c-2012" || typeStr == "misra-c-2023") {
1313-
mSettings.reportType = ReportType::misraC;
1312+
} else if (typeStr == "misra-c-2012") {
1313+
mSettings.reportType = ReportType::misraC2012;
1314+
} else if (typeStr == "misra-c-2023") {
1315+
mSettings.reportType = ReportType::misraC2023;
1316+
} else if (typeStr == "misra-c-2025") {
1317+
mSettings.reportType = ReportType::misraC2025;
13141318
} else if (typeStr == "misra-cpp-2008") {
13151319
mSettings.reportType = ReportType::misraCpp2008;
13161320
} else if (typeStr == "misra-cpp-2023") {
@@ -1963,6 +1967,7 @@ void CmdLineParser::printHelp() const
19631967
" * cert-cpp-2016 Cert C++ 2016\n"
19641968
" * misra-c-2012 Misra C 2012\n"
19651969
" * misra-c-2023 Misra C 2023\n"
1970+
" * misra-c-2025 Misra C 2025\n"
19661971
" * misra-cpp-2008 Misra C++ 2008\n"
19671972
" * misra-cpp-2023 Misra C++ 2023\n"
19681973
" --rule=<rule> Match regular expression.\n"

gui/mainwindow.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,9 @@ void MainWindow::loadSettings()
391391
mUI->mActionReportAutosar->setChecked(reportType == ReportType::autosar);
392392
mUI->mActionReportCertC->setChecked(reportType == ReportType::certC);
393393
mUI->mActionReportCertCpp->setChecked(reportType == ReportType::certCpp);
394-
mUI->mActionReportMisraC->setChecked(reportType == ReportType::misraC);
394+
mUI->mActionReportMisraC->setChecked(reportType == ReportType::misraC2012 ||
395+
reportType == ReportType::misraC2023 ||
396+
reportType == ReportType::misraC2025);
395397
mUI->mActionReportMisraCpp2008->setChecked(reportType == ReportType::misraCpp2008);
396398
mUI->mActionReportMisraCpp2023->setChecked(reportType == ReportType::misraCpp2023);
397399

@@ -470,6 +472,15 @@ void MainWindow::loadSettings()
470472
}
471473
}
472474

475+
static ReportType getMisraCReportType(const QStringList &standards)
476+
{
477+
if (standards.contains(CODING_STANDARD_MISRA_C_2023))
478+
return ReportType::misraC2023;
479+
if (standards.contains(CODING_STANDARD_MISRA_C_2025))
480+
return ReportType::misraC2025;
481+
return ReportType::misraC2012;
482+
}
483+
473484
void MainWindow::saveSettings() const
474485
{
475486
// Window/dialog sizes
@@ -480,7 +491,7 @@ void MainWindow::saveSettings() const
480491
const ReportType reportType = mUI->mActionReportAutosar->isChecked() ? ReportType::autosar :
481492
mUI->mActionReportCertC->isChecked() ? ReportType::certC :
482493
mUI->mActionReportCertCpp->isChecked() ? ReportType::certCpp :
483-
mUI->mActionReportMisraC->isChecked() ? ReportType::misraC :
494+
mUI->mActionReportMisraC->isChecked() ? (mProjectFile ? getMisraCReportType(mProjectFile->getCodingStandards()) : ReportType::misraC2012) :
484495
mUI->mActionReportMisraCpp2008->isChecked() ? ReportType::misraCpp2008 :
485496
mUI->mActionReportMisraCpp2023->isChecked() ? ReportType::misraCpp2023 :
486497
ReportType::normal;
@@ -2283,7 +2294,7 @@ void MainWindow::changeReportType() {
22832294
const ReportType reportType = mUI->mActionReportAutosar->isChecked() ? ReportType::autosar :
22842295
mUI->mActionReportCertC->isChecked() ? ReportType::certC :
22852296
mUI->mActionReportCertCpp->isChecked() ? ReportType::certCpp :
2286-
mUI->mActionReportMisraC->isChecked() ? ReportType::misraC :
2297+
mUI->mActionReportMisraC->isChecked() ? (mProjectFile ? getMisraCReportType(mProjectFile->getCodingStandards()) : ReportType::misraC2012) :
22872298
mUI->mActionReportMisraCpp2008->isChecked() ? ReportType::misraCpp2008 :
22882299
mUI->mActionReportMisraCpp2023->isChecked() ? ReportType::misraCpp2023 :
22892300
ReportType::normal;

gui/projectfiledialog.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@
5959
#include <QSpinBox>
6060
#include <QVariant>
6161

62-
static constexpr char ADDON_MISRA[] = "misra";
63-
static constexpr char CODING_STANDARD_MISRA_C_2023[] = "misra-c-2023";
64-
static constexpr char CODING_STANDARD_MISRA_C_2025[] = "misra-c-2025";
65-
static constexpr char CODING_STANDARD_MISRA_CPP_2008[] = "misra-cpp-2008";
66-
static constexpr char CODING_STANDARD_MISRA_CPP_2023[] = "misra-cpp-2023";
67-
static constexpr char CODING_STANDARD_CERT_C[] = "cert-c-2016";
68-
static constexpr char CODING_STANDARD_CERT_CPP[] = "cert-cpp-2016";
69-
static constexpr char CODING_STANDARD_AUTOSAR[] = "autosar";
62+
const char ADDON_MISRA[] = "misra";
63+
const char CODING_STANDARD_MISRA_C_2023[] = "misra-c-2023";
64+
const char CODING_STANDARD_MISRA_C_2025[] = "misra-c-2025";
65+
const char CODING_STANDARD_MISRA_CPP_2008[] = "misra-cpp-2008";
66+
const char CODING_STANDARD_MISRA_CPP_2023[] = "misra-cpp-2023";
67+
const char CODING_STANDARD_CERT_C[] = "cert-c-2016";
68+
const char CODING_STANDARD_CERT_CPP[] = "cert-cpp-2016";
69+
const char CODING_STANDARD_AUTOSAR[] = "autosar";
7070

7171
/** Return paths from QListWidget */
7272
static QStringList getPaths(const QListWidget *list)

gui/projectfiledialog.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ namespace Ui {
3333
class ProjectFile;
3434
}
3535

36+
extern const char ADDON_MISRA[];
37+
extern const char CODING_STANDARD_MISRA_C_2023[];
38+
extern const char CODING_STANDARD_MISRA_C_2025[];
39+
extern const char CODING_STANDARD_MISRA_CPP_2008[];
40+
extern const char CODING_STANDARD_MISRA_CPP_2023[];
41+
extern const char CODING_STANDARD_CERT_C[];
42+
extern const char CODING_STANDARD_CERT_CPP[];
43+
extern const char CODING_STANDARD_AUTOSAR[];
44+
3645
/// @addtogroup GUI
3746
/// @{
3847

gui/resultstree.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1536,7 +1536,9 @@ bool ResultsTree::isCertReport() const {
15361536

15371537
bool ResultsTree::isAutosarMisraReport() const {
15381538
return mReportType == ReportType::autosar ||
1539-
mReportType == ReportType::misraC ||
1539+
mReportType == ReportType::misraC2012 ||
1540+
mReportType == ReportType::misraC2023 ||
1541+
mReportType == ReportType::misraC2025 ||
15401542
mReportType == ReportType::misraCpp2008 ||
15411543
mReportType == ReportType::misraCpp2023;
15421544
}

gui/test/resultstree/testresultstree.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void TestResultsTree::testReportType() const
157157
QCOMPARE(report.output, "id1,,\nunusedVariable,,");
158158

159159
// switch to Misra C report and check that "id1" is not shown
160-
tree.setReportType(ReportType::misraC);
160+
tree.setReportType(ReportType::misraC2012);
161161
tree.saveResults(&report);
162162
QCOMPARE(report.output, "unusedVariable,Advisory,2.8");
163163

@@ -187,7 +187,7 @@ void TestResultsTree::testGetGuidelineError() const
187187

188188
// normal report with 2 errors
189189
ResultsTree tree(nullptr);
190-
tree.setReportType(ReportType::misraC);
190+
tree.setReportType(ReportType::misraC2012);
191191
tree.addErrorItem(createErrorItem(Severity::error, "id1")); // error severity => guideline 1.3
192192
tree.saveResults(&report);
193193
QCOMPARE(report.output, "id1,Required,1.3");

lib/checkers.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ enum class ReportType : std::uint8_t {
3131
autosar = 1,
3232
certC = 2,
3333
certCpp = 3,
34-
misraC = 4,
34+
misraC2012 = 4,
3535
misraCpp2008 = 5,
3636
misraCpp2023 = 6,
37+
misraC2023 = 7,
38+
misraC2025 = 8,
3739
};
3840

3941
namespace checkers {

lib/errorlogger.cpp

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -945,24 +945,40 @@ std::string getClassification(const std::string &guideline, ReportType reportTyp
945945
return getClassification(checkers::certCInfo, guideline);
946946
case ReportType::certCpp:
947947
return getClassification(checkers::certCppInfo, guideline);
948-
case ReportType::misraC:
948+
case ReportType::misraC2012:
949+
case ReportType::misraC2023:
950+
case ReportType::misraC2025:
949951
{
950-
auto components = splitString(guideline, '.');
952+
const bool isDirective = guideline.rfind("Dir ", 0) == 0;
953+
954+
const std::size_t offset = isDirective ? 4 : 0;
955+
auto components = splitString(guideline.substr(offset), '.');
951956
if (components.size() != 2)
952957
return "";
953958

954959
const int a = std::stoi(components[0]);
955960
const int b = std::stoi(components[1]);
956961

957-
const std::vector<checkers::MisraInfo> &info = checkers::misraC2012Rules;
958-
const auto it = std::find_if(info.cbegin(), info.cend(), [&](const checkers::MisraInfo &i) {
962+
const std::vector<checkers::MisraInfo> *info = nullptr;
963+
switch (reportType) {
964+
case ReportType::misraC2012:
965+
info = isDirective ? &checkers::misraC2012Directives : &checkers::misraC2012Rules;
966+
break;
967+
case ReportType::misraC2023:
968+
info = isDirective ? &checkers::misraC2023Directives : &checkers::misraC2023Rules;
969+
break;
970+
case ReportType::misraC2025:
971+
info = isDirective ? &checkers::misraC2025Directives : &checkers::misraC2025Rules;
972+
break;
973+
default:
974+
cppcheck::unreachable();
975+
}
976+
977+
const auto it = std::find_if(info->cbegin(), info->cend(), [&](const checkers::MisraInfo &i) {
959978
return i.a == a && i.b == b;
960979
});
961980

962-
if (it == info.cend())
963-
return "";
964-
965-
return it->str;
981+
return it == info->cend() ? "" : it->str;
966982
}
967983
case ReportType::misraCpp2008:
968984
case ReportType::misraCpp2023:
@@ -1022,7 +1038,9 @@ std::string getGuideline(const std::string &errId, ReportType reportType,
10221038
guideline.begin(), static_cast<int (*)(int)>(std::toupper));
10231039
}
10241040
break;
1025-
case ReportType::misraC:
1041+
case ReportType::misraC2012:
1042+
case ReportType::misraC2023:
1043+
case ReportType::misraC2025:
10261044
if (errId.rfind("misra-c20", 0) == 0 || errId.rfind("premium-misra-c-20", 0) == 0)
10271045
guideline = errId.substr(errId.rfind('-') + 1);
10281046
break;
@@ -1038,8 +1056,11 @@ std::string getGuideline(const std::string &errId, ReportType reportType,
10381056
break;
10391057
}
10401058

1041-
if (!guideline.empty())
1059+
if (!guideline.empty()) {
1060+
if (errId.find("-dir-") != std::string::npos)
1061+
guideline = "Dir " + guideline;
10421062
return guideline;
1063+
}
10431064

10441065
auto it = guidelineMapping.find(errId);
10451066

@@ -1074,7 +1095,9 @@ std::map<std::string, std::string> createGuidelineMapping(ReportType reportType)
10741095
idMapping1 = &checkers::idMappingCertC;
10751096
ext1 = "-C";
10761097
break;
1077-
case ReportType::misraC:
1098+
case ReportType::misraC2012:
1099+
case ReportType::misraC2023:
1100+
case ReportType::misraC2025:
10781101
idMapping1 = &checkers::idMappingMisraC;
10791102
break;
10801103
case ReportType::misraCpp2008:

man/cppcheck.1.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ There are false positives with this option. Each result must be carefully invest
594594
<glossentry><glossterm>cert-cpp-2016</glossterm><glossdef><para>Cert C++ 2016</para></glossdef></glossentry>
595595
<glossentry><glossterm>misra-c-2012</glossterm><glossdef><para>Misra C 2012</para></glossdef></glossentry>
596596
<glossentry><glossterm>misra-c-2023</glossterm><glossdef><para>Misra C 2023</para></glossdef></glossentry>
597+
<glossentry><glossterm>misra-c-2025</glossterm><glossdef><para>Misra C 2025</para></glossdef></glossentry>
597598
<glossentry><glossterm>misra-cpp-2008</glossterm><glossdef><para>Misra C++ 2008</para></glossdef></glossentry>
598599
<glossentry><glossterm>misra-cpp-2023</glossterm><glossdef><para>Misra C++ 2023</para></glossdef></glossentry>
599600
</glosslist>

test/testcmdlineparser.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ class TestCmdlineParser : public TestFixture {
502502
TEST_CASE(reportTypeCertC);
503503
TEST_CASE(reportTypeMisraC2012);
504504
TEST_CASE(reportTypeMisraC2023);
505+
TEST_CASE(reportTypeMisraC2025);
505506
TEST_CASE(reportTypeMisraCpp2008);
506507
TEST_CASE(reportTypeMisraCpp2023);
507508
TEST_CASE(invalidReportType);
@@ -3456,14 +3457,21 @@ class TestCmdlineParser : public TestFixture {
34563457
REDIRECT;
34573458
const char *const argv[] = { "cppcheck", "--report-type=misra-c-2012", "file.cpp" };
34583459
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
3459-
ASSERT_EQUALS_ENUM(ReportType::misraC, settings->reportType);
3460+
ASSERT_EQUALS_ENUM(ReportType::misraC2012, settings->reportType);
34603461
}
34613462

34623463
void reportTypeMisraC2023() {
34633464
REDIRECT;
34643465
const char *const argv[] = { "cppcheck", "--report-type=misra-c-2023", "file.cpp" };
34653466
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
3466-
ASSERT_EQUALS_ENUM(ReportType::misraC, settings->reportType);
3467+
ASSERT_EQUALS_ENUM(ReportType::misraC2023, settings->reportType);
3468+
}
3469+
3470+
void reportTypeMisraC2025() {
3471+
REDIRECT;
3472+
const char *const argv[] = { "cppcheck", "--report-type=misra-c-2025", "file.cpp" };
3473+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
3474+
ASSERT_EQUALS_ENUM(ReportType::misraC2025, settings->reportType);
34673475
}
34683476

34693477
void reportTypeMisraCpp2008() {

test/testerrorlogger.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class TestErrorLogger : public TestFixture {
7878
TEST_CASE(isCriticalErrorId);
7979

8080
TEST_CASE(ErrorMessageReportTypeMisraC);
81+
TEST_CASE(ErrorMessageReportTypeMisraCDirective);
8182
TEST_CASE(ErrorMessageReportTypeCertC);
8283
}
8384

@@ -317,7 +318,7 @@ class TestErrorLogger : public TestFixture {
317318

318319
void ErrorMessageReportTypeMisraC() const {
319320
std::list<ErrorMessage::FileLocation> locs = { fooCpp5 };
320-
const auto reportType = ReportType::misraC;
321+
const auto reportType = ReportType::misraC2012;
321322
const auto mapping = createGuidelineMapping(reportType);
322323
const std::string format = "{severity} {id}";
323324
ErrorMessage msg(std::move(locs), emptyString, Severity::error, "", "unusedVariable", Certainty::normal);
@@ -328,6 +329,19 @@ class TestErrorLogger : public TestFixture {
328329
ASSERT_EQUALS("Advisory 2.8", msg.toString(true, format, ""));
329330
}
330331

332+
void ErrorMessageReportTypeMisraCDirective() const {
333+
std::list<ErrorMessage::FileLocation> locs = { fooCpp5 };
334+
const auto reportType = ReportType::misraC2012;
335+
const auto mapping = createGuidelineMapping(reportType);
336+
const std::string format = "{severity} {id}";
337+
ErrorMessage msg(std::move(locs), emptyString, Severity::style, "", "premium-misra-c-2012-dir-4.6", Certainty::normal);
338+
msg.guideline = getGuideline(msg.id, reportType, mapping, msg.severity);
339+
msg.classification = getClassification(msg.guideline, reportType);
340+
ASSERT_EQUALS("Advisory", msg.classification);
341+
ASSERT_EQUALS("Dir 4.6", msg.guideline);
342+
ASSERT_EQUALS("Advisory Dir 4.6", msg.toString(true, format, ""));
343+
}
344+
331345
void ErrorMessageReportTypeCertC() const {
332346
std::list<ErrorMessage::FileLocation> locs = { fooCpp5 };
333347
const auto reportType = ReportType::certC;

0 commit comments

Comments
 (0)