diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index b0603c9591b0..5ae6a7a1ac4f 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -311,6 +311,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a { mSettings.exename = Path::getCurrentExecutablePath(argv[0]); + // default to --check-level=normal from CLI for now + mSettings.setCheckLevelNormal(); + if (argc <= 1) { printHelp(); return Result::Exit; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 9a8ba14504a5..2e358a1f0e6a 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -969,6 +969,9 @@ QPair MainWindow::getCppcheckSettings() result.exename = QCoreApplication::applicationFilePath().toStdString(); + // default to --check-level=normal for GUI for now + result.setCheckLevelNormal(); + const bool std = tryLoadLibrary(&result.library, "std.cfg"); if (!std) { QMessageBox::critical(this, tr("Error"), tr("Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir= 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")); diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 34780f7cd490..64c9a6428eb8 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1125,6 +1125,9 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti std::list suppressions; Settings temp; + // default to --check-level=normal for import for now + temp.setCheckLevelNormal(); + guiProject.analyzeAllVsConfigs.clear(); bool checkLevelExhaustive = false; diff --git a/lib/settings.cpp b/lib/settings.cpp index ae03f2476dee..d5e226da64dd 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -41,7 +41,7 @@ Settings::Settings() { severity.setEnabled(Severity::error, true); certainty.setEnabled(Certainty::normal, true); - setCheckLevelNormal(); + setCheckLevelExhaustive(); executor = defaultExecutor(); } diff --git a/lib/settings.h b/lib/settings.h index b5dc0951d4bf..03bf0b9530cb 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -259,10 +259,10 @@ class CPPCHECKLIB WARN_UNUSED Settings { int performanceValueFlowMaxTime = -1; /** @brief --performance-valueflow-max-if-count=C */ - int performanceValueFlowMaxIfCount; + int performanceValueFlowMaxIfCount = -1; /** @brief max number of sets of arguments to pass to subfuncions in valueflow */ - int performanceValueFlowMaxSubFunctionArgs; + int performanceValueFlowMaxSubFunctionArgs = 256; /** @brief plist output (--plist-output=<dir>) */ std::string plistOutput; @@ -463,7 +463,7 @@ class CPPCHECKLIB WARN_UNUSED Settings { normal, exhaustive }; - CheckLevel checkLevel = CheckLevel::normal; + CheckLevel checkLevel = CheckLevel::exhaustive; using ExecuteCmdFn = std::function,std::string,std::string&)>; void setMisraRuleTexts(const ExecuteCmdFn& executeCommand); diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index ca187287dcdc..a92047363fa2 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -383,6 +383,9 @@ class TestCmdlineParser : public TestFixture { #else TEST_CASE(executorProcessNotSupported); #endif + TEST_CASE(checkLevelDefault); + TEST_CASE(checkLevelNormal); + TEST_CASE(checkLevelExhaustive); TEST_CASE(ignorepaths1); TEST_CASE(ignorepaths2); @@ -2565,6 +2568,33 @@ class TestCmdlineParser : public TestFixture { } #endif + void checkLevelDefault() { + REDIRECT; + const char * const argv[] = {"cppcheck", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(2, argv)); + ASSERT_EQUALS_ENUM(Settings::CheckLevel::normal, settings->checkLevel); + ASSERT_EQUALS(100, settings->performanceValueFlowMaxIfCount); + ASSERT_EQUALS(8, settings->performanceValueFlowMaxSubFunctionArgs); + } + + void checkLevelNormal() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--check-level=normal", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); + ASSERT_EQUALS_ENUM(Settings::CheckLevel::normal, settings->checkLevel); + ASSERT_EQUALS(100, settings->performanceValueFlowMaxIfCount); + ASSERT_EQUALS(8, settings->performanceValueFlowMaxSubFunctionArgs); + } + + void checkLevelExhaustive() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--check-level=exhaustive", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); + ASSERT_EQUALS_ENUM(Settings::CheckLevel::exhaustive, settings->checkLevel); + ASSERT_EQUALS(-1, settings->performanceValueFlowMaxIfCount); + ASSERT_EQUALS(256, settings->performanceValueFlowMaxSubFunctionArgs); + } + void ignorepaths1() { REDIRECT; const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"}; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 7ae5338448fe..16b08f6e3ae1 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -140,7 +140,7 @@ class TestCondition : public TestFixture { } void check_(const char* file, int line, const char code[], const char* filename = "test.cpp", bool inconclusive = false) { - const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).exhaustive().build(); + const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).build(); check_(file, line, code, settings, filename); } diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 776d96cd9c5c..4ef130526a48 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -498,6 +498,7 @@ class TestGarbage : public TestFixture { void garbageCode16() { checkCode("{ } A() { delete }"); // #6080 + ignore_errout(); // we do not care about the output } void garbageCode17() { @@ -563,6 +564,7 @@ class TestGarbage : public TestFixture { " case struct Tree : break;\n" " }\n" "}"), SYNTAX); + ignore_errout(); // we do not care about the output } void garbageCode26() { @@ -633,10 +635,12 @@ class TestGarbage : public TestFixture { void garbageCode37() { // #5166 segmentation fault (invalid code) in lib/checkother.cpp:329 ( void * f { } void b ( ) { * f } ) checkCode("void * f { } void b ( ) { * f }"); + ignore_errout(); // we do not care about the output } void garbageCode38() { // Ticket #6666 checkCode("{ f2 { } } void f3 () { delete[] } { }"); + ignore_errout(); // we do not care about the output } void garbageCode40() { // #6620 @@ -1222,6 +1226,7 @@ class TestGarbage : public TestFixture { " for (j = 0; j < 1; j)\n" " j6;\n" "}"); + ignore_errout(); // we do not care about the output } void garbageCode150() { // #7089 @@ -1441,6 +1446,7 @@ class TestGarbage : public TestFixture { void garbageCode168() { // 7246 checkCode("long foo(void) { return *bar; }", false); + ignore_errout(); // we do not care about the output } void garbageCode169() { @@ -1581,6 +1587,7 @@ class TestGarbage : public TestFixture { " double e(b);\n" " if(e <= 0) {}\n" "}"); + ignore_errout(); // we do not care about the output } // #8265 @@ -1607,6 +1614,7 @@ class TestGarbage : public TestFixture { // #8752 void garbageCode199() { checkCode("d f(){e n00e0[]n00e0&" "0+f=0}"); + ignore_errout(); // we do not care about the output } // #8757 @@ -1623,6 +1631,7 @@ class TestGarbage : public TestFixture { void garbageCode202() { ASSERT_THROW_INTERNAL(checkCode("void f() { UNKNOWN_MACRO(return); }"), UNKNOWN_MACRO); ASSERT_THROW_INTERNAL(checkCode("void f() { UNKNOWN_MACRO(throw); }"), UNKNOWN_MACRO); + ignore_errout(); } void garbageCode203() { // #8972 @@ -1735,7 +1744,9 @@ class TestGarbage : public TestFixture { } void garbageCode224() { ASSERT_THROW_INTERNAL(checkCode("void f(){ auto* b = dynamic_cast foo* { return new foo(); };\n" "}"); + ignore_errout(); // we do not care about the output } }; diff --git a/test/testsettings.cpp b/test/testsettings.cpp index 803e49dcb541..2e04c5685592 100644 --- a/test/testsettings.cpp +++ b/test/testsettings.cpp @@ -36,6 +36,7 @@ class TestSettings : public TestFixture { TEST_CASE(loadCppcheckCfgSafety); TEST_CASE(getNameAndVersion); TEST_CASE(ruleTexts); + TEST_CASE(checkLevelDefault); } void simpleEnableGroup() const { @@ -266,6 +267,14 @@ class TestSettings : public TestFixture { ASSERT_EQUALS("text 1", s.getMisraRuleText("misra-c2012-1.1", "---")); ASSERT_EQUALS("text 2", s.getMisraRuleText("misra-c2012-1.2", "---")); } + + void checkLevelDefault() const + { + Settings s; + ASSERT_EQUALS_ENUM(s.checkLevel, Settings::CheckLevel::exhaustive); + ASSERT_EQUALS(s.performanceValueFlowMaxIfCount, -1); + ASSERT_EQUALS(s.performanceValueFlowMaxSubFunctionArgs, 256); + } }; REGISTER_TEST(TestSettings) diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 4f3fc5e47d30..ddb1fbb4718a 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -238,7 +238,7 @@ class TestSimplifyTypedef : public TestFixture { #define tok(...) tok_(__FILE__, __LINE__, __VA_ARGS__) std::string tok_(const char* file, int line, const char code[], bool simplify = true, Platform::Type type = Platform::Type::Native, bool debugwarnings = true) { // show warnings about unhandled typedef - const Settings settings = settingsBuilder(settings0).exhaustive().certainty(Certainty::inconclusive).debugwarnings(debugwarnings).platform(type).build(); + const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive).debugwarnings(debugwarnings).platform(type).build(); SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index fbeb0c8de15e..dd89c87eef90 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -737,7 +737,7 @@ class TestSimplifyUsing : public TestFixture { "cout << std :: string ( c ) << \"abc\" ; " "}"; ASSERT_EQUALS(expected, tok(code, Platform::Type::Native, /*debugwarnings*/ true)); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cout\n", errout_str()); } { const char code[] = "class T : private std::vector> {\n" // #12521 @@ -853,6 +853,9 @@ class TestSimplifyUsing : public TestFixture { "}"; ASSERT_EQUALS(exp, tok(code)); + ASSERT_EQUALS("[test.cpp:7]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable NS1\n" + "[test.cpp:11]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable NS2\n", + errout_str()); } void simplifyUsing9381() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 3b66387caffd..d56db42fef96 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2580,7 +2580,7 @@ class TestSymbolDatabase : public TestFixture { #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) void check_(const char* file, int line, const char code[], bool debug = true, bool cpp = true, const Settings* pSettings = nullptr) { // Check.. - const Settings settings = settingsBuilder(pSettings ? *pSettings : settings1).debugwarnings(debug).exhaustive().build(); + const Settings settings = settingsBuilder(pSettings ? *pSettings : settings1).debugwarnings(debug).build(); // Tokenize.. SimpleTokenizer tokenizer(settings, *this); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 5bac755589f7..0b8b4a962d2b 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -42,7 +42,7 @@ class TestValueFlow : public TestFixture { TestValueFlow() : TestFixture("TestValueFlow") {} private: - /*const*/ Settings settings = settingsBuilder().library("std.cfg").exhaustive().build(); + /*const*/ Settings settings = settingsBuilder().library("std.cfg").build(); void run() override { // strcpy, abort cfg @@ -473,7 +473,7 @@ class TestValueFlow : public TestFixture { #define bailout(...) bailout_(__FILE__, __LINE__, __VA_ARGS__) void bailout_(const char* file, int line, const char code[]) { - const Settings s = settingsBuilder().debugwarnings().exhaustive().build(); + const Settings s = settingsBuilder().debugwarnings().build(); std::vector files(1, "test.cpp"); Tokenizer tokenizer(s, this); @@ -6946,7 +6946,7 @@ class TestValueFlow : public TestFixture { void valueFlowSafeFunctionParameterValues() { const char *code; std::list values; - /*const*/ Settings s = settingsBuilder().exhaustive().library("std.cfg").build(); + /*const*/ Settings s = settingsBuilder().library("std.cfg").build(); s.safeChecks.classes = s.safeChecks.externalFunctions = s.safeChecks.internalFunctions = true; code = "short f(short x) {\n" @@ -6997,7 +6997,7 @@ class TestValueFlow : public TestFixture { void valueFlowUnknownFunctionReturn() { const char *code; std::list values; - /*const*/ Settings s = settingsBuilder().exhaustive().library("std.cfg").build(); + /*const*/ Settings s = settingsBuilder().library("std.cfg").build(); s.checkUnknownFunctionReturn.insert("rand"); code = "x = rand();";