diff --git a/Makefile b/Makefile index 7b060a7d77cc..efed24445b1b 100644 --- a/Makefile +++ b/Makefile @@ -260,6 +260,7 @@ LIBOBJ = $(libcppdir)/valueflow.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 \ @@ -471,7 +472,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_enumvalue.h lib/vf_globalconstvar.h lib/vf_globalstaticvar.h lib/vf_number.h lib/vf_pointeralias.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_array.h lib/vf_bitand.h lib/vf_common.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 @@ -681,6 +682,9 @@ $(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_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 diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index f045b63519f6..65300a9c81ab 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -95,6 +95,7 @@ + @@ -186,6 +187,7 @@ + diff --git a/lib/lib.pri b/lib/lib.pri index 5cc7ce5275bc..e5b07f526b73 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -86,6 +86,7 @@ HEADERS += $${PWD}/addoninfo.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 \ @@ -162,6 +163,7 @@ SOURCES += $${PWD}/valueflow.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 \ diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7fada25607c7..e5835479d45e 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -668,42 +668,6 @@ static void valueFlowArrayElement(TokenList& tokenlist, const Settings& 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()) { @@ -8382,7 +8346,7 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(valueFlowLifetime(tokenlist, errorLogger, settings)), VFA(valueFlowSymbolic(tokenlist, symboldatabase, errorLogger, settings)), VFA(analyzeBitAnd(tokenlist, settings)), - VFA(valueFlowSameExpressions(tokenlist, settings)), + VFA(analyzeSameExpressions(tokenlist, settings)), VFA(valueFlowConditionExpressions(tokenlist, symboldatabase, errorLogger, settings)), }); diff --git a/lib/vf_analyze.h b/lib/vf_analyze.h index 3c101a6990e1..83b4428bac89 100644 --- a/lib/vf_analyze.h +++ b/lib/vf_analyze.h @@ -26,6 +26,7 @@ #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 diff --git a/lib/vf_sameexpressions.cpp b/lib/vf_sameexpressions.cpp new file mode 100644 index 000000000000..2aca4453e6f4 --- /dev/null +++ b/lib/vf_sameexpressions.cpp @@ -0,0 +1,67 @@ +/* + * 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 new file mode 100644 index 000000000000..d8dbe209c2fb --- /dev/null +++ b/lib/vf_sameexpressions.h @@ -0,0 +1,30 @@ +/* + * 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/oss-fuzz/Makefile b/oss-fuzz/Makefile index 366ef9374e9e..963cabb38604 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -103,6 +103,7 @@ LIBOBJ = $(libcppdir)/valueflow.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 \ @@ -150,7 +151,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_enumvalue.h ../lib/vf_globalconstvar.h ../lib/vf_globalstaticvar.h ../lib/vf_number.h ../lib/vf_pointeralias.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_array.h ../lib/vf_bitand.h ../lib/vf_common.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 @@ -360,6 +361,9 @@ $(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_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