Skip to content

Commit 524e979

Browse files
authored
default to --check-level=exhaustive internally / several related cleanups (cppcheck-opensource#6225)
1 parent 83d4e31 commit 524e979

17 files changed

Lines changed: 203 additions & 96 deletions

cli/cmdlineparser.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
311311
{
312312
mSettings.exename = Path::getCurrentExecutablePath(argv[0]);
313313

314+
// default to --check-level=normal from CLI for now
315+
mSettings.setCheckLevel(Settings::CheckLevel::normal);
316+
314317
if (argc <= 1) {
315318
printHelp();
316319
return Result::Exit;
@@ -468,13 +471,21 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
468471
else if (std::strcmp(argv[i], "--check-config") == 0)
469472
mSettings.checkConfiguration = true;
470473

471-
// Check code exhaustively
472-
else if (std::strcmp(argv[i], "--check-level=exhaustive") == 0)
473-
mSettings.setCheckLevelExhaustive();
474+
// Check level
475+
else if (std::strncmp(argv[i], "--check-level=", 14) == 0) {
476+
Settings::CheckLevel level = Settings::CheckLevel::normal;
477+
const std::string level_s(argv[i] + 14);
478+
if (level_s == "normal")
479+
level = Settings::CheckLevel::normal;
480+
else if (level_s == "exhaustive")
481+
level = Settings::CheckLevel::exhaustive;
482+
else {
483+
mLogger.printError("unknown '--check-level' value '" + level_s + "'.");
484+
return Result::Fail;
485+
}
474486

475-
// Check code with normal analysis
476-
else if (std::strcmp(argv[i], "--check-level=normal") == 0)
477-
mSettings.setCheckLevelNormal();
487+
mSettings.setCheckLevel(level);
488+
}
478489

479490
// Check library definitions
480491
else if (std::strcmp(argv[i], "--check-library") == 0) {

gui/mainwindow.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,9 @@ QPair<bool,Settings> MainWindow::getCppcheckSettings()
969969

970970
result.exename = QCoreApplication::applicationFilePath().toStdString();
971971

972+
// default to --check-level=normal for GUI for now
973+
result.setCheckLevel(Settings::CheckLevel::normal);
974+
972975
const bool std = tryLoadLibrary(&result.library, "std.cfg");
973976
if (!std) {
974977
QMessageBox::critical(this, tr("Error"), tr("Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured.\n\nAnalysis is aborted.").arg("std.cfg"));
@@ -1061,9 +1064,9 @@ QPair<bool,Settings> MainWindow::getCppcheckSettings()
10611064
result.maxCtuDepth = mProjectFile->getMaxCtuDepth();
10621065
result.maxTemplateRecursion = mProjectFile->getMaxTemplateRecursion();
10631066
if (mProjectFile->isCheckLevelExhaustive())
1064-
result.setCheckLevelExhaustive();
1067+
result.setCheckLevel(Settings::CheckLevel::exhaustive);
10651068
else
1066-
result.setCheckLevelNormal();
1069+
result.setCheckLevel(Settings::CheckLevel::normal);
10671070
result.checkHeaders = mProjectFile->getCheckHeaders();
10681071
result.checkUnusedTemplates = mProjectFile->getCheckUnusedTemplates();
10691072
result.safeChecks.classes = mProjectFile->safeChecks.classes;

lib/importproject.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,9 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
11251125
std::list<SuppressionList::Suppression> suppressions;
11261126
Settings temp;
11271127

1128+
// default to --check-level=normal for import for now
1129+
temp.setCheckLevel(Settings::CheckLevel::normal);
1130+
11281131
guiProject.analyzeAllVsConfigs.clear();
11291132

11301133
bool checkLevelExhaustive = false;
@@ -1268,9 +1271,9 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
12681271
settings->safeChecks = temp.safeChecks;
12691272

12701273
if (checkLevelExhaustive)
1271-
settings->setCheckLevelExhaustive();
1274+
settings->setCheckLevel(Settings::CheckLevel::exhaustive);
12721275
else
1273-
settings->setCheckLevelNormal();
1276+
settings->setCheckLevel(Settings::CheckLevel::normal);
12741277

12751278
return true;
12761279
}

lib/settings.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Settings::Settings()
4141
{
4242
severity.setEnabled(Severity::error, true);
4343
certainty.setEnabled(Certainty::normal, true);
44-
setCheckLevelNormal();
44+
setCheckLevel(Settings::CheckLevel::exhaustive);
4545
executor = defaultExecutor();
4646
}
4747

@@ -268,21 +268,20 @@ void Settings::loadSummaries()
268268
Summaries::loadReturn(buildDir, summaryReturn);
269269
}
270270

271-
272-
void Settings::setCheckLevelExhaustive()
273-
{
274-
// Checking can take a little while. ~ 10 times slower than normal analysis is OK.
275-
checkLevel = CheckLevel::exhaustive;
276-
performanceValueFlowMaxIfCount = -1;
277-
performanceValueFlowMaxSubFunctionArgs = 256;
278-
}
279-
280-
void Settings::setCheckLevelNormal()
271+
void Settings::setCheckLevel(CheckLevel level)
281272
{
282-
// Checking should finish in reasonable time.
283-
checkLevel = CheckLevel::normal;
284-
performanceValueFlowMaxSubFunctionArgs = 8;
285-
performanceValueFlowMaxIfCount = 100;
273+
if (level == CheckLevel::normal) {
274+
// Checking should finish in reasonable time.
275+
checkLevel = level;
276+
performanceValueFlowMaxSubFunctionArgs = 8;
277+
performanceValueFlowMaxIfCount = 100;
278+
}
279+
else if (level == CheckLevel::exhaustive) {
280+
// Checking can take a little while. ~ 10 times slower than normal analysis is OK.
281+
checkLevel = CheckLevel::exhaustive;
282+
performanceValueFlowMaxIfCount = -1;
283+
performanceValueFlowMaxSubFunctionArgs = 256;
284+
}
286285
}
287286

288287
// TODO: auto generate these tables

lib/settings.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,10 @@ class CPPCHECKLIB WARN_UNUSED Settings {
259259
int performanceValueFlowMaxTime = -1;
260260

261261
/** @brief --performance-valueflow-max-if-count=C */
262-
int performanceValueFlowMaxIfCount;
262+
int performanceValueFlowMaxIfCount = -1;
263263

264264
/** @brief max number of sets of arguments to pass to subfuncions in valueflow */
265-
int performanceValueFlowMaxSubFunctionArgs;
265+
int performanceValueFlowMaxSubFunctionArgs = 256;
266266

267267
/** @brief plist output (--plist-output=&lt;dir&gt;) */
268268
std::string plistOutput;
@@ -456,14 +456,13 @@ class CPPCHECKLIB WARN_UNUSED Settings {
456456
return jobs == 1;
457457
}
458458

459-
void setCheckLevelExhaustive();
460-
void setCheckLevelNormal();
461-
462459
enum class CheckLevel {
463-
exhaustive,
464-
normal
460+
normal,
461+
exhaustive
465462
};
466-
CheckLevel checkLevel = CheckLevel::normal;
463+
CheckLevel checkLevel = CheckLevel::exhaustive;
464+
465+
void setCheckLevel(CheckLevel level);
467466

468467
using ExecuteCmdFn = std::function<int (std::string,std::vector<std::string>,std::string,std::string&)>;
469468
void setMisraRuleTexts(const ExecuteCmdFn& executeCommand);

test/fixture.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,8 @@ void TestFixture::setTemplateFormat(const std::string &templateFormat)
445445
}
446446
}
447447

448-
TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::exhaustive() {
449-
settings.setCheckLevelExhaustive();
448+
TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::checkLevel(Settings::CheckLevel level) {
449+
settings.setCheckLevel(level);
450450
return *this;
451451
}
452452

test/fixture.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ class TestFixture : public ErrorLogger {
208208
return *this;
209209
}
210210

211-
SettingsBuilder& exhaustive();
211+
SettingsBuilder& checkLevel(Settings::CheckLevel level);
212212

213213
SettingsBuilder& library(const char lib[]);
214214

test/testcmdlineparser.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,10 @@ class TestCmdlineParser : public TestFixture {
383383
#else
384384
TEST_CASE(executorProcessNotSupported);
385385
#endif
386+
TEST_CASE(checkLevelDefault);
387+
TEST_CASE(checkLevelNormal);
388+
TEST_CASE(checkLevelExhaustive);
389+
TEST_CASE(checkLevelUnknown);
386390

387391
TEST_CASE(ignorepaths1);
388392
TEST_CASE(ignorepaths2);
@@ -2565,6 +2569,40 @@ class TestCmdlineParser : public TestFixture {
25652569
}
25662570
#endif
25672571

2572+
void checkLevelDefault() {
2573+
REDIRECT;
2574+
const char * const argv[] = {"cppcheck", "file.cpp"};
2575+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(2, argv));
2576+
ASSERT_EQUALS_ENUM(Settings::CheckLevel::normal, settings->checkLevel);
2577+
ASSERT_EQUALS(100, settings->performanceValueFlowMaxIfCount);
2578+
ASSERT_EQUALS(8, settings->performanceValueFlowMaxSubFunctionArgs);
2579+
}
2580+
2581+
void checkLevelNormal() {
2582+
REDIRECT;
2583+
const char * const argv[] = {"cppcheck", "--check-level=normal", "file.cpp"};
2584+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
2585+
ASSERT_EQUALS_ENUM(Settings::CheckLevel::normal, settings->checkLevel);
2586+
ASSERT_EQUALS(100, settings->performanceValueFlowMaxIfCount);
2587+
ASSERT_EQUALS(8, settings->performanceValueFlowMaxSubFunctionArgs);
2588+
}
2589+
2590+
void checkLevelExhaustive() {
2591+
REDIRECT;
2592+
const char * const argv[] = {"cppcheck", "--check-level=exhaustive", "file.cpp"};
2593+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
2594+
ASSERT_EQUALS_ENUM(Settings::CheckLevel::exhaustive, settings->checkLevel);
2595+
ASSERT_EQUALS(-1, settings->performanceValueFlowMaxIfCount);
2596+
ASSERT_EQUALS(256, settings->performanceValueFlowMaxSubFunctionArgs);
2597+
}
2598+
2599+
void checkLevelUnknown() {
2600+
REDIRECT;
2601+
const char * const argv[] = {"cppcheck", "--check-level=default", "file.cpp"};
2602+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv));
2603+
ASSERT_EQUALS("cppcheck: error: unknown '--check-level' value 'default'.\n", logger->str());
2604+
}
2605+
25682606
void ignorepaths1() {
25692607
REDIRECT;
25702608
const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"};

test/testcondition.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class TestCondition : public TestFixture {
140140
}
141141

142142
void check_(const char* file, int line, const char code[], const char* filename = "test.cpp", bool inconclusive = false) {
143-
const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).exhaustive().build();
143+
const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).build();
144144
check_(file, line, code, settings, filename);
145145
}
146146

test/testgarbage.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ class TestGarbage : public TestFixture {
498498

499499
void garbageCode16() {
500500
checkCode("{ } A() { delete }"); // #6080
501+
ignore_errout(); // we do not care about the output
501502
}
502503

503504
void garbageCode17() {
@@ -563,6 +564,7 @@ class TestGarbage : public TestFixture {
563564
" case struct Tree : break;\n"
564565
" }\n"
565566
"}"), SYNTAX);
567+
ignore_errout(); // we do not care about the output
566568
}
567569

568570
void garbageCode26() {
@@ -633,10 +635,12 @@ class TestGarbage : public TestFixture {
633635
void garbageCode37() {
634636
// #5166 segmentation fault (invalid code) in lib/checkother.cpp:329 ( void * f { } void b ( ) { * f } )
635637
checkCode("void * f { } void b ( ) { * f }");
638+
ignore_errout(); // we do not care about the output
636639
}
637640

638641
void garbageCode38() { // Ticket #6666
639642
checkCode("{ f2 { } } void f3 () { delete[] } { }");
643+
ignore_errout(); // we do not care about the output
640644
}
641645

642646
void garbageCode40() { // #6620
@@ -1222,6 +1226,7 @@ class TestGarbage : public TestFixture {
12221226
" for (j = 0; j < 1; j)\n"
12231227
" j6;\n"
12241228
"}");
1229+
ignore_errout(); // we do not care about the output
12251230
}
12261231

12271232
void garbageCode150() { // #7089
@@ -1441,6 +1446,7 @@ class TestGarbage : public TestFixture {
14411446
void garbageCode168() {
14421447
// 7246
14431448
checkCode("long foo(void) { return *bar; }", false);
1449+
ignore_errout(); // we do not care about the output
14441450
}
14451451

14461452
void garbageCode169() {
@@ -1581,6 +1587,7 @@ class TestGarbage : public TestFixture {
15811587
" double e(b);\n"
15821588
" if(e <= 0) {}\n"
15831589
"}");
1590+
ignore_errout(); // we do not care about the output
15841591
}
15851592

15861593
// #8265
@@ -1607,6 +1614,7 @@ class TestGarbage : public TestFixture {
16071614
// #8752
16081615
void garbageCode199() {
16091616
checkCode("d f(){e n00e0[]n00e0&" "0+f=0}");
1617+
ignore_errout(); // we do not care about the output
16101618
}
16111619

16121620
// #8757
@@ -1623,6 +1631,7 @@ class TestGarbage : public TestFixture {
16231631
void garbageCode202() {
16241632
ASSERT_THROW_INTERNAL(checkCode("void f() { UNKNOWN_MACRO(return); }"), UNKNOWN_MACRO);
16251633
ASSERT_THROW_INTERNAL(checkCode("void f() { UNKNOWN_MACRO(throw); }"), UNKNOWN_MACRO);
1634+
ignore_errout();
16261635
}
16271636

16281637
void garbageCode203() { // #8972
@@ -1735,7 +1744,9 @@ class TestGarbage : public TestFixture {
17351744
}
17361745
void garbageCode224() {
17371746
ASSERT_THROW_INTERNAL(checkCode("void f(){ auto* b = dynamic_cast<const }"), SYNTAX); // don't crash
1747+
ASSERT_EQUALS("", errout_str());
17381748
ASSERT_THROW_INTERNAL(checkCode("void f(){ auto* b = dynamic_cast x; }"), SYNTAX);
1749+
ignore_errout();
17391750
}
17401751
void garbageCode225() {
17411752
ASSERT_THROW_INTERNAL(checkCode("int n() { c * s0, 0 s0 = c(sizeof = ) }"), SYNTAX);
@@ -1859,6 +1870,7 @@ class TestGarbage : public TestFixture {
18591870
"void f() {\n"
18601871
" auto fn = []() -> foo* { return new foo(); };\n"
18611872
"}");
1873+
ignore_errout(); // we do not care about the output
18621874
}
18631875
};
18641876

0 commit comments

Comments
 (0)