added command-line option `--valueflow-max-iterations` to control amount of valueflow iterations / also log debug warning when iterations are being exceeded (#4557)
This commit is contained in:
parent
3c68b9b29f
commit
b380fd2589
|
@ -915,6 +915,21 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (std::strncmp(argv[i], "--valueflow-max-iterations=", 27) == 0) {
|
||||||
|
long tmp;
|
||||||
|
try {
|
||||||
|
tmp = std::stol(argv[i] + 27);
|
||||||
|
} catch (const std::invalid_argument &) {
|
||||||
|
printError("argument to '--valueflow-max-iteration' is invalid.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (tmp < 0) {
|
||||||
|
printError("argument to '--valueflow-max-iteration' needs to be at least 0.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mSettings->valueFlowMaxIterations = static_cast<std::size_t>(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
else if (std::strcmp(argv[i], "-v") == 0 || std::strcmp(argv[i], "--verbose") == 0)
|
else if (std::strcmp(argv[i], "-v") == 0 || std::strcmp(argv[i], "--verbose") == 0)
|
||||||
mSettings->verbose = true;
|
mSettings->verbose = true;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ Settings::Settings()
|
||||||
relativePaths(false),
|
relativePaths(false),
|
||||||
reportProgress(false),
|
reportProgress(false),
|
||||||
showtime(SHOWTIME_MODES::SHOWTIME_NONE),
|
showtime(SHOWTIME_MODES::SHOWTIME_NONE),
|
||||||
|
valueFlowMaxIterations(4),
|
||||||
verbose(false),
|
verbose(false),
|
||||||
xml(false),
|
xml(false),
|
||||||
xml_version(2)
|
xml_version(2)
|
||||||
|
|
|
@ -351,6 +351,9 @@ public:
|
||||||
/** @brief forced includes given by the user */
|
/** @brief forced includes given by the user */
|
||||||
std::list<std::string> userIncludes;
|
std::list<std::string> userIncludes;
|
||||||
|
|
||||||
|
/** @brief the maximum iterations of valueflow (--valueflow-max-iterations=T) */
|
||||||
|
std::size_t valueFlowMaxIterations;
|
||||||
|
|
||||||
/** @brief Is --verbose given? */
|
/** @brief Is --verbose given? */
|
||||||
bool verbose;
|
bool verbose;
|
||||||
|
|
||||||
|
|
|
@ -8986,7 +8986,7 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase,
|
||||||
const std::uint64_t stopTime = getValueFlowStopTime(settings);
|
const std::uint64_t stopTime = getValueFlowStopTime(settings);
|
||||||
|
|
||||||
std::size_t values = 0;
|
std::size_t values = 0;
|
||||||
std::size_t n = 4;
|
std::size_t n = settings->valueFlowMaxIterations;
|
||||||
while (n > 0 && values != getTotalValues(tokenlist)) {
|
while (n > 0 && values != getTotalValues(tokenlist)) {
|
||||||
values = getTotalValues(tokenlist);
|
values = getTotalValues(tokenlist);
|
||||||
|
|
||||||
|
@ -9048,6 +9048,18 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase,
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings->debugwarnings) {
|
||||||
|
if (n == 0 && values != getTotalValues(tokenlist)) {
|
||||||
|
ErrorMessage errmsg({},
|
||||||
|
emptyString,
|
||||||
|
Severity::debug,
|
||||||
|
"ValueFlow maximum iterations exceeded",
|
||||||
|
"valueFlowMaxIterations",
|
||||||
|
Certainty::normal);
|
||||||
|
errorLogger->reportErr(errmsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (std::time(nullptr) < stopTime)
|
if (std::time(nullptr) < stopTime)
|
||||||
valueFlowDynamicBufferSize(tokenlist, symboldatabase, settings);
|
valueFlowDynamicBufferSize(tokenlist, symboldatabase, settings);
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,11 @@ private:
|
||||||
TEST_CASE(clang);
|
TEST_CASE(clang);
|
||||||
TEST_CASE(clang2);
|
TEST_CASE(clang2);
|
||||||
TEST_CASE(clangInvalid);
|
TEST_CASE(clangInvalid);
|
||||||
|
TEST_CASE(valueFlowMaxIterations);
|
||||||
|
TEST_CASE(valueFlowMaxIterations2);
|
||||||
|
TEST_CASE(valueFlowMaxIterationsInvalid);
|
||||||
|
TEST_CASE(valueFlowMaxIterationsInvalid2);
|
||||||
|
TEST_CASE(valueFlowMaxIterationsInvalid3);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// Disabling these tests since they use relative paths to the
|
// Disabling these tests since they use relative paths to the
|
||||||
|
@ -1260,6 +1265,45 @@ private:
|
||||||
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--clang-foo\".\n", GET_REDIRECT_OUTPUT);
|
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--clang-foo\".\n", GET_REDIRECT_OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void valueFlowMaxIterations() {
|
||||||
|
REDIRECT;
|
||||||
|
const char * const argv[] = {"cppcheck", "--valueflow-max-iterations=0"};
|
||||||
|
settings.valueFlowMaxIterations = -1;
|
||||||
|
ASSERT(defParser.parseFromArgs(2, argv));
|
||||||
|
ASSERT_EQUALS(0, settings.valueFlowMaxIterations);
|
||||||
|
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void valueFlowMaxIterations2() {
|
||||||
|
REDIRECT;
|
||||||
|
const char * const argv[] = {"cppcheck", "--valueflow-max-iterations=11"};
|
||||||
|
settings.valueFlowMaxIterations = -1;
|
||||||
|
ASSERT(defParser.parseFromArgs(2, argv));
|
||||||
|
ASSERT_EQUALS(11, settings.valueFlowMaxIterations);
|
||||||
|
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void valueFlowMaxIterationsInvalid() {
|
||||||
|
REDIRECT;
|
||||||
|
const char * const argv[] = {"cppcheck", "--valueflow-max-iterations"};
|
||||||
|
ASSERT(!defParser.parseFromArgs(2, argv));
|
||||||
|
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--valueflow-max-iterations\".\n", GET_REDIRECT_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void valueFlowMaxIterationsInvalid2() {
|
||||||
|
REDIRECT;
|
||||||
|
const char * const argv[] = {"cppcheck", "--valueflow-max-iterations=seven"};
|
||||||
|
ASSERT(!defParser.parseFromArgs(2, argv));
|
||||||
|
ASSERT_EQUALS("cppcheck: error: argument to '--valueflow-max-iteration' is invalid.\n", GET_REDIRECT_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void valueFlowMaxIterationsInvalid3() {
|
||||||
|
REDIRECT;
|
||||||
|
const char * const argv[] = {"cppcheck", "--valueflow-max-iterations=-1"};
|
||||||
|
ASSERT(!defParser.parseFromArgs(2, argv));
|
||||||
|
ASSERT_EQUALS("cppcheck: error: argument to '--valueflow-max-iteration' needs to be at least 0.\n", GET_REDIRECT_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void ignorepaths1() {
|
void ignorepaths1() {
|
||||||
REDIRECT;
|
REDIRECT;
|
||||||
|
|
Loading…
Reference in New Issue