Skip to content

Commit

Permalink
default to --check-level=exhaustive internally
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave committed Apr 11, 2024
1 parent d2127cb commit ef68c5d
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 64 deletions.
3 changes: 3 additions & 0 deletions cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,9 @@ QPair<bool,Settings> 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=<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"));
Expand Down
3 changes: 3 additions & 0 deletions lib/importproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,9 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
std::list<SuppressionList::Suppression> suppressions;
Settings temp;

// default to --check-level=normal for import for now
temp.setCheckLevelNormal();

guiProject.analyzeAllVsConfigs.clear();

bool checkLevelExhaustive = false;
Expand Down
2 changes: 1 addition & 1 deletion lib/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Settings::Settings()
{
severity.setEnabled(Severity::error, true);
certainty.setEnabled(Certainty::normal, true);
setCheckLevelNormal();
setCheckLevelExhaustive();
executor = defaultExecutor();
}

Expand Down
6 changes: 3 additions & 3 deletions lib/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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=&lt;dir&gt;) */
std::string plistOutput;
Expand Down Expand Up @@ -463,7 +463,7 @@ class CPPCHECKLIB WARN_UNUSED Settings {
normal,
exhaustive
};
CheckLevel checkLevel = CheckLevel::normal;
CheckLevel checkLevel = CheckLevel::exhaustive;

using ExecuteCmdFn = std::function<int (std::string,std::vector<std::string>,std::string,std::string&)>;
void setMisraRuleTexts(const ExecuteCmdFn& executeCommand);
Expand Down
30 changes: 30 additions & 0 deletions test/testcmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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"};
Expand Down
2 changes: 1 addition & 1 deletion test/testcondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
12 changes: 12 additions & 0 deletions test/testgarbage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -1735,7 +1744,9 @@ class TestGarbage : public TestFixture {
}
void garbageCode224() {
ASSERT_THROW_INTERNAL(checkCode("void f(){ auto* b = dynamic_cast<const }"), SYNTAX); // don't crash
ASSERT_EQUALS("", errout_str());
ASSERT_THROW_INTERNAL(checkCode("void f(){ auto* b = dynamic_cast x; }"), SYNTAX);
ignore_errout();
}
void garbageCode225() {
ASSERT_THROW_INTERNAL(checkCode("int n() { c * s0, 0 s0 = c(sizeof = ) }"), SYNTAX);
Expand Down Expand Up @@ -1859,6 +1870,7 @@ class TestGarbage : public TestFixture {
"void f() {\n"
" auto fn = []() -> foo* { return new foo(); };\n"
"}");
ignore_errout(); // we do not care about the output
}
};

Expand Down
9 changes: 9 additions & 0 deletions test/testsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class TestSettings : public TestFixture {
TEST_CASE(loadCppcheckCfgSafety);
TEST_CASE(getNameAndVersion);
TEST_CASE(ruleTexts);
TEST_CASE(checkLevelDefault);
}

void simpleEnableGroup() const {
Expand Down Expand Up @@ -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)
26 changes: 16 additions & 10 deletions test/testsimplifytokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2031,6 +2031,7 @@ class TestSimplifyTokens : public TestFixture {
"a [ x ] = 0 ;\n"
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str());
}

void simplifyKnownVariables36() {
Expand Down Expand Up @@ -2147,14 +2148,13 @@ class TestSimplifyTokens : public TestFixture {
" return x;\n"
"}";

{
const char expected[] = "void f ( ) {\n"
"int x ; x = 0 ;\n"
"cin >> x ;\n"
"return x ;\n"
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, true));
}
const char expected[] = "void f ( ) {\n"
"int x ; x = 0 ;\n"
"cin >> x ;\n"
"return x ;\n"
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, true));
ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str());
}

void simplifyKnownVariables47() {
Expand All @@ -2168,6 +2168,7 @@ class TestSimplifyTokens : public TestFixture {
"cin >> std :: hex >> x ;\n"
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, true));
ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str());
}

void simplifyKnownVariables48() {
Expand Down Expand Up @@ -2197,6 +2198,7 @@ class TestSimplifyTokens : public TestFixture {
"}\n"
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, false));
ASSERT_EQUALS("[test.c:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str());
}

void simplifyKnownVariables50() { // #4066
Expand All @@ -2219,6 +2221,7 @@ class TestSimplifyTokens : public TestFixture {
"return & x7 ;\n"
"}";
ASSERT_EQUALS(code, tokenizeAndStringify(code, true));
ASSERT_EQUALS("[test.cpp:5]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable y\n", errout_str());
}
{
//don't simplify '&x'!
Expand All @@ -2239,6 +2242,7 @@ class TestSimplifyTokens : public TestFixture {
"return & x7 ;\n"
"}";
ASSERT_EQUALS(code, tokenizeAndStringify(code, true));
ASSERT_EQUALS("[test.cpp:5]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable y\n", errout_str());
}
}

Expand All @@ -2258,6 +2262,7 @@ class TestSimplifyTokens : public TestFixture {
void simplifyKnownVariables56() { // ticket #5301 - >>
ASSERT_EQUALS("void f ( ) { int a ; a = 0 ; int b ; b = 0 ; * p >> a >> b ; return a / b ; }",
tokenizeAndStringify("void f() { int a=0,b=0; *p>>a>>b; return a/b; }", true));
ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str());
}

void simplifyKnownVariables58() { // #5268
Expand Down Expand Up @@ -2337,7 +2342,7 @@ class TestSimplifyTokens : public TestFixture {
"return i ;\n"
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
ASSERT_EQUALS("", filter_valueflow(errout_str()));
ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", filter_valueflow(errout_str()));
}

void simplifyKnownVariablesBailOutAssign2() {
Expand All @@ -2351,6 +2356,7 @@ class TestSimplifyTokens : public TestFixture {
"nr = ( last = list . prev ) . nr ;\n"
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable nr\n", errout_str());
}

void simplifyKnownVariablesBailOutFor1() {
Expand Down Expand Up @@ -2411,7 +2417,7 @@ class TestSimplifyTokens : public TestFixture {
" return a;\n"
"}\n";
tokenizeAndStringify(code,true);
ASSERT_EQUALS("", filter_valueflow(errout_str())); // no debug warnings
ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", filter_valueflow(errout_str())); // no debug warnings
}

void simplifyKnownVariablesBailOutSwitchBreak() {
Expand Down
2 changes: 1 addition & 1 deletion test/testsimplifytypedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion test/testsimplifyusing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<std::string, const int*>> {\n" // #12521
Expand Down Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/testsymboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit ef68c5d

Please sign in to comment.