From 22bfe509a438953b09c701c68b3824aeb92d458f Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 5 Nov 2024 09:41:31 -0600 Subject: [PATCH 01/13] Revert --- Makefile | 6 +- lib/cppcheck.vcxproj | 2 - lib/lib.pri | 204 +++++++++++++++++++++++++++++++++ lib/valueflow.cpp | 231 ++++++++++++++++++++++++++++++++++++- lib/vf_analyze.h | 1 - lib/vf_common.cpp | 24 ---- lib/vf_common.h | 6 - lib/vf_subfunction.cpp | 254 ----------------------------------------- lib/vf_subfunction.h | 32 ------ oss-fuzz/Makefile | 6 +- 10 files changed, 436 insertions(+), 330 deletions(-) create mode 100644 lib/lib.pri delete mode 100644 lib/vf_subfunction.cpp delete mode 100644 lib/vf_subfunction.h diff --git a/Makefile b/Makefile index 3fac13f0872..7c2acd1e7bd 100644 --- a/Makefile +++ b/Makefile @@ -278,7 +278,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_sameexpressions.o \ $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vf_string.o \ - $(libcppdir)/vf_subfunction.o \ $(libcppdir)/vf_switchvariable.o \ $(libcppdir)/vf_symbolicinfer.o \ $(libcppdir)/vf_symbolicoperators.o \ @@ -483,7 +482,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_conditionexpressions.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_reverse.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_subfunction.h lib/vf_switchvariable.h lib/vf_symbolicinfer.h lib/vf_symbolicoperators.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_conditionexpressions.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_reverse.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_switchvariable.h lib/vf_symbolicinfer.h lib/vf_symbolicoperators.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h @@ -747,9 +746,6 @@ $(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/as $(libcppdir)/vf_string.o: lib/vf_string.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_settokenvalue.h lib/vf_string.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_string.cpp -$(libcppdir)/vf_subfunction.o: lib/vf_subfunction.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vf_analyzers.h lib/vf_bailout.h lib/vf_common.h lib/vf_settokenvalue.h lib/vf_subfunction.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_subfunction.cpp - $(libcppdir)/vf_switchvariable.o: lib/vf_switchvariable.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_bailout.h lib/vf_reverse.h lib/vf_switchvariable.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_switchvariable.cpp diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index bff6f8ef7c7..e599da4e8f0 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -113,7 +113,6 @@ - @@ -225,7 +224,6 @@ - diff --git a/lib/lib.pri b/lib/lib.pri new file mode 100644 index 00000000000..1331bd4735a --- /dev/null +++ b/lib/lib.pri @@ -0,0 +1,204 @@ +# no manual edits - this file is autogenerated by dmake + +include($$PWD/pcrerules.pri) +include($$PWD/../externals/externals.pri) +INCLUDEPATH += $$PWD +HEADERS += $${PWD}/addoninfo.h \ + $${PWD}/analyzer.h \ + $${PWD}/analyzerinfo.h \ + $${PWD}/astutils.h \ + $${PWD}/calculate.h \ + $${PWD}/check.h \ + $${PWD}/check64bit.h \ + $${PWD}/checkassert.h \ + $${PWD}/checkautovariables.h \ + $${PWD}/checkbool.h \ + $${PWD}/checkboost.h \ + $${PWD}/checkbufferoverrun.h \ + $${PWD}/checkclass.h \ + $${PWD}/checkcondition.h \ + $${PWD}/checkers.h \ + $${PWD}/checkersreport.h \ + $${PWD}/checkexceptionsafety.h \ + $${PWD}/checkfunctions.h \ + $${PWD}/checkinternal.h \ + $${PWD}/checkio.h \ + $${PWD}/checkleakautovar.h \ + $${PWD}/checkmemoryleak.h \ + $${PWD}/checknullpointer.h \ + $${PWD}/checkother.h \ + $${PWD}/checkpostfixoperator.h \ + $${PWD}/checksizeof.h \ + $${PWD}/checkstl.h \ + $${PWD}/checkstring.h \ + $${PWD}/checktype.h \ + $${PWD}/checkuninitvar.h \ + $${PWD}/checkunusedfunctions.h \ + $${PWD}/checkunusedvar.h \ + $${PWD}/checkvaarg.h \ + $${PWD}/clangimport.h \ + $${PWD}/color.h \ + $${PWD}/config.h \ + $${PWD}/cppcheck.h \ + $${PWD}/ctu.h \ + $${PWD}/errorlogger.h \ + $${PWD}/errortypes.h \ + $${PWD}/filesettings.h \ + $${PWD}/findtoken.h \ + $${PWD}/forwardanalyzer.h \ + $${PWD}/fwdanalysis.h \ + $${PWD}/importproject.h \ + $${PWD}/infer.h \ + $${PWD}/json.h \ + $${PWD}/keywords.h \ + $${PWD}/library.h \ + $${PWD}/matchcompiler.h \ + $${PWD}/mathlib.h \ + $${PWD}/path.h \ + $${PWD}/pathanalysis.h \ + $${PWD}/pathmatch.h \ + $${PWD}/platform.h \ + $${PWD}/precompiled.h \ + $${PWD}/preprocessor.h \ + $${PWD}/programmemory.h \ + $${PWD}/reverseanalyzer.h \ + $${PWD}/settings.h \ + $${PWD}/smallvector.h \ + $${PWD}/sourcelocation.h \ + $${PWD}/standards.h \ + $${PWD}/summaries.h \ + $${PWD}/suppressions.h \ + $${PWD}/symboldatabase.h \ + $${PWD}/templatesimplifier.h \ + $${PWD}/timer.h \ + $${PWD}/token.h \ + $${PWD}/tokenize.h \ + $${PWD}/tokenlist.h \ + $${PWD}/tokenrange.h \ + $${PWD}/utils.h \ + $${PWD}/valueflow.h \ + $${PWD}/valueptr.h \ + $${PWD}/version.h \ + $${PWD}/vf_analyze.h \ + $${PWD}/vf_analyzers.h \ + $${PWD}/vf_array.h \ + $${PWD}/vf_arraybool.h \ + $${PWD}/vf_arrayelement.h \ + $${PWD}/vf_bailout.h \ + $${PWD}/vf_bitand.h \ + $${PWD}/vf_common.h \ + $${PWD}/vf_conditionexpressions.h \ + $${PWD}/vf_debug.h \ + $${PWD}/vf_enumvalue.h \ + $${PWD}/vf_functionreturn.h \ + $${PWD}/vf_globalconstvar.h \ + $${PWD}/vf_globalstaticvar.h \ + $${PWD}/vf_impossiblevalues.h \ + $${PWD}/vf_infercondition.h \ + $${PWD}/vf_iteratorinfer.h \ + $${PWD}/vf_iterators.h \ + $${PWD}/vf_number.h \ + $${PWD}/vf_pointeralias.h \ + $${PWD}/vf_reverse.h \ + $${PWD}/vf_rightshift.h \ + $${PWD}/vf_sameexpressions.h \ + $${PWD}/vf_settokenvalue.h \ + $${PWD}/vf_string.h \ + $${PWD}/vf_switchvariable.h \ + $${PWD}/vf_symbolicinfer.h \ + $${PWD}/vf_symbolicoperators.h \ + $${PWD}/vf_unknownfunctionreturn.h \ + $${PWD}/vfvalue.h \ + $${PWD}/xml.h + +SOURCES += $${PWD}/valueflow.cpp \ + $${PWD}/tokenize.cpp \ + $${PWD}/symboldatabase.cpp \ + $${PWD}/addoninfo.cpp \ + $${PWD}/analyzerinfo.cpp \ + $${PWD}/astutils.cpp \ + $${PWD}/check.cpp \ + $${PWD}/check64bit.cpp \ + $${PWD}/checkassert.cpp \ + $${PWD}/checkautovariables.cpp \ + $${PWD}/checkbool.cpp \ + $${PWD}/checkboost.cpp \ + $${PWD}/checkbufferoverrun.cpp \ + $${PWD}/checkclass.cpp \ + $${PWD}/checkcondition.cpp \ + $${PWD}/checkers.cpp \ + $${PWD}/checkersreport.cpp \ + $${PWD}/checkexceptionsafety.cpp \ + $${PWD}/checkfunctions.cpp \ + $${PWD}/checkinternal.cpp \ + $${PWD}/checkio.cpp \ + $${PWD}/checkleakautovar.cpp \ + $${PWD}/checkmemoryleak.cpp \ + $${PWD}/checknullpointer.cpp \ + $${PWD}/checkother.cpp \ + $${PWD}/checkpostfixoperator.cpp \ + $${PWD}/checksizeof.cpp \ + $${PWD}/checkstl.cpp \ + $${PWD}/checkstring.cpp \ + $${PWD}/checktype.cpp \ + $${PWD}/checkuninitvar.cpp \ + $${PWD}/checkunusedfunctions.cpp \ + $${PWD}/checkunusedvar.cpp \ + $${PWD}/checkvaarg.cpp \ + $${PWD}/clangimport.cpp \ + $${PWD}/color.cpp \ + $${PWD}/cppcheck.cpp \ + $${PWD}/ctu.cpp \ + $${PWD}/errorlogger.cpp \ + $${PWD}/errortypes.cpp \ + $${PWD}/forwardanalyzer.cpp \ + $${PWD}/fwdanalysis.cpp \ + $${PWD}/importproject.cpp \ + $${PWD}/infer.cpp \ + $${PWD}/keywords.cpp \ + $${PWD}/library.cpp \ + $${PWD}/mathlib.cpp \ + $${PWD}/path.cpp \ + $${PWD}/pathanalysis.cpp \ + $${PWD}/pathmatch.cpp \ + $${PWD}/platform.cpp \ + $${PWD}/preprocessor.cpp \ + $${PWD}/programmemory.cpp \ + $${PWD}/reverseanalyzer.cpp \ + $${PWD}/settings.cpp \ + $${PWD}/summaries.cpp \ + $${PWD}/suppressions.cpp \ + $${PWD}/templatesimplifier.cpp \ + $${PWD}/timer.cpp \ + $${PWD}/token.cpp \ + $${PWD}/tokenlist.cpp \ + $${PWD}/utils.cpp \ + $${PWD}/vf_analyzers.cpp \ + $${PWD}/vf_array.cpp \ + $${PWD}/vf_arraybool.cpp \ + $${PWD}/vf_arrayelement.cpp \ + $${PWD}/vf_bailout.cpp \ + $${PWD}/vf_bitand.cpp \ + $${PWD}/vf_common.cpp \ + $${PWD}/vf_conditionexpressions.cpp \ + $${PWD}/vf_debug.cpp \ + $${PWD}/vf_enumvalue.cpp \ + $${PWD}/vf_functionreturn.cpp \ + $${PWD}/vf_globalconstvar.cpp \ + $${PWD}/vf_globalstaticvar.cpp \ + $${PWD}/vf_impossiblevalues.cpp \ + $${PWD}/vf_infercondition.cpp \ + $${PWD}/vf_iteratorinfer.cpp \ + $${PWD}/vf_iterators.cpp \ + $${PWD}/vf_number.cpp \ + $${PWD}/vf_pointeralias.cpp \ + $${PWD}/vf_reverse.cpp \ + $${PWD}/vf_rightshift.cpp \ + $${PWD}/vf_sameexpressions.cpp \ + $${PWD}/vf_settokenvalue.cpp \ + $${PWD}/vf_string.cpp \ + $${PWD}/vf_switchvariable.cpp \ + $${PWD}/vf_symbolicinfer.cpp \ + $${PWD}/vf_symbolicoperators.cpp \ + $${PWD}/vf_unknownfunctionreturn.cpp \ + $${PWD}/vfvalue.cpp diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index b5d928d28a9..4d07cc069a5 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -79,6 +79,7 @@ #include "analyzer.h" #include "astutils.h" +#include "checkuninitvar.h" #include "config.h" #include "errorlogger.h" #include "errortypes.h" @@ -128,6 +129,30 @@ #include #include +static void changeKnownToPossible(std::list &values, int indirect=-1) +{ + for (ValueFlow::Value& v: values) { + if (indirect >= 0 && v.indirect != indirect) + continue; + v.changeKnownToPossible(); + } +} + +static void removeImpossible(std::list& values, int indirect = -1) +{ + values.remove_if([&](const ValueFlow::Value& v) { + if (indirect >= 0 && v.indirect != indirect) + return false; + return v.isImpossible(); + }); +} + +static void lowerToPossible(std::list& values, int indirect = -1) +{ + changeKnownToPossible(values, indirect); + removeImpossible(values, indirect); +} + static void changePossibleToKnown(std::list& values, int indirect = -1) { for (ValueFlow::Value& v : values) { @@ -4056,6 +4081,85 @@ static void valueFlowForLoop(TokenList &tokenlist, const SymbolDatabase& symbold } } +template +static bool productParams(const Settings& settings, const std::unordered_map>& vars, F f) +{ + using Args = std::vector>; + Args args(1); + // Compute cartesian product of all arguments + for (const auto& p:vars) { + if (p.second.empty()) + continue; + args.back()[p.first] = p.second.front(); + } + bool bail = false; + int max = settings.vfOptions.maxSubFunctionArgs; + for (const auto& p:vars) { + if (args.size() > max) { + bail = true; + break; + } + if (p.second.empty()) + continue; + std::for_each(std::next(p.second.begin()), p.second.end(), [&](const ValueFlow::Value& value) { + Args new_args; + for (auto arg:args) { + if (value.path != 0) { + for (const auto& q:arg) { + if (q.first == p.first) + continue; + if (q.second.path == 0) + continue; + if (q.second.path != value.path) + return; + } + } + arg[p.first] = value; + new_args.push_back(std::move(arg)); + } + std::copy(new_args.cbegin(), new_args.cend(), std::back_inserter(args)); + }); + } + + if (args.size() > max) { + bail = true; + args.resize(max); + // TODO: add bailout message + } + + for (const auto& arg:args) { + if (arg.empty()) + continue; + // Make sure all arguments are the same path + const MathLib::bigint path = arg.cbegin()->second.path; + if (std::any_of(arg.cbegin(), arg.cend(), [&](const std::pair& p) { + return p.second.path != path; + })) + continue; + f(arg); + } + return !bail; +} + +static void valueFlowInjectParameter(const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + const Scope* functionScope, + const std::unordered_map>& vars) +{ + const bool r = productParams(settings, vars, [&](const std::unordered_map& arg) { + auto a = makeMultiValueFlowAnalyzer(arg, settings); + valueFlowGenericForward(const_cast(functionScope->bodyStart), functionScope->bodyEnd, a, tokenlist, errorLogger, settings); + }); + if (!r) { + std::string fname = ""; + if (const Function* f = functionScope->function) + fname = f->name(); + if (settings.debugwarnings) + bailout(tokenlist, errorLogger, functionScope->bodyStart, "Too many argument passed to " + fname); + } +} + static void valueFlowInjectParameter(const TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings, @@ -4081,6 +4185,131 @@ static void valueFlowInjectParameter(const TokenList& tokenlist, settings); } +static std::list getFunctionArgumentValues(const Token *argtok) +{ + std::list argvalues(argtok->values()); + removeImpossible(argvalues); + if (argvalues.empty() && Token::Match(argtok, "%comp%|%oror%|&&|!")) { + argvalues.emplace_back(0); + argvalues.emplace_back(1); + } + return argvalues; +} + +static void valueFlowLibraryFunction(Token *tok, const std::string &returnValue, const Settings &settings) +{ + std::unordered_map> argValues; + int argn = 1; + for (const Token *argtok : getArguments(tok->previous())) { + argValues[argn] = getFunctionArgumentValues(argtok); + argn++; + } + if (returnValue.find("arg") != std::string::npos && argValues.empty()) + return; + productParams(settings, argValues, [&](const std::unordered_map& arg) { + ValueFlow::Value value = evaluateLibraryFunction(arg, returnValue, settings, tok->isCpp()); + if (value.isUninitValue()) + return; + ValueFlow::Value::ValueKind kind = ValueFlow::Value::ValueKind::Known; + for (auto&& p : arg) { + if (p.second.isPossible()) + kind = p.second.valueKind; + if (p.second.isInconclusive()) { + kind = p.second.valueKind; + break; + } + } + if (value.isImpossible() && kind != ValueFlow::Value::ValueKind::Known) + return; + if (!value.isImpossible()) + value.valueKind = kind; + setTokenValue(tok, std::move(value), settings); + }); +} + +static void valueFlowSubFunction(const TokenList& tokenlist, SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, const Settings& settings) +{ + int id = 0; + for (auto it = symboldatabase.functionScopes.crbegin(); it != symboldatabase.functionScopes.crend(); ++it) { + const Scope* scope = *it; + const Function* function = scope->function; + if (!function) + continue; + for (auto* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { + if (tok->isKeyword() || !Token::Match(tok, "%name% (")) + continue; + + const Function * const calledFunction = tok->function(); + if (!calledFunction) { + // library function? + const std::string& returnValue(settings.library.returnValue(tok)); + if (!returnValue.empty()) + valueFlowLibraryFunction(tok->next(), returnValue, settings); + continue; + } + + const Scope * const calledFunctionScope = calledFunction->functionScope; + if (!calledFunctionScope) + continue; + + id++; + std::unordered_map> argvars; + // TODO: Rewrite this. It does not work well to inject 1 argument at a time. + const std::vector &callArguments = getArguments(tok); + for (int argnr = 0U; argnr < callArguments.size(); ++argnr) { + const Token *argtok = callArguments[argnr]; + // Get function argument + const Variable * const argvar = calledFunction->getArgumentVar(argnr); + if (!argvar) + break; + + // passing value(s) to function + std::list argvalues(getFunctionArgumentValues(argtok)); + + // Remove non-local lifetimes + argvalues.remove_if([](const ValueFlow::Value& v) { + if (v.isLifetimeValue()) + return !v.isLocalLifetimeValue() && !v.isSubFunctionLifetimeValue(); + return false; + }); + // Remove uninit values if argument is passed by value + if (argtok->variable() && !argtok->variable()->isPointer() && argvalues.size() == 1 && argvalues.front().isUninitValue()) { + if (CheckUninitVar::isVariableUsage(argtok, settings.library, false, CheckUninitVar::Alloc::NO_ALLOC, 0)) + continue; + } + + if (argvalues.empty()) + continue; + + // Error path.. + for (ValueFlow::Value &v : argvalues) { + const std::string nr = std::to_string(argnr + 1) + getOrdinalText(argnr + 1); + + v.errorPath.emplace_back(argtok, + "Calling function '" + + calledFunction->name() + + "', " + + nr + + " argument '" + + argtok->expressionString() + + "' value is " + + v.infoString()); + v.path = 256 * v.path + id % 256; + // Change scope of lifetime values + if (v.isLifetimeValue()) + v.lifetimeScope = ValueFlow::Value::LifetimeScope::SubFunction; + } + + // passed values are not "known".. + lowerToPossible(argvalues); + + argvars[argvar] = std::move(argvalues); + } + valueFlowInjectParameter(tokenlist, errorLogger, settings, calledFunctionScope, argvars); + } + } +} + static void valueFlowFunctionDefaultParameter(const TokenList& tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, const Settings& settings) { if (!tokenlist.isCPP()) @@ -5459,7 +5688,7 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(analyzeInferCondition(tokenlist, settings)), VFA(analyzeSwitchVariable(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings)), - VFA(analyzeSubFunction(tokenlist, symboldatabase, errorLogger, settings)), + VFA(valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings)), VFA(analyzeFunctionReturn(tokenlist, errorLogger, settings)), VFA(valueFlowLifetime(tokenlist, errorLogger, settings)), VFA(valueFlowFunctionDefaultParameter(tokenlist, symboldatabase, errorLogger, settings)), diff --git a/lib/vf_analyze.h b/lib/vf_analyze.h index 7d9f0ff0b89..6a1263294bb 100644 --- a/lib/vf_analyze.h +++ b/lib/vf_analyze.h @@ -38,7 +38,6 @@ #include "vf_rightshift.h" // IWYU pragma: export #include "vf_sameexpressions.h" // IWYU pragma: export #include "vf_string.h" // IWYU pragma: export -#include "vf_subfunction.h" // IWYU pragma: export #include "vf_switchvariable.h" // IWYU pragma: export #include "vf_symbolicinfer.h" // IWYU pragma: export #include "vf_symbolicoperators.h" // IWYU pragma: export diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index bfe9824c406..cfc2b981712 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -454,28 +454,4 @@ namespace ValueFlow value.intvalue = delta; return value; } - - void removeImpossible(std::list& values, int indirect) - { - values.remove_if([&](const Value& v) { - if (indirect >= 0 && v.indirect != indirect) - return false; - return v.isImpossible(); - }); - } - - void changeKnownToPossible(std::list &values, int indirect) - { - for (Value& v: values) { - if (indirect >= 0 && v.indirect != indirect) - continue; - v.changeKnownToPossible(); - } - } - - void lowerToPossible(std::list& values, int indirect) - { - changeKnownToPossible(values, indirect); - removeImpossible(values, indirect); - } } diff --git a/lib/vf_common.h b/lib/vf_common.h index 21d1d8eeabb..6600e167a80 100644 --- a/lib/vf_common.h +++ b/lib/vf_common.h @@ -63,12 +63,6 @@ namespace ValueFlow void setSymbolic(Value& value, const Token* tok); Value makeSymbolic(const Token* tok, MathLib::bigint delta = 0); - - void removeImpossible(std::list& values, int indirect = -1); - - void changeKnownToPossible(std::list &values, int indirect=-1); - - void lowerToPossible(std::list& values, int indirect = -1); } #endif // vfCommonH diff --git a/lib/vf_subfunction.cpp b/lib/vf_subfunction.cpp deleted file mode 100644 index bfb8ffb5fbe..00000000000 --- a/lib/vf_subfunction.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_subfunction.h" - -#include "astutils.h" -#include "config.h" -#include "forwardanalyzer.h" -#include "library.h" -#include "mathlib.h" -#include "programmemory.h" -#include "settings.h" -#include "symboldatabase.h" -#include "token.h" -#include "utils.h" -#include "valueptr.h" -#include "vfvalue.h" - -#include "vf_analyzers.h" -#include "vf_bailout.h" -#include "vf_common.h" -#include "vf_settokenvalue.h" - -#include "checkuninitvar.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace ValueFlow -{ - static std::list getFunctionArgumentValues(const Token *argtok) - { - std::list argvalues(argtok->values()); - removeImpossible(argvalues); - if (argvalues.empty() && Token::Match(argtok, "%comp%|%oror%|&&|!")) { - argvalues.emplace_back(0); - argvalues.emplace_back(1); - } - return argvalues; - } - - template - static bool productParams(const Settings& settings, const std::unordered_map>& vars, F f) - { - using Args = std::vector>; - Args args(1); - // Compute cartesian product of all arguments - for (const auto& p:vars) { - if (p.second.empty()) - continue; - args.back()[p.first] = p.second.front(); - } - bool bail = false; - int max = settings.vfOptions.maxSubFunctionArgs; - for (const auto& p:vars) { - if (args.size() > max) { - bail = true; - break; - } - if (p.second.empty()) - continue; - std::for_each(std::next(p.second.begin()), p.second.end(), [&](const Value& value) { - Args new_args; - for (auto arg:args) { - if (value.path != 0) { - for (const auto& q:arg) { - if (q.first == p.first) - continue; - if (q.second.path == 0) - continue; - if (q.second.path != value.path) - return; - } - } - arg[p.first] = value; - new_args.push_back(std::move(arg)); - } - std::copy(new_args.cbegin(), new_args.cend(), std::back_inserter(args)); - }); - } - - if (args.size() > max) { - bail = true; - args.resize(max); - // TODO: add bailout message - } - - for (const auto& arg:args) { - if (arg.empty()) - continue; - // Make sure all arguments are the same path - const MathLib::bigint path = arg.cbegin()->second.path; - if (std::any_of(arg.cbegin(), arg.cend(), [&](const std::pair& p) { - return p.second.path != path; - })) - continue; - f(arg); - } - return !bail; - } - - static void valueFlowLibraryFunction(Token *tok, const std::string &returnValue, const Settings &settings) - { - std::unordered_map> argValues; - int argn = 1; - for (const Token *argtok : getArguments(tok->previous())) { - argValues[argn] = getFunctionArgumentValues(argtok); - argn++; - } - if (returnValue.find("arg") != std::string::npos && argValues.empty()) - return; - productParams(settings, argValues, [&](const std::unordered_map& arg) { - Value value = evaluateLibraryFunction(arg, returnValue, settings, tok->isCpp()); - if (value.isUninitValue()) - return; - Value::ValueKind kind = Value::ValueKind::Known; - for (auto&& p : arg) { - if (p.second.isPossible()) - kind = p.second.valueKind; - if (p.second.isInconclusive()) { - kind = p.second.valueKind; - break; - } - } - if (value.isImpossible() && kind != Value::ValueKind::Known) - return; - if (!value.isImpossible()) - value.valueKind = kind; - setTokenValue(tok, std::move(value), settings); - }); - } - - static void valueFlowInjectParameter(const TokenList& tokenlist, - ErrorLogger& errorLogger, - const Settings& settings, - const Scope* functionScope, - const std::unordered_map>& vars) - { - const bool r = productParams(settings, vars, [&](const std::unordered_map& arg) { - auto a = makeMultiValueFlowAnalyzer(arg, settings); - valueFlowGenericForward(const_cast(functionScope->bodyStart), functionScope->bodyEnd, a, tokenlist, errorLogger, settings); - }); - if (!r) { - std::string fname = ""; - if (const Function* f = functionScope->function) - fname = f->name(); - if (settings.debugwarnings) - bailout(tokenlist, errorLogger, functionScope->bodyStart, "Too many argument passed to " + fname); - } - } - - void analyzeSubFunction(const TokenList& tokenlist, SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, const Settings& settings) - { - int id = 0; - for (auto it = symboldatabase.functionScopes.crbegin(); it != symboldatabase.functionScopes.crend(); ++it) { - const Scope* scope = *it; - const Function* function = scope->function; - if (!function) - continue; - for (auto* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { - if (tok->isKeyword() || !Token::Match(tok, "%name% (")) - continue; - - const Function * const calledFunction = tok->function(); - if (!calledFunction) { - // library function? - const std::string& returnValue(settings.library.returnValue(tok)); - if (!returnValue.empty()) - valueFlowLibraryFunction(tok->next(), returnValue, settings); - continue; - } - - const Scope * const calledFunctionScope = calledFunction->functionScope; - if (!calledFunctionScope) - continue; - - id++; - std::unordered_map> argvars; - // TODO: Rewrite this. It does not work well to inject 1 argument at a time. - const std::vector &callArguments = getArguments(tok); - for (int argnr = 0U; argnr < callArguments.size(); ++argnr) { - const Token *argtok = callArguments[argnr]; - // Get function argument - const Variable * const argvar = calledFunction->getArgumentVar(argnr); - if (!argvar) - break; - - // passing value(s) to function - std::list argvalues(getFunctionArgumentValues(argtok)); - - // Remove non-local lifetimes - argvalues.remove_if([](const Value& v) { - if (v.isLifetimeValue()) - return !v.isLocalLifetimeValue() && !v.isSubFunctionLifetimeValue(); - return false; - }); - // Remove uninit values if argument is passed by value - if (argtok->variable() && !argtok->variable()->isPointer() && argvalues.size() == 1 && argvalues.front().isUninitValue()) { - if (CheckUninitVar::isVariableUsage(argtok, settings.library, false, CheckUninitVar::Alloc::NO_ALLOC, 0)) - continue; - } - - if (argvalues.empty()) - continue; - - // Error path.. - for (Value &v : argvalues) { - const std::string nr = std::to_string(argnr + 1) + getOrdinalText(argnr + 1); - - v.errorPath.emplace_back(argtok, - "Calling function '" + - calledFunction->name() + - "', " + - nr + - " argument '" + - argtok->expressionString() + - "' value is " + - v.infoString()); - v.path = 256 * v.path + id % 256; - // Change scope of lifetime values - if (v.isLifetimeValue()) - v.lifetimeScope = Value::LifetimeScope::SubFunction; - } - - // passed values are not "known".. - lowerToPossible(argvalues); - - argvars[argvar] = std::move(argvalues); - } - valueFlowInjectParameter(tokenlist, errorLogger, settings, calledFunctionScope, argvars); - } - } - } -} diff --git a/lib/vf_subfunction.h b/lib/vf_subfunction.h deleted file mode 100644 index 8f12d22d20d..00000000000 --- a/lib/vf_subfunction.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfSubFunctionH -#define vfSubFunctionH - -class TokenList; -class SymbolDatabase; -class ErrorLogger; -class Settings; - -namespace ValueFlow -{ - void analyzeSubFunction(const TokenList& tokenlist, SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, const Settings& settings); -} - -#endif // vfSubFunctionH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index b133b839651..58f3e46c467 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -121,7 +121,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_sameexpressions.o \ $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vf_string.o \ - $(libcppdir)/vf_subfunction.o \ $(libcppdir)/vf_switchvariable.o \ $(libcppdir)/vf_symbolicinfer.o \ $(libcppdir)/vf_symbolicoperators.o \ @@ -170,7 +169,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_conditionexpressions.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_reverse.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_subfunction.h ../lib/vf_switchvariable.h ../lib/vf_symbolicinfer.h ../lib/vf_symbolicoperators.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_conditionexpressions.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_reverse.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_switchvariable.h ../lib/vf_symbolicinfer.h ../lib/vf_symbolicoperators.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h @@ -434,9 +433,6 @@ $(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/addoninfo.h $(libcppdir)/vf_string.o: ../lib/vf_string.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_string.cpp -$(libcppdir)/vf_subfunction.o: ../lib/vf_subfunction.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_bailout.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vf_subfunction.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_subfunction.cpp - $(libcppdir)/vf_switchvariable.o: ../lib/vf_switchvariable.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_bailout.h ../lib/vf_reverse.h ../lib/vf_switchvariable.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_switchvariable.cpp From 0998cc0ca6418ab0b11a606f9837aad61c357baf Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 5 Nov 2024 09:41:40 -0600 Subject: [PATCH 02/13] Revert "ValueFlow: extracted `valueFlowSymbolicOperators()` into separate file (#6845)" This reverts commit 66d53a2fbdab59f893e1b70d04e578b4499d95f1. --- Makefile | 8 +- lib/astutils.cpp | 2 +- lib/cppcheck.vcxproj | 2 - lib/infer.cpp | 35 +------ lib/infer.h | 5 - lib/lib.pri | 2 - lib/programmemory.cpp | 4 +- lib/valueflow.cpp | 177 ++++++++++++++++++++++++++++++++++- lib/valueflow.h | 6 ++ lib/vf_analyze.h | 1 - lib/vf_common.cpp | 17 ---- lib/vf_common.h | 4 - lib/vf_symbolicoperators.cpp | 162 -------------------------------- lib/vf_symbolicoperators.h | 30 ------ oss-fuzz/Makefile | 8 +- 15 files changed, 188 insertions(+), 275 deletions(-) delete mode 100644 lib/vf_symbolicoperators.cpp delete mode 100644 lib/vf_symbolicoperators.h diff --git a/Makefile b/Makefile index 7c2acd1e7bd..a56f2706c9f 100644 --- a/Makefile +++ b/Makefile @@ -280,7 +280,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_string.o \ $(libcppdir)/vf_switchvariable.o \ $(libcppdir)/vf_symbolicinfer.o \ - $(libcppdir)/vf_symbolicoperators.o \ $(libcppdir)/vf_unknownfunctionreturn.o \ $(libcppdir)/vfvalue.o @@ -482,7 +481,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_conditionexpressions.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_reverse.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_switchvariable.h lib/vf_symbolicinfer.h lib/vf_symbolicoperators.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_conditionexpressions.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_reverse.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_switchvariable.h lib/vf_symbolicinfer.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h @@ -614,7 +613,7 @@ $(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/addoninfo.h lib/astutils.h l $(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/config.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp -$(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/infer.cpp $(libcppdir)/keywords.o: lib/keywords.cpp lib/config.h lib/keywords.h lib/standards.h lib/utils.h @@ -752,9 +751,6 @@ $(libcppdir)/vf_switchvariable.o: lib/vf_switchvariable.cpp lib/addoninfo.h lib/ $(libcppdir)/vf_symbolicinfer.o: lib/vf_symbolicinfer.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vf_settokenvalue.h lib/vf_symbolicinfer.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_symbolicinfer.cpp -$(libcppdir)/vf_symbolicoperators.o: lib/vf_symbolicoperators.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vf_symbolicoperators.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_symbolicoperators.cpp - $(libcppdir)/vf_unknownfunctionreturn.o: lib/vf_unknownfunctionreturn.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_unknownfunctionreturn.cpp diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 4fae5b39b79..6ad90614437 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -959,7 +959,7 @@ bool extractForLoopValues(const Token *forToken, const Token *incExpr = forToken->next()->astOperand2()->astOperand2()->astOperand2(); if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%")) return false; - std::vector minInitValue = getMinValue(makeIntegralInferModel(), initExpr->astOperand2()->values()); + std::vector minInitValue = getMinValue(ValueFlow::makeIntegralInferModel(), initExpr->astOperand2()->values()); if (minInitValue.empty()) { const ValueFlow::Value* v = initExpr->astOperand2()->getMinValue(true); if (v) diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index e599da4e8f0..b960cb009c7 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -115,7 +115,6 @@ - @@ -226,7 +225,6 @@ - diff --git a/lib/infer.cpp b/lib/infer.cpp index c5c578c9773..c49931bdade 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -20,7 +20,6 @@ #include "calculate.h" #include "errortypes.h" -#include "token.h" #include "valueptr.h" #include @@ -30,6 +29,8 @@ #include #include +class Token; + template static const ValueFlow::Value* getCompareValue(const std::list& values, Predicate pred, Compare compare) { @@ -387,35 +388,3 @@ std::vector getMaxValue(const ValuePtr& model, cons return model->match(v); }).maxvalue; } - -namespace { - struct IntegralInferModel : InferModel { - bool match(const ValueFlow::Value& value) const override { - return value.isIntValue(); - } - ValueFlow::Value yield(MathLib::bigint value) const override - { - ValueFlow::Value result(value); - result.valueType = ValueFlow::Value::ValueType::INT; - result.setKnown(); - return result; - } - }; -} - -ValuePtr makeIntegralInferModel() -{ - return IntegralInferModel{}; -} - -ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val) -{ - if (!varTok) - return ValueFlow::Value{}; - if (varTok->hasKnownIntValue()) - return ValueFlow::Value{}; - std::vector r = infer(makeIntegralInferModel(), op, varTok->values(), val); - if (r.size() == 1 && r.front().isKnown()) - return r.front(); - return ValueFlow::Value{}; -} diff --git a/lib/infer.h b/lib/infer.h index ed21d48a6c4..047dfe66b13 100644 --- a/lib/infer.h +++ b/lib/infer.h @@ -27,7 +27,6 @@ #include #include -class Token; template class ValuePtr; struct InferModel { @@ -57,8 +56,4 @@ std::vector infer(const ValuePtr& model, CPPCHECKLIB std::vector getMinValue(const ValuePtr& model, const std::list& values); std::vector getMaxValue(const ValuePtr& model, const std::list& values); -ValuePtr makeIntegralInferModel(); - -ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val); - #endif diff --git a/lib/lib.pri b/lib/lib.pri index 1331bd4735a..45ec38bad10 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -106,7 +106,6 @@ HEADERS += $${PWD}/addoninfo.h \ $${PWD}/vf_string.h \ $${PWD}/vf_switchvariable.h \ $${PWD}/vf_symbolicinfer.h \ - $${PWD}/vf_symbolicoperators.h \ $${PWD}/vf_unknownfunctionreturn.h \ $${PWD}/vfvalue.h \ $${PWD}/xml.h @@ -199,6 +198,5 @@ SOURCES += $${PWD}/valueflow.cpp \ $${PWD}/vf_string.cpp \ $${PWD}/vf_switchvariable.cpp \ $${PWD}/vf_symbolicinfer.cpp \ - $${PWD}/vf_symbolicoperators.cpp \ $${PWD}/vf_unknownfunctionreturn.cpp \ $${PWD}/vfvalue.cpp diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index e5781ad2d03..95fce1bb958 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1526,13 +1526,13 @@ namespace { if (expr->isComparisonOp() && (r.isUninitValue() || r.isImpossible())) { if (rhs.isIntValue() && !expr->astOperand1()->values().empty()) { std::vector result = - infer(makeIntegralInferModel(), expr->str(), expr->astOperand1()->values(), {std::move(rhs)}); + infer(ValueFlow::makeIntegralInferModel(), expr->str(), expr->astOperand1()->values(), {std::move(rhs)}); if (!result.empty() && result.front().isKnown()) return std::move(result.front()); } if (lhs.isIntValue() && !expr->astOperand2()->values().empty()) { std::vector result = - infer(makeIntegralInferModel(), expr->str(), {std::move(lhs)}, expr->astOperand2()->values()); + infer(ValueFlow::makeIntegralInferModel(), expr->str(), {std::move(lhs)}, expr->astOperand2()->values()); if (!result.empty() && result.front().isKnown()) return std::move(result.front()); } diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 4d07cc069a5..fc78c45c004 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2487,6 +2487,22 @@ static bool isTruncated(const ValueType* src, const ValueType* dst, const Settin return false; } +static void setSymbolic(ValueFlow::Value& value, const Token* tok) +{ + assert(tok && tok->exprId() > 0 && "Missing expr id for symbolic value"); + value.valueType = ValueFlow::Value::ValueType::SYMBOLIC; + value.tokvalue = tok; +} + +static ValueFlow::Value makeSymbolic(const Token* tok, MathLib::bigint delta = 0) +{ + ValueFlow::Value value; + value.setKnown(); + setSymbolic(value, tok); + value.intvalue = delta; + return value; +} + static std::set getVarIds(const Token* tok) { std::set result; @@ -2546,13 +2562,13 @@ static void valueFlowSymbolic(const TokenList& tokenlist, const SymbolDatabase& Token* start = nextAfterAstRightmostLeaf(tok); const Token* end = ValueFlow::getEndOfExprScope(tok->astOperand1(), scope); - ValueFlow::Value rhs = ValueFlow::makeSymbolic(tok->astOperand2()); + ValueFlow::Value rhs = makeSymbolic(tok->astOperand2()); rhs.errorPath.emplace_back(tok, tok->astOperand1()->expressionString() + " is assigned '" + tok->astOperand2()->expressionString() + "' here."); valueFlowForward(start, end, tok->astOperand1(), std::move(rhs), tokenlist, errorLogger, settings); - ValueFlow::Value lhs = ValueFlow::makeSymbolic(tok->astOperand1()); + ValueFlow::Value lhs = makeSymbolic(tok->astOperand1()); lhs.errorPath.emplace_back(tok, tok->astOperand1()->expressionString() + " is assigned '" + tok->astOperand2()->expressionString() + "' here."); @@ -2561,6 +2577,130 @@ static void valueFlowSymbolic(const TokenList& tokenlist, const SymbolDatabase& } } +static const Token* isStrlenOf(const Token* tok, const Token* expr, int depth = 10) +{ + if (depth < 0) + return nullptr; + if (!tok) + return nullptr; + if (!expr) + return nullptr; + if (expr->exprId() == 0) + return nullptr; + if (Token::simpleMatch(tok->previous(), "strlen (")) { + if (tok->astOperand2()->exprId() == expr->exprId()) + return tok; + } else { + for (const ValueFlow::Value& v : tok->values()) { + if (!v.isSymbolicValue()) + continue; + if (!v.isKnown()) + continue; + if (v.intvalue != 0) + continue; + if (const Token* next = isStrlenOf(v.tokvalue, expr, depth - 1)) + return next; + } + } + return nullptr; +} + +static ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val); + +static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, const Settings& settings) +{ + for (const Scope* scope : symboldatabase.functionScopes) { + for (auto* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { + if (tok->hasKnownIntValue()) + continue; + + if (Token::Match(tok, "abs|labs|llabs|fabs|fabsf|fabsl (")) { + const Token* arg = tok->next()->astOperand2(); + if (!arg) + continue; + if (arg->exprId() == 0) + continue; + ValueFlow::Value c = inferCondition(">=", arg, 0); + if (!c.isKnown()) + continue; + + ValueFlow::Value v = makeSymbolic(arg); + v.errorPath = c.errorPath; + v.errorPath.emplace_back(tok, "Passed to " + tok->str()); + if (c.intvalue == 0) + v.setImpossible(); + else + v.setKnown(); + setTokenValue(tok->next(), std::move(v), settings); + } else if (Token::Match(tok, "*|/|<<|>>|^|+|-|%or%")) { + if (!tok->astOperand1()) + continue; + if (!tok->astOperand2()) + continue; + if (!astIsIntegral(tok->astOperand1(), false) && !astIsIntegral(tok->astOperand2(), false)) + continue; + const ValueFlow::Value* constant = nullptr; + const Token* vartok = nullptr; + if (tok->astOperand1()->hasKnownIntValue()) { + constant = &tok->astOperand1()->values().front(); + vartok = tok->astOperand2(); + } + if (tok->astOperand2()->hasKnownIntValue()) { + constant = &tok->astOperand2()->values().front(); + vartok = tok->astOperand1(); + } + if (!constant) + continue; + if (!vartok) + continue; + if (vartok->exprId() == 0) + continue; + if (Token::Match(tok, "<<|>>|/") && !astIsLHS(vartok)) + continue; + if (Token::Match(tok, "<<|>>|^|+|-|%or%") && constant->intvalue != 0) + continue; + if (Token::Match(tok, "*|/") && constant->intvalue != 1) + continue; + std::vector values = {makeSymbolic(vartok)}; + std::unordered_set ids = {vartok->exprId()}; + std::copy_if(vartok->values().cbegin(), + vartok->values().cend(), + std::back_inserter(values), + [&](const ValueFlow::Value& v) { + if (!v.isSymbolicValue()) + return false; + if (!v.tokvalue) + return false; + return ids.insert(v.tokvalue->exprId()).second; + }); + for (ValueFlow::Value& v : values) + setTokenValue(tok, std::move(v), settings); + } else if (Token::simpleMatch(tok, "[")) { + const Token* arrayTok = tok->astOperand1(); + const Token* indexTok = tok->astOperand2(); + if (!arrayTok) + continue; + if (!indexTok) + continue; + for (const ValueFlow::Value& value : indexTok->values()) { + if (!value.isSymbolicValue()) + continue; + if (value.intvalue != 0) + continue; + const Token* strlenTok = isStrlenOf(value.tokvalue, arrayTok); + if (!strlenTok) + continue; + ValueFlow::Value v = value; + v.bound = ValueFlow::Value::Bound::Point; + v.valueType = ValueFlow::Value::ValueType::INT; + v.errorPath.emplace_back(strlenTok, "Return index of first '\\0' character in string"); + setTokenValue(tok, std::move(v), settings); + } + } + } + } +} + template static void valueFlowForwardConst(Token* start, const Token* end, @@ -3752,6 +3892,35 @@ struct SimpleConditionHandler : ConditionHandler { } }; +struct IntegralInferModel : InferModel { + bool match(const ValueFlow::Value& value) const override { + return value.isIntValue(); + } + ValueFlow::Value yield(MathLib::bigint value) const override + { + ValueFlow::Value result(value); + result.valueType = ValueFlow::Value::ValueType::INT; + result.setKnown(); + return result; + } +}; + +ValuePtr ValueFlow::makeIntegralInferModel() { + return IntegralInferModel{}; +} + +static ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val) +{ + if (!varTok) + return ValueFlow::Value{}; + if (varTok->hasKnownIntValue()) + return ValueFlow::Value{}; + std::vector r = infer(ValueFlow::makeIntegralInferModel(), op, varTok->values(), val); + if (r.size() == 1 && r.front().isKnown()) + return r.front(); + return ValueFlow::Value{}; +} + struct SymbolicConditionHandler : SimpleConditionHandler { static bool isNegatedBool(const Token* tok) @@ -4786,7 +4955,7 @@ static void valueFlowSmartPointer(TokenList &tokenlist, ErrorLogger & errorLogge v.setKnown(); valueFlowForwardAssign(ftok, tok, std::move(vars), {std::move(v)}, false, tokenlist, errorLogger, settings); } else if (Token::simpleMatch(tok->astParent(), ". get ( )")) { - ValueFlow::Value v = ValueFlow::makeSymbolic(tok); + ValueFlow::Value v = makeSymbolic(tok); setTokenValue(tok->astParent()->tokAt(2), std::move(v), settings); } } else if (Token::Match(tok->previous(), "%name%|> (|{") && astIsSmartPointer(tok) && @@ -5675,7 +5844,7 @@ void ValueFlow::setValues(TokenList& tokenlist, runner.run({ VFA(analyzeImpossibleValues(tokenlist, settings)), - VFA(analyzeSymbolicOperators(symboldatabase, settings)), + VFA(valueFlowSymbolicOperators(symboldatabase, settings)), VFA(valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA(valueFlowSymbolicInfer(symboldatabase, settings)), VFA(analyzeArrayBool(tokenlist, settings)), diff --git a/lib/valueflow.h b/lib/valueflow.h index 924f29dbfca..ba88e12106e 100644 --- a/lib/valueflow.h +++ b/lib/valueflow.h @@ -34,6 +34,7 @@ #include class ErrorLogger; +struct InferModel; class Settings; class SymbolDatabase; class TimerResultsIntf; @@ -43,6 +44,9 @@ class ValueType; class Variable; class Scope; +template +class ValuePtr; + namespace ValueFlow { /// Constant folding of expression. This can be used before the full ValueFlow has been executed (ValueFlow::setValues). const Value * valueFlowConstantFoldAST(Token *expr, const Settings &settings); @@ -100,6 +104,8 @@ namespace ValueFlow { const Token *parseCompareInt(const Token *tok, Value &true_value, Value &false_value, const std::function(const Token*)>& evaluate); const Token *parseCompareInt(const Token *tok, Value &true_value, Value &false_value); + CPPCHECKLIB ValuePtr makeIntegralInferModel(); + const Token* solveExprValue(const Token* expr, const std::function(const Token*)>& eval, Value& value); diff --git a/lib/vf_analyze.h b/lib/vf_analyze.h index 6a1263294bb..19bf76d01c4 100644 --- a/lib/vf_analyze.h +++ b/lib/vf_analyze.h @@ -40,7 +40,6 @@ #include "vf_string.h" // IWYU pragma: export #include "vf_switchvariable.h" // IWYU pragma: export #include "vf_symbolicinfer.h" // IWYU pragma: export -#include "vf_symbolicoperators.h" // IWYU pragma: export #include "vf_unknownfunctionreturn.h" // IWYU pragma: export #endif // vfAnalyzeH diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index cfc2b981712..93016be7d99 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -31,7 +31,6 @@ #include "vf_settokenvalue.h" -#include #include #include #include @@ -438,20 +437,4 @@ namespace ValueFlow scope = scope->nestedIn; return scope; } - - void setSymbolic(Value& value, const Token* tok) - { - assert(tok && tok->exprId() > 0 && "Missing expr id for symbolic value"); - value.valueType = Value::ValueType::SYMBOLIC; - value.tokvalue = tok; - } - - Value makeSymbolic(const Token* tok, MathLib::bigint delta) - { - Value value; - value.setKnown(); - setSymbolic(value, tok); - value.intvalue = delta; - return value; - } } diff --git a/lib/vf_common.h b/lib/vf_common.h index 6600e167a80..f542b51a527 100644 --- a/lib/vf_common.h +++ b/lib/vf_common.h @@ -59,10 +59,6 @@ namespace ValueFlow bool isBreakOrContinueScope(const Token* endToken); const Scope* getLoopScope(const Token* tok); - - void setSymbolic(Value& value, const Token* tok); - - Value makeSymbolic(const Token* tok, MathLib::bigint delta = 0); } #endif // vfCommonH diff --git a/lib/vf_symbolicoperators.cpp b/lib/vf_symbolicoperators.cpp deleted file mode 100644 index 54a6fce1ea8..00000000000 --- a/lib/vf_symbolicoperators.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_symbolicoperators.h" - -#include "astutils.h" -#include "config.h" -#include "infer.h" -#include "symboldatabase.h" -#include "token.h" -#include "vfvalue.h" - -#include "vf_common.h" -#include "vf_settokenvalue.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace ValueFlow -{ - static const Token* isStrlenOf(const Token* tok, const Token* expr, int depth = 10) - { - if (depth < 0) - return nullptr; - if (!tok) - return nullptr; - if (!expr) - return nullptr; - if (expr->exprId() == 0) - return nullptr; - if (Token::simpleMatch(tok->previous(), "strlen (")) { - if (tok->astOperand2()->exprId() == expr->exprId()) - return tok; - } else { - for (const Value& v : tok->values()) { - if (!v.isSymbolicValue()) - continue; - if (!v.isKnown()) - continue; - if (v.intvalue != 0) - continue; - if (const Token* next = isStrlenOf(v.tokvalue, expr, depth - 1)) - return next; - } - } - return nullptr; - } - - void analyzeSymbolicOperators(const SymbolDatabase& symboldatabase, const Settings& settings) - { - for (const Scope* scope : symboldatabase.functionScopes) { - for (auto* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { - if (tok->hasKnownIntValue()) - continue; - - if (Token::Match(tok, "abs|labs|llabs|fabs|fabsf|fabsl (")) { - const Token* arg = tok->next()->astOperand2(); - if (!arg) - continue; - if (arg->exprId() == 0) - continue; - Value c = inferCondition(">=", arg, 0); - if (!c.isKnown()) - continue; - - Value v = makeSymbolic(arg); - v.errorPath = c.errorPath; - v.errorPath.emplace_back(tok, "Passed to " + tok->str()); - if (c.intvalue == 0) - v.setImpossible(); - else - v.setKnown(); - setTokenValue(tok->next(), std::move(v), settings); - } else if (Token::Match(tok, "*|/|<<|>>|^|+|-|%or%")) { - if (!tok->astOperand1()) - continue; - if (!tok->astOperand2()) - continue; - if (!astIsIntegral(tok->astOperand1(), false) && !astIsIntegral(tok->astOperand2(), false)) - continue; - const Value* constant = nullptr; - const Token* vartok = nullptr; - if (tok->astOperand1()->hasKnownIntValue()) { - constant = &tok->astOperand1()->values().front(); - vartok = tok->astOperand2(); - } - if (tok->astOperand2()->hasKnownIntValue()) { - constant = &tok->astOperand2()->values().front(); - vartok = tok->astOperand1(); - } - if (!constant) - continue; - if (!vartok) - continue; - if (vartok->exprId() == 0) - continue; - if (Token::Match(tok, "<<|>>|/") && !astIsLHS(vartok)) - continue; - if (Token::Match(tok, "<<|>>|^|+|-|%or%") && constant->intvalue != 0) - continue; - if (Token::Match(tok, "*|/") && constant->intvalue != 1) - continue; - std::vector values = {makeSymbolic(vartok)}; - std::unordered_set ids = {vartok->exprId()}; - std::copy_if(vartok->values().cbegin(), - vartok->values().cend(), - std::back_inserter(values), - [&](const Value& v) { - if (!v.isSymbolicValue()) - return false; - if (!v.tokvalue) - return false; - return ids.insert(v.tokvalue->exprId()).second; - }); - for (Value& v : values) - setTokenValue(tok, std::move(v), settings); - } else if (Token::simpleMatch(tok, "[")) { - const Token* arrayTok = tok->astOperand1(); - const Token* indexTok = tok->astOperand2(); - if (!arrayTok) - continue; - if (!indexTok) - continue; - for (const Value& value : indexTok->values()) { - if (!value.isSymbolicValue()) - continue; - if (value.intvalue != 0) - continue; - const Token* strlenTok = isStrlenOf(value.tokvalue, arrayTok); - if (!strlenTok) - continue; - Value v = value; - v.bound = Value::Bound::Point; - v.valueType = Value::ValueType::INT; - v.errorPath.emplace_back(strlenTok, "Return index of first '\\0' character in string"); - setTokenValue(tok, std::move(v), settings); - } - } - } - } - } -} diff --git a/lib/vf_symbolicoperators.h b/lib/vf_symbolicoperators.h deleted file mode 100644 index 624f2d160da..00000000000 --- a/lib/vf_symbolicoperators.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfSymbolicOperatorsH -#define vfSymbolicOperatorsH - -class SymbolDatabase; -class Settings; - -namespace ValueFlow -{ - void analyzeSymbolicOperators(const SymbolDatabase& symboldatabase, const Settings& settings); -} - -#endif // vfSymbolicOperatorsH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 58f3e46c467..2184553571c 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -123,7 +123,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_string.o \ $(libcppdir)/vf_switchvariable.o \ $(libcppdir)/vf_symbolicinfer.o \ - $(libcppdir)/vf_symbolicoperators.o \ $(libcppdir)/vf_unknownfunctionreturn.o \ $(libcppdir)/vfvalue.o @@ -169,7 +168,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_conditionexpressions.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_reverse.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_switchvariable.h ../lib/vf_symbolicinfer.h ../lib/vf_symbolicoperators.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_conditionexpressions.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_reverse.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_switchvariable.h ../lib/vf_symbolicinfer.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h @@ -301,7 +300,7 @@ $(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/addoninfo.h ../lib/ast $(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp -$(libcppdir)/infer.o: ../lib/infer.cpp ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/mathlib.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/infer.o: ../lib/infer.cpp ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/mathlib.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/infer.cpp $(libcppdir)/keywords.o: ../lib/keywords.cpp ../lib/config.h ../lib/keywords.h ../lib/standards.h ../lib/utils.h @@ -439,9 +438,6 @@ $(libcppdir)/vf_switchvariable.o: ../lib/vf_switchvariable.cpp ../lib/addoninfo. $(libcppdir)/vf_symbolicinfer.o: ../lib/vf_symbolicinfer.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vf_settokenvalue.h ../lib/vf_symbolicinfer.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_symbolicinfer.cpp -$(libcppdir)/vf_symbolicoperators.o: ../lib/vf_symbolicoperators.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vf_symbolicoperators.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_symbolicoperators.cpp - $(libcppdir)/vf_unknownfunctionreturn.o: ../lib/vf_unknownfunctionreturn.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_unknownfunctionreturn.cpp From adbab1628c741d0ad335ae7534b68c8f78e1b271 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 5 Nov 2024 09:43:55 -0600 Subject: [PATCH 03/13] Revert --- Makefile | 6 +- lib/cppcheck.vcxproj | 2 - lib/lib.pri | 2 - lib/valueflow.cpp | 181 +++++++++++++++++++++++++++- lib/vf_analyze.h | 1 - lib/vf_common.cpp | 17 --- lib/vf_common.h | 4 - lib/vf_conditionexpressions.cpp | 203 -------------------------------- lib/vf_conditionexpressions.h | 32 ----- oss-fuzz/Makefile | 6 +- test/testsimplifytokens.cpp | 20 ++-- test/testsimplifytypedef.cpp | 4 +- test/testsimplifyusing.cpp | 2 +- test/testsymboldatabase.cpp | 2 +- test/testtokenize.cpp | 60 +++++----- test/testvalueflow.cpp | 20 ++-- 16 files changed, 234 insertions(+), 328 deletions(-) delete mode 100644 lib/vf_conditionexpressions.cpp delete mode 100644 lib/vf_conditionexpressions.h diff --git a/Makefile b/Makefile index a56f2706c9f..42741572c22 100644 --- a/Makefile +++ b/Makefile @@ -261,7 +261,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_bailout.o \ $(libcppdir)/vf_bitand.o \ $(libcppdir)/vf_common.o \ - $(libcppdir)/vf_conditionexpressions.o \ $(libcppdir)/vf_debug.o \ $(libcppdir)/vf_enumvalue.o \ $(libcppdir)/vf_functionreturn.o \ @@ -481,7 +480,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_conditionexpressions.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_reverse.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_switchvariable.h lib/vf_symbolicinfer.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_reverse.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_switchvariable.h lib/vf_symbolicinfer.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h @@ -694,9 +693,6 @@ $(libcppdir)/vf_bitand.o: lib/vf_bitand.cpp lib/config.h lib/errortypes.h lib/ma $(libcppdir)/vf_common.o: lib/vf_common.cpp lib/addoninfo.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_conditionexpressions.o: lib/vf_conditionexpressions.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vf_analyzers.h lib/vf_bailout.h lib/vf_common.h lib/vf_conditionexpressions.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_conditionexpressions.cpp - $(libcppdir)/vf_debug.o: lib/vf_debug.cpp lib/addoninfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_debug.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_debug.cpp diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index b960cb009c7..a740cada61d 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -96,7 +96,6 @@ - @@ -206,7 +205,6 @@ - diff --git a/lib/lib.pri b/lib/lib.pri index 45ec38bad10..2edc3d8ff00 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -87,7 +87,6 @@ HEADERS += $${PWD}/addoninfo.h \ $${PWD}/vf_bailout.h \ $${PWD}/vf_bitand.h \ $${PWD}/vf_common.h \ - $${PWD}/vf_conditionexpressions.h \ $${PWD}/vf_debug.h \ $${PWD}/vf_enumvalue.h \ $${PWD}/vf_functionreturn.h \ @@ -179,7 +178,6 @@ SOURCES += $${PWD}/valueflow.cpp \ $${PWD}/vf_bailout.cpp \ $${PWD}/vf_bitand.cpp \ $${PWD}/vf_common.cpp \ - $${PWD}/vf_conditionexpressions.cpp \ $${PWD}/vf_debug.cpp \ $${PWD}/vf_enumvalue.cpp \ $${PWD}/vf_functionreturn.cpp \ diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index fc78c45c004..2fcf8174fc6 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -335,6 +335,20 @@ const Token *ValueFlow::parseCompareInt(const Token *tok, ValueFlow::Value &true }); } +static bool isEscapeScope(const Token* tok, const Settings& settings, bool unknown = false) +{ + if (!Token::simpleMatch(tok, "{")) + return false; + // TODO this search for termTok in all subscopes. It should check the end of the scope. + const Token * termTok = Token::findmatch(tok, "return|continue|break|throw|goto", tok->link()); + if (termTok && termTok->scope() == tok->scope()) + return true; + std::string unknownFunction; + if (settings.library.isScopeNoReturn(tok->link(), &unknownFunction)) + return unknownFunction.empty() || unknown; + return false; +} + void ValueFlow::combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value &result) { if (value1.isKnown() && value2.isKnown()) @@ -2465,6 +2479,167 @@ static void valueFlowAfterMove(const TokenList& tokenlist, const SymbolDatabase& } } +static const Token* findIncompleteVar(const Token* start, const Token* end) +{ + for (const Token* tok = start; tok != end; tok = tok->next()) { + if (tok->isIncompleteVar()) + return tok; + } + return nullptr; +} + +static ValueFlow::Value makeConditionValue(long long val, + const Token* condTok, + bool assume, + bool impossible, + const Settings& settings, + SourceLocation loc = SourceLocation::current()) +{ + ValueFlow::Value v(val); + v.setKnown(); + if (impossible) { + v.intvalue = !v.intvalue; + v.setImpossible(); + } + v.condition = condTok; + if (assume) + v.errorPath.emplace_back(condTok, "Assuming condition '" + condTok->expressionString() + "' is true"); + else + v.errorPath.emplace_back(condTok, "Assuming condition '" + condTok->expressionString() + "' is false"); + if (settings.debugnormal) + setSourceLocation(v, loc, condTok); + return v; +} + +static std::vector getConditions(const Token* tok, const char* op) +{ + std::vector conds = {tok}; + if (tok->str() == op) { + std::vector args = astFlatten(tok, op); + std::copy_if(args.cbegin(), args.cend(), std::back_inserter(conds), [&](const Token* tok2) { + if (tok2->exprId() == 0) + return false; + if (tok2->hasKnownIntValue()) + return false; + if (Token::Match(tok2, "%var%|.") && !astIsBool(tok2)) + return false; + return true; + }); + } + return conds; +} + +static bool isBreakOrContinueScope(const Token* endToken) +{ + if (!Token::simpleMatch(endToken, "}")) + return false; + return Token::Match(endToken->tokAt(-2), "break|continue ;"); +} + +static const Scope* getLoopScope(const Token* tok) +{ + if (!tok) + return nullptr; + const Scope* scope = tok->scope(); + while (scope && scope->type != Scope::eWhile && scope->type != Scope::eFor && scope->type != Scope::eDo) + scope = scope->nestedIn; + return scope; +} + +// +static void valueFlowConditionExpressions(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings) +{ + if (!settings.daca && !settings.vfOptions.doConditionExpressionAnalysis) + { + if (settings.debugwarnings) { + ErrorMessage::FileLocation loc(tokenlist.getSourceFilePath(), 0, 0); + const ErrorMessage errmsg({std::move(loc)}, tokenlist.getSourceFilePath(), Severity::debug, "Analysis of condition expressions is disabled. Use --check-level=exhaustive to enable it.", "normalCheckLevelConditionExpressions", Certainty::normal); + errorLogger.reportErr(errmsg); + } + return; + } + + for (const Scope * scope : symboldatabase.functionScopes) { + if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) { + if (settings.debugwarnings) + bailoutIncompleteVar(tokenlist, errorLogger, incompleteTok, "Skipping function due to incomplete variable " + incompleteTok->str()); + continue; + } + + if (settings.daca && !settings.vfOptions.doConditionExpressionAnalysis) + continue; + + for (auto* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { + if (!Token::simpleMatch(tok, "if (")) + continue; + Token* parenTok = tok->next(); + if (!Token::simpleMatch(parenTok->link(), ") {")) + continue; + Token * blockTok = parenTok->link()->tokAt(1); + const Token* condTok = parenTok->astOperand2(); + if (condTok->exprId() == 0) + continue; + if (condTok->hasKnownIntValue()) + continue; + if (!isConstExpression(condTok, settings.library)) + continue; + const bool isOp = condTok->isComparisonOp() || condTok->tokType() == Token::eLogicalOp; + const bool is1 = isOp || astIsBool(condTok); + + Token* startTok = blockTok; + // Inner condition + { + for (const Token* condTok2 : getConditions(condTok, "&&")) { + if (is1) { + const bool isBool = astIsBool(condTok2) || Token::Match(condTok2, "%comp%|%oror%|&&"); + auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(1, condTok2, /*assume*/ true, !isBool, settings), settings); // don't set '1' for non-boolean expressions + valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); + } + + auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(0, condTok2, true, false, settings), settings); + valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); + } + } + + std::vector conds = getConditions(condTok, "||"); + + // Check else block + if (Token::simpleMatch(startTok->link(), "} else {")) { + startTok = startTok->link()->tokAt(2); + for (const Token* condTok2:conds) { + auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(0, condTok2, false, false, settings), settings); + valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); + + if (is1) { + auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(isOp, condTok2, false, false, settings), settings); + valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); + } + } + } + + // Check if the block terminates early + if (isEscapeScope(blockTok, settings)) { + const Scope* scope2 = scope; + // If escaping a loop then only use the loop scope + if (isBreakOrContinueScope(blockTok->link())) { + scope2 = getLoopScope(blockTok->link()); + if (!scope2) + continue; + } + for (const Token* condTok2:conds) { + auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(0, condTok2, false, false, settings), settings); + valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a1, tokenlist, errorLogger, settings); + + if (is1) { + auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(1, condTok2, false, false, settings), settings); + valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a2, tokenlist, errorLogger, settings); + } + } + } + } + } +} + static bool isTruncated(const ValueType* src, const ValueType* dst, const Settings& settings) { if (src->pointer > 0 || dst->pointer > 0) @@ -3811,8 +3986,8 @@ struct ConditionHandler { const bool isKnown = std::any_of(values.cbegin(), values.cend(), [&](const ValueFlow::Value& v) { return v.isKnown() || v.isImpossible(); }); - if (isKnown && ValueFlow::isBreakOrContinueScope(after)) { - const Scope* loopScope = ValueFlow::getLoopScope(cond.vartok); + if (isKnown && isBreakOrContinueScope(after)) { + const Scope* loopScope = getLoopScope(cond.vartok); if (loopScope) { Analyzer::Result r = forward(after, loopScope->bodyEnd, cond.vartok, values, tokenlist, errorLogger, settings); if (r.terminate != Analyzer::Terminate::None) @@ -5839,7 +6014,7 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(valueFlowSymbolic(tokenlist, symboldatabase, errorLogger, settings)), VFA(analyzeBitAnd(tokenlist, settings)), VFA(analyzeSameExpressions(tokenlist, settings)), - VFA(analyzeConditionExpressions(tokenlist, symboldatabase, errorLogger, settings)), + VFA(valueFlowConditionExpressions(tokenlist, symboldatabase, errorLogger, settings)), }); runner.run({ diff --git a/lib/vf_analyze.h b/lib/vf_analyze.h index 19bf76d01c4..22458a2b187 100644 --- a/lib/vf_analyze.h +++ b/lib/vf_analyze.h @@ -23,7 +23,6 @@ #include "vf_arraybool.h" // IWYU pragma: export #include "vf_arrayelement.h" // IWYU pragma: export #include "vf_bitand.h" // IWYU pragma: export -#include "vf_conditionexpressions.h" // IWYU pragma: export #include "vf_debug.h" // IWYU pragma: export #include "vf_enumvalue.h" // IWYU pragma: export #include "vf_functionreturn.h" // IWYU pragma: export diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index 93016be7d99..cf6abeff4a7 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -420,21 +420,4 @@ namespace ValueFlow } return 0; } - - bool isBreakOrContinueScope(const Token* endToken) - { - if (!Token::simpleMatch(endToken, "}")) - return false; - return Token::Match(endToken->tokAt(-2), "break|continue ;"); - } - - const Scope* getLoopScope(const Token* tok) - { - if (!tok) - return nullptr; - const Scope* scope = tok->scope(); - while (scope && scope->type != Scope::eWhile && scope->type != Scope::eFor && scope->type != Scope::eDo) - scope = scope->nestedIn; - return scope; - } } diff --git a/lib/vf_common.h b/lib/vf_common.h index f542b51a527..02a395d0e5f 100644 --- a/lib/vf_common.h +++ b/lib/vf_common.h @@ -55,10 +55,6 @@ namespace ValueFlow std::list getIteratorValues(std::list values, const Value::ValueKind* kind = nullptr); MathLib::bigint valueFlowGetStrLength(const Token* tok); - - bool isBreakOrContinueScope(const Token* endToken); - - const Scope* getLoopScope(const Token* tok); } #endif // vfCommonH diff --git a/lib/vf_conditionexpressions.cpp b/lib/vf_conditionexpressions.cpp deleted file mode 100644 index 38aeda46279..00000000000 --- a/lib/vf_conditionexpressions.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_conditionexpressions.h" - -#include "astutils.h" -#include "forwardanalyzer.h" -#include "symboldatabase.h" -#include "errorlogger.h" -#include "errortypes.h" -#include "library.h" -#include "settings.h" -#include "sourcelocation.h" -#include "token.h" -#include "tokenlist.h" -#include "valueptr.h" -#include "vfvalue.h" - -#include "vf_analyzers.h" -#include "vf_bailout.h" -#include "vf_common.h" - -#include -#include -#include -#include -#include -#include - -namespace ValueFlow -{ - static const Token* findIncompleteVar(const Token* start, const Token* end) - { - for (const Token* tok = start; tok != end; tok = tok->next()) { - if (tok->isIncompleteVar()) - return tok; - } - return nullptr; - } - - static std::vector getConditions(const Token* tok, const char* op) - { - std::vector conds = {tok}; - if (tok->str() == op) { - std::vector args = astFlatten(tok, op); - std::copy_if(args.cbegin(), args.cend(), std::back_inserter(conds), [&](const Token* tok2) { - if (tok2->exprId() == 0) - return false; - if (tok2->hasKnownIntValue()) - return false; - if (Token::Match(tok2, "%var%|.") && !astIsBool(tok2)) - return false; - return true; - }); - } - return conds; - } - - static Value makeConditionValue(long long val, - const Token* condTok, - bool assume, - bool impossible, - const Settings& settings, - SourceLocation loc = SourceLocation::current()) - { - Value v(val); - v.setKnown(); - if (impossible) { - v.intvalue = !v.intvalue; - v.setImpossible(); - } - v.condition = condTok; - if (assume) - v.errorPath.emplace_back(condTok, "Assuming condition '" + condTok->expressionString() + "' is true"); - else - v.errorPath.emplace_back(condTok, "Assuming condition '" + condTok->expressionString() + "' is false"); - if (settings.debugnormal) - setSourceLocation(v, loc, condTok); - return v; - } - - static bool isEscapeScope(const Token* tok, const Settings& settings, bool unknown = false) - { - if (!Token::simpleMatch(tok, "{")) - return false; - // TODO this search for termTok in all subscopes. It should check the end of the scope. - const Token * termTok = Token::findmatch(tok, "return|continue|break|throw|goto", tok->link()); - if (termTok && termTok->scope() == tok->scope()) - return true; - std::string unknownFunction; - if (settings.library.isScopeNoReturn(tok->link(), &unknownFunction)) - return unknownFunction.empty() || unknown; - return false; - } - - void analyzeConditionExpressions(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings) - { - if (!settings.daca && !settings.vfOptions.doConditionExpressionAnalysis) - { - if (settings.debugwarnings) { - ErrorMessage::FileLocation loc(tokenlist.getSourceFilePath(), 0, 0); - const ErrorMessage errmsg({std::move(loc)}, tokenlist.getSourceFilePath(), Severity::debug, "Analysis of condition expressions is disabled. Use --check-level=exhaustive to enable it.", "normalCheckLevelConditionExpressions", Certainty::normal); - errorLogger.reportErr(errmsg); - } - return; - } - - for (const Scope * scope : symboldatabase.functionScopes) { - if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) { - if (settings.debugwarnings) - bailoutIncompleteVar(tokenlist, errorLogger, incompleteTok, "Skipping function due to incomplete variable " + incompleteTok->str()); - continue; - } - - if (settings.daca && !settings.vfOptions.doConditionExpressionAnalysis) - continue; - - for (auto* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { - if (!Token::simpleMatch(tok, "if (")) - continue; - Token* parenTok = tok->next(); - if (!Token::simpleMatch(parenTok->link(), ") {")) - continue; - Token * blockTok = parenTok->link()->tokAt(1); - const Token* condTok = parenTok->astOperand2(); - if (condTok->exprId() == 0) - continue; - if (condTok->hasKnownIntValue()) - continue; - if (!isConstExpression(condTok, settings.library)) - continue; - const bool isOp = condTok->isComparisonOp() || condTok->tokType() == Token::eLogicalOp; - const bool is1 = isOp || astIsBool(condTok); - - Token* startTok = blockTok; - // Inner condition - { - for (const Token* condTok2 : getConditions(condTok, "&&")) { - if (is1) { - const bool isBool = astIsBool(condTok2) || Token::Match(condTok2, "%comp%|%oror%|&&"); - auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(1, condTok2, /*assume*/ true, !isBool, settings), settings); // don't set '1' for non-boolean expressions - valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); - } - - auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(0, condTok2, true, false, settings), settings); - valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); - } - } - - std::vector conds = getConditions(condTok, "||"); - - // Check else block - if (Token::simpleMatch(startTok->link(), "} else {")) { - startTok = startTok->link()->tokAt(2); - for (const Token* condTok2:conds) { - auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(0, condTok2, false, false, settings), settings); - valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); - - if (is1) { - auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(isOp, condTok2, false, false, settings), settings); - valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); - } - } - } - - // Check if the block terminates early - if (isEscapeScope(blockTok, settings)) { - const Scope* scope2 = scope; - // If escaping a loop then only use the loop scope - if (isBreakOrContinueScope(blockTok->link())) { - scope2 = getLoopScope(blockTok->link()); - if (!scope2) - continue; - } - for (const Token* condTok2:conds) { - auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(0, condTok2, false, false, settings), settings); - valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a1, tokenlist, errorLogger, settings); - - if (is1) { - auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(1, condTok2, false, false, settings), settings); - valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a2, tokenlist, errorLogger, settings); - } - } - } - } - } - } -} diff --git a/lib/vf_conditionexpressions.h b/lib/vf_conditionexpressions.h deleted file mode 100644 index 691a396381d..00000000000 --- a/lib/vf_conditionexpressions.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfConditionExpressionsH -#define vfConditionExpressionsH - -class TokenList; -class SymbolDatabase; -class ErrorLogger; -class Settings; - -namespace ValueFlow -{ - void analyzeConditionExpressions(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings); -} - -#endif // vfConditionExpressionsH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 2184553571c..a988ad31bc0 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -104,7 +104,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_bailout.o \ $(libcppdir)/vf_bitand.o \ $(libcppdir)/vf_common.o \ - $(libcppdir)/vf_conditionexpressions.o \ $(libcppdir)/vf_debug.o \ $(libcppdir)/vf_enumvalue.o \ $(libcppdir)/vf_functionreturn.o \ @@ -168,7 +167,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_conditionexpressions.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_reverse.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_switchvariable.h ../lib/vf_symbolicinfer.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_reverse.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_switchvariable.h ../lib/vf_symbolicinfer.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h @@ -381,9 +380,6 @@ $(libcppdir)/vf_bitand.o: ../lib/vf_bitand.cpp ../lib/config.h ../lib/errortypes $(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_conditionexpressions.o: ../lib/vf_conditionexpressions.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_bailout.h ../lib/vf_common.h ../lib/vf_conditionexpressions.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_conditionexpressions.cpp - $(libcppdir)/vf_debug.o: ../lib/vf_debug.cpp ../lib/addoninfo.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_debug.cpp diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index e4e1a371448..66c7b14c009 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2037,7 +2037,7 @@ class TestSimplifyTokens : public TestFixture { "a [ x ] = 0 ;\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str()); } void simplifyKnownVariables36() { @@ -2160,7 +2160,7 @@ class TestSimplifyTokens : public TestFixture { "return x ;\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, true)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str()); } void simplifyKnownVariables47() { @@ -2174,7 +2174,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) analyzeConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", errout_str()); } void simplifyKnownVariables48() { @@ -2204,7 +2204,7 @@ class TestSimplifyTokens : public TestFixture { "}\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, false)); - ASSERT_EQUALS("[test.c:2]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str()); + ASSERT_EQUALS("[test.c:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str()); } void simplifyKnownVariables50() { // #4066 @@ -2227,7 +2227,7 @@ class TestSimplifyTokens : public TestFixture { "return & x7 ;\n" "}"; ASSERT_EQUALS(code, tokenizeAndStringify(code, true)); - ASSERT_EQUALS("[test.cpp:5]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable y\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable y\n", errout_str()); } { //don't simplify '&x'! @@ -2248,7 +2248,7 @@ class TestSimplifyTokens : public TestFixture { "return & x7 ;\n" "}"; ASSERT_EQUALS(code, tokenizeAndStringify(code, true)); - ASSERT_EQUALS("[test.cpp:5]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable y\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable y\n", errout_str()); } } @@ -2268,7 +2268,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) analyzeConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); } void simplifyKnownVariables58() { // #5268 @@ -2348,7 +2348,7 @@ class TestSimplifyTokens : public TestFixture { "return i ;\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable x\n", 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() { @@ -2362,7 +2362,7 @@ class TestSimplifyTokens : public TestFixture { "nr = ( last = list . prev ) . nr ;\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable nr\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable nr\n", errout_str()); } void simplifyKnownVariablesBailOutFor1() { @@ -2423,7 +2423,7 @@ class TestSimplifyTokens : public TestFixture { " return a;\n" "}\n"; (void)tokenizeAndStringify(code,true); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable x\n", 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() { diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index ea36824669d..00a20f6a2b0 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -1154,7 +1154,7 @@ class TestSimplifyTypedef : public TestFixture { "}"; ASSERT_EQUALS(expected, tok(code, false)); - ASSERT_EQUALS("[test.cpp:4]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable value\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable value\n", errout_str()); } void simplifyTypedef28() { @@ -2014,7 +2014,7 @@ class TestSimplifyTypedef : public TestFixture { "( ( int * * * ) global [ 6 ] ) ( \"assoc\" , \"eggdrop\" , 106 , 0 ) ; " "}"; ASSERT_EQUALS(expected, tok(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable global\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable global\n", errout_str()); } void simplifyTypedef68() { // ticket #2355 diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index a94fd50b835..830fe45e84f 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -743,7 +743,7 @@ class TestSimplifyUsing : public TestFixture { "cout << std :: string ( c ) << \"abc\" ; " "}"; ASSERT_EQUALS(expected, tok(code, Platform::Type::Native, /*debugwarnings*/ true)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable cout\n", 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> {\n" // #12521 diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index f24c4455767..af2ed01dc13 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3410,7 +3410,7 @@ class TestSymbolDatabase : public TestFixture { check("::y(){x}"); ASSERT_EQUALS("[test.cpp:1]: (debug) Executable scope 'y' with unknown function.\n" - "[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable x\n" + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n" "[test.cpp:1]: (debug) Executable scope 'y' with unknown function.\n", // duplicate errout_str()); } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index c02def1f5e0..f737fa29213 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -547,7 +547,7 @@ class TestTokenizer : public TestFixture { const char code[] = "void f ( )\n" "{ if ( p . y ( ) > yof ) { } }"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable yof\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable yof\n", errout_str()); } void tokenize2() { @@ -873,7 +873,7 @@ class TestTokenizer : public TestFixture { //valid, when there's also this declaration: 'constexpr int g[1] = {0};' ASSERT_NO_THROW(tokenizeAndStringify("void f(int n) {switch (n) { case g[0]: z(); break;}}")); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable g\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable g\n", errout_str()); //valid, similar to above case ASSERT_NO_THROW(tokenizeAndStringify("void f(int n) {switch (n) { case *g: z(); break;}}")); @@ -881,7 +881,7 @@ class TestTokenizer : public TestFixture { //valid, when 'x' and 'y' are constexpr. ASSERT_NO_THROW(tokenizeAndStringify("void f(int n) {switch (n) { case sqrt(x+y): z(); break;}}")); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str()); } void removePragma() { @@ -901,12 +901,12 @@ class TestTokenizer : public TestFixture { // #3690,#5154 const char code[] ="void f() { for each ( char c in MyString ) { Console::Write(c); } }"; ASSERT_EQUALS("void f ( ) { asm ( \"char c in MyString\" ) { Console :: Write ( c ) ; } }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable c\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable c\n", errout_str()); } void ifconstexpr() { ASSERT_EQUALS("void f ( ) { if ( FOO ) { bar ( c ) ; } }", tokenizeAndStringify("void f() { if constexpr ( FOO ) { bar(c); } }")); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable FOO\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable FOO\n", filter_valueflow(errout_str())); } void combineOperators() { @@ -1071,7 +1071,7 @@ class TestTokenizer : public TestFixture { "if ( a ) { ; }\n" "else { ; }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); } void ifAddBraces2() { @@ -1083,7 +1083,7 @@ class TestTokenizer : public TestFixture { "{\n" "if ( a ) { if ( b ) { } }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); } void ifAddBraces3() { @@ -1095,7 +1095,7 @@ class TestTokenizer : public TestFixture { "{\n" "if ( a ) { for ( ; ; ) { } }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); } void ifAddBraces4() { @@ -1115,7 +1115,7 @@ class TestTokenizer : public TestFixture { "{ } }\n" "return str ;\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:4]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable somecondition\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:4]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable somecondition\n", filter_valueflow(errout_str())); } void ifAddBraces5() { @@ -1202,7 +1202,7 @@ class TestTokenizer : public TestFixture { "}"; ASSERT_EQUALS("void f ( ) { ( void ) ( { if ( * p ) { ( * p ) = x ( ) ; } } ) }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable p\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", filter_valueflow(errout_str())); } } @@ -1223,7 +1223,7 @@ class TestTokenizer : public TestFixture { "else {\n" "bar2 ( ) ; }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); } void ifAddBraces18() { @@ -1255,7 +1255,7 @@ class TestTokenizer : public TestFixture { "else {\n" "bar2 ( ) ; } } }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); } void ifAddBraces20() { // #5012 - syntax error 'else }' @@ -1450,7 +1450,7 @@ class TestTokenizer : public TestFixture { "do { while ( x ) { f ( ) ; } } while ( y ) ;\n" "}"; ASSERT_EQUALS(result, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable x\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", filter_valueflow(errout_str())); } } @@ -1509,7 +1509,7 @@ class TestTokenizer : public TestFixture { "else { } }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); } { @@ -1526,7 +1526,7 @@ class TestTokenizer : public TestFixture { "else { } } }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); } } @@ -1652,7 +1652,7 @@ class TestTokenizer : public TestFixture { " { }" "}"; ASSERT_EQUALS("void foo ( ) { if ( x ) { int x ; } { } }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable x\n", filter_valueflow(errout_str())); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", filter_valueflow(errout_str())); } } @@ -1766,7 +1766,7 @@ class TestTokenizer : public TestFixture { "}"; ASSERT_EQUALS("void foo ( ) { free ( ( void * ) p ) ; }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); } void removeParentheses3() { @@ -1802,7 +1802,7 @@ class TestTokenizer : public TestFixture { " (free(p));" "}"; ASSERT_EQUALS("void foo ( ) { free ( p ) ; }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); } void removeParentheses5() { @@ -1813,7 +1813,7 @@ class TestTokenizer : public TestFixture { " (delete p);" "}"; ASSERT_EQUALS("void foo ( ) { delete p ; }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); } // Simplify "( delete [] x )" into "delete [] x" @@ -1823,7 +1823,7 @@ class TestTokenizer : public TestFixture { " (delete [] p);" "}"; ASSERT_EQUALS("void foo ( ) { delete [ ] p ; }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); } } @@ -2111,7 +2111,7 @@ class TestTokenizer : public TestFixture { "}", tokenizeAndStringify("void foo(int nX) {\n" " int addI = frontPoint == 2 || frontPoint == 1 ? i = 0, 1 : (i = nX - 2, -1);\n" "}")); - ASSERT_EQUALS("[test.cpp:2]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable frontPoint\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable frontPoint\n", errout_str()); } void vardecl_stl_1() { @@ -2352,7 +2352,7 @@ class TestTokenizer : public TestFixture { " int a = (x < y) ? 1 : 0;\n" "}"; ASSERT_EQUALS("void f ( ) {\nint a ; a = ( x < y ) ? 1 : 0 ;\n}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str()); } void vardecl14() { @@ -2393,7 +2393,7 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("void f ( ) {\n" "g ( ( double ) v1 * v2 , v3 , v4 ) ;\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable v1\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable v1\n", errout_str()); } void vardecl19() { @@ -2677,7 +2677,7 @@ class TestTokenizer : public TestFixture { "} ;"; ASSERT_EQUALS(out5, tokenizeAndStringify(in5)); - ASSERT_EQUALS("[test.cpp:3]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable pos\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable pos\n", errout_str()); } { // Ticket #8679 @@ -3733,7 +3733,7 @@ class TestTokenizer : public TestFixture { "( void ) ( xy ( * p ) ( 0 ) ) ;\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); } void simplifyFunctionPointers4() { @@ -4041,7 +4041,7 @@ class TestTokenizer : public TestFixture { " FFABS ( sprite_delta [ 1 ] [ i ] ) >= INT_MAX >> shift_y ) ;\n" "}"; ASSERT_EQUALS(std::string::npos, tokenizeAndStringify(code).find("> >")); - ASSERT_EQUALS("[test.cpp:2]: (debug) analyzeConditionExpressions bailout: Skipping function due to incomplete variable sprite_shift\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable sprite_shift\n", errout_str()); } { const char code[] = "struct S { bool vector; };\n" @@ -4180,7 +4180,7 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("; int a [ 1 ] = { foo < bar1 , bar2 > ( 123 , 4 ) } ;", tokenizeAndStringify(";int a[]={foo(123,4)};")); ASSERT_EQUALS("; int a [ 2 ] = { b > c ? 1 : 2 , 3 } ;", tokenizeAndStringify(";int a[]={ b>c?1:2,3};")); ASSERT_EQUALS("int main ( ) { int a [ 2 ] = { b < c ? 1 : 2 , 3 } }", tokenizeAndStringify("int main(){int a[]={b Date: Tue, 5 Nov 2024 09:45:17 -0600 Subject: [PATCH 04/13] Revert "ValueFlow: extracted `valueFlowSwitchVariable()` into separate file (#6783)" This reverts commit c348128b1051f58659488f62f13b05cc0c721c25. --- Makefile | 10 +--- lib/cppcheck.vcxproj | 4 -- lib/lib.pri | 4 -- lib/valueflow.cpp | 104 ++++++++++++++++++++++++++++++++- lib/vf_analyze.h | 1 - lib/vf_reverse.cpp | 47 --------------- lib/vf_reverse.h | 47 --------------- lib/vf_switchvariable.cpp | 120 -------------------------------------- lib/vf_switchvariable.h | 32 ---------- oss-fuzz/Makefile | 10 +--- 10 files changed, 104 insertions(+), 275 deletions(-) delete mode 100644 lib/vf_reverse.cpp delete mode 100644 lib/vf_reverse.h delete mode 100644 lib/vf_switchvariable.cpp delete mode 100644 lib/vf_switchvariable.h diff --git a/Makefile b/Makefile index 42741572c22..cfebdedce0f 100644 --- a/Makefile +++ b/Makefile @@ -272,12 +272,10 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_iterators.o \ $(libcppdir)/vf_number.o \ $(libcppdir)/vf_pointeralias.o \ - $(libcppdir)/vf_reverse.o \ $(libcppdir)/vf_rightshift.o \ $(libcppdir)/vf_sameexpressions.o \ $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vf_string.o \ - $(libcppdir)/vf_switchvariable.o \ $(libcppdir)/vf_symbolicinfer.o \ $(libcppdir)/vf_unknownfunctionreturn.o \ $(libcppdir)/vfvalue.o @@ -480,7 +478,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_reverse.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_switchvariable.h lib/vf_symbolicinfer.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_symbolicinfer.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h @@ -726,9 +724,6 @@ $(libcppdir)/vf_number.o: lib/vf_number.cpp lib/config.h lib/errortypes.h lib/li $(libcppdir)/vf_pointeralias.o: lib/vf_pointeralias.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_pointeralias.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_pointeralias.cpp -$(libcppdir)/vf_reverse.o: lib/vf_reverse.cpp lib/addoninfo.h lib/analyzer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/reverseanalyzer.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_reverse.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_reverse.cpp - $(libcppdir)/vf_rightshift.o: lib/vf_rightshift.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_rightshift.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_rightshift.cpp @@ -741,9 +736,6 @@ $(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/as $(libcppdir)/vf_string.o: lib/vf_string.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_settokenvalue.h lib/vf_string.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_string.cpp -$(libcppdir)/vf_switchvariable.o: lib/vf_switchvariable.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_bailout.h lib/vf_reverse.h lib/vf_switchvariable.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_switchvariable.cpp - $(libcppdir)/vf_symbolicinfer.o: lib/vf_symbolicinfer.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vf_settokenvalue.h lib/vf_symbolicinfer.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_symbolicinfer.cpp diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index a740cada61d..f00acfdca2f 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -107,12 +107,10 @@ - - @@ -216,12 +214,10 @@ - - diff --git a/lib/lib.pri b/lib/lib.pri index 2edc3d8ff00..2765845d151 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -98,12 +98,10 @@ HEADERS += $${PWD}/addoninfo.h \ $${PWD}/vf_iterators.h \ $${PWD}/vf_number.h \ $${PWD}/vf_pointeralias.h \ - $${PWD}/vf_reverse.h \ $${PWD}/vf_rightshift.h \ $${PWD}/vf_sameexpressions.h \ $${PWD}/vf_settokenvalue.h \ $${PWD}/vf_string.h \ - $${PWD}/vf_switchvariable.h \ $${PWD}/vf_symbolicinfer.h \ $${PWD}/vf_unknownfunctionreturn.h \ $${PWD}/vfvalue.h \ @@ -189,12 +187,10 @@ SOURCES += $${PWD}/valueflow.cpp \ $${PWD}/vf_iterators.cpp \ $${PWD}/vf_number.cpp \ $${PWD}/vf_pointeralias.cpp \ - $${PWD}/vf_reverse.cpp \ $${PWD}/vf_rightshift.cpp \ $${PWD}/vf_sameexpressions.cpp \ $${PWD}/vf_settokenvalue.cpp \ $${PWD}/vf_string.cpp \ - $${PWD}/vf_switchvariable.cpp \ $${PWD}/vf_symbolicinfer.cpp \ $${PWD}/vf_unknownfunctionreturn.cpp \ $${PWD}/vfvalue.cpp diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 2fcf8174fc6..9cebf2bc770 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -90,6 +90,7 @@ #include "mathlib.h" #include "platform.h" #include "programmemory.h" +#include "reverseanalyzer.h" #include "settings.h" #include "smallvector.h" #include "sourcelocation.h" @@ -106,7 +107,6 @@ #include "vf_analyzers.h" #include "vf_bailout.h" #include "vf_common.h" -#include "vf_reverse.h" #include "vf_settokenvalue.h" #include @@ -593,6 +593,34 @@ static Analyzer::Result valueFlowForwardRecursive(Token* top, return result; } +static void valueFlowReverse(Token* tok, + const Token* const endToken, + const Token* const varToken, + std::list values, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc = SourceLocation::current()) +{ + for (ValueFlow::Value& v : values) { + if (settings.debugnormal) + setSourceLocation(v, loc, tok); + valueFlowGenericReverse(tok, endToken, makeReverseAnalyzer(varToken, std::move(v), settings), tokenlist, errorLogger, settings); + } +} + +// Deprecated +static void valueFlowReverse(const TokenList& tokenlist, + Token* tok, + const Token* const varToken, + ValueFlow::Value val, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc = SourceLocation::current()) +{ + valueFlowReverse(tok, nullptr, varToken, {std::move(val)}, tokenlist, errorLogger, settings, loc); +} + static bool isConditionKnown(const Token* tok, bool then) { const char* op = "||"; @@ -4529,6 +4557,78 @@ static void valueFlowInjectParameter(const TokenList& tokenlist, settings); } +static void valueFlowSwitchVariable(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings) +{ + for (const Scope &scope : symboldatabase.scopeList) { + if (scope.type != Scope::ScopeType::eSwitch) + continue; + if (!Token::Match(scope.classDef, "switch ( %var% ) {")) + continue; + const Token *vartok = scope.classDef->tokAt(2); + const Variable *var = vartok->variable(); + if (!var) + continue; + + // bailout: global non-const variables + if (!(var->isLocal() || var->isArgument()) && !var->isConst()) { + if (settings.debugwarnings) + bailout(tokenlist, errorLogger, vartok, "switch variable " + var->name() + " is global"); + continue; + } + + for (const Token *tok = scope.bodyStart->next(); tok != scope.bodyEnd; tok = tok->next()) { + if (tok->str() == "{") { + tok = tok->link(); + continue; + } + if (Token::Match(tok, "case %num% :")) { + std::list values; + values.emplace_back(MathLib::toBigNumber(tok->strAt(1))); + values.back().condition = tok; + values.back().errorPath.emplace_back(tok, "case " + tok->strAt(1) + ": " + vartok->str() + " is " + tok->strAt(1) + " here."); + bool known = false; + if ((Token::simpleMatch(tok->previous(), "{") || Token::simpleMatch(tok->tokAt(-2), "break ;")) && !Token::Match(tok->tokAt(3), ";| case")) + known = true; + while (Token::Match(tok->tokAt(3), ";| case %num% :")) { + known = false; + tok = tok->tokAt(3); + if (!tok->isName()) + tok = tok->next(); + values.emplace_back(MathLib::toBigNumber(tok->strAt(1))); + values.back().condition = tok; + values.back().errorPath.emplace_back(tok, "case " + tok->strAt(1) + ": " + vartok->str() + " is " + tok->strAt(1) + " here."); + } + for (auto val = values.cbegin(); val != values.cend(); ++val) { + valueFlowReverse(tokenlist, + const_cast(scope.classDef), + vartok, + *val, + errorLogger, + settings); + } + if (vartok->variable()->scope()) { + if (known) + values.back().setKnown(); + + // FIXME We must check if there is a return. See #9276 + /* + valueFlowForwardVariable(tok->tokAt(3), + vartok->variable()->scope()->bodyEnd, + vartok->variable(), + vartok->varId(), + values, + values.back().isKnown(), + false, + tokenlist, + errorLogger, + settings); + */ + } + } + } + } +} + static std::list getFunctionArgumentValues(const Token *argtok) { std::list argvalues(argtok->values()); @@ -6030,7 +6130,7 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA_CPP(valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA(analyzeInferCondition(tokenlist, settings)), - VFA(analyzeSwitchVariable(tokenlist, symboldatabase, errorLogger, settings)), + VFA(valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings)), VFA(analyzeFunctionReturn(tokenlist, errorLogger, settings)), diff --git a/lib/vf_analyze.h b/lib/vf_analyze.h index 22458a2b187..72b321743f1 100644 --- a/lib/vf_analyze.h +++ b/lib/vf_analyze.h @@ -37,7 +37,6 @@ #include "vf_rightshift.h" // IWYU pragma: export #include "vf_sameexpressions.h" // IWYU pragma: export #include "vf_string.h" // IWYU pragma: export -#include "vf_switchvariable.h" // IWYU pragma: export #include "vf_symbolicinfer.h" // IWYU pragma: export #include "vf_unknownfunctionreturn.h" // IWYU pragma: export diff --git a/lib/vf_reverse.cpp b/lib/vf_reverse.cpp deleted file mode 100644 index f72d157f38c..00000000000 --- a/lib/vf_reverse.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_reverse.h" - -#include "reverseanalyzer.h" -#include "settings.h" -#include "vfvalue.h" - -#include "vf_analyzers.h" -#include "vf_common.h" - -#include - -namespace ValueFlow -{ - void valueFlowReverse(Token* tok, - const Token* const endToken, - const Token* const varToken, - std::list values, - const TokenList& tokenlist, - ErrorLogger& errorLogger, - const Settings& settings, - SourceLocation loc) - { - for (Value& v : values) { - if (settings.debugnormal) - setSourceLocation(v, loc, tok); - valueFlowGenericReverse(tok, endToken, makeReverseAnalyzer(varToken, std::move(v), settings), tokenlist, errorLogger, settings); - } - } -} diff --git a/lib/vf_reverse.h b/lib/vf_reverse.h deleted file mode 100644 index a3db45ea03a..00000000000 --- a/lib/vf_reverse.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfReverseeH -#define vfReverseeH - -#include "sourcelocation.h" - -#include - -class TokenList; -class ErrorLogger; -class Settings; -class Token; -namespace ValueFlow -{ - class Value; -} - -namespace ValueFlow { - void valueFlowReverse(Token* tok, - const Token* const endToken, - const Token* const varToken, - std::list values, - const TokenList& tokenlist, - ErrorLogger& errorLogger, - const Settings& settings, - SourceLocation loc = SourceLocation::current()); - -} - -#endif // vfReverseeH diff --git a/lib/vf_switchvariable.cpp b/lib/vf_switchvariable.cpp deleted file mode 100644 index 463522095bd..00000000000 --- a/lib/vf_switchvariable.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_switchvariable.h" - -#include "mathlib.h" -#include "settings.h" -#include "sourcelocation.h" -#include "symboldatabase.h" -#include "token.h" -#include "vfvalue.h" - -#include "vf_bailout.h" -#include "vf_reverse.h" - -#include -#include -#include - -namespace ValueFlow -{ - // Deprecated - static void valueFlowReverse(const TokenList& tokenlist, - Token* tok, - const Token* const varToken, - Value val, - ErrorLogger& errorLogger, - const Settings& settings, - SourceLocation loc = SourceLocation::current()) - { - valueFlowReverse(tok, nullptr, varToken, {std::move(val)}, tokenlist, errorLogger, settings, loc); - } - - void analyzeSwitchVariable(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings) - { - for (const Scope &scope : symboldatabase.scopeList) { - if (scope.type != Scope::ScopeType::eSwitch) - continue; - if (!Token::Match(scope.classDef, "switch ( %var% ) {")) - continue; - const Token *vartok = scope.classDef->tokAt(2); - const Variable *var = vartok->variable(); - if (!var) - continue; - - // bailout: global non-const variables - if (!(var->isLocal() || var->isArgument()) && !var->isConst()) { - if (settings.debugwarnings) - bailout(tokenlist, errorLogger, vartok, "switch variable " + var->name() + " is global"); - continue; - } - - for (const Token *tok = scope.bodyStart->next(); tok != scope.bodyEnd; tok = tok->next()) { - if (tok->str() == "{") { - tok = tok->link(); - continue; - } - if (Token::Match(tok, "case %num% :")) { - std::list values; - values.emplace_back(MathLib::toBigNumber(tok->strAt(1))); - values.back().condition = tok; - values.back().errorPath.emplace_back(tok, "case " + tok->strAt(1) + ": " + vartok->str() + " is " + tok->strAt(1) + " here."); - bool known = false; - if ((Token::simpleMatch(tok->previous(), "{") || Token::simpleMatch(tok->tokAt(-2), "break ;")) && !Token::Match(tok->tokAt(3), ";| case")) - known = true; - while (Token::Match(tok->tokAt(3), ";| case %num% :")) { - known = false; - tok = tok->tokAt(3); - if (!tok->isName()) - tok = tok->next(); - values.emplace_back(MathLib::toBigNumber(tok->strAt(1))); - values.back().condition = tok; - values.back().errorPath.emplace_back(tok, "case " + tok->strAt(1) + ": " + vartok->str() + " is " + tok->strAt(1) + " here."); - } - for (auto val = values.cbegin(); val != values.cend(); ++val) { - valueFlowReverse(tokenlist, - const_cast(scope.classDef), - vartok, - *val, - errorLogger, - settings); - } - if (vartok->variable()->scope()) { - if (known) - values.back().setKnown(); - - // FIXME We must check if there is a return. See #9276 - /* - valueFlowForwardVariable(tok->tokAt(3), - vartok->variable()->scope()->bodyEnd, - vartok->variable(), - vartok->varId(), - values, - values.back().isKnown(), - false, - tokenlist, - errorLogger, - settings); - */ - } - } - } - } - } -} diff --git a/lib/vf_switchvariable.h b/lib/vf_switchvariable.h deleted file mode 100644 index 251ff71b143..00000000000 --- a/lib/vf_switchvariable.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfSwitchVariableH -#define vfSwitchVariableH - -class TokenList; -class SymbolDatabase; -class ErrorLogger; -class Settings; - -namespace ValueFlow -{ - void analyzeSwitchVariable(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings); -} - -#endif // vfSwitchVariableH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index a988ad31bc0..c1d27b22874 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -115,12 +115,10 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_iterators.o \ $(libcppdir)/vf_number.o \ $(libcppdir)/vf_pointeralias.o \ - $(libcppdir)/vf_reverse.o \ $(libcppdir)/vf_rightshift.o \ $(libcppdir)/vf_sameexpressions.o \ $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vf_string.o \ - $(libcppdir)/vf_switchvariable.o \ $(libcppdir)/vf_symbolicinfer.o \ $(libcppdir)/vf_unknownfunctionreturn.o \ $(libcppdir)/vfvalue.o @@ -167,7 +165,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_reverse.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_switchvariable.h ../lib/vf_symbolicinfer.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_symbolicinfer.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h @@ -413,9 +411,6 @@ $(libcppdir)/vf_number.o: ../lib/vf_number.cpp ../lib/config.h ../lib/errortypes $(libcppdir)/vf_pointeralias.o: ../lib/vf_pointeralias.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_pointeralias.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_pointeralias.cpp -$(libcppdir)/vf_reverse.o: ../lib/vf_reverse.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_reverse.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_reverse.cpp - $(libcppdir)/vf_rightshift.o: ../lib/vf_rightshift.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_rightshift.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_rightshift.cpp @@ -428,9 +423,6 @@ $(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/addoninfo.h $(libcppdir)/vf_string.o: ../lib/vf_string.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_string.cpp -$(libcppdir)/vf_switchvariable.o: ../lib/vf_switchvariable.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_bailout.h ../lib/vf_reverse.h ../lib/vf_switchvariable.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_switchvariable.cpp - $(libcppdir)/vf_symbolicinfer.o: ../lib/vf_symbolicinfer.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vf_settokenvalue.h ../lib/vf_symbolicinfer.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_symbolicinfer.cpp From c869d784faf27045d1dcaa839ab81be44a081af3 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 5 Nov 2024 09:45:29 -0600 Subject: [PATCH 05/13] Revert "ValueFlow: extracted `valueFlowInferCondition()` into separate file (#6782)" This reverts commit a63b165e3bf7ce4ac8f147863478f7332b44408c. --- Makefile | 6 +- lib/cppcheck.vcxproj | 2 - lib/lib.pri | 2 - lib/valueflow.cpp | 96 +++++++++++++++++++++++++++- lib/valueflow.h | 1 - lib/vf_analyze.h | 1 - lib/vf_infercondition.cpp | 128 -------------------------------------- lib/vf_infercondition.h | 30 --------- oss-fuzz/Makefile | 6 +- 9 files changed, 96 insertions(+), 176 deletions(-) delete mode 100644 lib/vf_infercondition.cpp delete mode 100644 lib/vf_infercondition.h diff --git a/Makefile b/Makefile index cfebdedce0f..74218f783c7 100644 --- a/Makefile +++ b/Makefile @@ -267,7 +267,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_globalconstvar.o \ $(libcppdir)/vf_globalstaticvar.o \ $(libcppdir)/vf_impossiblevalues.o \ - $(libcppdir)/vf_infercondition.o \ $(libcppdir)/vf_iteratorinfer.o \ $(libcppdir)/vf_iterators.o \ $(libcppdir)/vf_number.o \ @@ -478,7 +477,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_infercondition.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_symbolicinfer.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_symbolicinfer.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h @@ -709,9 +708,6 @@ $(libcppdir)/vf_globalstaticvar.o: lib/vf_globalstaticvar.cpp lib/astutils.h lib $(libcppdir)/vf_impossiblevalues.o: lib/vf_impossiblevalues.cpp lib/astutils.h lib/calculate.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_impossiblevalues.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_impossiblevalues.cpp -$(libcppdir)/vf_infercondition.o: lib/vf_infercondition.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_infercondition.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_infercondition.cpp - $(libcppdir)/vf_iteratorinfer.o: lib/vf_iteratorinfer.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_iteratorinfer.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_iteratorinfer.cpp diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index f00acfdca2f..471189dd4f1 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -102,7 +102,6 @@ - @@ -209,7 +208,6 @@ - diff --git a/lib/lib.pri b/lib/lib.pri index 2765845d151..72833b6476a 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -93,7 +93,6 @@ HEADERS += $${PWD}/addoninfo.h \ $${PWD}/vf_globalconstvar.h \ $${PWD}/vf_globalstaticvar.h \ $${PWD}/vf_impossiblevalues.h \ - $${PWD}/vf_infercondition.h \ $${PWD}/vf_iteratorinfer.h \ $${PWD}/vf_iterators.h \ $${PWD}/vf_number.h \ @@ -182,7 +181,6 @@ SOURCES += $${PWD}/valueflow.cpp \ $${PWD}/vf_globalconstvar.cpp \ $${PWD}/vf_globalstaticvar.cpp \ $${PWD}/vf_impossiblevalues.cpp \ - $${PWD}/vf_infercondition.cpp \ $${PWD}/vf_iteratorinfer.cpp \ $${PWD}/vf_iterators.cpp \ $${PWD}/vf_number.cpp \ diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 9cebf2bc770..357ea534f39 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -110,6 +110,7 @@ #include "vf_settokenvalue.h" #include +#include #include #include #include @@ -4118,12 +4119,103 @@ static ValueFlow::Value inferCondition(const std::string& op, const Token* varTo return ValueFlow::Value{}; if (varTok->hasKnownIntValue()) return ValueFlow::Value{}; - std::vector r = infer(ValueFlow::makeIntegralInferModel(), op, varTok->values(), val); + std::vector r = infer(IntegralInferModel{}, op, varTok->values(), val); if (r.size() == 1 && r.front().isKnown()) return r.front(); return ValueFlow::Value{}; } +struct IteratorInferModel : InferModel { + virtual ValueFlow::Value::ValueType getType() const = 0; + bool match(const ValueFlow::Value& value) const override { + return value.valueType == getType(); + } + ValueFlow::Value yield(MathLib::bigint value) const override + { + ValueFlow::Value result(value); + result.valueType = getType(); + result.setKnown(); + return result; + } +}; + +struct EndIteratorInferModel : IteratorInferModel { + ValueFlow::Value::ValueType getType() const override { + return ValueFlow::Value::ValueType::ITERATOR_END; + } +}; + +struct StartIteratorInferModel : IteratorInferModel { + ValueFlow::Value::ValueType getType() const override { + return ValueFlow::Value::ValueType::ITERATOR_END; + } +}; + +static bool isIntegralOnlyOperator(const Token* tok) { + return Token::Match(tok, "%|<<|>>|&|^|~|%or%"); +} + +static bool isIntegralOrPointer(const Token* tok) +{ + if (!tok) + return false; + if (astIsIntegral(tok, false)) + return true; + if (astIsPointer(tok)) + return true; + if (Token::Match(tok, "NULL|nullptr")) + return true; + if (tok->valueType()) + return false; + // These operators only work on integers + if (isIntegralOnlyOperator(tok)) + return true; + if (isIntegralOnlyOperator(tok->astParent())) + return true; + if (Token::Match(tok, "+|-|*|/") && tok->isBinaryOp()) + return isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2()); + return false; +} + +static void valueFlowInferCondition(TokenList& tokenlist, + const Settings& settings) +{ + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { + if (!tok->astParent()) + continue; + if (tok->hasKnownIntValue()) + continue; + if (Token::Match(tok, "%comp%|-") && tok->astOperand1() && tok->astOperand2()) { + if (astIsIterator(tok->astOperand1()) || astIsIterator(tok->astOperand2())) { + static const std::array, 2> iteratorModels = {EndIteratorInferModel{}, + StartIteratorInferModel{}}; + for (const ValuePtr& model : iteratorModels) { + std::vector result = + infer(model, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); + for (ValueFlow::Value value : result) { + value.valueType = ValueFlow::Value::ValueType::INT; + setTokenValue(tok, std::move(value), settings); + } + } + } else if (isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2())) { + std::vector result = + infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); + for (ValueFlow::Value& value : result) { + setTokenValue(tok, std::move(value), settings); + } + } + } else if (Token::Match(tok->astParent(), "?|&&|!|%oror%") || + Token::Match(tok->astParent()->previous(), "if|while (") || + (astIsPointer(tok) && isUsedAsBool(tok, settings))) { + std::vector result = infer(IntegralInferModel{}, "!=", tok->values(), 0); + if (result.size() != 1) + continue; + ValueFlow::Value value = result.front(); + setTokenValue(tok, std::move(value), settings); + } + } +} + struct SymbolicConditionHandler : SimpleConditionHandler { static bool isNegatedBool(const Token* tok) @@ -6129,7 +6221,7 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA_CPP(valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), - VFA(analyzeInferCondition(tokenlist, settings)), + VFA(valueFlowInferCondition(tokenlist, settings)), VFA(valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings)), diff --git a/lib/valueflow.h b/lib/valueflow.h index ba88e12106e..1f7554048ef 100644 --- a/lib/valueflow.h +++ b/lib/valueflow.h @@ -22,7 +22,6 @@ //--------------------------------------------------------------------------- #include "config.h" -#include "errortypes.h" #include "mathlib.h" #include "vfvalue.h" diff --git a/lib/vf_analyze.h b/lib/vf_analyze.h index 72b321743f1..0ae58676ec2 100644 --- a/lib/vf_analyze.h +++ b/lib/vf_analyze.h @@ -29,7 +29,6 @@ #include "vf_globalconstvar.h" // IWYU pragma: export #include "vf_globalstaticvar.h" // IWYU pragma: export #include "vf_impossiblevalues.h" // IWYU pragma: export -#include "vf_infercondition.h" // IWYU pragma: export #include "vf_iteratorinfer.h" // IWYU pragma: export #include "vf_iterators.h" // IWYU pragma: export #include "vf_number.h" // IWYU pragma: export diff --git a/lib/vf_infercondition.cpp b/lib/vf_infercondition.cpp deleted file mode 100644 index 78e3a0fed77..00000000000 --- a/lib/vf_infercondition.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_infercondition.h" - -#include "astutils.h" -#include "infer.h" -#include "mathlib.h" -#include "token.h" -#include "tokenlist.h" -#include "valueflow.h" -#include "valueptr.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include -#include -#include - -namespace ValueFlow -{ - struct IteratorInferModel : InferModel { - virtual Value::ValueType getType() const = 0; - bool match(const Value& value) const override { - return value.valueType == getType(); - } - Value yield(MathLib::bigint value) const override - { - Value result(value); - result.valueType = getType(); - result.setKnown(); - return result; - } - }; - - struct EndIteratorInferModel : IteratorInferModel { - Value::ValueType getType() const override { - return Value::ValueType::ITERATOR_END; - } - }; - - struct StartIteratorInferModel : IteratorInferModel { - Value::ValueType getType() const override { - return Value::ValueType::ITERATOR_END; - } - }; - - static bool isIntegralOnlyOperator(const Token* tok) { - return Token::Match(tok, "%|<<|>>|&|^|~|%or%"); - } - - static bool isIntegralOrPointer(const Token* tok) - { - if (!tok) - return false; - if (astIsIntegral(tok, false)) - return true; - if (astIsPointer(tok)) - return true; - if (Token::Match(tok, "NULL|nullptr")) - return true; - if (tok->valueType()) - return false; - // These operators only work on integers - if (isIntegralOnlyOperator(tok)) - return true; - if (isIntegralOnlyOperator(tok->astParent())) - return true; - if (Token::Match(tok, "+|-|*|/") && tok->isBinaryOp()) - return isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2()); - return false; - } - - void analyzeInferCondition(TokenList& tokenlist, const Settings& settings) - { - for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { - if (!tok->astParent()) - continue; - if (tok->hasKnownIntValue()) - continue; - if (Token::Match(tok, "%comp%|-") && tok->astOperand1() && tok->astOperand2()) { - if (astIsIterator(tok->astOperand1()) || astIsIterator(tok->astOperand2())) { - static const std::array, 2> iteratorModels = {EndIteratorInferModel{}, - StartIteratorInferModel{}}; - for (const ValuePtr& model : iteratorModels) { - std::vector result = - infer(model, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); - for (Value value : result) { - value.valueType = Value::ValueType::INT; - setTokenValue(tok, std::move(value), settings); - } - } - } else if (isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2())) { - std::vector result = - infer(makeIntegralInferModel(), tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); - for (Value& value : result) { - setTokenValue(tok, std::move(value), settings); - } - } - } else if (Token::Match(tok->astParent(), "?|&&|!|%oror%") || - Token::Match(tok->astParent()->previous(), "if|while (") || - (astIsPointer(tok) && isUsedAsBool(tok, settings))) { - std::vector result = infer(makeIntegralInferModel(), "!=", tok->values(), 0); - if (result.size() != 1) - continue; - Value value = result.front(); - setTokenValue(tok, std::move(value), settings); - } - } - } -} diff --git a/lib/vf_infercondition.h b/lib/vf_infercondition.h deleted file mode 100644 index 2bb5a3b6d2b..00000000000 --- a/lib/vf_infercondition.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfInferConditionH -#define vfInferConditionH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeInferCondition(TokenList& tokenlist, const Settings& settings); -} - -#endif // vfInferConditionH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index c1d27b22874..f488315f00c 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -110,7 +110,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_globalconstvar.o \ $(libcppdir)/vf_globalstaticvar.o \ $(libcppdir)/vf_impossiblevalues.o \ - $(libcppdir)/vf_infercondition.o \ $(libcppdir)/vf_iteratorinfer.o \ $(libcppdir)/vf_iterators.o \ $(libcppdir)/vf_number.o \ @@ -165,7 +164,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_infercondition.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_symbolicinfer.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_symbolicinfer.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h @@ -396,9 +395,6 @@ $(libcppdir)/vf_globalstaticvar.o: ../lib/vf_globalstaticvar.cpp ../lib/astutils $(libcppdir)/vf_impossiblevalues.o: ../lib/vf_impossiblevalues.cpp ../lib/astutils.h ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_impossiblevalues.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_impossiblevalues.cpp -$(libcppdir)/vf_infercondition.o: ../lib/vf_infercondition.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_infercondition.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_infercondition.cpp - $(libcppdir)/vf_iteratorinfer.o: ../lib/vf_iteratorinfer.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_iteratorinfer.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_iteratorinfer.cpp From 2b718a17a73c79e0e01d264691bbcc776cf81136 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 5 Nov 2024 09:50:08 -0600 Subject: [PATCH 06/13] Revert "ValueFlow: extracted even more code into separate files (#6617)" This reverts commit c1cd1e2ef21c09c0ac582056c9870471742cafed. --- Makefile | 38 +-- lib/cppcheck.vcxproj | 18 - lib/lib.pri | 18 - lib/valueflow.cpp | 655 +++++++++++++++++++++++++++++++++++- lib/vf_analyze.h | 8 - lib/vf_arraybool.cpp | 86 ----- lib/vf_arraybool.h | 30 -- lib/vf_arrayelement.cpp | 113 ------- lib/vf_arrayelement.h | 30 -- lib/vf_bailout.cpp | 40 --- lib/vf_bailout.h | 39 --- lib/vf_common.cpp | 10 - lib/vf_common.h | 2 - lib/vf_functionreturn.cpp | 139 -------- lib/vf_functionreturn.h | 31 -- lib/vf_impossiblevalues.cpp | 197 ----------- lib/vf_impossiblevalues.h | 30 -- lib/vf_iteratorinfer.cpp | 65 ---- lib/vf_iteratorinfer.h | 30 -- lib/vf_iterators.cpp | 71 ---- lib/vf_iterators.h | 30 -- lib/vf_rightshift.cpp | 140 -------- lib/vf_rightshift.h | 30 -- lib/vf_symbolicinfer.cpp | 93 ----- lib/vf_symbolicinfer.h | 30 -- oss-fuzz/Makefile | 38 +-- 26 files changed, 649 insertions(+), 1362 deletions(-) delete mode 100644 lib/vf_arraybool.cpp delete mode 100644 lib/vf_arraybool.h delete mode 100644 lib/vf_arrayelement.cpp delete mode 100644 lib/vf_arrayelement.h delete mode 100644 lib/vf_bailout.cpp delete mode 100644 lib/vf_bailout.h delete mode 100644 lib/vf_functionreturn.cpp delete mode 100644 lib/vf_functionreturn.h delete mode 100644 lib/vf_impossiblevalues.cpp delete mode 100644 lib/vf_impossiblevalues.h delete mode 100644 lib/vf_iteratorinfer.cpp delete mode 100644 lib/vf_iteratorinfer.h delete mode 100644 lib/vf_iterators.cpp delete mode 100644 lib/vf_iterators.h delete mode 100644 lib/vf_rightshift.cpp delete mode 100644 lib/vf_rightshift.h delete mode 100644 lib/vf_symbolicinfer.cpp delete mode 100644 lib/vf_symbolicinfer.h diff --git a/Makefile b/Makefile index 506b9ca6c21..e2a15da9dc5 100644 --- a/Makefile +++ b/Makefile @@ -253,26 +253,17 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/tokenlist.o \ $(libcppdir)/utils.o \ $(libcppdir)/vf_array.o \ - $(libcppdir)/vf_arraybool.o \ - $(libcppdir)/vf_arrayelement.o \ - $(libcppdir)/vf_bailout.o \ $(libcppdir)/vf_bitand.o \ $(libcppdir)/vf_common.o \ $(libcppdir)/vf_debug.o \ $(libcppdir)/vf_enumvalue.o \ - $(libcppdir)/vf_functionreturn.o \ $(libcppdir)/vf_globalconstvar.o \ $(libcppdir)/vf_globalstaticvar.o \ - $(libcppdir)/vf_impossiblevalues.o \ - $(libcppdir)/vf_iteratorinfer.o \ - $(libcppdir)/vf_iterators.o \ $(libcppdir)/vf_number.o \ $(libcppdir)/vf_pointeralias.o \ - $(libcppdir)/vf_rightshift.o \ $(libcppdir)/vf_sameexpressions.o \ $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vf_string.o \ - $(libcppdir)/vf_symbolicinfer.o \ $(libcppdir)/vf_unknownfunctionreturn.o \ $(libcppdir)/vfvalue.o @@ -482,7 +473,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_array.h lib/vf_arraybool.h lib/vf_arrayelement.h lib/vf_bailout.h lib/vf_bitand.h lib/vf_common.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_functionreturn.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_impossiblevalues.h lib/vf_iteratorinfer.h lib/vf_iterators.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_rightshift.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_symbolicinfer.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_array.h lib/vf_bitand.h lib/vf_common.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h @@ -671,15 +662,6 @@ $(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h $(libcppdir)/vf_array.o: lib/vf_array.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_array.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_array.cpp -$(libcppdir)/vf_arraybool.o: lib/vf_arraybool.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_arraybool.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_arraybool.cpp - -$(libcppdir)/vf_arrayelement.o: lib/vf_arrayelement.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_arrayelement.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_arrayelement.cpp - -$(libcppdir)/vf_bailout.o: lib/vf_bailout.cpp lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/path.h lib/standards.h lib/tokenlist.h lib/utils.h lib/vf_bailout.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_bailout.cpp - $(libcppdir)/vf_bitand.o: lib/vf_bitand.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_bitand.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_bitand.cpp @@ -692,33 +674,18 @@ $(libcppdir)/vf_debug.o: lib/vf_debug.cpp lib/addoninfo.h lib/color.h lib/config $(libcppdir)/vf_enumvalue.o: lib/vf_enumvalue.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_enumvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_enumvalue.cpp -$(libcppdir)/vf_functionreturn.o: lib/vf_functionreturn.cpp lib/addoninfo.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_bailout.h lib/vf_functionreturn.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_functionreturn.cpp - $(libcppdir)/vf_globalconstvar.o: lib/vf_globalconstvar.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_globalconstvar.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_globalconstvar.cpp $(libcppdir)/vf_globalstaticvar.o: lib/vf_globalstaticvar.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_globalstaticvar.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_globalstaticvar.cpp -$(libcppdir)/vf_impossiblevalues.o: lib/vf_impossiblevalues.cpp lib/astutils.h lib/calculate.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_impossiblevalues.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_impossiblevalues.cpp - -$(libcppdir)/vf_iteratorinfer.o: lib/vf_iteratorinfer.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_iteratorinfer.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_iteratorinfer.cpp - -$(libcppdir)/vf_iterators.o: lib/vf_iterators.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_iterators.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_iterators.cpp - $(libcppdir)/vf_number.o: lib/vf_number.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_number.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_number.cpp $(libcppdir)/vf_pointeralias.o: lib/vf_pointeralias.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_pointeralias.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_pointeralias.cpp -$(libcppdir)/vf_rightshift.o: lib/vf_rightshift.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_rightshift.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_rightshift.cpp - $(libcppdir)/vf_sameexpressions.o: lib/vf_sameexpressions.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_sameexpressions.cpp @@ -728,9 +695,6 @@ $(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/as $(libcppdir)/vf_string.o: lib/vf_string.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_settokenvalue.h lib/vf_string.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_string.cpp -$(libcppdir)/vf_symbolicinfer.o: lib/vf_symbolicinfer.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vf_settokenvalue.h lib/vf_symbolicinfer.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_symbolicinfer.cpp - $(libcppdir)/vf_unknownfunctionreturn.o: lib/vf_unknownfunctionreturn.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_unknownfunctionreturn.cpp diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 9373e394219..78171d08a45 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -88,26 +88,17 @@ - - - - - - - - - @@ -190,26 +181,17 @@ - - - - - - - - - diff --git a/lib/lib.pri b/lib/lib.pri index 4dd6782b633..b2bcdf5c70f 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -79,26 +79,17 @@ HEADERS += $${PWD}/addoninfo.h \ $${PWD}/version.h \ $${PWD}/vf_analyze.h \ $${PWD}/vf_array.h \ - $${PWD}/vf_arraybool.h \ - $${PWD}/vf_arrayelement.h \ - $${PWD}/vf_bailout.h \ $${PWD}/vf_bitand.h \ $${PWD}/vf_common.h \ $${PWD}/vf_debug.h \ $${PWD}/vf_enumvalue.h \ - $${PWD}/vf_functionreturn.h \ $${PWD}/vf_globalconstvar.h \ $${PWD}/vf_globalstaticvar.h \ - $${PWD}/vf_impossiblevalues.h \ - $${PWD}/vf_iteratorinfer.h \ - $${PWD}/vf_iterators.h \ $${PWD}/vf_number.h \ $${PWD}/vf_pointeralias.h \ - $${PWD}/vf_rightshift.h \ $${PWD}/vf_sameexpressions.h \ $${PWD}/vf_settokenvalue.h \ $${PWD}/vf_string.h \ - $${PWD}/vf_symbolicinfer.h \ $${PWD}/vf_unknownfunctionreturn.h \ $${PWD}/vfvalue.h \ $${PWD}/xml.h @@ -166,25 +157,16 @@ SOURCES += $${PWD}/valueflow.cpp \ $${PWD}/tokenlist.cpp \ $${PWD}/utils.cpp \ $${PWD}/vf_array.cpp \ - $${PWD}/vf_arraybool.cpp \ - $${PWD}/vf_arrayelement.cpp \ - $${PWD}/vf_bailout.cpp \ $${PWD}/vf_bitand.cpp \ $${PWD}/vf_common.cpp \ $${PWD}/vf_debug.cpp \ $${PWD}/vf_enumvalue.cpp \ - $${PWD}/vf_functionreturn.cpp \ $${PWD}/vf_globalconstvar.cpp \ $${PWD}/vf_globalstaticvar.cpp \ - $${PWD}/vf_impossiblevalues.cpp \ - $${PWD}/vf_iteratorinfer.cpp \ - $${PWD}/vf_iterators.cpp \ $${PWD}/vf_number.cpp \ $${PWD}/vf_pointeralias.cpp \ - $${PWD}/vf_rightshift.cpp \ $${PWD}/vf_sameexpressions.cpp \ $${PWD}/vf_settokenvalue.cpp \ $${PWD}/vf_string.cpp \ - $${PWD}/vf_symbolicinfer.cpp \ $${PWD}/vf_unknownfunctionreturn.cpp \ $${PWD}/vfvalue.cpp diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index f36f8b8ec07..73662baaa5f 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -89,6 +89,7 @@ #include "infer.h" #include "library.h" #include "mathlib.h" +#include "path.h" #include "platform.h" #include "programmemory.h" #include "reverseanalyzer.h" @@ -105,7 +106,6 @@ #include "vfvalue.h" #include "vf_analyze.h" -#include "vf_bailout.h" #include "vf_common.h" #include "vf_settokenvalue.h" @@ -131,6 +131,23 @@ #include #include +static void bailoutInternal(const std::string& type, const TokenList &tokenlist, ErrorLogger &errorLogger, const Token *tok, const std::string &what, const std::string &file, int line, std::string function) +{ + if (function.find("operator") != std::string::npos) + function = "(valueFlow)"; + ErrorMessage::FileLocation loc(tok, &tokenlist); + const std::string location = Path::stripDirectoryPart(file) + ":" + std::to_string(line) + ":"; + ErrorMessage errmsg({std::move(loc)}, tokenlist.getSourceFilePath(), Severity::debug, + (file.empty() ? "" : location) + function + " bailout: " + what, type, Certainty::normal); + errorLogger.reportErr(errmsg); +} + +#define bailout2(type, tokenlist, errorLogger, tok, what) bailoutInternal((type), (tokenlist), (errorLogger), (tok), (what), __FILE__, __LINE__, __func__) + +#define bailout(tokenlist, errorLogger, tok, what) bailout2("valueFlowBailout", (tokenlist), (errorLogger), (tok), (what)) + +#define bailoutIncompleteVar(tokenlist, errorLogger, tok, what) bailoutInternal("valueFlowBailoutIncompleteVar", (tokenlist), (errorLogger), (tok), (what), "", 0, __func__) + static void changeKnownToPossible(std::list &values, int indirect=-1) { for (ValueFlow::Value& v: values) { @@ -524,6 +541,393 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings, int m return 0; } +static bool isNonZero(const Token *tok) +{ + return tok && (!tok->hasKnownIntValue() || tok->values().front().intvalue != 0); +} + +static const Token *getOtherOperand(const Token *tok) +{ + if (!tok) + return nullptr; + if (!tok->astParent()) + return nullptr; + if (tok->astParent()->astOperand1() != tok) + return tok->astParent()->astOperand1(); + if (tok->astParent()->astOperand2() != tok) + return tok->astParent()->astOperand2(); + return nullptr; +} + +static void valueFlowArrayBool(TokenList &tokenlist, const Settings &settings) +{ + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + if (tok->hasKnownIntValue()) + continue; + const Variable *var = nullptr; + bool known = false; + const std::list::const_iterator val = + std::find_if(tok->values().cbegin(), tok->values().cend(), std::mem_fn(&ValueFlow::Value::isTokValue)); + if (val == tok->values().end()) { + var = tok->variable(); + known = true; + } else { + var = val->tokvalue->variable(); + known = val->isKnown(); + } + if (!var) + continue; + if (!var->isArray() || var->isArgument() || var->isStlType()) + continue; + if (isNonZero(getOtherOperand(tok)) && Token::Match(tok->astParent(), "%comp%")) + continue; + // TODO: Check for function argument + if ((astIsBool(tok->astParent()) && !Token::Match(tok->astParent(), "(|%name%")) || + (tok->astParent() && Token::Match(tok->astParent()->previous(), "if|while|for ("))) { + ValueFlow::Value value{1}; + if (known) + value.setKnown(); + setTokenValue(tok, std::move(value), settings); + } + } +} + +static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings) +{ + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { + if (tok->hasKnownIntValue()) + continue; + const Token* indexTok = nullptr; + const Token* arrayTok = nullptr; + if (Token::simpleMatch(tok, "[") && tok->isBinaryOp()) { + indexTok = tok->astOperand2(); + arrayTok = tok->astOperand1(); + } else if (Token::Match(tok->tokAt(-2), ". %name% (") && astIsContainer(tok->tokAt(-2)->astOperand1())) { + arrayTok = tok->tokAt(-2)->astOperand1(); + const Library::Container* container = getLibraryContainer(arrayTok); + if (!container || container->stdAssociativeLike) + continue; + const Library::Container::Yield yield = container->getYield(tok->strAt(-1)); + if (yield != Library::Container::Yield::AT_INDEX) + continue; + indexTok = tok->astOperand2(); + } + + if (!indexTok || !arrayTok) + continue; + + for (const ValueFlow::Value& arrayValue : arrayTok->values()) { + if (!arrayValue.isTokValue()) + continue; + if (arrayValue.isImpossible()) + continue; + for (const ValueFlow::Value& indexValue : indexTok->values()) { + if (!indexValue.isIntValue()) + continue; + if (indexValue.isImpossible()) + continue; + if (!arrayValue.isKnown() && !indexValue.isKnown() && arrayValue.varId != 0 && indexValue.varId != 0 && + !(arrayValue.varId == indexValue.varId && arrayValue.varvalue == indexValue.varvalue)) + continue; + + ValueFlow::Value result(0); + result.condition = arrayValue.condition ? arrayValue.condition : indexValue.condition; + result.setInconclusive(arrayValue.isInconclusive() || indexValue.isInconclusive()); + result.varId = (arrayValue.varId != 0) ? arrayValue.varId : indexValue.varId; + result.varvalue = (result.varId == arrayValue.varId) ? arrayValue.intvalue : indexValue.intvalue; + if (arrayValue.valueKind == indexValue.valueKind) + result.valueKind = arrayValue.valueKind; + + result.errorPath.insert(result.errorPath.end(), arrayValue.errorPath.cbegin(), arrayValue.errorPath.cend()); + result.errorPath.insert(result.errorPath.end(), indexValue.errorPath.cbegin(), indexValue.errorPath.cend()); + + const MathLib::bigint index = indexValue.intvalue; + + if (arrayValue.tokvalue->tokType() == Token::eString) { + const std::string s = arrayValue.tokvalue->strValue(); + if (index == s.size()) { + result.intvalue = 0; + setTokenValue(tok, std::move(result), settings); + } else if (index >= 0 && index < s.size()) { + result.intvalue = s[index]; + setTokenValue(tok, std::move(result), settings); + } + } else if (Token::simpleMatch(arrayValue.tokvalue, "{")) { + std::vector args = getArguments(arrayValue.tokvalue); + if (index < 0 || index >= args.size()) + continue; + const Token* arg = args[index]; + if (!arg->hasKnownIntValue()) + continue; + const ValueFlow::Value& v = arg->values().front(); + result.intvalue = v.intvalue; + result.errorPath.insert(result.errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend()); + setTokenValue(tok, std::move(result), settings); + } + } + } + } +} + +static bool getExpressionRange(const Token *expr, MathLib::bigint *minvalue, MathLib::bigint *maxvalue) +{ + if (expr->hasKnownIntValue()) { + if (minvalue) + *minvalue = expr->values().front().intvalue; + if (maxvalue) + *maxvalue = expr->values().front().intvalue; + return true; + } + + if (expr->str() == "&" && expr->astOperand1() && expr->astOperand2()) { + MathLib::bigint vals[4]; + const bool lhsHasKnownRange = getExpressionRange(expr->astOperand1(), &vals[0], &vals[1]); + const bool rhsHasKnownRange = getExpressionRange(expr->astOperand2(), &vals[2], &vals[3]); + if (!lhsHasKnownRange && !rhsHasKnownRange) + return false; + if (!lhsHasKnownRange || !rhsHasKnownRange) { + if (minvalue) + *minvalue = lhsHasKnownRange ? vals[0] : vals[2]; + if (maxvalue) + *maxvalue = lhsHasKnownRange ? vals[1] : vals[3]; + } else { + if (minvalue) + *minvalue = vals[0] & vals[2]; + if (maxvalue) + *maxvalue = vals[1] & vals[3]; + } + return true; + } + + if (expr->str() == "%" && expr->astOperand1() && expr->astOperand2()) { + MathLib::bigint vals[4]; + if (!getExpressionRange(expr->astOperand2(), &vals[2], &vals[3])) + return false; + if (vals[2] <= 0) + return false; + const bool lhsHasKnownRange = getExpressionRange(expr->astOperand1(), &vals[0], &vals[1]); + if (lhsHasKnownRange && vals[0] < 0) + return false; + // If lhs has unknown value, it must be unsigned + if (!lhsHasKnownRange && (!expr->astOperand1()->valueType() || expr->astOperand1()->valueType()->sign != ValueType::Sign::UNSIGNED)) + return false; + if (minvalue) + *minvalue = 0; + if (maxvalue) + *maxvalue = vals[3] - 1; + return true; + } + + return false; +} + +static void valueFlowRightShift(TokenList &tokenList, const Settings& settings) +{ + for (Token *tok = tokenList.front(); tok; tok = tok->next()) { + if (tok->str() != ">>") + continue; + + if (tok->hasKnownValue()) + continue; + + if (!tok->astOperand1() || !tok->astOperand2()) + continue; + + if (!tok->astOperand2()->hasKnownValue()) + continue; + + const MathLib::bigint rhsvalue = tok->astOperand2()->values().front().intvalue; + if (rhsvalue < 0) + continue; + + if (!tok->astOperand1()->valueType() || !tok->astOperand1()->valueType()->isIntegral()) + continue; + + if (!tok->astOperand2()->valueType() || !tok->astOperand2()->valueType()->isIntegral()) + continue; + + MathLib::bigint lhsmax=0; + if (!getExpressionRange(tok->astOperand1(), nullptr, &lhsmax)) + continue; + if (lhsmax < 0) + continue; + int lhsbits; + if ((tok->astOperand1()->valueType()->type == ValueType::Type::CHAR) || + (tok->astOperand1()->valueType()->type == ValueType::Type::SHORT) || + (tok->astOperand1()->valueType()->type == ValueType::Type::WCHAR_T) || + (tok->astOperand1()->valueType()->type == ValueType::Type::BOOL) || + (tok->astOperand1()->valueType()->type == ValueType::Type::INT)) + lhsbits = settings.platform.int_bit; + else if (tok->astOperand1()->valueType()->type == ValueType::Type::LONG) + lhsbits = settings.platform.long_bit; + else if (tok->astOperand1()->valueType()->type == ValueType::Type::LONGLONG) + lhsbits = settings.platform.long_long_bit; + else + continue; + if (rhsvalue >= lhsbits || rhsvalue >= MathLib::bigint_bits || (1ULL << rhsvalue) <= lhsmax) + continue; + + ValueFlow::Value val(0); + val.setKnown(); + setTokenValue(tok, std::move(val), settings); + } +} + +static std::vector minUnsignedValue(const Token* tok, int depth = 8) +{ + std::vector result; + if (!tok) + return result; + if (depth < 0) + return result; + if (tok->hasKnownIntValue()) { + result = {tok->values().front().intvalue}; + } else if (!Token::Match(tok, "-|%|&|^") && tok->isConstOp() && tok->astOperand1() && tok->astOperand2()) { + std::vector op1 = minUnsignedValue(tok->astOperand1(), depth - 1); + std::vector op2 = minUnsignedValue(tok->astOperand2(), depth - 1); + if (!op1.empty() && !op2.empty()) { + result = calculate>(tok->str(), op1.front(), op2.front()); + } + } + if (result.empty() && astIsUnsigned(tok)) + result = {0}; + return result; +} + +static bool isConvertedToIntegral(const Token* tok, const Settings& settings) +{ + if (!tok) + return false; + std::vector parentTypes = getParentValueTypes(tok, settings); + if (parentTypes.empty()) + return false; + const ValueType& vt = parentTypes.front(); + return vt.type != ValueType::UNKNOWN_INT && vt.isIntegral(); +} + +static bool isSameToken(const Token* tok1, const Token* tok2) +{ + if (!tok1 || !tok2) + return false; + if (tok1->exprId() != 0 && tok1->exprId() == tok2->exprId()) + return true; + if (tok1->hasKnownIntValue() && tok2->hasKnownIntValue()) + return tok1->values().front().intvalue == tok2->values().front().intvalue; + return false; +} + +static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& settings) +{ + for (Token* tok = tokenList.front(); tok; tok = tok->next()) { + if (tok->hasKnownIntValue()) + continue; + if (Token::Match(tok, "true|false")) + continue; + if (astIsBool(tok) || Token::Match(tok, "%comp%")) { + ValueFlow::Value lower{-1}; + lower.bound = ValueFlow::Value::Bound::Upper; + lower.setImpossible(); + setTokenValue(tok, std::move(lower), settings); + + ValueFlow::Value upper{2}; + upper.bound = ValueFlow::Value::Bound::Lower; + upper.setImpossible(); + setTokenValue(tok, std::move(upper), settings); + } else if (astIsUnsigned(tok) && !astIsPointer(tok)) { + std::vector minvalue = minUnsignedValue(tok); + if (minvalue.empty()) + continue; + ValueFlow::Value value{std::max(0, minvalue.front()) - 1}; + value.bound = ValueFlow::Value::Bound::Upper; + value.setImpossible(); + setTokenValue(tok, std::move(value), settings); + } + if (Token::simpleMatch(tok, "?") && Token::Match(tok->astOperand1(), "<|<=|>|>=")) { + const Token* condTok = tok->astOperand1(); + const Token* branchesTok = tok->astOperand2(); + + auto tokens = makeArray(condTok->astOperand1(), condTok->astOperand2()); + auto branches = makeArray(branchesTok->astOperand1(), branchesTok->astOperand2()); + bool flipped = false; + if (std::equal(tokens.cbegin(), tokens.cend(), branches.crbegin(), &isSameToken)) + flipped = true; + else if (!std::equal(tokens.cbegin(), tokens.cend(), branches.cbegin(), &isSameToken)) + continue; + const bool isMin = Token::Match(condTok, "<|<=") ^ flipped; + std::vector values; + for (const Token* tok2 : tokens) { + if (tok2->hasKnownIntValue()) { + values.emplace_back(tok2->values().front()); + } else { + ValueFlow::Value symValue{}; + symValue.valueType = ValueFlow::Value::ValueType::SYMBOLIC; + symValue.tokvalue = tok2; + values.push_back(symValue); + std::copy_if(tok2->values().cbegin(), + tok2->values().cend(), + std::back_inserter(values), + [](const ValueFlow::Value& v) { + if (!v.isKnown()) + return false; + return v.isSymbolicValue(); + }); + } + } + for (ValueFlow::Value& value : values) { + value.setImpossible(); + if (isMin) { + value.intvalue++; + value.bound = ValueFlow::Value::Bound::Lower; + } else { + value.intvalue--; + value.bound = ValueFlow::Value::Bound::Upper; + } + setTokenValue(tok, std::move(value), settings); + } + + } else if (Token::simpleMatch(tok, "%") && tok->astOperand2() && tok->astOperand2()->hasKnownIntValue()) { + ValueFlow::Value value{tok->astOperand2()->values().front()}; + value.bound = ValueFlow::Value::Bound::Lower; + value.setImpossible(); + setTokenValue(tok, std::move(value), settings); + } else if (Token::Match(tok, "abs|labs|llabs|fabs|fabsf|fabsl (")) { + ValueFlow::Value value{-1}; + value.bound = ValueFlow::Value::Bound::Upper; + value.setImpossible(); + setTokenValue(tok->next(), std::move(value), settings); + } else if (Token::Match(tok, ". data|c_str (") && astIsContainerOwned(tok->astOperand1())) { + const Library::Container* container = getLibraryContainer(tok->astOperand1()); + if (!container) + continue; + if (!container->stdStringLike) + continue; + if (container->view) + continue; + ValueFlow::Value value{0}; + value.setImpossible(); + setTokenValue(tok->tokAt(2), std::move(value), settings); + } else if (Token::Match(tok, "make_shared|make_unique <") && Token::simpleMatch(tok->linkAt(1), "> (")) { + ValueFlow::Value value{0}; + value.setImpossible(); + setTokenValue(tok->linkAt(1)->next(), std::move(value), settings); + } else if ((tokenList.isCPP() && Token::simpleMatch(tok, "this")) || tok->isUnaryOp("&")) { + ValueFlow::Value value{0}; + value.setImpossible(); + setTokenValue(tok, std::move(value), settings); + } else if (tok->variable() && tok->variable()->isArray() && !tok->variable()->isArgument() && + !tok->variable()->isStlType()) { + ValueFlow::Value value{0}; + value.setImpossible(); + setTokenValue(tok, std::move(value), settings); + } else if (tok->isIncompleteVar() && tok->astParent() && tok->astParent()->isUnaryOp("-") && + isConvertedToIntegral(tok->astParent(), settings)) { + ValueFlow::Value value{0}; + value.setImpossible(); + setTokenValue(tok, std::move(value), settings); + } + } +} + static ValuePtr makeAnalyzer(const Token* exprTok, ValueFlow::Value value, const Settings& settings); static ValuePtr makeReverseAnalyzer(const Token* exprTok, ValueFlow::Value value, const Settings& settings); @@ -4112,6 +4516,63 @@ static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, con } } +struct SymbolicInferModel : InferModel { + const Token* expr; + explicit SymbolicInferModel(const Token* tok) : expr(tok) { + assert(expr->exprId() != 0); + } + bool match(const ValueFlow::Value& value) const override + { + return value.isSymbolicValue() && value.tokvalue && value.tokvalue->exprId() == expr->exprId(); + } + ValueFlow::Value yield(MathLib::bigint value) const override + { + ValueFlow::Value result(value); + result.valueType = ValueFlow::Value::ValueType::SYMBOLIC; + result.tokvalue = expr; + result.setKnown(); + return result; + } +}; + +static void valueFlowSymbolicInfer(const SymbolDatabase& symboldatabase, const Settings& settings) +{ + for (const Scope* scope : symboldatabase.functionScopes) { + for (auto* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { + if (!Token::Match(tok, "-|%comp%")) + continue; + if (tok->hasKnownIntValue()) + continue; + if (!tok->astOperand1()) + continue; + if (!tok->astOperand2()) + continue; + if (tok->astOperand1()->exprId() == 0) + continue; + if (tok->astOperand2()->exprId() == 0) + continue; + if (tok->astOperand1()->hasKnownIntValue()) + continue; + if (tok->astOperand2()->hasKnownIntValue()) + continue; + if (astIsFloat(tok->astOperand1(), false)) + continue; + if (astIsFloat(tok->astOperand2(), false)) + continue; + + SymbolicInferModel leftModel{tok->astOperand1()}; + std::vector values = infer(leftModel, tok->str(), 0, tok->astOperand2()->values()); + if (values.empty()) { + SymbolicInferModel rightModel{tok->astOperand2()}; + values = infer(rightModel, tok->str(), tok->astOperand1()->values(), 0); + } + for (ValueFlow::Value& value : values) { + setTokenValue(tok, std::move(value), settings); + } + } + } +} + template static void valueFlowForwardConst(Token* start, const Token* end, @@ -6248,6 +6709,104 @@ static void valueFlowFunctionDefaultParameter(const TokenList& tokenlist, const } } +static const ValueFlow::Value* getKnownValueFromToken(const Token* tok) +{ + if (!tok) + return nullptr; + auto it = std::find_if(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) { + return (v.isIntValue() || v.isContainerSizeValue() || v.isFloatValue()) && v.isKnown(); + }); + if (it == tok->values().end()) + return nullptr; + return std::addressof(*it); +} + +static const ValueFlow::Value* getKnownValueFromTokens(const std::vector& toks) +{ + if (toks.empty()) + return nullptr; + const ValueFlow::Value* result = getKnownValueFromToken(toks.front()); + if (!result) + return nullptr; + if (!std::all_of(std::next(toks.begin()), toks.end(), [&](const Token* tok) { + return std::any_of(tok->values().begin(), tok->values().end(), [&](const ValueFlow::Value& v) { + return v.equalValue(*result) && v.valueKind == result->valueKind; + }); + })) + return nullptr; + return result; +} + +static void setFunctionReturnValue(const Function* f, Token* tok, ValueFlow::Value v, const Settings& settings) +{ + if (f->hasVirtualSpecifier()) { + if (v.isImpossible()) + return; + v.setPossible(); + } else if (!v.isImpossible()) { + v.setKnown(); + } + v.errorPath.emplace_back(tok, "Calling function '" + f->name() + "' returns " + v.toString()); + setTokenValue(tok, std::move(v), settings); +} + +static void valueFlowFunctionReturn(TokenList &tokenlist, ErrorLogger &errorLogger, const Settings& settings) +{ + for (Token *tok = tokenlist.back(); tok; tok = tok->previous()) { + if (tok->str() != "(" || !tok->astOperand1() || tok->isCast()) + continue; + + const Function* function = nullptr; + if (Token::Match(tok->previous(), "%name% (")) + function = tok->previous()->function(); + else + function = tok->astOperand1()->function(); + if (!function) + continue; + // TODO: Check if member variable is a pointer or reference + if (function->isImplicitlyVirtual() && !function->hasFinalSpecifier()) + continue; + + if (tok->hasKnownValue()) + continue; + + std::vector returns = Function::findReturns(function); + if (returns.empty()) + continue; + + if (const ValueFlow::Value* v = getKnownValueFromTokens(returns)) { + setFunctionReturnValue(function, tok, *v, settings); + continue; + } + + // Arguments.. + std::vector arguments = getArguments(tok); + + ProgramMemory programMemory; + for (std::size_t i = 0; i < arguments.size(); ++i) { + const Variable * const arg = function->getArgumentVar(i); + if (!arg) { + if (settings.debugwarnings) + bailout(tokenlist, errorLogger, tok, "function return; unhandled argument type"); + programMemory.clear(); + break; + } + const ValueFlow::Value* v = getKnownValueFromToken(arguments[i]); + if (!v) + continue; + programMemory.setValue(arg->nameToken(), *v); + } + if (programMemory.empty() && !arguments.empty()) + continue; + std::vector values = execute(function->functionScope, programMemory, settings); + for (const ValueFlow::Value& v : values) { + if (v.isUninitValue()) + continue; + setFunctionReturnValue(function, tok, v, settings); + } + } +} + static bool needsInitialization(const Variable* var) { if (!var) @@ -6840,6 +7399,54 @@ static void valueFlowSmartPointer(TokenList &tokenlist, ErrorLogger & errorLogge } } +static Library::Container::Yield findIteratorYield(Token* tok, const Token** ftok, const Settings &settings) +{ + auto yield = astContainerYield(tok, ftok); + if (ftok && *ftok) + return yield; + + if (!tok->astParent()) + return yield; + + //begin/end free functions + return astFunctionYield(tok->astParent()->previous(), settings, ftok); +} + +static void valueFlowIterators(TokenList &tokenlist, const Settings &settings) +{ + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + if (!tok->scope()) + continue; + if (!tok->scope()->isExecutable()) + continue; + if (!astIsContainer(tok)) + continue; + Token* ftok = nullptr; + const Library::Container::Yield yield = findIteratorYield(tok, const_cast(&ftok), settings); + if (ftok) { + ValueFlow::Value v(0); + v.setKnown(); + if (yield == Library::Container::Yield::START_ITERATOR) { + v.valueType = ValueFlow::Value::ValueType::ITERATOR_START; + setTokenValue(ftok->next(), std::move(v), settings); + } else if (yield == Library::Container::Yield::END_ITERATOR) { + v.valueType = ValueFlow::Value::ValueType::ITERATOR_END; + setTokenValue(ftok->next(), std::move(v), settings); + } + } + } +} + +static std::list getIteratorValues(std::list values, const ValueFlow::Value::ValueKind* kind = nullptr) +{ + values.remove_if([&](const ValueFlow::Value& v) { + if (kind && v.valueKind != *kind) + return true; + return !v.isIteratorValue(); + }); + return values; +} + struct IteratorConditionHandler : SimpleConditionHandler { std::vector parse(const Token* tok, const Settings& /*settings*/) const override { Condition cond; @@ -6869,6 +7476,38 @@ struct IteratorConditionHandler : SimpleConditionHandler { } }; +static void valueFlowIteratorInfer(TokenList &tokenlist, const Settings &settings) +{ + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + if (!tok->scope()) + continue; + if (!tok->scope()->isExecutable()) + continue; + std::list values = getIteratorValues(tok->values()); + values.remove_if([&](const ValueFlow::Value& v) { + if (!v.isImpossible()) + return true; + if (!v.condition) + return true; + if (v.bound != ValueFlow::Value::Bound::Point) + return true; + if (v.isIteratorEndValue() && v.intvalue <= 0) + return true; + if (v.isIteratorStartValue() && v.intvalue >= 0) + return true; + return false; + }); + for (ValueFlow::Value& v:values) { + v.setPossible(); + if (v.isIteratorStartValue()) + v.intvalue++; + if (v.isIteratorEndValue()) + v.intvalue--; + setTokenValue(tok, std::move(v), settings); + } + } +} + static std::vector getContainerValues(const Token* tok) { std::vector values; @@ -7703,13 +8342,13 @@ void ValueFlow::setValues(TokenList& tokenlist, }); runner.run({ - VFA(analyzeImpossibleValues(tokenlist, settings)), + VFA(valueFlowImpossibleValues(tokenlist, settings)), VFA(valueFlowSymbolicOperators(symboldatabase, settings)), VFA(valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA(valueFlowSymbolicInfer(symboldatabase, settings)), - VFA(analyzeArrayBool(tokenlist, settings)), - VFA(analyzeArrayElement(tokenlist, settings)), - VFA(analyzeRightShift(tokenlist, settings)), + VFA(valueFlowArrayBool(tokenlist, settings)), + VFA(valueFlowArrayElement(tokenlist, settings)), + VFA(valueFlowRightShift(tokenlist, settings)), VFA(valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA_CPP(valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), @@ -7717,16 +8356,16 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings)), - VFA(analyzeFunctionReturn(tokenlist, errorLogger, settings)), + VFA(valueFlowFunctionReturn(tokenlist, errorLogger, settings)), VFA(valueFlowLifetime(tokenlist, errorLogger, settings)), VFA(valueFlowFunctionDefaultParameter(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowUninit(tokenlist, errorLogger, settings)), VFA_CPP(valueFlowAfterMove(tokenlist, symboldatabase, errorLogger, settings)), VFA_CPP(valueFlowSmartPointer(tokenlist, errorLogger, settings)), - VFA_CPP(analyzeIterators(tokenlist, settings)), + VFA_CPP(valueFlowIterators(tokenlist, settings)), VFA_CPP( valueFlowCondition(IteratorConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), - VFA_CPP(analyzeIteratorInfer(tokenlist, settings)), + VFA_CPP(valueFlowIteratorInfer(tokenlist, settings)), VFA_CPP(valueFlowContainerSize(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA_CPP( valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), diff --git a/lib/vf_analyze.h b/lib/vf_analyze.h index 97145576da5..6ad7b910f2b 100644 --- a/lib/vf_analyze.h +++ b/lib/vf_analyze.h @@ -20,23 +20,15 @@ #define vfAnalyzeH #include "vf_array.h" // IWYU pragma: export -#include "vf_arraybool.h" // IWYU pragma: export -#include "vf_arrayelement.h" // IWYU pragma: export #include "vf_bitand.h" // IWYU pragma: export #include "vf_debug.h" // IWYU pragma: export #include "vf_enumvalue.h" // IWYU pragma: export -#include "vf_functionreturn.h" // IWYU pragma: export #include "vf_globalconstvar.h" // IWYU pragma: export #include "vf_globalstaticvar.h" // IWYU pragma: export -#include "vf_impossiblevalues.h" // IWYU pragma: export -#include "vf_iteratorinfer.h" // IWYU pragma: export -#include "vf_iterators.h" // IWYU pragma: export #include "vf_number.h" // IWYU pragma: export #include "vf_pointeralias.h" // IWYU pragma: export -#include "vf_rightshift.h" // IWYU pragma: export #include "vf_sameexpressions.h" // IWYU pragma: export #include "vf_string.h" // IWYU pragma: export -#include "vf_symbolicinfer.h" // IWYU pragma: export #include "vf_unknownfunctionreturn.h" // IWYU pragma: export #endif // vfAnalyzeH diff --git a/lib/vf_arraybool.cpp b/lib/vf_arraybool.cpp deleted file mode 100644 index 41ee4cc0846..00000000000 --- a/lib/vf_arraybool.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_arraybool.h" - -#include "astutils.h" -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include -#include -#include - -namespace ValueFlow -{ - static bool isNonZero(const Token *tok) - { - return tok && (!tok->hasKnownIntValue() || tok->values().front().intvalue != 0); - } - - static const Token *getOtherOperand(const Token *tok) - { - if (!tok) - return nullptr; - if (!tok->astParent()) - return nullptr; - if (tok->astParent()->astOperand1() != tok) - return tok->astParent()->astOperand1(); - if (tok->astParent()->astOperand2() != tok) - return tok->astParent()->astOperand2(); - return nullptr; - } - - void analyzeArrayBool(TokenList &tokenlist, const Settings &settings) - { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->hasKnownIntValue()) - continue; - const Variable *var = nullptr; - bool known = false; - const std::list::const_iterator val = - std::find_if(tok->values().cbegin(), tok->values().cend(), std::mem_fn(&Value::isTokValue)); - if (val == tok->values().end()) { - var = tok->variable(); - known = true; - } else { - var = val->tokvalue->variable(); - known = val->isKnown(); - } - if (!var) - continue; - if (!var->isArray() || var->isArgument() || var->isStlType()) - continue; - if (isNonZero(getOtherOperand(tok)) && Token::Match(tok->astParent(), "%comp%")) - continue; - // TODO: Check for function argument - if ((astIsBool(tok->astParent()) && !Token::Match(tok->astParent(), "(|%name%")) || - (tok->astParent() && Token::Match(tok->astParent()->previous(), "if|while|for ("))) { - Value value{1}; - if (known) - value.setKnown(); - setTokenValue(tok, std::move(value), settings); - } - } - } -} diff --git a/lib/vf_arraybool.h b/lib/vf_arraybool.h deleted file mode 100644 index be35c897bd5..00000000000 --- a/lib/vf_arraybool.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfArrayBoolH -#define vfArrayBoolH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeArrayBool(TokenList &tokenlist, const Settings &settings); -} - -#endif // vfArrayBoolH diff --git a/lib/vf_arrayelement.cpp b/lib/vf_arrayelement.cpp deleted file mode 100644 index 90be4b412a9..00000000000 --- a/lib/vf_arrayelement.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_arrayelement.h" - -#include "astutils.h" -#include "library.h" -#include "mathlib.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include -#include -#include - -namespace ValueFlow -{ - void analyzeArrayElement(TokenList& tokenlist, const Settings& settings) - { - for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->hasKnownIntValue()) - continue; - const Token* indexTok = nullptr; - const Token* arrayTok = nullptr; - if (Token::simpleMatch(tok, "[") && tok->isBinaryOp()) { - indexTok = tok->astOperand2(); - arrayTok = tok->astOperand1(); - } else if (Token::Match(tok->tokAt(-2), ". %name% (") && astIsContainer(tok->tokAt(-2)->astOperand1())) { - arrayTok = tok->tokAt(-2)->astOperand1(); - const Library::Container* container = getLibraryContainer(arrayTok); - if (!container || container->stdAssociativeLike) - continue; - const Library::Container::Yield yield = container->getYield(tok->strAt(-1)); - if (yield != Library::Container::Yield::AT_INDEX) - continue; - indexTok = tok->astOperand2(); - } - - if (!indexTok || !arrayTok) - continue; - - for (const Value& arrayValue : arrayTok->values()) { - if (!arrayValue.isTokValue()) - continue; - if (arrayValue.isImpossible()) - continue; - for (const Value& indexValue : indexTok->values()) { - if (!indexValue.isIntValue()) - continue; - if (indexValue.isImpossible()) - continue; - if (!arrayValue.isKnown() && !indexValue.isKnown() && arrayValue.varId != 0 && indexValue.varId != 0 && - !(arrayValue.varId == indexValue.varId && arrayValue.varvalue == indexValue.varvalue)) - continue; - - Value result(0); - result.condition = arrayValue.condition ? arrayValue.condition : indexValue.condition; - result.setInconclusive(arrayValue.isInconclusive() || indexValue.isInconclusive()); - result.varId = (arrayValue.varId != 0) ? arrayValue.varId : indexValue.varId; - result.varvalue = (result.varId == arrayValue.varId) ? arrayValue.intvalue : indexValue.intvalue; - if (arrayValue.valueKind == indexValue.valueKind) - result.valueKind = arrayValue.valueKind; - - result.errorPath.insert(result.errorPath.end(), arrayValue.errorPath.cbegin(), arrayValue.errorPath.cend()); - result.errorPath.insert(result.errorPath.end(), indexValue.errorPath.cbegin(), indexValue.errorPath.cend()); - - const MathLib::bigint index = indexValue.intvalue; - - if (arrayValue.tokvalue->tokType() == Token::eString) { - const std::string s = arrayValue.tokvalue->strValue(); - if (index == s.size()) { - result.intvalue = 0; - setTokenValue(tok, std::move(result), settings); - } else if (index >= 0 && index < s.size()) { - result.intvalue = s[index]; - setTokenValue(tok, std::move(result), settings); - } - } else if (Token::simpleMatch(arrayValue.tokvalue, "{")) { - std::vector args = getArguments(arrayValue.tokvalue); - if (index < 0 || index >= args.size()) - continue; - const Token* arg = args[index]; - if (!arg->hasKnownIntValue()) - continue; - const Value& v = arg->values().front(); - result.intvalue = v.intvalue; - result.errorPath.insert(result.errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend()); - setTokenValue(tok, std::move(result), settings); - } - } - } - } - } -} diff --git a/lib/vf_arrayelement.h b/lib/vf_arrayelement.h deleted file mode 100644 index d924109f875..00000000000 --- a/lib/vf_arrayelement.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfArrayElementH -#define vfArrayElementH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeArrayElement(TokenList& tokenlist, const Settings& settings); -} - -#endif // vfArrayElementH diff --git a/lib/vf_bailout.cpp b/lib/vf_bailout.cpp deleted file mode 100644 index 05cb24a3439..00000000000 --- a/lib/vf_bailout.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_bailout.h" - -#include "errorlogger.h" -#include "errortypes.h" -#include "path.h" -#include "tokenlist.h" - -#include - -namespace ValueFlow -{ - void bailoutInternal(const std::string& type, const TokenList &tokenlist, ErrorLogger &errorLogger, const Token *tok, const std::string &what, const std::string &file, int line, std::string function) - { - if (function.find("operator") != std::string::npos) - function = "(valueFlow)"; - ErrorMessage::FileLocation loc(tok, &tokenlist); - const std::string location = Path::stripDirectoryPart(file) + ":" + std::to_string(line) + ":"; - ErrorMessage errmsg({std::move(loc)}, tokenlist.getSourceFilePath(), Severity::debug, - (file.empty() ? "" : location) + function + " bailout: " + what, type, Certainty::normal); - errorLogger.reportErr(errmsg); - } -} diff --git a/lib/vf_bailout.h b/lib/vf_bailout.h deleted file mode 100644 index 5dac1265309..00000000000 --- a/lib/vf_bailout.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfBailoutH -#define vfBailoutH - -#include - -class TokenList; -class ErrorLogger; -class Token; - -namespace ValueFlow -{ - void bailoutInternal(const std::string& type, const TokenList &tokenlist, ErrorLogger &errorLogger, const Token *tok, const std::string &what, const std::string &file, int line, std::string function); -} - -#define bailout2(type, tokenlist, errorLogger, tok, what) ValueFlow::bailoutInternal((type), (tokenlist), (errorLogger), (tok), (what), __FILE__, __LINE__, __func__) - -#define bailout(tokenlist, errorLogger, tok, what) bailout2("valueFlowBailout", (tokenlist), (errorLogger), (tok), (what)) - -#define bailoutIncompleteVar(tokenlist, errorLogger, tok, what) ValueFlow::bailoutInternal("valueFlowBailoutIncompleteVar", (tokenlist), (errorLogger), (tok), (what), "", 0, __func__) - -#endif // vfBailoutH diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index 4cf812b3797..a65a173651d 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -394,14 +394,4 @@ namespace ValueFlow " => " + local.function_name() + ": " + debugString(v); v.debugPath.emplace_back(tok, std::move(s)); } - - std::list getIteratorValues(std::list values, const Value::ValueKind* kind) - { - values.remove_if([&](const Value& v) { - if (kind && v.valueKind != *kind) - return true; - return !v.isIteratorValue(); - }); - return values; - } } diff --git a/lib/vf_common.h b/lib/vf_common.h index 8e9a7a042ae..e2ce89e2ec6 100644 --- a/lib/vf_common.h +++ b/lib/vf_common.h @@ -51,8 +51,6 @@ namespace ValueFlow SourceLocation ctx, const Token* tok, SourceLocation local = SourceLocation::current()); - - std::list getIteratorValues(std::list values, const Value::ValueKind* kind = nullptr); } #endif // vfCommonH diff --git a/lib/vf_functionreturn.cpp b/lib/vf_functionreturn.cpp deleted file mode 100644 index a786dbe1f08..00000000000 --- a/lib/vf_functionreturn.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_functionreturn.h" - -#include "astutils.h" -#include "programmemory.h" -#include "settings.h" -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_bailout.h" -#include "vf_settokenvalue.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace ValueFlow -{ - static const Value* getKnownValueFromToken(const Token* tok) - { - if (!tok) - return nullptr; - auto it = std::find_if(tok->values().begin(), tok->values().end(), [&](const Value& v) { - return (v.isIntValue() || v.isContainerSizeValue() || v.isFloatValue()) && v.isKnown(); - }); - if (it == tok->values().end()) - return nullptr; - return std::addressof(*it); - } - - static const Value* getKnownValueFromTokens(const std::vector& toks) - { - if (toks.empty()) - return nullptr; - const Value* result = getKnownValueFromToken(toks.front()); - if (!result) - return nullptr; - if (!std::all_of(std::next(toks.begin()), toks.end(), [&](const Token* tok) { - return std::any_of(tok->values().begin(), tok->values().end(), [&](const Value& v) { - return v.equalValue(*result) && v.valueKind == result->valueKind; - }); - })) - return nullptr; - return result; - } - - static void setFunctionReturnValue(const Function* f, Token* tok, Value v, const Settings& settings) - { - if (f->hasVirtualSpecifier()) { - if (v.isImpossible()) - return; - v.setPossible(); - } else if (!v.isImpossible()) { - v.setKnown(); - } - v.errorPath.emplace_back(tok, "Calling function '" + f->name() + "' returns " + v.toString()); - setTokenValue(tok, std::move(v), settings); - } - - void analyzeFunctionReturn(TokenList &tokenlist, ErrorLogger &errorLogger, const Settings& settings) - { - for (Token *tok = tokenlist.back(); tok; tok = tok->previous()) { - if (tok->str() != "(" || !tok->astOperand1() || tok->isCast()) - continue; - - const Function* function = nullptr; - if (Token::Match(tok->previous(), "%name% (")) - function = tok->previous()->function(); - else - function = tok->astOperand1()->function(); - if (!function) - continue; - // TODO: Check if member variable is a pointer or reference - if (function->isImplicitlyVirtual() && !function->hasFinalSpecifier()) - continue; - - if (tok->hasKnownValue()) - continue; - - std::vector returns = Function::findReturns(function); - if (returns.empty()) - continue; - - if (const Value* v = getKnownValueFromTokens(returns)) { - setFunctionReturnValue(function, tok, *v, settings); - continue; - } - - // Arguments.. - std::vector arguments = getArguments(tok); - - ProgramMemory programMemory; - for (std::size_t i = 0; i < arguments.size(); ++i) { - const Variable * const arg = function->getArgumentVar(i); - if (!arg) { - if (settings.debugwarnings) - bailout(tokenlist, errorLogger, tok, "function return; unhandled argument type"); - programMemory.clear(); - break; - } - const Value* v = getKnownValueFromToken(arguments[i]); - if (!v) - continue; - programMemory.setValue(arg->nameToken(), *v); - } - if (programMemory.empty() && !arguments.empty()) - continue; - std::vector values = execute(function->functionScope, programMemory, settings); - for (const Value& v : values) { - if (v.isUninitValue()) - continue; - setFunctionReturnValue(function, tok, v, settings); - } - } - } -} diff --git a/lib/vf_functionreturn.h b/lib/vf_functionreturn.h deleted file mode 100644 index b32af39f70b..00000000000 --- a/lib/vf_functionreturn.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfFunctionReturnH -#define vfFunctionReturnH - -class TokenList; -class ErrorLogger; -class Settings; - -namespace ValueFlow -{ - void analyzeFunctionReturn(TokenList &tokenlist, ErrorLogger &errorLogger, const Settings& settings); -} - -#endif // vfFunctionReturnH diff --git a/lib/vf_impossiblevalues.cpp b/lib/vf_impossiblevalues.cpp deleted file mode 100644 index 591e0880588..00000000000 --- a/lib/vf_impossiblevalues.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_impossiblevalues.h" - -#include "astutils.h" -#include "calculate.h" -#include "library.h" -#include "mathlib.h" -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "utils.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace ValueFlow -{ - static std::vector minUnsignedValue(const Token* tok, int depth = 8) - { - std::vector result; - if (!tok) - return result; - if (depth < 0) - return result; - if (tok->hasKnownIntValue()) { - result = {tok->values().front().intvalue}; - } else if (!Token::Match(tok, "-|%|&|^") && tok->isConstOp() && tok->astOperand1() && tok->astOperand2()) { - std::vector op1 = minUnsignedValue(tok->astOperand1(), depth - 1); - std::vector op2 = minUnsignedValue(tok->astOperand2(), depth - 1); - if (!op1.empty() && !op2.empty()) { - result = calculate>(tok->str(), op1.front(), op2.front()); - } - } - if (result.empty() && astIsUnsigned(tok)) - result = {0}; - return result; - } - - static bool isSameToken(const Token* tok1, const Token* tok2) - { - if (!tok1 || !tok2) - return false; - if (tok1->exprId() != 0 && tok1->exprId() == tok2->exprId()) - return true; - if (tok1->hasKnownIntValue() && tok2->hasKnownIntValue()) - return tok1->values().front().intvalue == tok2->values().front().intvalue; - return false; - } - - static bool isConvertedToIntegral(const Token* tok, const Settings& settings) - { - if (!tok) - return false; - std::vector parentTypes = getParentValueTypes(tok, settings); - if (parentTypes.empty()) - return false; - const ValueType& vt = parentTypes.front(); - return vt.type != ValueType::UNKNOWN_INT && vt.isIntegral(); - } - - void analyzeImpossibleValues(TokenList& tokenList, const Settings& settings) - { - for (Token* tok = tokenList.front(); tok; tok = tok->next()) { - if (tok->hasKnownIntValue()) - continue; - if (Token::Match(tok, "true|false")) - continue; - if (astIsBool(tok) || Token::Match(tok, "%comp%")) { - Value lower{-1}; - lower.bound = Value::Bound::Upper; - lower.setImpossible(); - setTokenValue(tok, std::move(lower), settings); - - Value upper{2}; - upper.bound = Value::Bound::Lower; - upper.setImpossible(); - setTokenValue(tok, std::move(upper), settings); - } else if (astIsUnsigned(tok) && !astIsPointer(tok)) { - std::vector minvalue = minUnsignedValue(tok); - if (minvalue.empty()) - continue; - Value value{std::max(0, minvalue.front()) - 1}; - value.bound = Value::Bound::Upper; - value.setImpossible(); - setTokenValue(tok, std::move(value), settings); - } - if (Token::simpleMatch(tok, "?") && Token::Match(tok->astOperand1(), "<|<=|>|>=")) { - const Token* condTok = tok->astOperand1(); - const Token* branchesTok = tok->astOperand2(); - - auto tokens = makeArray(condTok->astOperand1(), condTok->astOperand2()); - auto branches = makeArray(branchesTok->astOperand1(), branchesTok->astOperand2()); - bool flipped = false; - if (std::equal(tokens.cbegin(), tokens.cend(), branches.crbegin(), &isSameToken)) - flipped = true; - else if (!std::equal(tokens.cbegin(), tokens.cend(), branches.cbegin(), &isSameToken)) - continue; - const bool isMin = Token::Match(condTok, "<|<=") ^ flipped; - std::vector values; - for (const Token* tok2 : tokens) { - if (tok2->hasKnownIntValue()) { - values.emplace_back(tok2->values().front()); - } else { - Value symValue{}; - symValue.valueType = Value::ValueType::SYMBOLIC; - symValue.tokvalue = tok2; - values.push_back(symValue); - std::copy_if(tok2->values().cbegin(), - tok2->values().cend(), - std::back_inserter(values), - [](const Value& v) { - if (!v.isKnown()) - return false; - return v.isSymbolicValue(); - }); - } - } - for (Value& value : values) { - value.setImpossible(); - if (isMin) { - value.intvalue++; - value.bound = Value::Bound::Lower; - } else { - value.intvalue--; - value.bound = Value::Bound::Upper; - } - setTokenValue(tok, std::move(value), settings); - } - - } else if (Token::simpleMatch(tok, "%") && tok->astOperand2() && tok->astOperand2()->hasKnownIntValue()) { - Value value{tok->astOperand2()->values().front()}; - value.bound = Value::Bound::Lower; - value.setImpossible(); - setTokenValue(tok, std::move(value), settings); - } else if (Token::Match(tok, "abs|labs|llabs|fabs|fabsf|fabsl (")) { - Value value{-1}; - value.bound = Value::Bound::Upper; - value.setImpossible(); - setTokenValue(tok->next(), std::move(value), settings); - } else if (Token::Match(tok, ". data|c_str (") && astIsContainerOwned(tok->astOperand1())) { - const Library::Container* container = getLibraryContainer(tok->astOperand1()); - if (!container) - continue; - if (!container->stdStringLike) - continue; - if (container->view) - continue; - Value value{0}; - value.setImpossible(); - setTokenValue(tok->tokAt(2), std::move(value), settings); - } else if (Token::Match(tok, "make_shared|make_unique <") && Token::simpleMatch(tok->linkAt(1), "> (")) { - Value value{0}; - value.setImpossible(); - setTokenValue(tok->linkAt(1)->next(), std::move(value), settings); - } else if ((tokenList.isCPP() && Token::simpleMatch(tok, "this")) || tok->isUnaryOp("&")) { - Value value{0}; - value.setImpossible(); - setTokenValue(tok, std::move(value), settings); - } else if (tok->variable() && tok->variable()->isArray() && !tok->variable()->isArgument() && - !tok->variable()->isStlType()) { - Value value{0}; - value.setImpossible(); - setTokenValue(tok, std::move(value), settings); - } else if (tok->isIncompleteVar() && tok->astParent() && tok->astParent()->isUnaryOp("-") && - isConvertedToIntegral(tok->astParent(), settings)) { - Value value{0}; - value.setImpossible(); - setTokenValue(tok, std::move(value), settings); - } - } - } -} diff --git a/lib/vf_impossiblevalues.h b/lib/vf_impossiblevalues.h deleted file mode 100644 index 018976ec605..00000000000 --- a/lib/vf_impossiblevalues.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfImpossibleValuesH -#define vfImpossibleValuesH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeImpossibleValues(TokenList& tokenList, const Settings& settings); -} - -#endif // vfImpossibleValuesH diff --git a/lib/vf_iteratorinfer.cpp b/lib/vf_iteratorinfer.cpp deleted file mode 100644 index cd1d26b1675..00000000000 --- a/lib/vf_iteratorinfer.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_iteratorinfer.h" - -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_common.h" -#include "vf_settokenvalue.h" - -#include -#include - -namespace ValueFlow -{ - void analyzeIteratorInfer(TokenList &tokenlist, const Settings &settings) - { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (!tok->scope()) - continue; - if (!tok->scope()->isExecutable()) - continue; - std::list values = getIteratorValues(tok->values()); - values.remove_if([&](const Value& v) { - if (!v.isImpossible()) - return true; - if (!v.condition) - return true; - if (v.bound != Value::Bound::Point) - return true; - if (v.isIteratorEndValue() && v.intvalue <= 0) - return true; - if (v.isIteratorStartValue() && v.intvalue >= 0) - return true; - return false; - }); - for (Value& v:values) { - v.setPossible(); - if (v.isIteratorStartValue()) - v.intvalue++; - if (v.isIteratorEndValue()) - v.intvalue--; - setTokenValue(tok, std::move(v), settings); - } - } - } -} diff --git a/lib/vf_iteratorinfer.h b/lib/vf_iteratorinfer.h deleted file mode 100644 index a2bc4964886..00000000000 --- a/lib/vf_iteratorinfer.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfIteratorInferH -#define vfIteratorInferH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeIteratorInfer(TokenList &tokenlist, const Settings &settings); -} - -#endif // vfIteratorInferH diff --git a/lib/vf_iterators.cpp b/lib/vf_iterators.cpp deleted file mode 100644 index 1f85a27873a..00000000000 --- a/lib/vf_iterators.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_iterators.h" - -#include "astutils.h" -#include "library.h" -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include - -namespace ValueFlow -{ - static Library::Container::Yield findIteratorYield(Token* tok, const Token** ftok, const Settings &settings) - { - auto yield = astContainerYield(tok, ftok); - if (ftok && *ftok) - return yield; - - if (!tok->astParent()) - return yield; - - //begin/end free functions - return astFunctionYield(tok->astParent()->previous(), settings, ftok); - } - - void analyzeIterators(TokenList &tokenlist, const Settings &settings) - { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (!tok->scope()) - continue; - if (!tok->scope()->isExecutable()) - continue; - if (!astIsContainer(tok)) - continue; - Token* ftok = nullptr; - const Library::Container::Yield yield = findIteratorYield(tok, const_cast(&ftok), settings); - if (ftok) { - Value v(0); - v.setKnown(); - if (yield == Library::Container::Yield::START_ITERATOR) { - v.valueType = Value::ValueType::ITERATOR_START; - setTokenValue(ftok->next(), std::move(v), settings); - } else if (yield == Library::Container::Yield::END_ITERATOR) { - v.valueType = Value::ValueType::ITERATOR_END; - setTokenValue(ftok->next(), std::move(v), settings); - } - } - } - } -} diff --git a/lib/vf_iterators.h b/lib/vf_iterators.h deleted file mode 100644 index 22b2d6ab87c..00000000000 --- a/lib/vf_iterators.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfIteratorsH -#define vfIteratorsH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeIterators(TokenList &tokenlist, const Settings &settings); -} - -#endif // vfIteratorsH diff --git a/lib/vf_rightshift.cpp b/lib/vf_rightshift.cpp deleted file mode 100644 index f27599fbb01..00000000000 --- a/lib/vf_rightshift.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_rightshift.h" - -#include "mathlib.h" -#include "platform.h" -#include "settings.h" -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include -#include - -namespace ValueFlow -{ - static bool getExpressionRange(const Token *expr, MathLib::bigint *minvalue, MathLib::bigint *maxvalue) - { - if (expr->hasKnownIntValue()) { - if (minvalue) - *minvalue = expr->values().front().intvalue; - if (maxvalue) - *maxvalue = expr->values().front().intvalue; - return true; - } - - if (expr->str() == "&" && expr->astOperand1() && expr->astOperand2()) { - MathLib::bigint vals[4]; - const bool lhsHasKnownRange = getExpressionRange(expr->astOperand1(), &vals[0], &vals[1]); - const bool rhsHasKnownRange = getExpressionRange(expr->astOperand2(), &vals[2], &vals[3]); - if (!lhsHasKnownRange && !rhsHasKnownRange) - return false; - if (!lhsHasKnownRange || !rhsHasKnownRange) { - if (minvalue) - *minvalue = lhsHasKnownRange ? vals[0] : vals[2]; - if (maxvalue) - *maxvalue = lhsHasKnownRange ? vals[1] : vals[3]; - } else { - if (minvalue) - *minvalue = vals[0] & vals[2]; - if (maxvalue) - *maxvalue = vals[1] & vals[3]; - } - return true; - } - - if (expr->str() == "%" && expr->astOperand1() && expr->astOperand2()) { - MathLib::bigint vals[4]; - if (!getExpressionRange(expr->astOperand2(), &vals[2], &vals[3])) - return false; - if (vals[2] <= 0) - return false; - const bool lhsHasKnownRange = getExpressionRange(expr->astOperand1(), &vals[0], &vals[1]); - if (lhsHasKnownRange && vals[0] < 0) - return false; - // If lhs has unknown value, it must be unsigned - if (!lhsHasKnownRange && (!expr->astOperand1()->valueType() || expr->astOperand1()->valueType()->sign != ValueType::Sign::UNSIGNED)) - return false; - if (minvalue) - *minvalue = 0; - if (maxvalue) - *maxvalue = vals[3] - 1; - return true; - } - - return false; - } - - void analyzeRightShift(TokenList &tokenList, const Settings& settings) - { - for (Token *tok = tokenList.front(); tok; tok = tok->next()) { - if (tok->str() != ">>") - continue; - - if (tok->hasKnownValue()) - continue; - - if (!tok->astOperand1() || !tok->astOperand2()) - continue; - - if (!tok->astOperand2()->hasKnownValue()) - continue; - - const MathLib::bigint rhsvalue = tok->astOperand2()->values().front().intvalue; - if (rhsvalue < 0) - continue; - - if (!tok->astOperand1()->valueType() || !tok->astOperand1()->valueType()->isIntegral()) - continue; - - if (!tok->astOperand2()->valueType() || !tok->astOperand2()->valueType()->isIntegral()) - continue; - - MathLib::bigint lhsmax=0; - if (!getExpressionRange(tok->astOperand1(), nullptr, &lhsmax)) - continue; - if (lhsmax < 0) - continue; - int lhsbits; - if ((tok->astOperand1()->valueType()->type == ValueType::Type::CHAR) || - (tok->astOperand1()->valueType()->type == ValueType::Type::SHORT) || - (tok->astOperand1()->valueType()->type == ValueType::Type::WCHAR_T) || - (tok->astOperand1()->valueType()->type == ValueType::Type::BOOL) || - (tok->astOperand1()->valueType()->type == ValueType::Type::INT)) - lhsbits = settings.platform.int_bit; - else if (tok->astOperand1()->valueType()->type == ValueType::Type::LONG) - lhsbits = settings.platform.long_bit; - else if (tok->astOperand1()->valueType()->type == ValueType::Type::LONGLONG) - lhsbits = settings.platform.long_long_bit; - else - continue; - if (rhsvalue >= lhsbits || rhsvalue >= MathLib::bigint_bits || (1ULL << rhsvalue) <= lhsmax) - continue; - - Value val(0); - val.setKnown(); - setTokenValue(tok, std::move(val), settings); - } - } -} diff --git a/lib/vf_rightshift.h b/lib/vf_rightshift.h deleted file mode 100644 index cf7c9c61b46..00000000000 --- a/lib/vf_rightshift.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfRightShiftH -#define vfRightShiftH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeRightShift(TokenList &tokenList, const Settings& settings); -} - -#endif // vfRightShiftH diff --git a/lib/vf_symbolicinfer.cpp b/lib/vf_symbolicinfer.cpp deleted file mode 100644 index ef933912e21..00000000000 --- a/lib/vf_symbolicinfer.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_symbolicinfer.h" - -#include "astutils.h" -#include "infer.h" -#include "mathlib.h" -#include "symboldatabase.h" -#include "token.h" -#include "valueptr.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include -#include - -namespace ValueFlow -{ - struct SymbolicInferModel : InferModel { - const Token* expr; - explicit SymbolicInferModel(const Token* tok) : expr(tok) { - assert(expr->exprId() != 0); - } - bool match(const Value& value) const override - { - return value.isSymbolicValue() && value.tokvalue && value.tokvalue->exprId() == expr->exprId(); - } - Value yield(MathLib::bigint value) const override - { - Value result(value); - result.valueType = Value::ValueType::SYMBOLIC; - result.tokvalue = expr; - result.setKnown(); - return result; - } - }; - - void valueFlowSymbolicInfer(const SymbolDatabase& symboldatabase, const Settings& settings) - { - for (const Scope* scope : symboldatabase.functionScopes) { - for (auto* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { - if (!Token::Match(tok, "-|%comp%")) - continue; - if (tok->hasKnownIntValue()) - continue; - if (!tok->astOperand1()) - continue; - if (!tok->astOperand2()) - continue; - if (tok->astOperand1()->exprId() == 0) - continue; - if (tok->astOperand2()->exprId() == 0) - continue; - if (tok->astOperand1()->hasKnownIntValue()) - continue; - if (tok->astOperand2()->hasKnownIntValue()) - continue; - if (astIsFloat(tok->astOperand1(), false)) - continue; - if (astIsFloat(tok->astOperand2(), false)) - continue; - - SymbolicInferModel leftModel{tok->astOperand1()}; - std::vector values = infer(leftModel, tok->str(), 0, tok->astOperand2()->values()); - if (values.empty()) { - SymbolicInferModel rightModel{tok->astOperand2()}; - values = infer(rightModel, tok->str(), tok->astOperand1()->values(), 0); - } - for (Value& value : values) { - setTokenValue(tok, std::move(value), settings); - } - } - } - } -} diff --git a/lib/vf_symbolicinfer.h b/lib/vf_symbolicinfer.h deleted file mode 100644 index 6a21e4a9e55..00000000000 --- a/lib/vf_symbolicinfer.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfSymbolicInferH -#define vfSymbolicInferH - -class SymbolDatabase; -class Settings; - -namespace ValueFlow -{ - void valueFlowSymbolicInfer(const SymbolDatabase& symboldatabase, const Settings& settings); -} - -#endif // vfSymbolicInferH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index b7dee5fd426..bd46c392669 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -96,26 +96,17 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/tokenlist.o \ $(libcppdir)/utils.o \ $(libcppdir)/vf_array.o \ - $(libcppdir)/vf_arraybool.o \ - $(libcppdir)/vf_arrayelement.o \ - $(libcppdir)/vf_bailout.o \ $(libcppdir)/vf_bitand.o \ $(libcppdir)/vf_common.o \ $(libcppdir)/vf_debug.o \ $(libcppdir)/vf_enumvalue.o \ - $(libcppdir)/vf_functionreturn.o \ $(libcppdir)/vf_globalconstvar.o \ $(libcppdir)/vf_globalstaticvar.o \ - $(libcppdir)/vf_impossiblevalues.o \ - $(libcppdir)/vf_iteratorinfer.o \ - $(libcppdir)/vf_iterators.o \ $(libcppdir)/vf_number.o \ $(libcppdir)/vf_pointeralias.o \ - $(libcppdir)/vf_rightshift.o \ $(libcppdir)/vf_sameexpressions.o \ $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vf_string.o \ - $(libcppdir)/vf_symbolicinfer.o \ $(libcppdir)/vf_unknownfunctionreturn.o \ $(libcppdir)/vfvalue.o @@ -161,7 +152,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_array.h ../lib/vf_arraybool.h ../lib/vf_arrayelement.h ../lib/vf_bailout.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_functionreturn.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_impossiblevalues.h ../lib/vf_iteratorinfer.h ../lib/vf_iterators.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_rightshift.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_symbolicinfer.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_array.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h @@ -350,15 +341,6 @@ $(libcppdir)/utils.o: ../lib/utils.cpp ../lib/config.h ../lib/utils.h $(libcppdir)/vf_array.o: ../lib/vf_array.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_array.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_array.cpp -$(libcppdir)/vf_arraybool.o: ../lib/vf_arraybool.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_arraybool.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_arraybool.cpp - -$(libcppdir)/vf_arrayelement.o: ../lib/vf_arrayelement.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_arrayelement.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_arrayelement.cpp - -$(libcppdir)/vf_bailout.o: ../lib/vf_bailout.cpp ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/path.h ../lib/standards.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_bailout.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_bailout.cpp - $(libcppdir)/vf_bitand.o: ../lib/vf_bitand.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_bitand.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_bitand.cpp @@ -371,33 +353,18 @@ $(libcppdir)/vf_debug.o: ../lib/vf_debug.cpp ../lib/addoninfo.h ../lib/color.h . $(libcppdir)/vf_enumvalue.o: ../lib/vf_enumvalue.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_enumvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_enumvalue.cpp -$(libcppdir)/vf_functionreturn.o: ../lib/vf_functionreturn.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_bailout.h ../lib/vf_functionreturn.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_functionreturn.cpp - $(libcppdir)/vf_globalconstvar.o: ../lib/vf_globalconstvar.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_globalconstvar.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_globalconstvar.cpp $(libcppdir)/vf_globalstaticvar.o: ../lib/vf_globalstaticvar.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_globalstaticvar.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_globalstaticvar.cpp -$(libcppdir)/vf_impossiblevalues.o: ../lib/vf_impossiblevalues.cpp ../lib/astutils.h ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_impossiblevalues.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_impossiblevalues.cpp - -$(libcppdir)/vf_iteratorinfer.o: ../lib/vf_iteratorinfer.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_iteratorinfer.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_iteratorinfer.cpp - -$(libcppdir)/vf_iterators.o: ../lib/vf_iterators.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_iterators.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_iterators.cpp - $(libcppdir)/vf_number.o: ../lib/vf_number.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_number.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_number.cpp $(libcppdir)/vf_pointeralias.o: ../lib/vf_pointeralias.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_pointeralias.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_pointeralias.cpp -$(libcppdir)/vf_rightshift.o: ../lib/vf_rightshift.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_rightshift.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_rightshift.cpp - $(libcppdir)/vf_sameexpressions.o: ../lib/vf_sameexpressions.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_sameexpressions.cpp @@ -407,9 +374,6 @@ $(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/addoninfo.h $(libcppdir)/vf_string.o: ../lib/vf_string.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_string.cpp -$(libcppdir)/vf_symbolicinfer.o: ../lib/vf_symbolicinfer.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vf_settokenvalue.h ../lib/vf_symbolicinfer.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_symbolicinfer.cpp - $(libcppdir)/vf_unknownfunctionreturn.o: ../lib/vf_unknownfunctionreturn.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_unknownfunctionreturn.cpp From 4d6467746f08e2611756ed4871d45e1e6dd127e6 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 5 Nov 2024 09:50:17 -0600 Subject: [PATCH 07/13] Revert "ValueFlow: extracted more code into separate files (#6449)" This reverts commit 25d79210e748509e00acb899059d2b001a371998. --- Makefile | 40 +--- lib/cppcheck.vcxproj | 18 -- lib/lib.pri | 18 -- lib/valueflow.cpp | 328 ++++++++++++++++++++++++++++++- lib/vf_analyze.h | 9 - lib/vf_array.cpp | 90 --------- lib/vf_array.h | 30 --- lib/vf_bitand.cpp | 62 ------ lib/vf_bitand.h | 30 --- lib/vf_common.cpp | 14 -- lib/vf_common.h | 2 - lib/vf_debug.cpp | 53 ----- lib/vf_debug.h | 31 --- lib/vf_globalconstvar.cpp | 67 ------- lib/vf_globalconstvar.h | 30 --- lib/vf_globalstaticvar.cpp | 82 -------- lib/vf_globalstaticvar.h | 30 --- lib/vf_pointeralias.cpp | 63 ------ lib/vf_pointeralias.h | 30 --- lib/vf_sameexpressions.cpp | 67 ------- lib/vf_sameexpressions.h | 30 --- lib/vf_string.cpp | 43 ---- lib/vf_string.h | 30 --- lib/vf_unknownfunctionreturn.cpp | 65 ------ lib/vf_unknownfunctionreturn.h | 30 --- oss-fuzz/Makefile | 40 +--- 26 files changed, 323 insertions(+), 1009 deletions(-) delete mode 100644 lib/vf_array.cpp delete mode 100644 lib/vf_array.h delete mode 100644 lib/vf_bitand.cpp delete mode 100644 lib/vf_bitand.h delete mode 100644 lib/vf_debug.cpp delete mode 100644 lib/vf_debug.h delete mode 100644 lib/vf_globalconstvar.cpp delete mode 100644 lib/vf_globalconstvar.h delete mode 100644 lib/vf_globalstaticvar.cpp delete mode 100644 lib/vf_globalstaticvar.h delete mode 100644 lib/vf_pointeralias.cpp delete mode 100644 lib/vf_pointeralias.h delete mode 100644 lib/vf_sameexpressions.cpp delete mode 100644 lib/vf_sameexpressions.h delete mode 100644 lib/vf_string.cpp delete mode 100644 lib/vf_string.h delete mode 100644 lib/vf_unknownfunctionreturn.cpp delete mode 100644 lib/vf_unknownfunctionreturn.h diff --git a/Makefile b/Makefile index e2a15da9dc5..ad9f84ee8ce 100644 --- a/Makefile +++ b/Makefile @@ -252,19 +252,10 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/token.o \ $(libcppdir)/tokenlist.o \ $(libcppdir)/utils.o \ - $(libcppdir)/vf_array.o \ - $(libcppdir)/vf_bitand.o \ $(libcppdir)/vf_common.o \ - $(libcppdir)/vf_debug.o \ $(libcppdir)/vf_enumvalue.o \ - $(libcppdir)/vf_globalconstvar.o \ - $(libcppdir)/vf_globalstaticvar.o \ $(libcppdir)/vf_number.o \ - $(libcppdir)/vf_pointeralias.o \ - $(libcppdir)/vf_sameexpressions.o \ $(libcppdir)/vf_settokenvalue.o \ - $(libcppdir)/vf_string.o \ - $(libcppdir)/vf_unknownfunctionreturn.o \ $(libcppdir)/vfvalue.o EXTOBJ = externals/simplecpp/simplecpp.o \ @@ -473,7 +464,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_array.h lib/vf_bitand.h lib/vf_common.h lib/vf_debug.h lib/vf_enumvalue.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_number.h lib/vf_pointeralias.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vf_string.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_common.h lib/vf_enumvalue.h lib/vf_number.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h @@ -659,45 +650,18 @@ $(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/ $(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_array.o: lib/vf_array.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_array.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_array.cpp - -$(libcppdir)/vf_bitand.o: lib/vf_bitand.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_bitand.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_bitand.cpp - -$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_debug.o: lib/vf_debug.cpp lib/addoninfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_debug.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_debug.cpp - $(libcppdir)/vf_enumvalue.o: lib/vf_enumvalue.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_enumvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_enumvalue.cpp -$(libcppdir)/vf_globalconstvar.o: lib/vf_globalconstvar.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_globalconstvar.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_globalconstvar.cpp - -$(libcppdir)/vf_globalstaticvar.o: lib/vf_globalstaticvar.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_globalstaticvar.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_globalstaticvar.cpp - $(libcppdir)/vf_number.o: lib/vf_number.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_number.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_number.cpp -$(libcppdir)/vf_pointeralias.o: lib/vf_pointeralias.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_pointeralias.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_pointeralias.cpp - -$(libcppdir)/vf_sameexpressions.o: lib/vf_sameexpressions.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_sameexpressions.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_sameexpressions.cpp - $(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp -$(libcppdir)/vf_string.o: lib/vf_string.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_settokenvalue.h lib/vf_string.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_string.cpp - -$(libcppdir)/vf_unknownfunctionreturn.o: lib/vf_unknownfunctionreturn.cpp lib/addoninfo.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vf_unknownfunctionreturn.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_unknownfunctionreturn.cpp - $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vfvalue.cpp diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 78171d08a45..1ec10c8dbe8 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -87,19 +87,10 @@ - - - - - - - - - @@ -180,19 +171,10 @@ - - - - - - - - - diff --git a/lib/lib.pri b/lib/lib.pri index b2bcdf5c70f..45e0624dbf9 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -78,19 +78,10 @@ HEADERS += $${PWD}/addoninfo.h \ $${PWD}/valueptr.h \ $${PWD}/version.h \ $${PWD}/vf_analyze.h \ - $${PWD}/vf_array.h \ - $${PWD}/vf_bitand.h \ $${PWD}/vf_common.h \ - $${PWD}/vf_debug.h \ $${PWD}/vf_enumvalue.h \ - $${PWD}/vf_globalconstvar.h \ - $${PWD}/vf_globalstaticvar.h \ $${PWD}/vf_number.h \ - $${PWD}/vf_pointeralias.h \ - $${PWD}/vf_sameexpressions.h \ $${PWD}/vf_settokenvalue.h \ - $${PWD}/vf_string.h \ - $${PWD}/vf_unknownfunctionreturn.h \ $${PWD}/vfvalue.h \ $${PWD}/xml.h @@ -156,17 +147,8 @@ SOURCES += $${PWD}/valueflow.cpp \ $${PWD}/token.cpp \ $${PWD}/tokenlist.cpp \ $${PWD}/utils.cpp \ - $${PWD}/vf_array.cpp \ - $${PWD}/vf_bitand.cpp \ $${PWD}/vf_common.cpp \ - $${PWD}/vf_debug.cpp \ $${PWD}/vf_enumvalue.cpp \ - $${PWD}/vf_globalconstvar.cpp \ - $${PWD}/vf_globalstaticvar.cpp \ $${PWD}/vf_number.cpp \ - $${PWD}/vf_pointeralias.cpp \ - $${PWD}/vf_sameexpressions.cpp \ $${PWD}/vf_settokenvalue.cpp \ - $${PWD}/vf_string.cpp \ - $${PWD}/vf_unknownfunctionreturn.cpp \ $${PWD}/vfvalue.cpp diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 73662baaa5f..d6921734c0f 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -125,6 +125,7 @@ #include #include #include +#include #include #include #include @@ -541,6 +542,75 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings, int m return 0; } +static void valueFlowString(TokenList &tokenlist, const Settings& settings) +{ + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + if (tok->tokType() == Token::eString) { + ValueFlow::Value strvalue; + strvalue.valueType = ValueFlow::Value::ValueType::TOK; + strvalue.tokvalue = tok; + strvalue.setKnown(); + setTokenValue(tok, std::move(strvalue), settings); + } + } +} + +static void valueFlowArray(TokenList &tokenlist, const Settings &settings) +{ + std::map constantArrays; + + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + if (tok->varId() > 0) { + // array + const std::map::const_iterator it = constantArrays.find(tok->varId()); + if (it != constantArrays.end()) { + ValueFlow::Value value; + value.valueType = ValueFlow::Value::ValueType::TOK; + value.tokvalue = it->second; + value.setKnown(); + setTokenValue(tok, std::move(value), settings); + } + + // const array decl + else if (tok->variable() && tok->variable()->isArray() && tok->variable()->isConst() && + tok->variable()->nameToken() == tok && Token::Match(tok, "%var% [ %num%| ] = {")) { + Token* rhstok = tok->linkAt(1)->tokAt(2); + constantArrays[tok->varId()] = rhstok; + tok = rhstok->link(); + } + + // pointer = array + else if (tok->variable() && tok->variable()->isArray() && Token::simpleMatch(tok->astParent(), "=") && + astIsRHS(tok) && tok->astParent()->astOperand1() && + tok->astParent()->astOperand1()->variable() && + tok->astParent()->astOperand1()->variable()->isPointer()) { + ValueFlow::Value value; + value.valueType = ValueFlow::Value::ValueType::TOK; + value.tokvalue = tok; + value.setKnown(); + setTokenValue(tok, std::move(value), settings); + } + continue; + } + + if (Token::Match(tok, "const %type% %var% [ %num%| ] = {")) { + Token *vartok = tok->tokAt(2); + Token *rhstok = vartok->linkAt(1)->tokAt(2); + constantArrays[vartok->varId()] = rhstok; + tok = rhstok->link(); + continue; + } + + if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) { + Token *vartok = tok->tokAt(2); + Token *strtok = vartok->linkAt(1)->tokAt(2); + constantArrays[vartok->varId()] = strtok; + tok = strtok->next(); + continue; + } + } +} + static bool isNonZero(const Token *tok) { return tok && (!tok->hasKnownIntValue() || tok->values().front().intvalue != 0); @@ -669,6 +739,104 @@ static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings } } +static void valueFlowPointerAlias(TokenList &tokenlist, const Settings& settings) +{ + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + // not address of + if (!tok->isUnaryOp("&")) + continue; + + // parent should be a '=' + if (!Token::simpleMatch(tok->astParent(), "=")) + continue; + + // child should be some buffer or variable + const Token *vartok = tok->astOperand1(); + while (vartok) { + if (vartok->str() == "[") + vartok = vartok->astOperand1(); + else if (vartok->str() == "." || vartok->str() == "::") + vartok = vartok->astOperand2(); + else + break; + } + if (!(vartok && vartok->variable() && !vartok->variable()->isPointer())) + continue; + + ValueFlow::Value value; + value.valueType = ValueFlow::Value::ValueType::TOK; + value.tokvalue = tok; + setTokenValue(tok, std::move(value), settings); + } +} + +static void valueFlowBitAnd(TokenList &tokenlist, const Settings& settings) +{ + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + if (tok->str() != "&") + continue; + + if (tok->hasKnownValue()) + continue; + + if (!tok->astOperand1() || !tok->astOperand2()) + continue; + + MathLib::bigint number; + if (MathLib::isInt(tok->astOperand1()->str())) + number = MathLib::toBigNumber(tok->astOperand1()->str()); + else if (MathLib::isInt(tok->astOperand2()->str())) + number = MathLib::toBigNumber(tok->astOperand2()->str()); + else + continue; + + int bit = 0; + while (bit <= (MathLib::bigint_bits - 2) && ((((MathLib::bigint)1) << bit) < number)) + ++bit; + + if ((((MathLib::bigint)1) << bit) == number) { + setTokenValue(tok, ValueFlow::Value(0), settings); + setTokenValue(tok, ValueFlow::Value(number), settings); + } + } +} + +static void valueFlowSameExpressions(TokenList &tokenlist, const Settings& settings) +{ + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + if (tok->hasKnownIntValue()) + continue; + + if (!tok->astOperand1() || !tok->astOperand2()) + continue; + + if (tok->astOperand1()->isLiteral() || tok->astOperand2()->isLiteral()) + continue; + + if (!astIsIntegral(tok->astOperand1(), false) && !astIsIntegral(tok->astOperand2(), false)) + continue; + + ValueFlow::Value val; + + if (Token::Match(tok, "==|>=|<=|/")) { + val = ValueFlow::Value(1); + val.setKnown(); + } + + if (Token::Match(tok, "!=|>|<|%|-")) { + val = ValueFlow::Value(0); + val.setKnown(); + } + + if (!val.isKnown()) + continue; + + if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings, true, true, &val.errorPath)) { + setTokenValue(tok, std::move(val), settings); + } + } +} + static bool getExpressionRange(const Token *expr, MathLib::bigint *minvalue, MathLib::bigint *maxvalue) { if (expr->hasKnownIntValue()) { @@ -928,6 +1096,88 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& sett } } +static void valueFlowGlobalConstVar(TokenList& tokenList, const Settings &settings) +{ + // Get variable values... + std::map vars; + for (const Token* tok = tokenList.front(); tok; tok = tok->next()) { + if (!tok->variable()) + continue; + // Initialization... + if (tok == tok->variable()->nameToken() && + !tok->variable()->isVolatile() && + !tok->variable()->isArgument() && + tok->variable()->isConst() && + tok->valueType() && + tok->valueType()->isIntegral() && + tok->valueType()->pointer == 0 && + tok->valueType()->constness == 1 && + Token::Match(tok, "%name% =") && + tok->next()->astOperand2() && + tok->next()->astOperand2()->hasKnownIntValue()) { + vars[tok->variable()] = tok->next()->astOperand2()->values().front(); + } + } + + // Set values.. + for (Token* tok = tokenList.front(); tok; tok = tok->next()) { + if (!tok->variable()) + continue; + const std::map::const_iterator var = vars.find(tok->variable()); + if (var == vars.end()) + continue; + setTokenValue(tok, var->second, settings); + } +} + +static void valueFlowGlobalStaticVar(TokenList &tokenList, const Settings &settings) +{ + // Get variable values... + std::map vars; + for (const Token *tok = tokenList.front(); tok; tok = tok->next()) { + if (!tok->variable()) + continue; + // Initialization... + if (tok == tok->variable()->nameToken() && + tok->variable()->isStatic() && + !tok->variable()->isConst() && + tok->valueType() && + tok->valueType()->isIntegral() && + tok->valueType()->pointer == 0 && + tok->valueType()->constness == 0 && + Token::Match(tok, "%name% =") && + tok->next()->astOperand2() && + tok->next()->astOperand2()->hasKnownIntValue()) { + vars[tok->variable()] = tok->next()->astOperand2()->values().front(); + } else { + // If variable is written anywhere in TU then remove it from vars + if (!tok->astParent()) + continue; + if (Token::Match(tok->astParent(), "++|--|&") && !tok->astParent()->astOperand2()) + vars.erase(tok->variable()); + else if (tok->astParent()->isAssignmentOp()) { + if (tok == tok->astParent()->astOperand1()) + vars.erase(tok->variable()); + else if (tok->isCpp() && Token::Match(tok->astParent()->tokAt(-2), "& %name% =")) + vars.erase(tok->variable()); + } else if (isLikelyStreamRead(tok->astParent())) { + vars.erase(tok->variable()); + } else if (Token::Match(tok->astParent(), "[(,]")) + vars.erase(tok->variable()); + } + } + + // Set values.. + for (Token *tok = tokenList.front(); tok; tok = tok->next()) { + if (!tok->variable()) + continue; + const std::map::const_iterator var = vars.find(tok->variable()); + if (var == vars.end()) + continue; + setTokenValue(tok, var->second, settings); + } +} + static ValuePtr makeAnalyzer(const Token* exprTok, ValueFlow::Value value, const Settings& settings); static ValuePtr makeReverseAnalyzer(const Token* exprTok, ValueFlow::Value value, const Settings& settings); @@ -8006,6 +8256,18 @@ static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolD } } +static bool getMinMaxValues(const std::string &typestr, const Settings &settings, bool cpp, MathLib::bigint &minvalue, MathLib::bigint &maxvalue) +{ + TokenList typeTokens(&settings); + std::istringstream istr(typestr+";"); + if (!typeTokens.createTokens(istr, cpp ? Standards::Language::CPP : Standards::Language::C)) + return false; + typeTokens.simplifyPlatformTypes(); + typeTokens.simplifyStdType(); + const ValueType &vt = ValueType::parseDecl(typeTokens.front(), settings); + return ValueFlow::getMinMaxValues(&vt, settings.platform, minvalue, maxvalue); +} + static void valueFlowSafeFunctions(const TokenList& tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, const Settings& settings) { for (const Scope *functionScope : symboldatabase.functionScopes) { @@ -8104,6 +8366,54 @@ static void valueFlowSafeFunctions(const TokenList& tokenlist, const SymbolDatab } } +static void valueFlowUnknownFunctionReturn(TokenList &tokenlist, const Settings &settings) +{ + if (settings.checkUnknownFunctionReturn.empty()) + return; + for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + if (!tok->astParent() || tok->str() != "(" || !tok->previous()->isName()) + continue; + if (settings.checkUnknownFunctionReturn.find(tok->strAt(-1)) == settings.checkUnknownFunctionReturn.end()) + continue; + std::vector unknownValues = settings.library.unknownReturnValues(tok->astOperand1()); + if (unknownValues.empty()) + continue; + + // Get min/max values for return type + const std::string &typestr = settings.library.returnValueType(tok->previous()); + MathLib::bigint minvalue, maxvalue; + if (!getMinMaxValues(typestr, settings, tok->isCpp(), minvalue, maxvalue)) + continue; + + for (MathLib::bigint value : unknownValues) { + if (value < minvalue) + value = minvalue; + else if (value > maxvalue) + value = maxvalue; + setTokenValue(tok, ValueFlow::Value(value), settings); + } + } +} + +static void valueFlowDebug(TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) +{ + if (!settings.debugnormal && !settings.debugwarnings) + return; + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { + if (tok->getTokenDebug() != TokenDebug::ValueFlow) + continue; + if (tok->astParent() && tok->astParent()->getTokenDebug() == TokenDebug::ValueFlow) + continue; + for (const ValueFlow::Value& v : tok->values()) { + std::string msg = "The value is " + debugString(v); + ErrorPath errorPath = v.errorPath; + errorPath.insert(errorPath.end(), v.debugPath.cbegin(), v.debugPath.cend()); + errorPath.emplace_back(tok, ""); + errorLogger.reportErr({errorPath, &tokenlist, Severity::debug, "valueFlow", msg, CWE{0}, Certainty::normal}); + } + } +} + const ValueFlow::Value *ValueFlow::valueFlowConstantFoldAST(Token *expr, const Settings &settings) { if (expr && expr->values().empty()) { @@ -8327,17 +8637,17 @@ void ValueFlow::setValues(TokenList& tokenlist, runner.run_once({ VFA(analyzeEnumValue(symboldatabase, settings)), VFA(analyzeNumber(tokenlist, settings)), - VFA(analyzeString(tokenlist, settings)), - VFA(analyzeArray(tokenlist, settings)), - VFA(analyzeUnknownFunctionReturn(tokenlist, settings)), - VFA(analyzeGlobalConstVar(tokenlist, settings)), + VFA(valueFlowString(tokenlist, settings)), + VFA(valueFlowArray(tokenlist, settings)), + VFA(valueFlowUnknownFunctionReturn(tokenlist, settings)), + VFA(valueFlowGlobalConstVar(tokenlist, settings)), VFA(analyzeEnumValue(symboldatabase, settings)), - VFA(analyzeGlobalStaticVar(tokenlist, settings)), - VFA(analyzePointerAlias(tokenlist, settings)), + VFA(valueFlowGlobalStaticVar(tokenlist, settings)), + VFA(valueFlowPointerAlias(tokenlist, settings)), VFA(valueFlowLifetime(tokenlist, errorLogger, settings)), VFA(valueFlowSymbolic(tokenlist, symboldatabase, errorLogger, settings)), - VFA(analyzeBitAnd(tokenlist, settings)), - VFA(analyzeSameExpressions(tokenlist, settings)), + VFA(valueFlowBitAnd(tokenlist, settings)), + VFA(valueFlowSameExpressions(tokenlist, settings)), VFA(valueFlowConditionExpressions(tokenlist, symboldatabase, errorLogger, settings)), }); @@ -8374,7 +8684,7 @@ void ValueFlow::setValues(TokenList& tokenlist, runner.run_once({ VFA(valueFlowDynamicBufferSize(tokenlist, symboldatabase, errorLogger, settings)), - VFA(analyzeDebug(tokenlist, errorLogger, settings)), + VFA(valueFlowDebug(tokenlist, errorLogger, settings)), }); } diff --git a/lib/vf_analyze.h b/lib/vf_analyze.h index 6ad7b910f2b..41608a06ede 100644 --- a/lib/vf_analyze.h +++ b/lib/vf_analyze.h @@ -19,16 +19,7 @@ #ifndef vfAnalyzeH #define vfAnalyzeH -#include "vf_array.h" // IWYU pragma: export -#include "vf_bitand.h" // IWYU pragma: export -#include "vf_debug.h" // IWYU pragma: export #include "vf_enumvalue.h" // IWYU pragma: export -#include "vf_globalconstvar.h" // IWYU pragma: export -#include "vf_globalstaticvar.h" // IWYU pragma: export #include "vf_number.h" // IWYU pragma: export -#include "vf_pointeralias.h" // IWYU pragma: export -#include "vf_sameexpressions.h" // IWYU pragma: export -#include "vf_string.h" // IWYU pragma: export -#include "vf_unknownfunctionreturn.h" // IWYU pragma: export #endif // vfAnalyzeH diff --git a/lib/vf_array.cpp b/lib/vf_array.cpp deleted file mode 100644 index 1fd14a9bff4..00000000000 --- a/lib/vf_array.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_array.h" - -#include "astutils.h" -#include "config.h" -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include - -namespace ValueFlow -{ - void analyzeArray(TokenList &tokenlist, const Settings &settings) - { - std::map constantArrays; - - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->varId() > 0) { - // array - const std::map::const_iterator it = constantArrays.find(tok->varId()); - if (it != constantArrays.end()) { - Value value; - value.valueType = Value::ValueType::TOK; - value.tokvalue = it->second; - value.setKnown(); - setTokenValue(tok, std::move(value), settings); - } - - // const array decl - else if (tok->variable() && tok->variable()->isArray() && tok->variable()->isConst() && - tok->variable()->nameToken() == tok && Token::Match(tok, "%var% [ %num%| ] = {")) { - Token* rhstok = tok->linkAt(1)->tokAt(2); - constantArrays[tok->varId()] = rhstok; - tok = rhstok->link(); - } - - // pointer = array - else if (tok->variable() && tok->variable()->isArray() && Token::simpleMatch(tok->astParent(), "=") && - astIsRHS(tok) && tok->astParent()->astOperand1() && - tok->astParent()->astOperand1()->variable() && - tok->astParent()->astOperand1()->variable()->isPointer()) { - Value value; - value.valueType = Value::ValueType::TOK; - value.tokvalue = tok; - value.setKnown(); - setTokenValue(tok, std::move(value), settings); - } - continue; - } - - if (Token::Match(tok, "const %type% %var% [ %num%| ] = {")) { - Token *vartok = tok->tokAt(2); - Token *rhstok = vartok->linkAt(1)->tokAt(2); - constantArrays[vartok->varId()] = rhstok; - tok = rhstok->link(); - continue; - } - - if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) { - Token *vartok = tok->tokAt(2); - Token *strtok = vartok->linkAt(1)->tokAt(2); - constantArrays[vartok->varId()] = strtok; - tok = strtok->next(); - continue; - } - } - } -} diff --git a/lib/vf_array.h b/lib/vf_array.h deleted file mode 100644 index a7ef79c7e79..00000000000 --- a/lib/vf_array.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfArrayH -#define vfArrayH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeArray(TokenList &tokenlist, const Settings &settings); -} - -#endif // vfArrayH diff --git a/lib/vf_bitand.cpp b/lib/vf_bitand.cpp deleted file mode 100644 index 89a7405dcd0..00000000000 --- a/lib/vf_bitand.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_bitand.h" - -#include "mathlib.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include - -namespace ValueFlow -{ - void analyzeBitAnd(TokenList &tokenlist, const Settings& settings) - { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->str() != "&") - continue; - - if (tok->hasKnownValue()) - continue; - - if (!tok->astOperand1() || !tok->astOperand2()) - continue; - - MathLib::bigint number; - if (MathLib::isInt(tok->astOperand1()->str())) - number = MathLib::toBigNumber(tok->astOperand1()->str()); - else if (MathLib::isInt(tok->astOperand2()->str())) - number = MathLib::toBigNumber(tok->astOperand2()->str()); - else - continue; - - int bit = 0; - while (bit <= (MathLib::bigint_bits - 2) && ((((MathLib::bigint)1) << bit) < number)) - ++bit; - - if ((((MathLib::bigint)1) << bit) == number) { - setTokenValue(tok, Value(0), settings); - setTokenValue(tok, Value(number), settings); - } - } - } -} diff --git a/lib/vf_bitand.h b/lib/vf_bitand.h deleted file mode 100644 index df958254291..00000000000 --- a/lib/vf_bitand.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfBitAndH -#define vfBitAndH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeBitAnd(TokenList &tokenlist, const Settings& settings); -} - -#endif // vfBitAndH diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index a65a173651d..ae1f4a43d8f 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -25,7 +25,6 @@ #include "standards.h" #include "symboldatabase.h" #include "token.h" -#include "tokenlist.h" #include "valueflow.h" #include "vf_settokenvalue.h" @@ -34,7 +33,6 @@ #include #include #include -#include #include #include @@ -95,18 +93,6 @@ namespace ValueFlow return true; } - bool getMinMaxValues(const std::string &typestr, const Settings &settings, bool cpp, MathLib::bigint &minvalue, MathLib::bigint &maxvalue) - { - TokenList typeTokens(&settings); - std::istringstream istr(typestr+";"); - if (!typeTokens.createTokens(istr, cpp ? Standards::Language::CPP : Standards::Language::C)) - return false; - typeTokens.simplifyPlatformTypes(); - typeTokens.simplifyStdType(); - const ValueType &vt = ValueType::parseDecl(typeTokens.front(), settings); - return getMinMaxValues(&vt, settings.platform, minvalue, maxvalue); - } - long long truncateIntValue(long long value, size_t value_size, const ValueType::Sign dst_sign) { if (value_size == 0) diff --git a/lib/vf_common.h b/lib/vf_common.h index e2ce89e2ec6..f20b0e630be 100644 --- a/lib/vf_common.h +++ b/lib/vf_common.h @@ -37,8 +37,6 @@ namespace ValueFlow { bool getMinMaxValues(const ValueType* vt, const Platform& platform, MathLib::bigint& minValue, MathLib::bigint& maxValue); - bool getMinMaxValues(const std::string &typestr, const Settings &settings, bool cpp, MathLib::bigint &minvalue, MathLib::bigint &maxvalue); - long long truncateIntValue(long long value, size_t value_size, const ValueType::Sign dst_sign); Token * valueFlowSetConstantValue(Token *tok, const Settings &settings); diff --git a/lib/vf_debug.cpp b/lib/vf_debug.cpp deleted file mode 100644 index 9bc54af31b8..00000000000 --- a/lib/vf_debug.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_debug.h" - -#include "errorlogger.h" -#include "errortypes.h" -#include "settings.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_common.h" - -#include -#include - -namespace ValueFlow -{ - void analyzeDebug(TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) - { - if (!settings.debugnormal && !settings.debugwarnings) - return; - for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->getTokenDebug() != TokenDebug::ValueFlow) - continue; - if (tok->astParent() && tok->astParent()->getTokenDebug() == TokenDebug::ValueFlow) - continue; - for (const Value& v : tok->values()) { - std::string msg = "The value is " + debugString(v); - ErrorPath errorPath = v.errorPath; - errorPath.insert(errorPath.end(), v.debugPath.cbegin(), v.debugPath.cend()); - errorPath.emplace_back(tok, ""); - errorLogger.reportErr({errorPath, &tokenlist, Severity::debug, "valueFlow", msg, CWE{0}, Certainty::normal}); - } - } - } -} diff --git a/lib/vf_debug.h b/lib/vf_debug.h deleted file mode 100644 index 8e5de01db1a..00000000000 --- a/lib/vf_debug.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfDebugH -#define vfDebugH - -class TokenList; -class ErrorLogger; -class Settings; - -namespace ValueFlow -{ - void analyzeDebug(TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings); -} - -#endif // vfDebugH diff --git a/lib/vf_globalconstvar.cpp b/lib/vf_globalconstvar.cpp deleted file mode 100644 index 47cd59adb30..00000000000 --- a/lib/vf_globalconstvar.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_globalconstvar.h" - -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include -#include - -namespace ValueFlow -{ - void analyzeGlobalConstVar(TokenList& tokenList, const Settings &settings) - { - // Get variable values... - std::map vars; - for (const Token* tok = tokenList.front(); tok; tok = tok->next()) { - if (!tok->variable()) - continue; - // Initialization... - if (tok == tok->variable()->nameToken() && - !tok->variable()->isVolatile() && - !tok->variable()->isArgument() && - tok->variable()->isConst() && - tok->valueType() && - tok->valueType()->isIntegral() && - tok->valueType()->pointer == 0 && - tok->valueType()->constness == 1 && - Token::Match(tok, "%name% =") && - tok->next()->astOperand2() && - tok->next()->astOperand2()->hasKnownIntValue()) { - vars[tok->variable()] = tok->next()->astOperand2()->values().front(); - } - } - - // Set values.. - for (Token* tok = tokenList.front(); tok; tok = tok->next()) { - if (!tok->variable()) - continue; - const std::map::const_iterator var = vars.find(tok->variable()); - if (var == vars.end()) - continue; - setTokenValue(tok, var->second, settings); - } - } -} diff --git a/lib/vf_globalconstvar.h b/lib/vf_globalconstvar.h deleted file mode 100644 index b0f79ae68f9..00000000000 --- a/lib/vf_globalconstvar.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfGlobalConstVarH -#define vfGlobalConstVarH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeGlobalConstVar(TokenList& tokenList, const Settings &settings); -} - -#endif // vfGlobalConstVarH diff --git a/lib/vf_globalstaticvar.cpp b/lib/vf_globalstaticvar.cpp deleted file mode 100644 index 545850c9baf..00000000000 --- a/lib/vf_globalstaticvar.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_globalstaticvar.h" - -#include "astutils.h" -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include -#include - -namespace ValueFlow -{ - void analyzeGlobalStaticVar(TokenList &tokenList, const Settings &settings) - { - // Get variable values... - std::map vars; - for (const Token *tok = tokenList.front(); tok; tok = tok->next()) { - if (!tok->variable()) - continue; - // Initialization... - if (tok == tok->variable()->nameToken() && - tok->variable()->isStatic() && - !tok->variable()->isConst() && - tok->valueType() && - tok->valueType()->isIntegral() && - tok->valueType()->pointer == 0 && - tok->valueType()->constness == 0 && - Token::Match(tok, "%name% =") && - tok->next()->astOperand2() && - tok->next()->astOperand2()->hasKnownIntValue()) { - vars[tok->variable()] = tok->next()->astOperand2()->values().front(); - } else { - // If variable is written anywhere in TU then remove it from vars - if (!tok->astParent()) - continue; - if (Token::Match(tok->astParent(), "++|--|&") && !tok->astParent()->astOperand2()) - vars.erase(tok->variable()); - else if (tok->astParent()->isAssignmentOp()) { - if (tok == tok->astParent()->astOperand1()) - vars.erase(tok->variable()); - else if (tok->isCpp() && Token::Match(tok->astParent()->tokAt(-2), "& %name% =")) - vars.erase(tok->variable()); - } else if (isLikelyStreamRead(tok->astParent())) { - vars.erase(tok->variable()); - } else if (Token::Match(tok->astParent(), "[(,]")) - vars.erase(tok->variable()); - } - } - - // Set values.. - for (Token *tok = tokenList.front(); tok; tok = tok->next()) { - if (!tok->variable()) - continue; - const std::map::const_iterator var = vars.find(tok->variable()); - if (var == vars.end()) - continue; - setTokenValue(tok, var->second, settings); - } - } -} diff --git a/lib/vf_globalstaticvar.h b/lib/vf_globalstaticvar.h deleted file mode 100644 index 8e0cdbc16b4..00000000000 --- a/lib/vf_globalstaticvar.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfGlobalStaticVarH -#define vfGlobalStaticVarH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeGlobalStaticVar(TokenList &tokenList, const Settings &settings); -} - -#endif // vfGlobalStaticVarH diff --git a/lib/vf_pointeralias.cpp b/lib/vf_pointeralias.cpp deleted file mode 100644 index 225f87872e4..00000000000 --- a/lib/vf_pointeralias.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_pointeralias.h" - -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include -#include - -namespace ValueFlow -{ - void analyzePointerAlias(TokenList &tokenlist, const Settings& settings) - { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - // not address of - if (!tok->isUnaryOp("&")) - continue; - - // parent should be a '=' - if (!Token::simpleMatch(tok->astParent(), "=")) - continue; - - // child should be some buffer or variable - const Token *vartok = tok->astOperand1(); - while (vartok) { - if (vartok->str() == "[") - vartok = vartok->astOperand1(); - else if (vartok->str() == "." || vartok->str() == "::") - vartok = vartok->astOperand2(); - else - break; - } - if (!(vartok && vartok->variable() && !vartok->variable()->isPointer())) - continue; - - Value value; - value.valueType = Value::ValueType::TOK; - value.tokvalue = tok; - setTokenValue(tok, std::move(value), settings); - } - } -} diff --git a/lib/vf_pointeralias.h b/lib/vf_pointeralias.h deleted file mode 100644 index 8ef12c37146..00000000000 --- a/lib/vf_pointeralias.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfPointerAliasH -#define vfPointerAliasH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzePointerAlias(TokenList &tokenlist, const Settings& settings); -} - -#endif // vfPointerAliasH diff --git a/lib/vf_sameexpressions.cpp b/lib/vf_sameexpressions.cpp deleted file mode 100644 index 2aca4453e6f..00000000000 --- a/lib/vf_sameexpressions.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_sameexpressions.h" - -#include "astutils.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include - -namespace ValueFlow -{ - void analyzeSameExpressions(TokenList &tokenlist, const Settings& settings) - { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->hasKnownIntValue()) - continue; - - if (!tok->astOperand1() || !tok->astOperand2()) - continue; - - if (tok->astOperand1()->isLiteral() || tok->astOperand2()->isLiteral()) - continue; - - if (!astIsIntegral(tok->astOperand1(), false) && !astIsIntegral(tok->astOperand2(), false)) - continue; - - Value val; - - if (Token::Match(tok, "==|>=|<=|/")) { - val = ValueFlow::Value(1); - val.setKnown(); - } - - if (Token::Match(tok, "!=|>|<|%|-")) { - val = ValueFlow::Value(0); - val.setKnown(); - } - - if (!val.isKnown()) - continue; - - if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings, true, true, &val.errorPath)) { - setTokenValue(tok, std::move(val), settings); - } - } - } -} diff --git a/lib/vf_sameexpressions.h b/lib/vf_sameexpressions.h deleted file mode 100644 index d8dbe209c2f..00000000000 --- a/lib/vf_sameexpressions.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfSameExpressionsH -#define vfSameExpressionsH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeSameExpressions(TokenList &tokenlist, const Settings& settings); -} - -#endif // vfSameExpressionsH diff --git a/lib/vf_string.cpp b/lib/vf_string.cpp deleted file mode 100644 index b472279369b..00000000000 --- a/lib/vf_string.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_string.h" - -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include - -namespace ValueFlow -{ - void analyzeString(TokenList &tokenlist, const Settings& settings) - { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->tokType() == Token::eString) { - Value strvalue; - strvalue.valueType = Value::ValueType::TOK; - strvalue.tokvalue = tok; - strvalue.setKnown(); - setTokenValue(tok, std::move(strvalue), settings); - } - } - } -} diff --git a/lib/vf_string.h b/lib/vf_string.h deleted file mode 100644 index b899fbcb25e..00000000000 --- a/lib/vf_string.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfStringH -#define vfStringH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeString(TokenList &tokenlist, const Settings& settings); -} - -#endif // vfStringH diff --git a/lib/vf_unknownfunctionreturn.cpp b/lib/vf_unknownfunctionreturn.cpp deleted file mode 100644 index 8577b3b173c..00000000000 --- a/lib/vf_unknownfunctionreturn.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_unknownfunctionreturn.h" - -#include "library.h" -#include "mathlib.h" -#include "settings.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_common.h" -#include "vf_settokenvalue.h" - -#include -#include -#include - -namespace ValueFlow -{ - void analyzeUnknownFunctionReturn(TokenList &tokenlist, const Settings &settings) - { - if (settings.checkUnknownFunctionReturn.empty()) - return; - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (!tok->astParent() || tok->str() != "(" || !tok->previous()->isName()) - continue; - if (settings.checkUnknownFunctionReturn.find(tok->strAt(-1)) == settings.checkUnknownFunctionReturn.end()) - continue; - std::vector unknownValues = settings.library.unknownReturnValues(tok->astOperand1()); - if (unknownValues.empty()) - continue; - - // Get min/max values for return type - const std::string &typestr = settings.library.returnValueType(tok->previous()); - MathLib::bigint minvalue, maxvalue; - if (!getMinMaxValues(typestr, settings, tok->isCpp(), minvalue, maxvalue)) - continue; - - for (MathLib::bigint value : unknownValues) { - if (value < minvalue) - value = minvalue; - else if (value > maxvalue) - value = maxvalue; - setTokenValue(tok, Value(value), settings); - } - } - } -} diff --git a/lib/vf_unknownfunctionreturn.h b/lib/vf_unknownfunctionreturn.h deleted file mode 100644 index 1de8072e4d2..00000000000 --- a/lib/vf_unknownfunctionreturn.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfUnknownFunctionReturnH -#define vfUnknownFunctionReturnH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeUnknownFunctionReturn(TokenList &tokenlist, const Settings &settings); -} - -#endif // vfUnknownFunctionReturnH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index bd46c392669..30559784264 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -95,19 +95,10 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/token.o \ $(libcppdir)/tokenlist.o \ $(libcppdir)/utils.o \ - $(libcppdir)/vf_array.o \ - $(libcppdir)/vf_bitand.o \ $(libcppdir)/vf_common.o \ - $(libcppdir)/vf_debug.o \ $(libcppdir)/vf_enumvalue.o \ - $(libcppdir)/vf_globalconstvar.o \ - $(libcppdir)/vf_globalstaticvar.o \ $(libcppdir)/vf_number.o \ - $(libcppdir)/vf_pointeralias.o \ - $(libcppdir)/vf_sameexpressions.o \ $(libcppdir)/vf_settokenvalue.o \ - $(libcppdir)/vf_string.o \ - $(libcppdir)/vf_unknownfunctionreturn.o \ $(libcppdir)/vfvalue.o EXTOBJ = simplecpp.o \ @@ -152,7 +143,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_array.h ../lib/vf_bitand.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vf_enumvalue.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_number.h ../lib/vf_pointeralias.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_common.h ../lib/vf_enumvalue.h ../lib/vf_number.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h @@ -338,45 +329,18 @@ $(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp. $(libcppdir)/utils.o: ../lib/utils.cpp ../lib/config.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_array.o: ../lib/vf_array.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_array.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_array.cpp - -$(libcppdir)/vf_bitand.o: ../lib/vf_bitand.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_bitand.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_bitand.cpp - -$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_debug.o: ../lib/vf_debug.cpp ../lib/addoninfo.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_debug.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_debug.cpp - $(libcppdir)/vf_enumvalue.o: ../lib/vf_enumvalue.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_enumvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_enumvalue.cpp -$(libcppdir)/vf_globalconstvar.o: ../lib/vf_globalconstvar.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_globalconstvar.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_globalconstvar.cpp - -$(libcppdir)/vf_globalstaticvar.o: ../lib/vf_globalstaticvar.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_globalstaticvar.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_globalstaticvar.cpp - $(libcppdir)/vf_number.o: ../lib/vf_number.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_number.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_number.cpp -$(libcppdir)/vf_pointeralias.o: ../lib/vf_pointeralias.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_pointeralias.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_pointeralias.cpp - -$(libcppdir)/vf_sameexpressions.o: ../lib/vf_sameexpressions.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_sameexpressions.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_sameexpressions.cpp - $(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp -$(libcppdir)/vf_string.o: ../lib/vf_string.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_settokenvalue.h ../lib/vf_string.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_string.cpp - -$(libcppdir)/vf_unknownfunctionreturn.o: ../lib/vf_unknownfunctionreturn.cpp ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vf_unknownfunctionreturn.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_unknownfunctionreturn.cpp - $(libcppdir)/vfvalue.o: ../lib/vfvalue.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vfvalue.cpp From 235e12ffeac421bcaf56d2abc6365535b3045f4c Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 5 Nov 2024 09:58:11 -0600 Subject: [PATCH 08/13] Format --- lib/astutils.cpp | 3 +- lib/programmemory.cpp | 12 +- lib/valueflow.cpp | 340 ++++++++++++++++++++--------------- test/testsimplifytokens.cpp | 40 +++-- test/testsimplifytypedef.cpp | 8 +- test/testsimplifyusing.cpp | 4 +- test/testsymboldatabase.cpp | 9 +- test/testtokenize.cpp | 120 +++++++++---- 8 files changed, 341 insertions(+), 195 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 6ad90614437..aafb812e1e6 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -959,7 +959,8 @@ bool extractForLoopValues(const Token *forToken, const Token *incExpr = forToken->next()->astOperand2()->astOperand2()->astOperand2(); if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%")) return false; - std::vector minInitValue = getMinValue(ValueFlow::makeIntegralInferModel(), initExpr->astOperand2()->values()); + std::vector minInitValue = + getMinValue(ValueFlow::makeIntegralInferModel(), initExpr->astOperand2()->values()); if (minInitValue.empty()) { const ValueFlow::Value* v = initExpr->astOperand2()->getMinValue(true); if (v) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 95fce1bb958..c22af0c35f9 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1525,14 +1525,18 @@ namespace { r = evaluate(expr->str(), lhs, rhs); if (expr->isComparisonOp() && (r.isUninitValue() || r.isImpossible())) { if (rhs.isIntValue() && !expr->astOperand1()->values().empty()) { - std::vector result = - infer(ValueFlow::makeIntegralInferModel(), expr->str(), expr->astOperand1()->values(), {std::move(rhs)}); + std::vector result = infer(ValueFlow::makeIntegralInferModel(), + expr->str(), + expr->astOperand1()->values(), + {std::move(rhs)}); if (!result.empty() && result.front().isKnown()) return std::move(result.front()); } if (lhs.isIntValue() && !expr->astOperand2()->values().empty()) { - std::vector result = - infer(ValueFlow::makeIntegralInferModel(), expr->str(), {std::move(lhs)}, expr->astOperand2()->values()); + std::vector result = infer(ValueFlow::makeIntegralInferModel(), + expr->str(), + {std::move(lhs)}, + expr->astOperand2()->values()); if (!result.empty() && result.front().isKnown()) return std::move(result.front()); } diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 3ee58ef6cbe..00a52aabbad 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -79,8 +79,8 @@ #include "analyzer.h" #include "astutils.h" -#include "checkuninitvar.h" #include "calculate.h" +#include "checkuninitvar.h" #include "config.h" #include "errorlogger.h" #include "errortypes.h" @@ -133,26 +133,40 @@ #include #include -static void bailoutInternal(const std::string& type, const TokenList &tokenlist, ErrorLogger &errorLogger, const Token *tok, const std::string &what, const std::string &file, int line, std::string function) +static void bailoutInternal(const std::string& type, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Token* tok, + const std::string& what, + const std::string& file, + int line, + std::string function) { if (function.find("operator") != std::string::npos) function = "(valueFlow)"; ErrorMessage::FileLocation loc(tok, &tokenlist); const std::string location = Path::stripDirectoryPart(file) + ":" + std::to_string(line) + ":"; - ErrorMessage errmsg({std::move(loc)}, tokenlist.getSourceFilePath(), Severity::debug, - (file.empty() ? "" : location) + function + " bailout: " + what, type, Certainty::normal); + ErrorMessage errmsg({std::move(loc)}, + tokenlist.getSourceFilePath(), + Severity::debug, + (file.empty() ? "" : location) + function + " bailout: " + what, + type, + Certainty::normal); errorLogger.reportErr(errmsg); } -#define bailout2(type, tokenlist, errorLogger, tok, what) bailoutInternal((type), (tokenlist), (errorLogger), (tok), (what), __FILE__, __LINE__, __func__) +#define bailout2(type, tokenlist, errorLogger, tok, what) \ + bailoutInternal((type), (tokenlist), (errorLogger), (tok), (what), __FILE__, __LINE__, __func__) -#define bailout(tokenlist, errorLogger, tok, what) bailout2("valueFlowBailout", (tokenlist), (errorLogger), (tok), (what)) +#define bailout(tokenlist, errorLogger, tok, what) \ + bailout2("valueFlowBailout", (tokenlist), (errorLogger), (tok), (what)) -#define bailoutIncompleteVar(tokenlist, errorLogger, tok, what) bailoutInternal("valueFlowBailoutIncompleteVar", (tokenlist), (errorLogger), (tok), (what), "", 0, __func__) +#define bailoutIncompleteVar(tokenlist, errorLogger, tok, what) \ + bailoutInternal("valueFlowBailoutIncompleteVar", (tokenlist), (errorLogger), (tok), (what), "", 0, __func__) -static void changeKnownToPossible(std::list &values, int indirect=-1) +static void changeKnownToPossible(std::list& values, int indirect = -1) { - for (ValueFlow::Value& v: values) { + for (ValueFlow::Value& v : values) { if (indirect >= 0 && v.indirect != indirect) continue; v.changeKnownToPossible(); @@ -361,7 +375,7 @@ static bool isEscapeScope(const Token* tok, const Settings& settings, bool unkno if (!Token::simpleMatch(tok, "{")) return false; // TODO this search for termTok in all subscopes. It should check the end of the scope. - const Token * termTok = Token::findmatch(tok, "return|continue|break|throw|goto", tok->link()); + const Token* termTok = Token::findmatch(tok, "return|continue|break|throw|goto", tok->link()); if (termTok && termTok->scope() == tok->scope()) return true; std::string unknownFunction; @@ -543,9 +557,9 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings, int m return 0; } -static void valueFlowString(TokenList &tokenlist, const Settings& settings) +static void valueFlowString(TokenList& tokenlist, const Settings& settings) { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (tok->tokType() == Token::eString) { ValueFlow::Value strvalue; strvalue.valueType = ValueFlow::Value::ValueType::TOK; @@ -556,14 +570,14 @@ static void valueFlowString(TokenList &tokenlist, const Settings& settings) } } -static void valueFlowArray(TokenList &tokenlist, const Settings &settings) +static void valueFlowArray(TokenList& tokenlist, const Settings& settings) { - std::map constantArrays; + std::map constantArrays; - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (tok->varId() > 0) { // array - const std::map::const_iterator it = constantArrays.find(tok->varId()); + const std::map::const_iterator it = constantArrays.find(tok->varId()); if (it != constantArrays.end()) { ValueFlow::Value value; value.valueType = ValueFlow::Value::ValueType::TOK; @@ -582,8 +596,7 @@ static void valueFlowArray(TokenList &tokenlist, const Settings &settings) // pointer = array else if (tok->variable() && tok->variable()->isArray() && Token::simpleMatch(tok->astParent(), "=") && - astIsRHS(tok) && tok->astParent()->astOperand1() && - tok->astParent()->astOperand1()->variable() && + astIsRHS(tok) && tok->astParent()->astOperand1() && tok->astParent()->astOperand1()->variable() && tok->astParent()->astOperand1()->variable()->isPointer()) { ValueFlow::Value value; value.valueType = ValueFlow::Value::ValueType::TOK; @@ -595,16 +608,16 @@ static void valueFlowArray(TokenList &tokenlist, const Settings &settings) } if (Token::Match(tok, "const %type% %var% [ %num%| ] = {")) { - Token *vartok = tok->tokAt(2); - Token *rhstok = vartok->linkAt(1)->tokAt(2); + Token* vartok = tok->tokAt(2); + Token* rhstok = vartok->linkAt(1)->tokAt(2); constantArrays[vartok->varId()] = rhstok; tok = rhstok->link(); continue; } if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) { - Token *vartok = tok->tokAt(2); - Token *strtok = vartok->linkAt(1)->tokAt(2); + Token* vartok = tok->tokAt(2); + Token* strtok = vartok->linkAt(1)->tokAt(2); constantArrays[vartok->varId()] = strtok; tok = strtok->next(); continue; @@ -612,12 +625,12 @@ static void valueFlowArray(TokenList &tokenlist, const Settings &settings) } } -static bool isNonZero(const Token *tok) +static bool isNonZero(const Token* tok) { return tok && (!tok->hasKnownIntValue() || tok->values().front().intvalue != 0); } -static const Token *getOtherOperand(const Token *tok) +static const Token* getOtherOperand(const Token* tok) { if (!tok) return nullptr; @@ -630,12 +643,12 @@ static const Token *getOtherOperand(const Token *tok) return nullptr; } -static void valueFlowArrayBool(TokenList &tokenlist, const Settings &settings) +static void valueFlowArrayBool(TokenList& tokenlist, const Settings& settings) { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (tok->hasKnownIntValue()) continue; - const Variable *var = nullptr; + const Variable* var = nullptr; bool known = false; const std::list::const_iterator val = std::find_if(tok->values().cbegin(), tok->values().cend(), std::mem_fn(&ValueFlow::Value::isTokValue)); @@ -709,8 +722,12 @@ static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings if (arrayValue.valueKind == indexValue.valueKind) result.valueKind = arrayValue.valueKind; - result.errorPath.insert(result.errorPath.end(), arrayValue.errorPath.cbegin(), arrayValue.errorPath.cend()); - result.errorPath.insert(result.errorPath.end(), indexValue.errorPath.cbegin(), indexValue.errorPath.cend()); + result.errorPath.insert(result.errorPath.end(), + arrayValue.errorPath.cbegin(), + arrayValue.errorPath.cend()); + result.errorPath.insert(result.errorPath.end(), + indexValue.errorPath.cbegin(), + indexValue.errorPath.cend()); const MathLib::bigint index = indexValue.intvalue; @@ -740,9 +757,9 @@ static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings } } -static void valueFlowPointerAlias(TokenList &tokenlist, const Settings& settings) +static void valueFlowPointerAlias(TokenList& tokenlist, const Settings& settings) { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { // not address of if (!tok->isUnaryOp("&")) continue; @@ -752,7 +769,7 @@ static void valueFlowPointerAlias(TokenList &tokenlist, const Settings& settings continue; // child should be some buffer or variable - const Token *vartok = tok->astOperand1(); + const Token* vartok = tok->astOperand1(); while (vartok) { if (vartok->str() == "[") vartok = vartok->astOperand1(); @@ -771,9 +788,9 @@ static void valueFlowPointerAlias(TokenList &tokenlist, const Settings& settings } } -static void valueFlowBitAnd(TokenList &tokenlist, const Settings& settings) +static void valueFlowBitAnd(TokenList& tokenlist, const Settings& settings) { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (tok->str() != "&") continue; @@ -802,9 +819,9 @@ static void valueFlowBitAnd(TokenList &tokenlist, const Settings& settings) } } -static void valueFlowSameExpressions(TokenList &tokenlist, const Settings& settings) +static void valueFlowSameExpressions(TokenList& tokenlist, const Settings& settings) { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (tok->hasKnownIntValue()) continue; @@ -838,7 +855,7 @@ static void valueFlowSameExpressions(TokenList &tokenlist, const Settings& setti } } -static bool getExpressionRange(const Token *expr, MathLib::bigint *minvalue, MathLib::bigint *maxvalue) +static bool getExpressionRange(const Token* expr, MathLib::bigint* minvalue, MathLib::bigint* maxvalue) { if (expr->hasKnownIntValue()) { if (minvalue) @@ -878,7 +895,8 @@ static bool getExpressionRange(const Token *expr, MathLib::bigint *minvalue, Mat if (lhsHasKnownRange && vals[0] < 0) return false; // If lhs has unknown value, it must be unsigned - if (!lhsHasKnownRange && (!expr->astOperand1()->valueType() || expr->astOperand1()->valueType()->sign != ValueType::Sign::UNSIGNED)) + if (!lhsHasKnownRange && + (!expr->astOperand1()->valueType() || expr->astOperand1()->valueType()->sign != ValueType::Sign::UNSIGNED)) return false; if (minvalue) *minvalue = 0; @@ -890,9 +908,9 @@ static bool getExpressionRange(const Token *expr, MathLib::bigint *minvalue, Mat return false; } -static void valueFlowRightShift(TokenList &tokenList, const Settings& settings) +static void valueFlowRightShift(TokenList& tokenList, const Settings& settings) { - for (Token *tok = tokenList.front(); tok; tok = tok->next()) { + for (Token* tok = tokenList.front(); tok; tok = tok->next()) { if (tok->str() != ">>") continue; @@ -915,7 +933,7 @@ static void valueFlowRightShift(TokenList &tokenList, const Settings& settings) if (!tok->astOperand2()->valueType() || !tok->astOperand2()->valueType()->isIntegral()) continue; - MathLib::bigint lhsmax=0; + MathLib::bigint lhsmax = 0; if (!getExpressionRange(tok->astOperand1(), nullptr, &lhsmax)) continue; if (lhsmax < 0) @@ -1097,7 +1115,7 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& sett } } -static void valueFlowGlobalConstVar(TokenList& tokenList, const Settings &settings) +static void valueFlowGlobalConstVar(TokenList& tokenList, const Settings& settings) { // Get variable values... std::map vars; @@ -1105,17 +1123,10 @@ static void valueFlowGlobalConstVar(TokenList& tokenList, const Settings &settin if (!tok->variable()) continue; // Initialization... - if (tok == tok->variable()->nameToken() && - !tok->variable()->isVolatile() && - !tok->variable()->isArgument() && - tok->variable()->isConst() && - tok->valueType() && - tok->valueType()->isIntegral() && - tok->valueType()->pointer == 0 && - tok->valueType()->constness == 1 && - Token::Match(tok, "%name% =") && - tok->next()->astOperand2() && - tok->next()->astOperand2()->hasKnownIntValue()) { + if (tok == tok->variable()->nameToken() && !tok->variable()->isVolatile() && !tok->variable()->isArgument() && + tok->variable()->isConst() && tok->valueType() && tok->valueType()->isIntegral() && + tok->valueType()->pointer == 0 && tok->valueType()->constness == 1 && Token::Match(tok, "%name% =") && + tok->next()->astOperand2() && tok->next()->astOperand2()->hasKnownIntValue()) { vars[tok->variable()] = tok->next()->astOperand2()->values().front(); } } @@ -1131,23 +1142,17 @@ static void valueFlowGlobalConstVar(TokenList& tokenList, const Settings &settin } } -static void valueFlowGlobalStaticVar(TokenList &tokenList, const Settings &settings) +static void valueFlowGlobalStaticVar(TokenList& tokenList, const Settings& settings) { // Get variable values... - std::map vars; - for (const Token *tok = tokenList.front(); tok; tok = tok->next()) { + std::map vars; + for (const Token* tok = tokenList.front(); tok; tok = tok->next()) { if (!tok->variable()) continue; // Initialization... - if (tok == tok->variable()->nameToken() && - tok->variable()->isStatic() && - !tok->variable()->isConst() && - tok->valueType() && - tok->valueType()->isIntegral() && - tok->valueType()->pointer == 0 && - tok->valueType()->constness == 0 && - Token::Match(tok, "%name% =") && - tok->next()->astOperand2() && + if (tok == tok->variable()->nameToken() && tok->variable()->isStatic() && !tok->variable()->isConst() && + tok->valueType() && tok->valueType()->isIntegral() && tok->valueType()->pointer == 0 && + tok->valueType()->constness == 0 && Token::Match(tok, "%name% =") && tok->next()->astOperand2() && tok->next()->astOperand2()->hasKnownIntValue()) { vars[tok->variable()] = tok->next()->astOperand2()->values().front(); } else { @@ -1169,10 +1174,10 @@ static void valueFlowGlobalStaticVar(TokenList &tokenList, const Settings &setti } // Set values.. - for (Token *tok = tokenList.front(); tok; tok = tok->next()) { + for (Token* tok = tokenList.front(); tok; tok = tok->next()) { if (!tok->variable()) continue; - const std::map::const_iterator var = vars.find(tok->variable()); + const std::map::const_iterator var = vars.find(tok->variable()); if (var == vars.end()) continue; setTokenValue(tok, var->second, settings); @@ -1262,7 +1267,12 @@ static void valueFlowReverse(Token* tok, for (ValueFlow::Value& v : values) { if (settings.debugnormal) setSourceLocation(v, loc, tok); - valueFlowGenericReverse(tok, endToken, makeReverseAnalyzer(varToken, std::move(v), settings), tokenlist, errorLogger, settings); + valueFlowGenericReverse(tok, + endToken, + makeReverseAnalyzer(varToken, std::move(v), settings), + tokenlist, + errorLogger, + settings); } } @@ -3232,22 +3242,33 @@ static const Scope* getLoopScope(const Token* tok) } // -static void valueFlowConditionExpressions(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings) +static void valueFlowConditionExpressions(const TokenList& tokenlist, + const SymbolDatabase& symboldatabase, + ErrorLogger& errorLogger, + const Settings& settings) { - if (!settings.daca && !settings.vfOptions.doConditionExpressionAnalysis) - { + if (!settings.daca && !settings.vfOptions.doConditionExpressionAnalysis) { if (settings.debugwarnings) { ErrorMessage::FileLocation loc(tokenlist.getSourceFilePath(), 0, 0); - const ErrorMessage errmsg({std::move(loc)}, tokenlist.getSourceFilePath(), Severity::debug, "Analysis of condition expressions is disabled. Use --check-level=exhaustive to enable it.", "normalCheckLevelConditionExpressions", Certainty::normal); + const ErrorMessage errmsg( + {std::move(loc)}, + tokenlist.getSourceFilePath(), + Severity::debug, + "Analysis of condition expressions is disabled. Use --check-level=exhaustive to enable it.", + "normalCheckLevelConditionExpressions", + Certainty::normal); errorLogger.reportErr(errmsg); } return; } - for (const Scope * scope : symboldatabase.functionScopes) { + for (const Scope* scope : symboldatabase.functionScopes) { if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) { if (settings.debugwarnings) - bailoutIncompleteVar(tokenlist, errorLogger, incompleteTok, "Skipping function due to incomplete variable " + incompleteTok->str()); + bailoutIncompleteVar(tokenlist, + errorLogger, + incompleteTok, + "Skipping function due to incomplete variable " + incompleteTok->str()); continue; } @@ -3260,7 +3281,7 @@ static void valueFlowConditionExpressions(const TokenList &tokenlist, const Symb Token* parenTok = tok->next(); if (!Token::simpleMatch(parenTok->link(), ") {")) continue; - Token * blockTok = parenTok->link()->tokAt(1); + Token* blockTok = parenTok->link()->tokAt(1); const Token* condTok = parenTok->astOperand2(); if (condTok->exprId() == 0) continue; @@ -3277,11 +3298,17 @@ static void valueFlowConditionExpressions(const TokenList &tokenlist, const Symb for (const Token* condTok2 : getConditions(condTok, "&&")) { if (is1) { const bool isBool = astIsBool(condTok2) || Token::Match(condTok2, "%comp%|%oror%|&&"); - auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(1, condTok2, /*assume*/ true, !isBool, settings), settings); // don't set '1' for non-boolean expressions + auto a1 = makeSameExpressionAnalyzer( + condTok2, + makeConditionValue(1, condTok2, /*assume*/ true, !isBool, settings), + settings); // don't set '1' for non-boolean expressions valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); } - auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(0, condTok2, true, false, settings), settings); + auto a2 = makeOppositeExpressionAnalyzer(true, + condTok2, + makeConditionValue(0, condTok2, true, false, settings), + settings); valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); } } @@ -3291,12 +3318,18 @@ static void valueFlowConditionExpressions(const TokenList &tokenlist, const Symb // Check else block if (Token::simpleMatch(startTok->link(), "} else {")) { startTok = startTok->link()->tokAt(2); - for (const Token* condTok2:conds) { - auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(0, condTok2, false, false, settings), settings); + for (const Token* condTok2 : conds) { + auto a1 = makeSameExpressionAnalyzer(condTok2, + makeConditionValue(0, condTok2, false, false, settings), + settings); valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); if (is1) { - auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(isOp, condTok2, false, false, settings), settings); + auto a2 = + makeOppositeExpressionAnalyzer(true, + condTok2, + makeConditionValue(isOp, condTok2, false, false, settings), + settings); valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); } } @@ -3311,13 +3344,23 @@ static void valueFlowConditionExpressions(const TokenList &tokenlist, const Symb if (!scope2) continue; } - for (const Token* condTok2:conds) { - auto a1 = makeSameExpressionAnalyzer(condTok2, makeConditionValue(0, condTok2, false, false, settings), settings); + for (const Token* condTok2 : conds) { + auto a1 = makeSameExpressionAnalyzer(condTok2, + makeConditionValue(0, condTok2, false, false, settings), + settings); valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a1, tokenlist, errorLogger, settings); if (is1) { - auto a2 = makeOppositeExpressionAnalyzer(true, condTok2, makeConditionValue(1, condTok2, false, false, settings), settings); - valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a2, tokenlist, errorLogger, settings); + auto a2 = makeOppositeExpressionAnalyzer(true, + condTok2, + makeConditionValue(1, condTok2, false, false, settings), + settings); + valueFlowGenericForward(startTok->link()->next(), + scope2->bodyEnd, + a2, + tokenlist, + errorLogger, + settings); } } } @@ -4890,8 +4933,7 @@ static bool isIntegralOrPointer(const Token* tok) return false; } -static void valueFlowInferCondition(TokenList& tokenlist, - const Settings& settings) +static void valueFlowInferCondition(TokenList& tokenlist, const Settings& settings) { for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (!tok->astParent()) @@ -5264,14 +5306,14 @@ static bool productParams(const Settings& settings, const std::unordered_map>; Args args(1); // Compute cartesian product of all arguments - for (const auto& p:vars) { + for (const auto& p : vars) { if (p.second.empty()) continue; args.back()[p.first] = p.second.front(); } bool bail = false; int max = settings.vfOptions.maxSubFunctionArgs; - for (const auto& p:vars) { + for (const auto& p : vars) { if (args.size() > max) { bail = true; break; @@ -5280,9 +5322,9 @@ static bool productParams(const Settings& settings, const std::unordered_map& arg) { auto a = makeMultiValueFlowAnalyzer(arg, settings); - valueFlowGenericForward(const_cast(functionScope->bodyStart), functionScope->bodyEnd, a, tokenlist, errorLogger, settings); + valueFlowGenericForward(const_cast(functionScope->bodyStart), + functionScope->bodyEnd, + a, + tokenlist, + errorLogger, + settings); }); if (!r) { std::string fname = ""; @@ -5362,15 +5409,18 @@ static void valueFlowInjectParameter(const TokenList& tokenlist, settings); } -static void valueFlowSwitchVariable(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings) +static void valueFlowSwitchVariable(const TokenList& tokenlist, + const SymbolDatabase& symboldatabase, + ErrorLogger& errorLogger, + const Settings& settings) { - for (const Scope &scope : symboldatabase.scopeList) { + for (const Scope& scope : symboldatabase.scopeList) { if (scope.type != Scope::ScopeType::eSwitch) continue; if (!Token::Match(scope.classDef, "switch ( %var% ) {")) continue; - const Token *vartok = scope.classDef->tokAt(2); - const Variable *var = vartok->variable(); + const Token* vartok = scope.classDef->tokAt(2); + const Variable* var = vartok->variable(); if (!var) continue; @@ -5381,7 +5431,7 @@ static void valueFlowSwitchVariable(const TokenList &tokenlist, const SymbolData continue; } - for (const Token *tok = scope.bodyStart->next(); tok != scope.bodyEnd; tok = tok->next()) { + for (const Token* tok = scope.bodyStart->next(); tok != scope.bodyEnd; tok = tok->next()) { if (tok->str() == "{") { tok = tok->link(); continue; @@ -5390,9 +5440,12 @@ static void valueFlowSwitchVariable(const TokenList &tokenlist, const SymbolData std::list values; values.emplace_back(MathLib::toBigNumber(tok->strAt(1))); values.back().condition = tok; - values.back().errorPath.emplace_back(tok, "case " + tok->strAt(1) + ": " + vartok->str() + " is " + tok->strAt(1) + " here."); + values.back().errorPath.emplace_back(tok, + "case " + tok->strAt(1) + ": " + vartok->str() + " is " + + tok->strAt(1) + " here."); bool known = false; - if ((Token::simpleMatch(tok->previous(), "{") || Token::simpleMatch(tok->tokAt(-2), "break ;")) && !Token::Match(tok->tokAt(3), ";| case")) + if ((Token::simpleMatch(tok->previous(), "{") || Token::simpleMatch(tok->tokAt(-2), "break ;")) && + !Token::Match(tok->tokAt(3), ";| case")) known = true; while (Token::Match(tok->tokAt(3), ";| case %num% :")) { known = false; @@ -5401,15 +5454,12 @@ static void valueFlowSwitchVariable(const TokenList &tokenlist, const SymbolData tok = tok->next(); values.emplace_back(MathLib::toBigNumber(tok->strAt(1))); values.back().condition = tok; - values.back().errorPath.emplace_back(tok, "case " + tok->strAt(1) + ": " + vartok->str() + " is " + tok->strAt(1) + " here."); + values.back().errorPath.emplace_back(tok, + "case " + tok->strAt(1) + ": " + vartok->str() + " is " + + tok->strAt(1) + " here."); } for (auto val = values.cbegin(); val != values.cend(); ++val) { - valueFlowReverse(tokenlist, - const_cast(scope.classDef), - vartok, - *val, - errorLogger, - settings); + valueFlowReverse(tokenlist, const_cast(scope.classDef), vartok, *val, errorLogger, settings); } if (vartok->variable()->scope()) { if (known) @@ -5434,7 +5484,7 @@ static void valueFlowSwitchVariable(const TokenList &tokenlist, const SymbolData } } -static std::list getFunctionArgumentValues(const Token *argtok) +static std::list getFunctionArgumentValues(const Token* argtok) { std::list argvalues(argtok->values()); removeImpossible(argvalues); @@ -5445,11 +5495,11 @@ static std::list getFunctionArgumentValues(const Token *argtok return argvalues; } -static void valueFlowLibraryFunction(Token *tok, const std::string &returnValue, const Settings &settings) +static void valueFlowLibraryFunction(Token* tok, const std::string& returnValue, const Settings& settings) { std::unordered_map> argValues; int argn = 1; - for (const Token *argtok : getArguments(tok->previous())) { + for (const Token* argtok : getArguments(tok->previous())) { argValues[argn] = getFunctionArgumentValues(argtok); argn++; } @@ -5476,7 +5526,10 @@ static void valueFlowLibraryFunction(Token *tok, const std::string &returnValue, }); } -static void valueFlowSubFunction(const TokenList& tokenlist, SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, const Settings& settings) +static void valueFlowSubFunction(const TokenList& tokenlist, + SymbolDatabase& symboldatabase, + ErrorLogger& errorLogger, + const Settings& settings) { int id = 0; for (auto it = symboldatabase.functionScopes.crbegin(); it != symboldatabase.functionScopes.crend(); ++it) { @@ -5488,7 +5541,7 @@ static void valueFlowSubFunction(const TokenList& tokenlist, SymbolDatabase& sym if (tok->isKeyword() || !Token::Match(tok, "%name% (")) continue; - const Function * const calledFunction = tok->function(); + const Function* const calledFunction = tok->function(); if (!calledFunction) { // library function? const std::string& returnValue(settings.library.returnValue(tok)); @@ -5497,18 +5550,18 @@ static void valueFlowSubFunction(const TokenList& tokenlist, SymbolDatabase& sym continue; } - const Scope * const calledFunctionScope = calledFunction->functionScope; + const Scope* const calledFunctionScope = calledFunction->functionScope; if (!calledFunctionScope) continue; id++; std::unordered_map> argvars; // TODO: Rewrite this. It does not work well to inject 1 argument at a time. - const std::vector &callArguments = getArguments(tok); + const std::vector& callArguments = getArguments(tok); for (int argnr = 0U; argnr < callArguments.size(); ++argnr) { - const Token *argtok = callArguments[argnr]; + const Token* argtok = callArguments[argnr]; // Get function argument - const Variable * const argvar = calledFunction->getArgumentVar(argnr); + const Variable* const argvar = calledFunction->getArgumentVar(argnr); if (!argvar) break; @@ -5522,7 +5575,8 @@ static void valueFlowSubFunction(const TokenList& tokenlist, SymbolDatabase& sym return false; }); // Remove uninit values if argument is passed by value - if (argtok->variable() && !argtok->variable()->isPointer() && argvalues.size() == 1 && argvalues.front().isUninitValue()) { + if (argtok->variable() && !argtok->variable()->isPointer() && argvalues.size() == 1 && + argvalues.front().isUninitValue()) { if (CheckUninitVar::isVariableUsage(argtok, settings.library, false, CheckUninitVar::Alloc::NO_ALLOC, 0)) continue; } @@ -5531,18 +5585,12 @@ static void valueFlowSubFunction(const TokenList& tokenlist, SymbolDatabase& sym continue; // Error path.. - for (ValueFlow::Value &v : argvalues) { + for (ValueFlow::Value& v : argvalues) { const std::string nr = std::to_string(argnr + 1) + getOrdinalText(argnr + 1); v.errorPath.emplace_back(argtok, - "Calling function '" + - calledFunction->name() + - "', " + - nr + - " argument '" + - argtok->expressionString() + - "' value is " + - v.infoString()); + "Calling function '" + calledFunction->name() + "', " + nr + " argument '" + + argtok->expressionString() + "' value is " + v.infoString()); v.path = 256 * v.path + id % 256; // Change scope of lifetime values if (v.isLifetimeValue()) @@ -5628,9 +5676,9 @@ static void setFunctionReturnValue(const Function* f, Token* tok, ValueFlow::Val setTokenValue(tok, std::move(v), settings); } -static void valueFlowFunctionReturn(TokenList &tokenlist, ErrorLogger &errorLogger, const Settings& settings) +static void valueFlowFunctionReturn(TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) { - for (Token *tok = tokenlist.back(); tok; tok = tok->previous()) { + for (Token* tok = tokenlist.back(); tok; tok = tok->previous()) { if (tok->str() != "(" || !tok->astOperand1() || tok->isCast()) continue; @@ -5662,7 +5710,7 @@ static void valueFlowFunctionReturn(TokenList &tokenlist, ErrorLogger &errorLogg ProgramMemory programMemory; for (std::size_t i = 0; i < arguments.size(); ++i) { - const Variable * const arg = function->getArgumentVar(i); + const Variable* const arg = function->getArgumentVar(i); if (!arg) { if (settings.debugwarnings) bailout(tokenlist, errorLogger, tok, "function return; unhandled argument type"); @@ -6147,7 +6195,7 @@ static void valueFlowSmartPointer(TokenList &tokenlist, ErrorLogger & errorLogge } } -static Library::Container::Yield findIteratorYield(Token* tok, const Token** ftok, const Settings &settings) +static Library::Container::Yield findIteratorYield(Token* tok, const Token** ftok, const Settings& settings) { auto yield = astContainerYield(tok, ftok); if (ftok && *ftok) @@ -6156,13 +6204,13 @@ static Library::Container::Yield findIteratorYield(Token* tok, const Token** fto if (!tok->astParent()) return yield; - //begin/end free functions + // begin/end free functions return astFunctionYield(tok->astParent()->previous(), settings, ftok); } -static void valueFlowIterators(TokenList &tokenlist, const Settings &settings) +static void valueFlowIterators(TokenList& tokenlist, const Settings& settings) { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (!tok->scope()) continue; if (!tok->scope()->isExecutable()) @@ -6185,7 +6233,8 @@ static void valueFlowIterators(TokenList &tokenlist, const Settings &settings) } } -static std::list getIteratorValues(std::list values, const ValueFlow::Value::ValueKind* kind = nullptr) +static std::list getIteratorValues(std::list values, + const ValueFlow::Value::ValueKind* kind = nullptr) { values.remove_if([&](const ValueFlow::Value& v) { if (kind && v.valueKind != *kind) @@ -6224,9 +6273,9 @@ struct IteratorConditionHandler : SimpleConditionHandler { } }; -static void valueFlowIteratorInfer(TokenList &tokenlist, const Settings &settings) +static void valueFlowIteratorInfer(TokenList& tokenlist, const Settings& settings) { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (!tok->scope()) continue; if (!tok->scope()->isExecutable()) @@ -6245,7 +6294,7 @@ static void valueFlowIteratorInfer(TokenList &tokenlist, const Settings &setting return true; return false; }); - for (ValueFlow::Value& v:values) { + for (ValueFlow::Value& v : values) { v.setPossible(); if (v.isIteratorStartValue()) v.intvalue++; @@ -6765,15 +6814,19 @@ static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolD } } -static bool getMinMaxValues(const std::string &typestr, const Settings &settings, bool cpp, MathLib::bigint &minvalue, MathLib::bigint &maxvalue) +static bool getMinMaxValues(const std::string& typestr, + const Settings& settings, + bool cpp, + MathLib::bigint& minvalue, + MathLib::bigint& maxvalue) { TokenList typeTokens(&settings); - std::istringstream istr(typestr+";"); + std::istringstream istr(typestr + ";"); if (!typeTokens.createTokens(istr, cpp ? Standards::Language::CPP : Standards::Language::C)) return false; typeTokens.simplifyPlatformTypes(); typeTokens.simplifyStdType(); - const ValueType &vt = ValueType::parseDecl(typeTokens.front(), settings); + const ValueType& vt = ValueType::parseDecl(typeTokens.front(), settings); return ValueFlow::getMinMaxValues(&vt, settings.platform, minvalue, maxvalue); } @@ -6875,11 +6928,11 @@ static void valueFlowSafeFunctions(const TokenList& tokenlist, const SymbolDatab } } -static void valueFlowUnknownFunctionReturn(TokenList &tokenlist, const Settings &settings) +static void valueFlowUnknownFunctionReturn(TokenList& tokenlist, const Settings& settings) { if (settings.checkUnknownFunctionReturn.empty()) return; - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { + for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { if (!tok->astParent() || tok->str() != "(" || !tok->previous()->isName()) continue; if (settings.checkUnknownFunctionReturn.find(tok->strAt(-1)) == settings.checkUnknownFunctionReturn.end()) @@ -6889,7 +6942,7 @@ static void valueFlowUnknownFunctionReturn(TokenList &tokenlist, const Settings continue; // Get min/max values for return type - const std::string &typestr = settings.library.returnValueType(tok->previous()); + const std::string& typestr = settings.library.returnValueType(tok->previous()); MathLib::bigint minvalue, maxvalue; if (!getMinMaxValues(typestr, settings, tok->isCpp(), minvalue, maxvalue)) continue; @@ -7168,7 +7221,8 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(valueFlowArrayBool(tokenlist, settings)), VFA(valueFlowArrayElement(tokenlist, settings)), VFA(valueFlowRightShift(tokenlist, settings)), - VFA_CPP(valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), + VFA_CPP( + valueFlowCondition(ContainerConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA(valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA_CPP(valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings)), VFA(valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 66c7b14c009..d84690837f8 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2037,7 +2037,9 @@ 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()); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", + errout_str()); } void simplifyKnownVariables36() { @@ -2160,7 +2162,9 @@ class TestSimplifyTokens : public TestFixture { "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()); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", + errout_str()); } void simplifyKnownVariables47() { @@ -2174,7 +2178,9 @@ 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()); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cin\n", + errout_str()); } void simplifyKnownVariables48() { @@ -2204,7 +2210,9 @@ 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()); + ASSERT_EQUALS( + "[test.c:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", + errout_str()); } void simplifyKnownVariables50() { // #4066 @@ -2227,7 +2235,9 @@ 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()); + ASSERT_EQUALS( + "[test.cpp:5]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable y\n", + errout_str()); } { //don't simplify '&x'! @@ -2248,7 +2258,9 @@ 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()); + ASSERT_EQUALS( + "[test.cpp:5]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable y\n", + errout_str()); } } @@ -2268,7 +2280,9 @@ 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()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", + errout_str()); } void simplifyKnownVariables58() { // #5268 @@ -2348,7 +2362,9 @@ class TestSimplifyTokens : public TestFixture { "return i ;\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", 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() { @@ -2362,7 +2378,9 @@ 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()); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable nr\n", + errout_str()); } void simplifyKnownVariablesBailOutFor1() { @@ -2423,7 +2441,9 @@ class TestSimplifyTokens : public TestFixture { " return a;\n" "}\n"; (void)tokenizeAndStringify(code,true); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", 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() { diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 00a20f6a2b0..8a79f93a94a 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -1154,7 +1154,9 @@ class TestSimplifyTypedef : public TestFixture { "}"; ASSERT_EQUALS(expected, tok(code, false)); - ASSERT_EQUALS("[test.cpp:4]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable value\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:4]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable value\n", + errout_str()); } void simplifyTypedef28() { @@ -2014,7 +2016,9 @@ class TestSimplifyTypedef : public TestFixture { "( ( int * * * ) global [ 6 ] ) ( \"assoc\" , \"eggdrop\" , 106 , 0 ) ; " "}"; ASSERT_EQUALS(expected, tok(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable global\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable global\n", + errout_str()); } void simplifyTypedef68() { // ticket #2355 diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index 830fe45e84f..adb631d8314 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -743,7 +743,9 @@ class TestSimplifyUsing : public TestFixture { "cout << std :: string ( c ) << \"abc\" ; " "}"; ASSERT_EQUALS(expected, tok(code, Platform::Type::Native, /*debugwarnings*/ true)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cout\n", 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> {\n" // #12521 diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index af2ed01dc13..de4e519ac5b 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3409,10 +3409,11 @@ class TestSymbolDatabase : public TestFixture { // ticket #2991 - segmentation fault check("::y(){x}"); - ASSERT_EQUALS("[test.cpp:1]: (debug) Executable scope 'y' with unknown function.\n" - "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n" - "[test.cpp:1]: (debug) Executable scope 'y' with unknown function.\n", // duplicate - errout_str()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) Executable scope 'y' with unknown function.\n" + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n" + "[test.cpp:1]: (debug) Executable scope 'y' with unknown function.\n", // duplicate + errout_str()); } void symboldatabase20() { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index f737fa29213..bff7e0b98de 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -547,7 +547,9 @@ class TestTokenizer : public TestFixture { const char code[] = "void f ( )\n" "{ if ( p . y ( ) > yof ) { } }"; ASSERT_EQUALS(code, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable yof\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable yof\n", + errout_str()); } void tokenize2() { @@ -873,7 +875,9 @@ class TestTokenizer : public TestFixture { //valid, when there's also this declaration: 'constexpr int g[1] = {0};' ASSERT_NO_THROW(tokenizeAndStringify("void f(int n) {switch (n) { case g[0]: z(); break;}}")); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable g\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable g\n", + errout_str()); //valid, similar to above case ASSERT_NO_THROW(tokenizeAndStringify("void f(int n) {switch (n) { case *g: z(); break;}}")); @@ -881,7 +885,9 @@ class TestTokenizer : public TestFixture { //valid, when 'x' and 'y' are constexpr. ASSERT_NO_THROW(tokenizeAndStringify("void f(int n) {switch (n) { case sqrt(x+y): z(); break;}}")); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", + errout_str()); } void removePragma() { @@ -901,12 +907,16 @@ class TestTokenizer : public TestFixture { // #3690,#5154 const char code[] ="void f() { for each ( char c in MyString ) { Console::Write(c); } }"; ASSERT_EQUALS("void f ( ) { asm ( \"char c in MyString\" ) { Console :: Write ( c ) ; } }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable c\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable c\n", + errout_str()); } void ifconstexpr() { ASSERT_EQUALS("void f ( ) { if ( FOO ) { bar ( c ) ; } }", tokenizeAndStringify("void f() { if constexpr ( FOO ) { bar(c); } }")); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable FOO\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable FOO\n", + filter_valueflow(errout_str())); } void combineOperators() { @@ -1071,7 +1081,9 @@ class TestTokenizer : public TestFixture { "if ( a ) { ; }\n" "else { ; }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", + filter_valueflow(errout_str())); } void ifAddBraces2() { @@ -1083,7 +1095,9 @@ class TestTokenizer : public TestFixture { "{\n" "if ( a ) { if ( b ) { } }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", + filter_valueflow(errout_str())); } void ifAddBraces3() { @@ -1095,7 +1109,9 @@ class TestTokenizer : public TestFixture { "{\n" "if ( a ) { for ( ; ; ) { } }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", + filter_valueflow(errout_str())); } void ifAddBraces4() { @@ -1115,7 +1131,9 @@ class TestTokenizer : public TestFixture { "{ } }\n" "return str ;\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:4]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable somecondition\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:4]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable somecondition\n", + filter_valueflow(errout_str())); } void ifAddBraces5() { @@ -1202,7 +1220,9 @@ class TestTokenizer : public TestFixture { "}"; ASSERT_EQUALS("void f ( ) { ( void ) ( { if ( * p ) { ( * p ) = x ( ) ; } } ) }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", + filter_valueflow(errout_str())); } } @@ -1223,7 +1243,9 @@ class TestTokenizer : public TestFixture { "else {\n" "bar2 ( ) ; }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", + filter_valueflow(errout_str())); } void ifAddBraces18() { @@ -1255,7 +1277,9 @@ class TestTokenizer : public TestFixture { "else {\n" "bar2 ( ) ; } } }\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", + filter_valueflow(errout_str())); } void ifAddBraces20() { // #5012 - syntax error 'else }' @@ -1450,7 +1474,9 @@ class TestTokenizer : public TestFixture { "do { while ( x ) { f ( ) ; } } while ( y ) ;\n" "}"; ASSERT_EQUALS(result, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", + filter_valueflow(errout_str())); } } @@ -1509,7 +1535,9 @@ class TestTokenizer : public TestFixture { "else { } }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", + filter_valueflow(errout_str())); } { @@ -1526,7 +1554,9 @@ class TestTokenizer : public TestFixture { "else { } } }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable a\n", + filter_valueflow(errout_str())); } } @@ -1652,7 +1682,9 @@ class TestTokenizer : public TestFixture { " { }" "}"; ASSERT_EQUALS("void foo ( ) { if ( x ) { int x ; } { } }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", filter_valueflow(errout_str())); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", + filter_valueflow(errout_str())); } } @@ -1766,7 +1798,9 @@ class TestTokenizer : public TestFixture { "}"; ASSERT_EQUALS("void foo ( ) { free ( ( void * ) p ) ; }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", + errout_str()); } void removeParentheses3() { @@ -1802,7 +1836,9 @@ class TestTokenizer : public TestFixture { " (free(p));" "}"; ASSERT_EQUALS("void foo ( ) { free ( p ) ; }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", + errout_str()); } void removeParentheses5() { @@ -1813,7 +1849,9 @@ class TestTokenizer : public TestFixture { " (delete p);" "}"; ASSERT_EQUALS("void foo ( ) { delete p ; }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", + errout_str()); } // Simplify "( delete [] x )" into "delete [] x" @@ -1823,7 +1861,9 @@ class TestTokenizer : public TestFixture { " (delete [] p);" "}"; ASSERT_EQUALS("void foo ( ) { delete [ ] p ; }", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", + errout_str()); } } @@ -2111,7 +2151,9 @@ class TestTokenizer : public TestFixture { "}", tokenizeAndStringify("void foo(int nX) {\n" " int addI = frontPoint == 2 || frontPoint == 1 ? i = 0, 1 : (i = nX - 2, -1);\n" "}")); - ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable frontPoint\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable frontPoint\n", + errout_str()); } void vardecl_stl_1() { @@ -2352,7 +2394,9 @@ class TestTokenizer : public TestFixture { " int a = (x < y) ? 1 : 0;\n" "}"; ASSERT_EQUALS("void f ( ) {\nint a ; a = ( x < y ) ? 1 : 0 ;\n}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable x\n", + errout_str()); } void vardecl14() { @@ -2393,7 +2437,9 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("void f ( ) {\n" "g ( ( double ) v1 * v2 , v3 , v4 ) ;\n" "}", tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable v1\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable v1\n", + errout_str()); } void vardecl19() { @@ -2677,7 +2723,9 @@ class TestTokenizer : public TestFixture { "} ;"; ASSERT_EQUALS(out5, tokenizeAndStringify(in5)); - ASSERT_EQUALS("[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable pos\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:3]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable pos\n", + errout_str()); } { // Ticket #8679 @@ -3733,7 +3781,9 @@ class TestTokenizer : public TestFixture { "( void ) ( xy ( * p ) ( 0 ) ) ;\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code)); - ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable p\n", + errout_str()); } void simplifyFunctionPointers4() { @@ -4041,7 +4091,9 @@ class TestTokenizer : public TestFixture { " FFABS ( sprite_delta [ 1 ] [ i ] ) >= INT_MAX >> shift_y ) ;\n" "}"; ASSERT_EQUALS(std::string::npos, tokenizeAndStringify(code).find("> >")); - ASSERT_EQUALS("[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable sprite_shift\n", errout_str()); + ASSERT_EQUALS( + "[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable sprite_shift\n", + errout_str()); } { const char code[] = "struct S { bool vector; };\n" @@ -4180,7 +4232,9 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("; int a [ 1 ] = { foo < bar1 , bar2 > ( 123 , 4 ) } ;", tokenizeAndStringify(";int a[]={foo(123,4)};")); ASSERT_EQUALS("; int a [ 2 ] = { b > c ? 1 : 2 , 3 } ;", tokenizeAndStringify(";int a[]={ b>c?1:2,3};")); ASSERT_EQUALS("int main ( ) { int a [ 2 ] = { b < c ? 1 : 2 , 3 } }", tokenizeAndStringify("int main(){int a[]={b Date: Tue, 5 Nov 2024 10:03:17 -0600 Subject: [PATCH 09/13] Remove lib.pri file --- lib/lib.pri | 174 ---------------------------------------------------- 1 file changed, 174 deletions(-) delete mode 100644 lib/lib.pri diff --git a/lib/lib.pri b/lib/lib.pri deleted file mode 100644 index f0a95ce0bca..00000000000 --- a/lib/lib.pri +++ /dev/null @@ -1,174 +0,0 @@ -# no manual edits - this file is autogenerated by dmake - -include($$PWD/pcrerules.pri) -include($$PWD/../externals/externals.pri) -INCLUDEPATH += $$PWD -HEADERS += $${PWD}/addoninfo.h \ - $${PWD}/analyzer.h \ - $${PWD}/analyzerinfo.h \ - $${PWD}/astutils.h \ - $${PWD}/calculate.h \ - $${PWD}/check.h \ - $${PWD}/check64bit.h \ - $${PWD}/checkassert.h \ - $${PWD}/checkautovariables.h \ - $${PWD}/checkbool.h \ - $${PWD}/checkboost.h \ - $${PWD}/checkbufferoverrun.h \ - $${PWD}/checkclass.h \ - $${PWD}/checkcondition.h \ - $${PWD}/checkers.h \ - $${PWD}/checkersreport.h \ - $${PWD}/checkexceptionsafety.h \ - $${PWD}/checkfunctions.h \ - $${PWD}/checkinternal.h \ - $${PWD}/checkio.h \ - $${PWD}/checkleakautovar.h \ - $${PWD}/checkmemoryleak.h \ - $${PWD}/checknullpointer.h \ - $${PWD}/checkother.h \ - $${PWD}/checkpostfixoperator.h \ - $${PWD}/checksizeof.h \ - $${PWD}/checkstl.h \ - $${PWD}/checkstring.h \ - $${PWD}/checktype.h \ - $${PWD}/checkuninitvar.h \ - $${PWD}/checkunusedfunctions.h \ - $${PWD}/checkunusedvar.h \ - $${PWD}/checkvaarg.h \ - $${PWD}/clangimport.h \ - $${PWD}/color.h \ - $${PWD}/config.h \ - $${PWD}/cppcheck.h \ - $${PWD}/ctu.h \ - $${PWD}/errorlogger.h \ - $${PWD}/errortypes.h \ - $${PWD}/filesettings.h \ - $${PWD}/findtoken.h \ - $${PWD}/forwardanalyzer.h \ - $${PWD}/fwdanalysis.h \ - $${PWD}/importproject.h \ - $${PWD}/infer.h \ - $${PWD}/json.h \ - $${PWD}/keywords.h \ - $${PWD}/library.h \ - $${PWD}/matchcompiler.h \ - $${PWD}/mathlib.h \ - $${PWD}/path.h \ - $${PWD}/pathanalysis.h \ - $${PWD}/pathmatch.h \ - $${PWD}/platform.h \ - $${PWD}/precompiled.h \ - $${PWD}/preprocessor.h \ - $${PWD}/programmemory.h \ - $${PWD}/reverseanalyzer.h \ - $${PWD}/settings.h \ - $${PWD}/smallvector.h \ - $${PWD}/sourcelocation.h \ - $${PWD}/standards.h \ - $${PWD}/summaries.h \ - $${PWD}/suppressions.h \ - $${PWD}/symboldatabase.h \ - $${PWD}/templatesimplifier.h \ - $${PWD}/timer.h \ - $${PWD}/token.h \ - $${PWD}/tokenize.h \ - $${PWD}/tokenlist.h \ - $${PWD}/tokenrange.h \ - $${PWD}/utils.h \ - $${PWD}/valueflow.h \ - $${PWD}/valueptr.h \ - $${PWD}/version.h \ - $${PWD}/vf_analyze.h \ -<<<<<<< HEAD - $${PWD}/vf_analyzers.h \ - $${PWD}/vf_array.h \ - $${PWD}/vf_arraybool.h \ - $${PWD}/vf_arrayelement.h \ - $${PWD}/vf_bailout.h \ - $${PWD}/vf_bitand.h \ -======= ->>>>>>> revert-valueflow-split2 - $${PWD}/vf_common.h \ - $${PWD}/vf_enumvalue.h \ - $${PWD}/vf_number.h \ - $${PWD}/vf_settokenvalue.h \ - $${PWD}/vfvalue.h \ - $${PWD}/xml.h - -SOURCES += $${PWD}/valueflow.cpp \ - $${PWD}/tokenize.cpp \ - $${PWD}/symboldatabase.cpp \ - $${PWD}/addoninfo.cpp \ - $${PWD}/analyzerinfo.cpp \ - $${PWD}/astutils.cpp \ - $${PWD}/check.cpp \ - $${PWD}/check64bit.cpp \ - $${PWD}/checkassert.cpp \ - $${PWD}/checkautovariables.cpp \ - $${PWD}/checkbool.cpp \ - $${PWD}/checkboost.cpp \ - $${PWD}/checkbufferoverrun.cpp \ - $${PWD}/checkclass.cpp \ - $${PWD}/checkcondition.cpp \ - $${PWD}/checkers.cpp \ - $${PWD}/checkersreport.cpp \ - $${PWD}/checkexceptionsafety.cpp \ - $${PWD}/checkfunctions.cpp \ - $${PWD}/checkinternal.cpp \ - $${PWD}/checkio.cpp \ - $${PWD}/checkleakautovar.cpp \ - $${PWD}/checkmemoryleak.cpp \ - $${PWD}/checknullpointer.cpp \ - $${PWD}/checkother.cpp \ - $${PWD}/checkpostfixoperator.cpp \ - $${PWD}/checksizeof.cpp \ - $${PWD}/checkstl.cpp \ - $${PWD}/checkstring.cpp \ - $${PWD}/checktype.cpp \ - $${PWD}/checkuninitvar.cpp \ - $${PWD}/checkunusedfunctions.cpp \ - $${PWD}/checkunusedvar.cpp \ - $${PWD}/checkvaarg.cpp \ - $${PWD}/clangimport.cpp \ - $${PWD}/color.cpp \ - $${PWD}/cppcheck.cpp \ - $${PWD}/ctu.cpp \ - $${PWD}/errorlogger.cpp \ - $${PWD}/errortypes.cpp \ - $${PWD}/forwardanalyzer.cpp \ - $${PWD}/fwdanalysis.cpp \ - $${PWD}/importproject.cpp \ - $${PWD}/infer.cpp \ - $${PWD}/keywords.cpp \ - $${PWD}/library.cpp \ - $${PWD}/mathlib.cpp \ - $${PWD}/path.cpp \ - $${PWD}/pathanalysis.cpp \ - $${PWD}/pathmatch.cpp \ - $${PWD}/platform.cpp \ - $${PWD}/preprocessor.cpp \ - $${PWD}/programmemory.cpp \ - $${PWD}/reverseanalyzer.cpp \ - $${PWD}/settings.cpp \ - $${PWD}/summaries.cpp \ - $${PWD}/suppressions.cpp \ - $${PWD}/templatesimplifier.cpp \ - $${PWD}/timer.cpp \ - $${PWD}/token.cpp \ - $${PWD}/tokenlist.cpp \ - $${PWD}/utils.cpp \ -<<<<<<< HEAD - $${PWD}/vf_analyzers.cpp \ - $${PWD}/vf_array.cpp \ - $${PWD}/vf_arraybool.cpp \ - $${PWD}/vf_arrayelement.cpp \ - $${PWD}/vf_bailout.cpp \ - $${PWD}/vf_bitand.cpp \ -======= ->>>>>>> revert-valueflow-split2 - $${PWD}/vf_common.cpp \ - $${PWD}/vf_enumvalue.cpp \ - $${PWD}/vf_number.cpp \ - $${PWD}/vf_settokenvalue.cpp \ - $${PWD}/vfvalue.cpp From 878ac2f96c06049dffa5803850865567e15cc8d9 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 7 Nov 2024 18:30:44 -0600 Subject: [PATCH 10/13] Remove vf_iterators --- Makefile | 4 --- lib/cppcheck.vcxproj | 2 -- lib/vf_iterators.cpp | 71 -------------------------------------------- lib/vf_iterators.h | 30 ------------------- oss-fuzz/Makefile | 4 --- 5 files changed, 111 deletions(-) delete mode 100644 lib/vf_iterators.cpp delete mode 100644 lib/vf_iterators.h diff --git a/Makefile b/Makefile index ff81a0c1802..dcb0e30d1ab 100644 --- a/Makefile +++ b/Makefile @@ -257,7 +257,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_analyzers.o \ $(libcppdir)/vf_common.o \ $(libcppdir)/vf_enumvalue.o \ - $(libcppdir)/vf_iterators.o \ $(libcppdir)/vf_number.o \ $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vfvalue.o @@ -661,9 +660,6 @@ $(libcppdir)/vf_common.o: lib/vf_common.cpp lib/addoninfo.h lib/astutils.h lib/c $(libcppdir)/vf_enumvalue.o: lib/vf_enumvalue.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_enumvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_enumvalue.cpp -$(libcppdir)/vf_iterators.o: lib/vf_iterators.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_iterators.h lib/vf_settokenvalue.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_iterators.cpp - $(libcppdir)/vf_number.o: lib/vf_number.cpp lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vf_common.h lib/vf_number.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_number.cpp diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 05681cf4e48..502351e6924 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -92,7 +92,6 @@ - @@ -181,7 +180,6 @@ - diff --git a/lib/vf_iterators.cpp b/lib/vf_iterators.cpp deleted file mode 100644 index 6e813c19bf8..00000000000 --- a/lib/vf_iterators.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "vf_iterators.h" - -#include "astutils.h" -#include "library.h" -#include "symboldatabase.h" -#include "token.h" -#include "tokenlist.h" -#include "vfvalue.h" - -#include "vf_settokenvalue.h" - -#include - -namespace ValueFlow -{ - static Library::Container::Yield findIteratorYield(Token* tok, const Token*& ftok, const Settings &settings) - { - auto yield = astContainerYield(tok, &ftok); - if (ftok) - return yield; - - if (!tok->astParent()) - return yield; - - //begin/end free functions - return astFunctionYield(tok->astParent()->previous(), settings, &ftok); - } - - void analyzeIterators(TokenList &tokenlist, const Settings &settings) - { - for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { - if (!tok->scope()) - continue; - if (!tok->scope()->isExecutable()) - continue; - if (!astIsContainer(tok)) - continue; - const Token* ftok = nullptr; - const Library::Container::Yield yield = findIteratorYield(tok, ftok, settings); - if (!ftok) - continue; - Value v(0); - v.setKnown(); - if (yield == Library::Container::Yield::START_ITERATOR) { - v.valueType = Value::ValueType::ITERATOR_START; - setTokenValue(const_cast(ftok)->next(), std::move(v), settings); - } else if (yield == Library::Container::Yield::END_ITERATOR) { - v.valueType = Value::ValueType::ITERATOR_END; - setTokenValue(const_cast(ftok)->next(), std::move(v), settings); - } - } - } -} diff --git a/lib/vf_iterators.h b/lib/vf_iterators.h deleted file mode 100644 index 2b1a9ad9255..00000000000 --- a/lib/vf_iterators.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfIteratorsH -#define vfIteratorsH - -class TokenList; -class Settings; - -namespace ValueFlow -{ - void analyzeIterators(TokenList &tokenlist, const Settings &settings); -} - -#endif // vfIteratorsH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index c8a200d0d13..cf6742f7f2b 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -100,7 +100,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_analyzers.o \ $(libcppdir)/vf_common.o \ $(libcppdir)/vf_enumvalue.o \ - $(libcppdir)/vf_iterators.o \ $(libcppdir)/vf_number.o \ $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vfvalue.o @@ -348,9 +347,6 @@ $(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/addoninfo.h ../lib/astutil $(libcppdir)/vf_enumvalue.o: ../lib/vf_enumvalue.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_enumvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_enumvalue.cpp -$(libcppdir)/vf_iterators.o: ../lib/vf_iterators.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_iterators.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h - $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_iterators.cpp - $(libcppdir)/vf_number.o: ../lib/vf_number.cpp ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_number.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_number.cpp From 3928d1f56c3650cfaf6916dd0d37d49eef185f71 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 7 Nov 2024 18:34:22 -0600 Subject: [PATCH 11/13] Remove vf_bailout --- Makefile | 2 +- lib/valueflow.cpp | 1 - lib/vf_bailout.h | 39 --------------------------------------- oss-fuzz/Makefile | 2 +- 4 files changed, 2 insertions(+), 42 deletions(-) delete mode 100644 lib/vf_bailout.h diff --git a/Makefile b/Makefile index dcb0e30d1ab..7394dae6c96 100644 --- a/Makefile +++ b/Makefile @@ -459,7 +459,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_bailout.h lib/vf_common.h lib/vf_enumvalue.h lib/vf_number.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyze.h lib/vf_analyzers.h lib/vf_common.h lib/vf_enumvalue.h lib/vf_number.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 00a52aabbad..af6f6b140a3 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -107,7 +107,6 @@ #include "vf_analyze.h" #include "vf_analyzers.h" -#include "vf_bailout.h" #include "vf_common.h" #include "vf_settokenvalue.h" diff --git a/lib/vf_bailout.h b/lib/vf_bailout.h deleted file mode 100644 index 868755d3a25..00000000000 --- a/lib/vf_bailout.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- C++ -*- - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2024 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef vfBailoutH -#define vfBailoutH - -#include - -class TokenList; -class ErrorLogger; -class Token; - -namespace ValueFlow -{ - void bailoutInternal(const std::string& type, const TokenList &tokenlist, ErrorLogger &errorLogger, const Token *tok, const std::string &what, const std::string &file, int line, std::string function); -} - -#define bailout2(type, tokenlist, errorLogger, tok, what) ValueFlow::bailoutInternal((type), (tokenlist), (errorLogger), (tok), (what), __FILE__, __LINE__, __func__) - -#define bailout(tokenlist, errorLogger, tok, what) bailout2("valueFlowBailout", (tokenlist), (errorLogger), (tok), (what)) - -#define bailoutIncompleteVar(tokenlist, errorLogger, tok, what) ValueFlow::bailoutInternal("valueFlowBailoutIncompleteVar", (tokenlist), (errorLogger), (tok), (what), "", 0, __func__) - -#endif // vfBailoutH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index cf6742f7f2b..ca9d428cb6f 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -146,7 +146,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_bailout.h ../lib/vf_common.h ../lib/vf_enumvalue.h ../lib/vf_number.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyze.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_enumvalue.h ../lib/vf_number.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h From b4f626d75d18214ea2da002bbc2cc2a82228f153 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 20 Nov 2024 12:17:40 -0600 Subject: [PATCH 12/13] Move infer function --- Makefile | 2 +- lib/astutils.cpp | 2 +- lib/infer.cpp | 33 +++++++++++++++++++++++++++++++++ lib/infer.h | 4 ++++ lib/programmemory.cpp | 4 ++-- lib/valueflow.cpp | 35 ++--------------------------------- lib/valueflow.h | 5 ----- oss-fuzz/Makefile | 2 +- 8 files changed, 44 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 69e471e565f..77ffc1ca6b2 100644 --- a/Makefile +++ b/Makefile @@ -591,7 +591,7 @@ $(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/addoninfo.h lib/astutils.h l $(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/config.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp -$(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/infer.cpp $(libcppdir)/keywords.o: lib/keywords.cpp lib/config.h lib/keywords.h lib/standards.h lib/utils.h diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 91c954d7bfd..cc6a0e21748 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -960,7 +960,7 @@ bool extractForLoopValues(const Token *forToken, if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%")) return false; std::vector minInitValue = - getMinValue(ValueFlow::makeIntegralInferModel(), initExpr->astOperand2()->values()); + getMinValue(makeIntegralInferModel(), initExpr->astOperand2()->values()); if (minInitValue.empty()) { const ValueFlow::Value* v = initExpr->astOperand2()->getMinValue(true); if (v) diff --git a/lib/infer.cpp b/lib/infer.cpp index c49931bdade..e3fd9b73216 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -20,6 +20,7 @@ #include "calculate.h" #include "errortypes.h" +#include "token.h" #include "valueptr.h" #include @@ -388,3 +389,35 @@ std::vector getMaxValue(const ValuePtr& model, cons return model->match(v); }).maxvalue; } + +namespace { + struct IntegralInferModel : InferModel { + bool match(const ValueFlow::Value& value) const override { + return value.isIntValue(); + } + ValueFlow::Value yield(MathLib::bigint value) const override + { + ValueFlow::Value result(value); + result.valueType = ValueFlow::Value::ValueType::INT; + result.setKnown(); + return result; + } + }; +} + +ValuePtr makeIntegralInferModel() +{ + return IntegralInferModel{}; +} + +ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val) +{ + if (!varTok) + return ValueFlow::Value{}; + if (varTok->hasKnownIntValue()) + return ValueFlow::Value{}; + std::vector r = infer(makeIntegralInferModel(), op, varTok->values(), val); + if (r.size() == 1 && r.front().isKnown()) + return r.front(); + return ValueFlow::Value{}; +} diff --git a/lib/infer.h b/lib/infer.h index 047dfe66b13..17945e23086 100644 --- a/lib/infer.h +++ b/lib/infer.h @@ -56,4 +56,8 @@ std::vector infer(const ValuePtr& model, CPPCHECKLIB std::vector getMinValue(const ValuePtr& model, const std::list& values); std::vector getMaxValue(const ValuePtr& model, const std::list& values); +ValuePtr makeIntegralInferModel(); + +ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val); + #endif diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index c22af0c35f9..3d02208a0ed 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1525,7 +1525,7 @@ namespace { r = evaluate(expr->str(), lhs, rhs); if (expr->isComparisonOp() && (r.isUninitValue() || r.isImpossible())) { if (rhs.isIntValue() && !expr->astOperand1()->values().empty()) { - std::vector result = infer(ValueFlow::makeIntegralInferModel(), + std::vector result = infer(makeIntegralInferModel(), expr->str(), expr->astOperand1()->values(), {std::move(rhs)}); @@ -1533,7 +1533,7 @@ namespace { return std::move(result.front()); } if (lhs.isIntValue() && !expr->astOperand2()->values().empty()) { - std::vector result = infer(ValueFlow::makeIntegralInferModel(), + std::vector result = infer(makeIntegralInferModel(), expr->str(), {std::move(lhs)}, expr->astOperand2()->values()); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index af6f6b140a3..ae9a34ab43a 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3507,8 +3507,6 @@ static const Token* isStrlenOf(const Token* tok, const Token* expr, int depth = return nullptr; } -static ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val); - static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, const Settings& settings) { for (const Scope* scope : symboldatabase.functionScopes) { @@ -4851,35 +4849,6 @@ struct SimpleConditionHandler : ConditionHandler { } }; -struct IntegralInferModel : InferModel { - bool match(const ValueFlow::Value& value) const override { - return value.isIntValue(); - } - ValueFlow::Value yield(MathLib::bigint value) const override - { - ValueFlow::Value result(value); - result.valueType = ValueFlow::Value::ValueType::INT; - result.setKnown(); - return result; - } -}; - -ValuePtr ValueFlow::makeIntegralInferModel() { - return IntegralInferModel{}; -} - -static ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val) -{ - if (!varTok) - return ValueFlow::Value{}; - if (varTok->hasKnownIntValue()) - return ValueFlow::Value{}; - std::vector r = infer(IntegralInferModel{}, op, varTok->values(), val); - if (r.size() == 1 && r.front().isKnown()) - return r.front(); - return ValueFlow::Value{}; -} - struct IteratorInferModel : InferModel { virtual ValueFlow::Value::ValueType getType() const = 0; bool match(const ValueFlow::Value& value) const override { @@ -4953,7 +4922,7 @@ static void valueFlowInferCondition(TokenList& tokenlist, const Settings& settin } } else if (isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2())) { std::vector result = - infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); + infer(makeIntegralInferModel(), tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); for (ValueFlow::Value& value : result) { setTokenValue(tok, std::move(value), settings); } @@ -4961,7 +4930,7 @@ static void valueFlowInferCondition(TokenList& tokenlist, const Settings& settin } else if (Token::Match(tok->astParent(), "?|&&|!|%oror%") || Token::Match(tok->astParent()->previous(), "if|while (") || (astIsPointer(tok) && isUsedAsBool(tok, settings))) { - std::vector result = infer(IntegralInferModel{}, "!=", tok->values(), 0); + std::vector result = infer(makeIntegralInferModel(), "!=", tok->values(), 0); if (result.size() != 1) continue; ValueFlow::Value value = result.front(); diff --git a/lib/valueflow.h b/lib/valueflow.h index 1f7554048ef..bc60c519948 100644 --- a/lib/valueflow.h +++ b/lib/valueflow.h @@ -43,9 +43,6 @@ class ValueType; class Variable; class Scope; -template -class ValuePtr; - namespace ValueFlow { /// Constant folding of expression. This can be used before the full ValueFlow has been executed (ValueFlow::setValues). const Value * valueFlowConstantFoldAST(Token *expr, const Settings &settings); @@ -103,8 +100,6 @@ namespace ValueFlow { const Token *parseCompareInt(const Token *tok, Value &true_value, Value &false_value, const std::function(const Token*)>& evaluate); const Token *parseCompareInt(const Token *tok, Value &true_value, Value &false_value); - CPPCHECKLIB ValuePtr makeIntegralInferModel(); - const Token* solveExprValue(const Token* expr, const std::function(const Token*)>& eval, Value& value); diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 947eb6e43d8..353c33b569f 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -278,7 +278,7 @@ $(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/addoninfo.h ../lib/ast $(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp -$(libcppdir)/infer.o: ../lib/infer.cpp ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/mathlib.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/infer.o: ../lib/infer.cpp ../lib/calculate.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/mathlib.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/infer.cpp $(libcppdir)/keywords.o: ../lib/keywords.cpp ../lib/config.h ../lib/keywords.h ../lib/standards.h ../lib/utils.h From 4fa62cd81625968754504ceb7fceb588c270e8d1 Mon Sep 17 00:00:00 2001 From: firewave Date: Fri, 22 Nov 2024 13:10:12 +0100 Subject: [PATCH 13/13] revert `.ts` changes --- gui/cppcheck_de.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_es.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_fi.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_fr.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_it.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_ja.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_ka.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_ko.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_nl.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_ru.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_sr.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_sv.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_zh_CN.ts | 38 +++++++++++++++++++------------------- gui/cppcheck_zh_TW.ts | 38 +++++++++++++++++++------------------- 14 files changed, 266 insertions(+), 266 deletions(-) diff --git a/gui/cppcheck_de.ts b/gui/cppcheck_de.ts index c68e905e006..8a472e571e0 100644 --- a/gui/cppcheck_de.ts +++ b/gui/cppcheck_de.ts @@ -2347,27 +2347,27 @@ Options: Undefinierte Datei - + Copy Kopieren - + Could not find file: Kann Datei nicht finden: - + Please select the folder '%1' Bitte wählen Sie den Ordner '%1' - + Select Directory '%1' Wähle Verzeichnis '%1' - + Please select the directory where file is located. Bitte wählen Sie das Verzeichnis, wo sich die Datei befindet @@ -2382,27 +2382,27 @@ Options: Anmerkung - + Recheck Erneut prüfen - + Hide Verstecken - + Hide all with id Verstecke alle mit gleicher ID - + Suppress selected id(s) Ausgewählte ID(s) unterdrücken - + Open containing folder Übergeordneten Ordner öffnen @@ -2412,23 +2412,23 @@ Options: - + Tag Tag - + No tag Kein Tag - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2437,7 +2437,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2446,12 +2446,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! Datei konnte nicht gefunden werden! - + Could not start %1 Please check the application path and parameters are correct. @@ -2460,7 +2460,7 @@ Please check the application path and parameters are correct. Bitte überprüfen Sie ob der Pfad und die Parameter der Anwendung richtig eingestellt sind. - + Select Directory Wähle Verzeichnis diff --git a/gui/cppcheck_es.ts b/gui/cppcheck_es.ts index 53e4d68a4a8..c522a46ee31 100644 --- a/gui/cppcheck_es.ts +++ b/gui/cppcheck_es.ts @@ -2312,27 +2312,27 @@ Options: Fichero no definido - + Copy - + Could not find file: - + Please select the folder '%1' - + Select Directory '%1' - + Please select the directory where file is located. @@ -2357,27 +2357,27 @@ Options: depuración - + Recheck - + Hide Ocultar - + Hide all with id Ocultar todos con el mismo id - + Suppress selected id(s) - + Open containing folder Abrir carpeta contenedora @@ -2387,23 +2387,23 @@ Options: - + Tag - + No tag - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2413,7 +2413,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2422,12 +2422,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! ¡No se ha encontrado el fichero! - + Could not start %1 Please check the application path and parameters are correct. @@ -2436,7 +2436,7 @@ Please check the application path and parameters are correct. Por favor comprueba que la ruta a la aplicación y los parámetros son correctos. - + Select Directory Selecciona carpeta diff --git a/gui/cppcheck_fi.ts b/gui/cppcheck_fi.ts index ca820e8a950..5262f8f9cbb 100644 --- a/gui/cppcheck_fi.ts +++ b/gui/cppcheck_fi.ts @@ -2304,27 +2304,27 @@ Options: Määrittelemätön tiedosto - + Copy - + Could not find file: - + Please select the folder '%1' - + Select Directory '%1' - + Please select the directory where file is located. @@ -2339,27 +2339,27 @@ Options: - + Recheck - + Hide - + Hide all with id - + Suppress selected id(s) - + Open containing folder @@ -2369,23 +2369,23 @@ Options: - + Tag - + No tag - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2393,19 +2393,19 @@ Configure the editor application for Cppcheck in preferences/Applications.Voit asetuksista määritellä muita ohjelmia joilla avata tämän virheen sisältävän tiedoston. - + No default editor application selected. Please select the default editor application in preferences/Applications. - + Could not find the file! - + Could not start %1 Please check the application path and parameters are correct. @@ -2414,7 +2414,7 @@ Please check the application path and parameters are correct. Tarkista että ohjelman polku ja parametrit ovat oikeat. - + Select Directory diff --git a/gui/cppcheck_fr.ts b/gui/cppcheck_fr.ts index d1cbd07c084..0c69d48d028 100644 --- a/gui/cppcheck_fr.ts +++ b/gui/cppcheck_fr.ts @@ -2290,13 +2290,13 @@ Do you want to proceed? Fichier indéterminé - - + + Cppcheck - + Could not start %1 Please check the application path and parameters are correct. @@ -2319,17 +2319,17 @@ Merci de vérifier que le chemin de l'application et que les paramètres so Résumé - + Hide Cacher - + Could not find the file! Fichier introuvable ! - + Select Directory Selectionner dossier @@ -2364,14 +2364,14 @@ Merci de vérifier que le chemin de l'application et que les paramètres so - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2382,17 +2382,17 @@ Please select the default editor application in preferences/Applications.Id - + Hide all with id - + Open containing folder Ouvrir l'emplacement du fichier - + Recheck Revérifier @@ -2402,42 +2402,42 @@ Please select the default editor application in preferences/Applications. - + Suppress selected id(s) - + Tag - + No tag - + Could not find file: - + Please select the folder '%1' - + Select Directory '%1' - + Please select the directory where file is located. - + Copy diff --git a/gui/cppcheck_it.ts b/gui/cppcheck_it.ts index ad2f10756e7..590071ef9d7 100644 --- a/gui/cppcheck_it.ts +++ b/gui/cppcheck_it.ts @@ -2325,27 +2325,27 @@ Options: File indefinito - + Copy - + Could not find file: - + Please select the folder '%1' - + Select Directory '%1' - + Please select the directory where file is located. @@ -2360,27 +2360,27 @@ Options: - + Recheck - + Hide Nascondi - + Hide all with id - + Suppress selected id(s) - + Open containing folder @@ -2390,23 +2390,23 @@ Options: - + Tag - + No tag - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2415,7 +2415,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2424,12 +2424,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! Non è stato possibile trovare il file! - + Could not start %1 Please check the application path and parameters are correct. @@ -2438,7 +2438,7 @@ Please check the application path and parameters are correct. Per favore verifica che il percorso dell'applicazione e i parametri siano corretti. - + Select Directory Seleziona Cartella diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index 544ab025c0e..f26a88f42f8 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -2381,27 +2381,27 @@ Options: 未定義ファイル - + Copy コピー - + Could not find file: ファイルが見つかりません: - + Please select the folder '%1' フォルダ '%1' を選択してください - + Select Directory '%1' ディレクトリ '%1' 選択 - + Please select the directory where file is located. ファイルのあるディレクトリを選択してください。 @@ -2416,27 +2416,27 @@ Options: 注意 - + Recheck 再チェック - + Hide 非表示 - + Hide all with id IDで非表示を指定 - + Suppress selected id(s) 選択したidを抑制 - + Open containing folder 含まれるフォルダを開く @@ -2446,23 +2446,23 @@ Options: 内部 - + Tag タグ - + No tag タグなし - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2472,7 +2472,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2481,12 +2481,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! ファイルが見つかりません! - + Could not start %1 Please check the application path and parameters are correct. @@ -2495,7 +2495,7 @@ Please check the application path and parameters are correct. 実行ファイルパスや引数の設定を確認してください。 - + Select Directory ディレクトリを選択 diff --git a/gui/cppcheck_ka.ts b/gui/cppcheck_ka.ts index d915826b284..63d6f0aa44c 100644 --- a/gui/cppcheck_ka.ts +++ b/gui/cppcheck_ka.ts @@ -2343,27 +2343,27 @@ Options: გაურკვეველი ფაილი - + Copy კოპირება - + Could not find file: ვერ ვიპოვე ფაილი: - + Please select the folder '%1' აირჩიეთ საქაღალდე '%1' - + Select Directory '%1' აირჩიეთ საქაღალდე '%1' - + Please select the directory where file is located. აირჩიეთ საქაღალდე, სადაც ფაილია მოთავსებული. @@ -2378,27 +2378,27 @@ Options: ნოტა - + Recheck თავიდან შემოწმება - + Hide დამალვა - + Hide all with id დამალვა ყველასი id-ით - + Suppress selected id(s) მონიშნული id(ებ)-ის ჩახშობა - + Open containing folder შემცველი საქაღალდის გახსნა @@ -2408,23 +2408,23 @@ Options: შიდა - + Tag იარლიყი - + No tag ჭდის გარეშე - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2434,7 +2434,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2443,12 +2443,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! ფაილი ვერ ვიპოვე! - + Could not start %1 Please check the application path and parameters are correct. @@ -2457,7 +2457,7 @@ Please check the application path and parameters are correct. შეამოწმეთ, სწორია, თუ არა აპლიკაციის ბილიკი და მისი პარამეტრები. - + Select Directory აირჩიეთ საქაღალდე diff --git a/gui/cppcheck_ko.ts b/gui/cppcheck_ko.ts index 6164c650315..9fa96968ffd 100644 --- a/gui/cppcheck_ko.ts +++ b/gui/cppcheck_ko.ts @@ -2342,18 +2342,18 @@ Do you want to proceed? - + Hide 숨기기 - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2362,7 +2362,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2371,12 +2371,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! 파일을 찾을 수 없습니다! - + Could not start %1 Please check the application path and parameters are correct. @@ -2385,22 +2385,22 @@ Please check the application path and parameters are correct. 경로와 인자가 정확한지 확인하세요. - + Select Directory 디렉토리 선택 - + Hide all with id - + Open containing folder - + Recheck @@ -2410,42 +2410,42 @@ Please check the application path and parameters are correct. - + Suppress selected id(s) - + Tag - + No tag - + Could not find file: - + Please select the folder '%1' - + Select Directory '%1' - + Please select the directory where file is located. - + Copy diff --git a/gui/cppcheck_nl.ts b/gui/cppcheck_nl.ts index 7d33d8af848..e1064b8bc15 100644 --- a/gui/cppcheck_nl.ts +++ b/gui/cppcheck_nl.ts @@ -2326,27 +2326,27 @@ Options: Niet gedefinieerd bestand - + Copy - + Could not find file: - + Please select the folder '%1' - + Select Directory '%1' - + Please select the directory where file is located. @@ -2361,27 +2361,27 @@ Options: - + Recheck - + Hide Verberg - + Hide all with id Verberg alles met id - + Suppress selected id(s) - + Open containing folder @@ -2391,23 +2391,23 @@ Options: - + Tag - + No tag - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2417,7 +2417,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2425,12 +2425,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! Kon het bestand niet vinden! - + Could not start %1 Please check the application path and parameters are correct. @@ -2439,7 +2439,7 @@ Please check the application path and parameters are correct. Gelieve te controleren of de het pad en de parameters correct zijn. - + Select Directory Selecteer map diff --git a/gui/cppcheck_ru.ts b/gui/cppcheck_ru.ts index 5cdf97b4a97..d6a262bbd5f 100644 --- a/gui/cppcheck_ru.ts +++ b/gui/cppcheck_ru.ts @@ -2361,27 +2361,27 @@ Options: Неопределенный файл - + Copy Копировать - + Could not find file: Невозможно найти файл: - + Please select the folder '%1' Выберите каталог '%1' - + Select Directory '%1' Выбрать каталог '%1' - + Please select the directory where file is located. Укажите каталог с расположением файла. @@ -2396,27 +2396,27 @@ Options: заметка - + Recheck Проверить заново - + Hide Скрыть - + Hide all with id Скрыть все с id - + Suppress selected id(s) Подавить выбранные id - + Open containing folder Открыть содержащую папку @@ -2426,23 +2426,23 @@ Options: - + Tag Тег - + No tag Тег отсутствует - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2451,7 +2451,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2459,12 +2459,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! Не удается найти файл! - + Could not start %1 Please check the application path and parameters are correct. @@ -2472,7 +2472,7 @@ Please check the application path and parameters are correct. Пожалуйста, проверьте путь приложения, и верны ли параметры. - + Select Directory Выберите директорию diff --git a/gui/cppcheck_sr.ts b/gui/cppcheck_sr.ts index 2584bceb2ef..72ef39bc0a6 100644 --- a/gui/cppcheck_sr.ts +++ b/gui/cppcheck_sr.ts @@ -2300,27 +2300,27 @@ Options: Undefined file - + Copy - + Could not find file: - + Please select the folder '%1' - + Select Directory '%1' - + Please select the directory where file is located. @@ -2335,27 +2335,27 @@ Options: - + Recheck - + Hide - + Hide all with id - + Suppress selected id(s) - + Open containing folder @@ -2365,42 +2365,42 @@ Options: - + Tag - + No tag - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. You can open this error by specifying applications in program's settings. - + No default editor application selected. Please select the default editor application in preferences/Applications. - + Could not find the file! - + Could not start %1 Please check the application path and parameters are correct. @@ -2409,7 +2409,7 @@ Please check the application path and parameters are correct. Please check the application path and parameters are correct. - + Select Directory diff --git a/gui/cppcheck_sv.ts b/gui/cppcheck_sv.ts index c422a91bccc..50472f11c2f 100644 --- a/gui/cppcheck_sv.ts +++ b/gui/cppcheck_sv.ts @@ -2362,27 +2362,27 @@ Options: Odefinierad fil - + Copy - + Could not find file: - + Please select the folder '%1' - + Select Directory '%1' - + Please select the directory where file is located. @@ -2397,27 +2397,27 @@ Options: note - + Recheck Analysera om - + Hide Dölj - + Hide all with id Dölj alla med id - + Suppress selected id(s) Stäng av valda id - + Open containing folder Öppna mapp @@ -2427,23 +2427,23 @@ Options: - + Tag Tag - + No tag Ingen tag - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2453,7 +2453,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2462,12 +2462,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! Kunde inte hitta filen! - + Could not start %1 Please check the application path and parameters are correct. @@ -2476,7 +2476,7 @@ Please check the application path and parameters are correct. Kontrollera att sökvägen och parametrarna är korrekta. - + Select Directory Välj mapp diff --git a/gui/cppcheck_zh_CN.ts b/gui/cppcheck_zh_CN.ts index 34e74ad8a3b..f87bf42c548 100644 --- a/gui/cppcheck_zh_CN.ts +++ b/gui/cppcheck_zh_CN.ts @@ -2366,27 +2366,27 @@ Options: 未定义文件 - + Copy 复制 - + Could not find file: 找不到文件: - + Please select the folder '%1' 请选择文件夹 '%1' - + Select Directory '%1' 选择目录 '%1' - + Please select the directory where file is located. 请选择文件所在的目录。 @@ -2401,27 +2401,27 @@ Options: 注意 - + Recheck 重新检查 - + Hide 隐藏 - + Hide all with id 隐藏全部 ID - + Suppress selected id(s) 抑制选择的 ID - + Open containing folder 打开包含的文件夹 @@ -2431,23 +2431,23 @@ Options: - + Tag 标记 - + No tag 取消标记 - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. @@ -2457,7 +2457,7 @@ Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. @@ -2466,12 +2466,12 @@ Please select the default editor application in preferences/Applications. - + Could not find the file! 找不到文件! - + Could not start %1 Please check the application path and parameters are correct. @@ -2480,7 +2480,7 @@ Please check the application path and parameters are correct. 请检查此应用程序的路径与参数是否正确。 - + Select Directory 选择目录 diff --git a/gui/cppcheck_zh_TW.ts b/gui/cppcheck_zh_TW.ts index 824e31d19ce..d6ab4dc47d6 100644 --- a/gui/cppcheck_zh_TW.ts +++ b/gui/cppcheck_zh_TW.ts @@ -2333,99 +2333,99 @@ Do you want to remove the file from the recently used projects -list? - + Recheck - + Copy 複製 - + Hide 隱藏 - + Hide all with id - + Open containing folder - + Suppress selected id(s) - + Tag 標記 - + No tag 取消標記 - - + + Cppcheck Cppcheck - + No editor application configured. Configure the editor application for Cppcheck in preferences/Applications. - + No default editor application selected. Please select the default editor application in preferences/Applications. - + Could not find the file! 找不到該檔案! - + Could not start %1 Please check the application path and parameters are correct. - + Could not find file: - + Please select the folder '%1' 請選取資料夾 '%1' - + Select Directory '%1' 選取目錄 '%1' - + Please select the directory where file is located. 請選取資料夾所在的目錄。 - + Select Directory 選取目錄