diff --git a/lib/token.h b/lib/token.h index fada7d4296ca..402fdd147d28 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1162,6 +1162,8 @@ class CPPCHECKLIB Token { } const std::list& values() const { + if (mTokensFrontBack && !mTokensFrontBack->list->isValuesSet()) + mTokensFrontBack->list->setValues(); return mImpl->mValues ? *mImpl->mValues : TokenImpl::mEmptyValueList; } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index dfa282b8e888..9bd2b549c082 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2796,6 +2796,7 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration) createSymbolDatabase(); } + // TODO: this accesses ValueFlow information before it has been generated if (mTimerResults) { Timer t("Tokenizer::simplifyTokens1::setValueType", mSettings->showtime, mTimerResults); mSymbolDatabase->setValueTypeInTokenList(true); @@ -2819,11 +2820,7 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration) } } - // TODO: do not run valueflow if no checks are being performed at all - e.g. unusedFunctions only - const char* disableValueflowEnv = std::getenv("DISABLE_VALUEFLOW"); - const bool doValueFlow = !disableValueflowEnv || (std::strcmp(disableValueflowEnv, "1") != 0); - - if (doValueFlow) { + auto setValues = [&](){ if (mTimerResults) { Timer t("Tokenizer::simplifyTokens1::ValueFlow", mSettings->showtime, mTimerResults); ValueFlow::setValues(&list, mSymbolDatabase, mErrorLogger, mSettings); @@ -2832,6 +2829,15 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration) } mSymbolDatabase->setArrayDimensionsUsingValueFlow(); + }; + + const char* disableValueflowEnv = std::getenv("DISABLE_VALUEFLOW"); + const bool doLazyValueFlow = disableValueflowEnv && (std::strcmp(disableValueflowEnv, "2") == 0); + const bool doValueFlow = !disableValueflowEnv || (std::strcmp(disableValueflowEnv, "1") != 0); + if (doLazyValueFlow) { + list.setValuesFunc(std::move(setValues)); + } else if (doValueFlow) { + setValues(); } printDebugOutput(1); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index b632085eef3d..f6cce4dd1e21 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -49,7 +49,9 @@ TokenList::TokenList(const Settings* settings) : mTokensFrontBack(), mSettings(settings), mIsC(false), - mIsCpp(false) + mIsCpp(false), + mValuesSet(false), + mInSetValues(false) { mTokensFrontBack.list = this; mKeywords.insert("asm"); diff --git a/lib/tokenlist.h b/lib/tokenlist.h index 695160ed99ca..3a9cda6b721e 100644 --- a/lib/tokenlist.h +++ b/lib/tokenlist.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -207,6 +208,23 @@ class CPPCHECKLIB TokenList { bool isKeyword(const std::string &str) const; + void setValuesFunc(std::function f) { + mValuesFunc = std::move(f); + } + + void setValues() const { + if (!mInSetValues && !mValuesSet && mValuesFunc) { + mInSetValues = true; + mValuesFunc(); + mValuesSet = true; + mInSetValues = false; + } + } + + bool isValuesSet() const { + return mValuesSet; + } + private: void determineCppC(); @@ -227,6 +245,10 @@ class CPPCHECKLIB TokenList { /** File is known to be C/C++ code */ bool mIsC; bool mIsCpp; + + std::function mValuesFunc; + mutable bool mValuesSet; + mutable bool mInSetValues; }; /// @}