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)
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
else if (std::strncmp(argv[i], "--platform=", 11) == 0) {
const std::string platform(11+argv[i]);

View File

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

View File

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

View File

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