Skip to content

Commit 591d47f

Browse files
authored
Fix #13923 (Misra: Add --premium option misra-c-2025, do not fetch misra rule texts from premiumaddon) (danmar#7585)
1 parent e25ca46 commit 591d47f

26 files changed

+1366
-1286
lines changed

cli/cmdlineparser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
11451145
"metrics",
11461146
"misra-c-2012",
11471147
"misra-c-2023",
1148+
"misra-c-2025",
11481149
"misra-c++-2008",
11491150
"misra-cpp-2008",
11501151
"misra-c++-2023",

cli/cppcheckexecutor.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,6 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
396396
mFiles = parser.getFiles();
397397
mFileSettings = parser.getFileSettings();
398398

399-
settings.setMisraRuleTexts(executeCommand);
400-
401399
const int ret = check_wrapper(settings, supprs);
402400

403401
return ret;

gui/cppcheck_de.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_es.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_fi.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_fr.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_it.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_ja.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_ka.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_ko.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_nl.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_ru.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_sr.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_sv.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_zh_CN.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/cppcheck_zh_TW.ts

Lines changed: 90 additions & 85 deletions
Large diffs are not rendered by default.

gui/mainwindow.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,6 @@ bool MainWindow::getCppcheckSettings(Settings& settings, Suppressions& supprs)
11751175
if (!premiumArgs.contains("--misra-c-") && mProjectFile->getAddons().contains("misra"))
11761176
premiumArgs += " --misra-c-2012";
11771177
settings.premiumArgs = premiumArgs.mid(1).toStdString();
1178-
settings.setMisraRuleTexts(CheckThread::executeCommand);
11791178
}
11801179
}
11811180
else

gui/projectfile.ui

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,11 @@
846846
<string>2023</string>
847847
</property>
848848
</item>
849+
<item>
850+
<property name="text">
851+
<string>2025</string>
852+
</property>
853+
</item>
849854
</widget>
850855
</item>
851856
<item>

gui/projectfiledialog.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161

6262
static constexpr char ADDON_MISRA[] = "misra";
6363
static constexpr char CODING_STANDARD_MISRA_C_2023[] = "misra-c-2023";
64+
static constexpr char CODING_STANDARD_MISRA_C_2025[] = "misra-c-2025";
6465
static constexpr char CODING_STANDARD_MISRA_CPP_2008[] = "misra-cpp-2008";
6566
static constexpr char CODING_STANDARD_MISRA_CPP_2023[] = "misra-cpp-2023";
6667
static constexpr char CODING_STANDARD_CERT_C[] = "cert-c-2016";
@@ -396,7 +397,14 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
396397
const QString &misraFile = settings.value(SETTINGS_MISRA_FILE, QString()).toString();
397398
mUI->mEditMisraFile->setText(misraFile);
398399
mUI->mMisraVersion->setVisible(mPremium);
399-
mUI->mMisraVersion->setCurrentIndex(projectFile->getCodingStandards().contains(CODING_STANDARD_MISRA_C_2023));
400+
if (projectFile->getCodingStandards().contains(CODING_STANDARD_MISRA_C_2023))
401+
mUI->mMisraVersion->setCurrentIndex(1);
402+
else if (projectFile->getCodingStandards().contains(CODING_STANDARD_MISRA_C_2025))
403+
mUI->mMisraVersion->setCurrentIndex(2);
404+
else if (projectFile->getAddons().contains(ADDON_MISRA))
405+
mUI->mMisraVersion->setCurrentIndex(0);
406+
else
407+
mUI->mMisraVersion->setCurrentIndex(-1);
400408
if (mPremium) {
401409
mUI->mLabelMisraFile->setVisible(false);
402410
mUI->mEditMisraFile->setVisible(false);
@@ -519,6 +527,8 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const
519527
codingStandards << CODING_STANDARD_CERT_CPP;
520528
if (mPremium && mUI->mMisraVersion->currentIndex() == 1)
521529
codingStandards << CODING_STANDARD_MISRA_C_2023;
530+
if (mPremium && mUI->mMisraVersion->currentIndex() == 2)
531+
codingStandards << CODING_STANDARD_MISRA_C_2025;
522532
if (mUI->mMisraCpp->isChecked() && mUI->mMisraCppVersion->currentIndex() == 0)
523533
codingStandards << CODING_STANDARD_MISRA_CPP_2008;
524534
if (mUI->mMisraCpp->isChecked() && mUI->mMisraCppVersion->currentIndex() == 1)

lib/checkersidmapping.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
// This file is auto generated by script, do not edit
1919
// Mappings of Cppcheck warning IDs to guidelines
2020
#include "checkers.h"
21-
2221
#include <vector>
2322

2423
std::vector<checkers::IdMapping> checkers::idMappingAutosar{
@@ -79,8 +78,10 @@ std::vector<checkers::IdMapping> checkers::idMappingCertC{
7978
{"EXP34", "nullPointer,nullPointerDefaultArg,nullPointerRedundantCheck,nullPointerArithmetic,nullPointerArithmeticRedundantCheck"},
8079
{"EXP44", "sizeofCalculation"},
8180
{"EXP46", "bitwiseOnBoolean"},
81+
{"INT32", "integerOverflow"},
8282
{"FLP32", "invalidFunctionArg"},
8383
{"FLP34", "floatConversionOverflow"},
84+
{"ARR30", "arrayIndexOutOfBounds,arrayIndexOutOfBoundsCond,pointerOutOfBounds,pointerOutOfBoundsCond,negativeIndex,arrayIndexThenCheck,bufferAccessOutOfBounds,objectIndex,argumentSize"},
8485
{"ARR36", "comparePointers"},
8586
{"STR30", "stringLiteralWrite"},
8687
{"STR37", "invalidFunctionArg"},
@@ -95,28 +96,28 @@ std::vector<checkers::IdMapping> checkers::idMappingCertC{
9596
};
9697

9798
std::vector<checkers::IdMapping> checkers::idMappingCertCpp{
99+
{"CTR51", "eraseDereference"},
100+
{"CTR54", "comparePointers"},
101+
{"CTR55", "containerOutOfBounds"},
98102
{"DCL57", "deallocThrow,exceptThrowInDestructor"},
99103
{"DCL60", "ctuOneDefinitionRuleViolation"},
104+
{"ERR57", "memleak"},
100105
{"EXP52", "sizeofCalculation"},
101-
{"EXP53", "uninitvar"},
106+
{"EXP53", "uninitvar,uninitdata,uninitStructMember"},
102107
{"EXP54", "uninitvar,danglingLifetime,danglingReference,danglingTemporaryLifetime,danglingTempReference,returnDanglingLifetime"},
103108
{"EXP61", "danglingLifetime,danglingReference,danglingTemporaryLifetime,danglingTempReference,returnDanglingLifetime"},
104109
{"EXP63", "accessMoved"},
105-
{"CTR51", "eraseDereference"},
106-
{"CTR54", "comparePointers"},
107-
{"CTR55", "containerOutOfBounds"},
108-
{"STR51", "nullPointer"},
109-
{"STR52", "invalidContainer"},
110+
{"FIO50", "IOWithoutPositioning"},
110111
{"MEM50", "deallocuse"},
111112
{"MEM51", "mismatchAllocDealloc"},
112113
{"MEM56", "doubleFree"},
113-
{"FIO50", "IOWithoutPositioning"},
114-
{"ERR57", "memleak"},
114+
{"MSC52", "missingReturn"},
115115
{"OOP50", "virtualCallInConstructor"},
116116
{"OOP52", "virtualDestructor"},
117117
{"OOP53", "initializerList"},
118118
{"OOP54", "operatorEqToSelf"},
119-
{"MSC52", "missingReturn"},
119+
{"STR51", "nullPointer"},
120+
{"STR52", "invalidContainer"},
120121
};
121122

122123
std::vector<checkers::IdMapping> checkers::idMappingMisraC{
@@ -192,6 +193,7 @@ std::vector<checkers::IdMapping> checkers::idMappingMisraCpp2023{
192193
{"0.0.1", "unreachableCode"},
193194
{"0.0.2", "compareBoolExpressionWithInt,compareValueOutOfTypeRangeError,identicalConditionAfterEarlyExit,identicalInnerCondition,knownConditionTrueFalse"},
194195
{"0.1.1", "redundantAssignInSwitch,redundantAssignment,redundantCopy,redundantInitialization,unreadVariable"},
196+
{"Dir 0.3.1", "floatConversionOverflow"},
195197
{"Dir 0.3.2", "invalidFunctionArg,invalidFunctionArgBool,invalidFunctionArgStr"},
196198
{"4.1.3", "error"},
197199
{"4.6.1", "unknownEvaluationOrder"},

lib/checkersreport.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ static bool isCppcheckPremium(const Settings& settings) {
3535
}
3636

3737
static int getMisraCVersion(const Settings& settings) {
38-
if (settings.premiumArgs.find("misra-c-2012") != std::string::npos)
39-
return 2012;
38+
if (settings.premiumArgs.find("misra-c-2025") != std::string::npos)
39+
return 2025;
4040
if (settings.premiumArgs.find("misra-c-2023") != std::string::npos)
4141
return 2023;
42+
if (settings.premiumArgs.find("misra-c-2012") != std::string::npos)
43+
return 2012;
4244
if (settings.addons.count("misra"))
4345
return 2012;
4446
const bool misraAddonInfo = std::any_of(settings.addonInfos.cbegin(), settings.addonInfos.cend(), [](const AddonInfo& addonInfo) {

lib/cppcheck.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,8 +1732,6 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
17321732
mErrorLogger.reportErr(errmsg);
17331733
}
17341734

1735-
const bool misraC2023 = mSettings.premiumArgs.find("--misra-c-2023") != std::string::npos;
1736-
17371735
for (const picojson::value& res : results) {
17381736
// TODO: get rid of copy?
17391737
// this is a copy so we can access missing fields and get a default value
@@ -1789,9 +1787,7 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
17891787
}
17901788

17911789
errmsg.id = obj["addon"].get<std::string>() + "-" + obj["errorId"].get<std::string>();
1792-
if (misraC2023 && startsWith(errmsg.id, "misra-c2012-"))
1793-
errmsg.id = "misra-c2023-" + errmsg.id.substr(12);
1794-
errmsg.setmsg(mSettings.getMisraRuleText(errmsg.id, obj["message"].get<std::string>()));
1790+
errmsg.setmsg(obj["message"].get<std::string>());
17951791
const std::string severity = obj["severity"].get<std::string>();
17961792
errmsg.severity = severityFromString(severity);
17971793
if (errmsg.severity == Severity::none || errmsg.severity == Severity::internal) {
@@ -2122,10 +2118,8 @@ void CppCheck::printTimerResults(SHOWTIME_MODES mode)
21222118
}
21232119

21242120
bool CppCheck::isPremiumCodingStandardId(const std::string& id) const {
2125-
if (mSettings.premiumArgs.find("--misra") != std::string::npos) {
2126-
if (startsWith(id, "misra-") || startsWith(id, "premium-misra-"))
2127-
return true;
2128-
}
2121+
if (mSettings.premiumArgs.find("--misra") != std::string::npos && startsWith(id, "premium-misra-"))
2122+
return true;
21292123
if (mSettings.premiumArgs.find("--cert") != std::string::npos && startsWith(id, "premium-cert-"))
21302124
return true;
21312125
if (mSettings.premiumArgs.find("--autosar") != std::string::npos && startsWith(id, "premium-autosar-"))

lib/settings.cpp

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -392,15 +392,21 @@ static const std::set<std::string> autosarCheckers{
392392

393393
static const std::set<std::string> certCCheckers{
394394
"IOWithoutPositioning",
395+
"argumentSize",
396+
"arrayIndexOutOfBounds",
397+
"arrayIndexOutOfBoundsCond",
398+
"arrayIndexThenCheck",
395399
"autoVariables",
396400
"autovarInvalidDeallocation",
397401
"bitwiseOnBoolean",
402+
"bufferAccessOutOfBounds",
398403
"comparePointers",
399404
"danglingLifetime",
400405
"deallocret",
401406
"deallocuse",
402407
"doubleFree",
403408
"floatConversionOverflow",
409+
"integerOverflow",
404410
"invalidFunctionArg",
405411
"invalidLengthModifierError",
406412
"invalidLifetime",
@@ -412,11 +418,15 @@ static const std::set<std::string> certCCheckers{
412418
"memleakOnRealloc",
413419
"mismatchAllocDealloc",
414420
"missingReturn",
421+
"negativeIndex",
415422
"nullPointer",
416423
"nullPointerArithmetic",
417424
"nullPointerArithmeticRedundantCheck",
418425
"nullPointerDefaultArg",
419426
"nullPointerRedundantCheck",
427+
"objectIndex",
428+
"pointerOutOfBounds",
429+
"pointerOutOfBoundsCond",
420430
"preprocessorErrorDirective",
421431
"resourceLeak",
422432
"returnDanglingLifetime",
@@ -455,6 +465,8 @@ static const std::set<std::string> certCppCheckers{
455465
"operatorEqToSelf",
456466
"returnDanglingLifetime",
457467
"sizeofCalculation",
468+
"uninitStructMember",
469+
"uninitdata",
458470
"uninitvar",
459471
"virtualCallInConstructor",
460472
"virtualDestructor"
@@ -546,6 +558,49 @@ static const std::set<std::string> misrac2023Checkers{
546558
"writeReadOnlyFile"
547559
};
548560

561+
static const std::set<std::string> misrac2025Checkers{
562+
"argumentSize",
563+
"autovarInvalidDeallocation",
564+
"bufferAccessOutOfBounds",
565+
"comparePointers",
566+
"compareValueOutOfTypeRangeError",
567+
"constParameterPointer",
568+
"constStatement",
569+
"danglingLifetime",
570+
"danglingTemporaryLifetime",
571+
"duplicateBreak",
572+
"funcArgNamesDifferent",
573+
"incompatibleFileOpen",
574+
"invalidFunctionArg",
575+
"knownConditionTrueFalse",
576+
"leakNoVarFunctionCall",
577+
"leakReturnValNotUsed",
578+
"memleak",
579+
"memleakOnRealloc",
580+
"missingReturn",
581+
"overlappingWriteFunction",
582+
"overlappingWriteUnion",
583+
"pointerOutOfBounds",
584+
"preprocessorErrorDirective",
585+
"redundantAssignInSwitch",
586+
"redundantAssignment",
587+
"redundantCondition",
588+
"resourceLeak",
589+
"returnDanglingLifetime",
590+
"shadowVariable",
591+
"sizeofCalculation",
592+
"sizeofwithsilentarraypointer",
593+
"syntaxError",
594+
"uninitvar",
595+
"unknownEvaluationOrder",
596+
"unreachableCode",
597+
"unreadVariable",
598+
"unusedLabel",
599+
"unusedVariable",
600+
"useClosedFile",
601+
"writeReadOnlyFile"
602+
};
603+
549604
static const std::set<std::string> misracpp2008Checkers{
550605
"autoVariables",
551606
"comparePointers",
@@ -602,6 +657,7 @@ static const std::set<std::string> misracpp2023Checkers{
602657
"constParameterReference",
603658
"ctuOneDefinitionRuleViolation",
604659
"danglingLifetime",
660+
"floatConversionOverflow",
605661
"identicalConditionAfterEarlyExit",
606662
"identicalInnerCondition",
607663
"ignoredReturnValue",
@@ -639,7 +695,7 @@ bool Settings::isPremiumEnabled(const char id[]) const
639695
return true;
640696
if (premiumArgs.find("cert-c++") != std::string::npos && certCppCheckers.count(id))
641697
return true;
642-
if (premiumArgs.find("misra-c-") != std::string::npos && (misrac2012Checkers.count(id) || misrac2023Checkers.count(id)))
698+
if (premiumArgs.find("misra-c-") != std::string::npos && (misrac2012Checkers.count(id) || misrac2023Checkers.count(id) || misrac2025Checkers.count(id)))
643699
return true;
644700
if (premiumArgs.find("misra-c++-2008") != std::string::npos && misracpp2008Checkers.count(id))
645701
return true;
@@ -648,51 +704,6 @@ bool Settings::isPremiumEnabled(const char id[]) const
648704
return false;
649705
}
650706

651-
void Settings::setMisraRuleTexts(const ExecuteCmdFn& executeCommand)
652-
{
653-
if (premiumArgs.find("--misra-c-20") != std::string::npos) {
654-
const auto it = std::find_if(addonInfos.cbegin(), addonInfos.cend(), [](const AddonInfo& a) {
655-
return a.name == "premiumaddon.json";
656-
});
657-
if (it != addonInfos.cend()) {
658-
std::string arg;
659-
if (premiumArgs.find("--misra-c-2023") != std::string::npos)
660-
arg = "--misra-c-2023-rule-texts";
661-
else
662-
arg = "--misra-c-2012-rule-texts";
663-
std::string output;
664-
executeCommand(it->executable, {std::move(arg)}, "2>&1", output);
665-
setMisraRuleTexts(output);
666-
}
667-
}
668-
}
669-
670-
void Settings::setMisraRuleTexts(const std::string& data)
671-
{
672-
mMisraRuleTexts.clear();
673-
std::istringstream istr(data);
674-
std::string line;
675-
while (std::getline(istr, line)) {
676-
std::string::size_type pos = line.find(' ');
677-
if (pos == std::string::npos)
678-
continue;
679-
std::string id = line.substr(0, pos);
680-
std::string text = line.substr(pos + 1);
681-
if (id.empty() || text.empty())
682-
continue;
683-
if (text[text.size() -1] == '\r')
684-
text.erase(text.size() -1);
685-
mMisraRuleTexts[id] = std::move(text);
686-
}
687-
}
688-
689-
std::string Settings::getMisraRuleText(const std::string& id, const std::string& text) const {
690-
if (id.compare(0, 9, "misra-c20") != 0)
691-
return text;
692-
const auto it = mMisraRuleTexts.find(id.substr(id.rfind('-') + 1));
693-
return it != mMisraRuleTexts.end() ? it->second : text;
694-
}
695-
696707
Settings::ExecutorType Settings::defaultExecutor()
697708
{
698709
static constexpr ExecutorType defaultExecutor =

lib/settings.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -543,17 +543,12 @@ class CPPCHECKLIB WARN_UNUSED Settings {
543543

544544
void setCheckLevel(CheckLevel level);
545545

546-
using ExecuteCmdFn = std::function<int (std::string,std::vector<std::string>,std::string,std::string&)>;
547-
void setMisraRuleTexts(const ExecuteCmdFn& executeCommand);
548-
void setMisraRuleTexts(const std::string& data);
549-
std::string getMisraRuleText(const std::string& id, const std::string& text) const;
550546

551547
static ExecutorType defaultExecutor();
552548

553549
private:
554550
static std::string parseEnabled(const std::string &str, std::tuple<SimpleEnableGroup<Severity>, SimpleEnableGroup<Checks>> &groups);
555551
std::string applyEnabled(const std::string &str, bool enable);
556-
std::map<std::string, std::string> mMisraRuleTexts;
557552
};
558553

559554
/// @}

0 commit comments

Comments
 (0)