diff --git a/Makefile b/Makefile index 3fac13f0872..ec0c9687292 100644 --- a/Makefile +++ b/Makefile @@ -264,6 +264,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_conditionexpressions.o \ $(libcppdir)/vf_debug.o \ $(libcppdir)/vf_enumvalue.o \ + $(libcppdir)/vf_forward.o \ $(libcppdir)/vf_functionreturn.o \ $(libcppdir)/vf_globalconstvar.o \ $(libcppdir)/vf_globalstaticvar.o \ @@ -483,7 +484,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/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_forward.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 $(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 @@ -705,6 +706,9 @@ $(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_forward.o: lib/vf_forward.cpp lib/addoninfo.h lib/analyzer.h lib/config.h lib/errortypes.h lib/forwardanalyzer.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/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_forward.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_forward.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 diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index bff6f8ef7c7..9dbe4c2f837 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -99,6 +99,7 @@ + @@ -211,6 +212,7 @@ + diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index b5d928d28a9..a9b3f151b03 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -105,6 +105,7 @@ #include "vf_analyzers.h" #include "vf_bailout.h" #include "vf_common.h" +#include "vf_forward.h" #include "vf_reverse.h" #include "vf_settokenvalue.h" @@ -483,76 +484,7 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings, int m return 0; } -static Analyzer::Result valueFlowForward(Token* startToken, - const Token* endToken, - const Token* exprTok, - ValueFlow::Value value, - const TokenList& tokenlist, - ErrorLogger& errorLogger, - const Settings& settings, - SourceLocation loc = SourceLocation::current()) -{ - if (settings.debugnormal) - setSourceLocation(value, loc, startToken); - return valueFlowGenericForward(startToken, - endToken, - makeAnalyzer(exprTok, std::move(value), settings), - tokenlist, - errorLogger, - settings); -} - -static Analyzer::Result valueFlowForward(Token* startToken, - const Token* endToken, - const Token* exprTok, - std::list values, - const TokenList& tokenlist, - ErrorLogger& errorLogger, - const Settings& settings, - SourceLocation loc = SourceLocation::current()) -{ - Analyzer::Result result{}; - for (ValueFlow::Value& v : values) { - result.update(valueFlowForward(startToken, endToken, exprTok, std::move(v), tokenlist, errorLogger, settings, loc)); - } - return result; -} -template -static Analyzer::Result valueFlowForward(Token* startToken, - const Token* exprTok, - ValueOrValues v, - const TokenList& tokenlist, - ErrorLogger& errorLogger, - const Settings& settings, - SourceLocation loc = SourceLocation::current()) -{ - const Token* endToken = nullptr; - const Function* f = Scope::nestedInFunction(startToken->scope()); - if (f && f->functionScope) - endToken = f->functionScope->bodyEnd; - if (!endToken && exprTok && exprTok->variable() && !exprTok->variable()->isLocal()) - endToken = startToken->scope()->bodyEnd; - return valueFlowForward(startToken, endToken, exprTok, std::move(v), tokenlist, errorLogger, settings, loc); -} - -static Analyzer::Result valueFlowForwardRecursive(Token* top, - const Token* exprTok, - std::list values, - const TokenList& tokenlist, - ErrorLogger& errorLogger, - const Settings& settings, - SourceLocation loc = SourceLocation::current()) -{ - Analyzer::Result result{}; - for (ValueFlow::Value& v : values) { - if (settings.debugnormal) - setSourceLocation(v, loc, top); - result.update( - valueFlowGenericForward(top, makeAnalyzer(exprTok, std::move(v), settings), tokenlist, errorLogger, settings)); - } - return result; -} static bool isConditionKnown(const Token* tok, bool then) { diff --git a/lib/vf_forward.cpp b/lib/vf_forward.cpp new file mode 100644 index 00000000000..253221aab7a --- /dev/null +++ b/lib/vf_forward.cpp @@ -0,0 +1,103 @@ +/* + * 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_forward.h" + +#include "forwardanalyzer.h" +#include "settings.h" +#include "symboldatabase.h" +#include "token.h" +#include "vfvalue.h" + +#include "vf_common.h" +#include "vf_analyzers.h" + +#include + +namespace ValueFlow +{ + Analyzer::Result valueFlowForward(Token* startToken, + const Token* endToken, + const Token* exprTok, + ValueFlow::Value value, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc) + { + if (settings.debugnormal) + setSourceLocation(value, loc, startToken); + return valueFlowGenericForward(startToken, + endToken, + makeAnalyzer(exprTok, std::move(value), settings), + tokenlist, + errorLogger, + settings); + } + + Analyzer::Result valueFlowForward(Token* startToken, + const Token* endToken, + const Token* exprTok, + std::list values, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc) + { + Analyzer::Result result{}; + for (ValueFlow::Value& v : values) { + result.update(valueFlowForward(startToken, endToken, exprTok, std::move(v), tokenlist, errorLogger, settings, loc)); + } + return result; + } + + Analyzer::Result valueFlowForward(Token* startToken, + const Token* exprTok, + ValueFlow::Value v, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc) + { + const Token* endToken = nullptr; + const Function* f = Scope::nestedInFunction(startToken->scope()); + if (f && f->functionScope) + endToken = f->functionScope->bodyEnd; + if (!endToken && exprTok && exprTok->variable() && !exprTok->variable()->isLocal()) + endToken = startToken->scope()->bodyEnd; + return valueFlowForward(startToken, endToken, exprTok, std::move(v), tokenlist, errorLogger, settings, loc); + } + + Analyzer::Result valueFlowForwardRecursive(Token* top, + const Token* exprTok, + std::list values, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc) + { + Analyzer::Result result{}; + for (ValueFlow::Value& v : values) { + if (settings.debugnormal) + setSourceLocation(v, loc, top); + result.update( + valueFlowGenericForward(top, makeAnalyzer(exprTok, std::move(v), settings), tokenlist, errorLogger, settings)); + } + return result; + } +} diff --git a/lib/vf_forward.h b/lib/vf_forward.h new file mode 100644 index 00000000000..f45fab0d9c7 --- /dev/null +++ b/lib/vf_forward.h @@ -0,0 +1,72 @@ +/* -*- 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 vfForwardH +#define vfForwardH + +#include "analyzer.h" +#include "sourcelocation.h" + +#include + +class Token; +class TokenList; +class ErrorLogger; +class Settings; +namespace ValueFlow { + class Value; +} + +namespace ValueFlow +{ + Analyzer::Result valueFlowForward(Token* startToken, + const Token* endToken, + const Token* exprTok, + ValueFlow::Value value, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc = SourceLocation::current()); + + Analyzer::Result valueFlowForward(Token* startToken, + const Token* endToken, + const Token* exprTok, + std::list values, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc = SourceLocation::current()); + + Analyzer::Result valueFlowForward(Token* startToken, + const Token* exprTok, + ValueFlow::Value v, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc = SourceLocation::current()); + + Analyzer::Result valueFlowForwardRecursive(Token* top, + const Token* exprTok, + std::list values, + const TokenList& tokenlist, + ErrorLogger& errorLogger, + const Settings& settings, + SourceLocation loc = SourceLocation::current()); +} + +#endif // vfForwardH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index b133b839651..56f5fc1d296 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -107,6 +107,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \ $(libcppdir)/vf_conditionexpressions.o \ $(libcppdir)/vf_debug.o \ $(libcppdir)/vf_enumvalue.o \ + $(libcppdir)/vf_forward.o \ $(libcppdir)/vf_functionreturn.o \ $(libcppdir)/vf_globalconstvar.o \ $(libcppdir)/vf_globalstaticvar.o \ @@ -170,7 +171,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/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_forward.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 $(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 @@ -392,6 +393,9 @@ $(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_forward.o: ../lib/vf_forward.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.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/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_forward.h ../lib/vfvalue.h + $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_forward.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