Add experimental option --performance-valueflow-max-time=T

This commit is contained in:
Daniel Marjamäki 2022-10-04 14:02:55 +02:00
parent 6c11e2a4ee
commit 8686997292
4 changed files with 70 additions and 28 deletions

View File

@ -567,6 +567,11 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
else if (std::strncmp(argv[i], "--output-file=", 14) == 0) else if (std::strncmp(argv[i], "--output-file=", 14) == 0)
mSettings->outputFile = Path::simplifyPath(Path::fromNativeSeparators(argv[i] + 14)); mSettings->outputFile = Path::simplifyPath(Path::fromNativeSeparators(argv[i] + 14));
// Experimental: limit execution time for extended valueflow analysis. basic valueflow analysis
// is always executed.
else if (std::strncmp(argv[i], "--performance-valueflow-max-time=", 33) == 0)
mSettings->performanceValueFlowMaxTime = std::atoi(argv[i] + 33);
// Specify platform // Specify platform
else if (std::strncmp(argv[i], "--platform=", 11) == 0) { else if (std::strncmp(argv[i], "--platform=", 11) == 0) {
const std::string platform(11+argv[i]); const std::string platform(11+argv[i]);

View File

@ -60,6 +60,7 @@ Settings::Settings()
maxConfigs(12), maxConfigs(12),
maxCtuDepth(2), maxCtuDepth(2),
maxTemplateRecursion(100), maxTemplateRecursion(100),
performanceValueFlowMaxTime(-1),
preprocessOnly(false), preprocessOnly(false),
quiet(false), quiet(false),
relativePaths(false), relativePaths(false),

View File

@ -234,6 +234,9 @@ public:
/** @brief write results (--output-file=<file>) */ /** @brief write results (--output-file=<file>) */
std::string outputFile; std::string outputFile;
/** @brief Experimental: --performance-valueflow-max-time=T */
int performanceValueFlowMaxTime;
/** @brief plist output (--plist-output=<dir>) */ /** @brief plist output (--plist-output=<dir>) */
std::string plistOutput; std::string plistOutput;

View File

@ -107,6 +107,7 @@
#include <climits> #include <climits>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <ctime>
#include <exception> #include <exception>
#include <functional> #include <functional>
#include <initializer_list> #include <initializer_list>
@ -8880,43 +8881,75 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase,
valueFlowSameExpressions(tokenlist); valueFlowSameExpressions(tokenlist);
valueFlowConditionExpressions(tokenlist, symboldatabase, errorLogger, settings); valueFlowConditionExpressions(tokenlist, symboldatabase, errorLogger, settings);
const std::time_t stopTime = (settings->performanceValueFlowMaxTime >= 0) ? (std::time(nullptr) + settings->performanceValueFlowMaxTime) : (~0ULL/2);
std::size_t values = 0; std::size_t values = 0;
std::size_t n = 4; std::size_t n = 4;
while (n > 0 && values != getTotalValues(tokenlist)) { while (n > 0 && values != getTotalValues(tokenlist)) {
values = getTotalValues(tokenlist); values = getTotalValues(tokenlist);
if (std::time(nullptr) < stopTime)
valueFlowImpossibleValues(tokenlist, settings); valueFlowImpossibleValues(tokenlist, settings);
if (std::time(nullptr) < stopTime)
valueFlowSymbolicOperators(tokenlist, symboldatabase); valueFlowSymbolicOperators(tokenlist, symboldatabase);
if (std::time(nullptr) < stopTime)
valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings); valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowSymbolicInfer(tokenlist, symboldatabase); valueFlowSymbolicInfer(tokenlist, symboldatabase);
if (std::time(nullptr) < stopTime)
valueFlowArrayBool(tokenlist); valueFlowArrayBool(tokenlist);
if (std::time(nullptr) < stopTime)
valueFlowArrayElement(tokenlist, settings); valueFlowArrayElement(tokenlist, settings);
if (std::time(nullptr) < stopTime)
valueFlowRightShift(tokenlist, settings); valueFlowRightShift(tokenlist, settings);
if (std::time(nullptr) < stopTime)
valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings); valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings); valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings); valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowInferCondition(tokenlist, settings); valueFlowInferCondition(tokenlist, settings);
if (std::time(nullptr) < stopTime)
valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings); valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings); valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings); valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowFunctionReturn(tokenlist, errorLogger); valueFlowFunctionReturn(tokenlist, errorLogger);
if (std::time(nullptr) < stopTime)
valueFlowLifetime(tokenlist, symboldatabase, errorLogger, settings); valueFlowLifetime(tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowFunctionDefaultParameter(tokenlist, symboldatabase); valueFlowFunctionDefaultParameter(tokenlist, symboldatabase);
if (std::time(nullptr) < stopTime)
valueFlowUninit(tokenlist, symboldatabase, settings); valueFlowUninit(tokenlist, symboldatabase, settings);
if (tokenlist->isCPP()) { if (tokenlist->isCPP()) {
if (std::time(nullptr) < stopTime)
valueFlowAfterMove(tokenlist, symboldatabase, settings); valueFlowAfterMove(tokenlist, symboldatabase, settings);
if (std::time(nullptr) < stopTime)
valueFlowSmartPointer(tokenlist, errorLogger, settings); valueFlowSmartPointer(tokenlist, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowIterators(tokenlist, settings); valueFlowIterators(tokenlist, settings);
if (std::time(nullptr) < stopTime)
valueFlowCondition(IteratorConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings); valueFlowCondition(IteratorConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowIteratorInfer(tokenlist, settings); valueFlowIteratorInfer(tokenlist, settings);
if (std::time(nullptr) < stopTime)
valueFlowContainerSize(tokenlist, symboldatabase, errorLogger, settings); valueFlowContainerSize(tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime)
valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings); valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings);
} }
if (std::time(nullptr) < stopTime)
valueFlowSafeFunctions(tokenlist, symboldatabase, settings); valueFlowSafeFunctions(tokenlist, symboldatabase, settings);
n--; n--;
} }
if (std::time(nullptr) < stopTime)
valueFlowDynamicBufferSize(tokenlist, symboldatabase, settings); valueFlowDynamicBufferSize(tokenlist, symboldatabase, settings);
if (std::time(nullptr) < stopTime)
valueFlowDebug(tokenlist, errorLogger); valueFlowDebug(tokenlist, errorLogger);
} }