diff --git a/Makefile b/Makefile
index 261f73feae0..1c6973fc418 100644
--- a/Makefile
+++ b/Makefile
@@ -191,7 +191,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \
$(libcppdir)/checkassert.o \
$(libcppdir)/checkautovariables.o \
$(libcppdir)/checkbool.o \
- $(libcppdir)/checkboost.o \
$(libcppdir)/checkbufferoverrun.o \
$(libcppdir)/checkclass.o \
$(libcppdir)/checkcondition.o \
@@ -275,7 +274,6 @@ TESTOBJ = test/fixture.o \
test/testastutils.o \
test/testautovariables.o \
test/testbool.o \
- test/testboost.o \
test/testbufferoverrun.o \
test/testcharvar.o \
test/testcheck.o \
@@ -482,9 +480,6 @@ $(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h li
$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.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/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp
-$(libcppdir)/checkboost.o: lib/checkboost.cpp lib/check.h lib/checkboost.h 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/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
- $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkboost.cpp
-
$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.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/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h lib/xml.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp
@@ -719,9 +714,6 @@ test/testautovariables.o: test/testautovariables.cpp externals/simplecpp/simplec
test/testbool.o: test/testbool.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkbool.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp
-test/testboost.o: test/testboost.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkboost.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
- $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testboost.cpp
-
test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp
diff --git a/lib/checkboost.cpp b/lib/checkboost.cpp
deleted file mode 100644
index a246426f8b5..00000000000
--- a/lib/checkboost.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 "checkboost.h"
-
-#include "errortypes.h"
-#include "symboldatabase.h"
-#include "token.h"
-#include "tokenize.h"
-
-#include
-
-// Register this check class (by creating a static instance of it)
-namespace {
- CheckBoost instance;
-}
-
-static const CWE CWE664(664);
-
-void CheckBoost::checkBoostForeachModification()
-{
- logChecker("CheckBoost::checkBoostForeachModification");
- const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
- for (const Scope * scope : symbolDatabase->functionScopes) {
- for (const Token *tok = scope->bodyStart->next(); tok && tok != scope->bodyEnd; tok = tok->next()) {
- if (!Token::simpleMatch(tok, "BOOST_FOREACH ("))
- continue;
-
- const Token *containerTok = tok->linkAt(1)->previous();
- if (!Token::Match(containerTok, "%var% ) {"))
- continue;
-
- const Token *tok2 = containerTok->tokAt(2);
- const Token *end = tok2->link();
- for (; tok2 != end; tok2 = tok2->next()) {
- if (Token::Match(tok2, "%varid% . insert|erase|push_back|push_front|pop_front|pop_back|clear|swap|resize|assign|merge|remove|remove_if|reverse|sort|splice|unique|pop|push", containerTok->varId())) {
- const Token* nextStatement = Token::findsimplematch(tok2->linkAt(3), ";", end);
- if (!Token::Match(nextStatement, "; break|return|throw"))
- boostForeachError(tok2);
- break;
- }
- }
- }
- }
-}
-
-void CheckBoost::boostForeachError(const Token *tok)
-{
- reportError(tok, Severity::error, "boostForeachError",
- "BOOST_FOREACH caches the end() iterator. It's undefined behavior if you modify the container inside.", CWE664, Certainty::normal
- );
-}
-
-void CheckBoost::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
-{
- if (!tokenizer.isCPP())
- return;
-
- CheckBoost checkBoost(&tokenizer, &tokenizer.getSettings(), errorLogger);
- checkBoost.checkBoostForeachModification();
-}
-
-void CheckBoost::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const
-{
- CheckBoost c(nullptr, settings, errorLogger);
- c.boostForeachError(nullptr);
-}
diff --git a/lib/checkboost.h b/lib/checkboost.h
deleted file mode 100644
index 97eb5c3e712..00000000000
--- a/lib/checkboost.h
+++ /dev/null
@@ -1,71 +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 checkboostH
-#define checkboostH
-//---------------------------------------------------------------------------
-
-#include "check.h"
-#include "config.h"
-
-#include
-
-class ErrorLogger;
-class Settings;
-class Token;
-class Tokenizer;
-
-/// @addtogroup Checks
-/// @{
-
-
-/** @brief %Check Boost usage */
-class CPPCHECKLIB CheckBoost : public Check {
-public:
- /** This constructor is used when registering the CheckClass */
- CheckBoost() : Check(myName()) {}
-
-private:
- /** This constructor is used when running checks. */
- CheckBoost(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
- : Check(myName(), tokenizer, settings, errorLogger) {}
-
- /** @brief Run checks against the normal token list */
- void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override;
-
- /** @brief %Check for container modification while using the BOOST_FOREACH macro */
- void checkBoostForeachModification();
-
- void boostForeachError(const Token *tok);
-
- void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override;
-
- static std::string myName() {
- return "Boost usage";
- }
-
- std::string classInfo() const override {
- return "Check for invalid usage of Boost:\n"
- "- container modification during BOOST_FOREACH\n";
- }
-};
-/// @}
-//---------------------------------------------------------------------------
-#endif // checkboostH
diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj
index a19b770596a..3d830e2894c 100644
--- a/lib/cppcheck.vcxproj
+++ b/lib/cppcheck.vcxproj
@@ -36,7 +36,6 @@
-
@@ -108,7 +107,6 @@
-
diff --git a/lib/cppcheck.vcxproj.filters b/lib/cppcheck.vcxproj.filters
index 7d69edfa230..a4c000fd9a6 100644
--- a/lib/cppcheck.vcxproj.filters
+++ b/lib/cppcheck.vcxproj.filters
@@ -89,9 +89,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -382,9 +379,6 @@
Header Files
-
- Header Files
-
Header Files
diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp
index c22877fc1a1..e7d5b074824 100644
--- a/lib/tokenize.cpp
+++ b/lib/tokenize.cpp
@@ -5500,10 +5500,11 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
// if MACRO
for (Token *tok = list.front(); tok; tok = tok->next()) {
- if (Token::Match(tok, "if|for|while|BOOST_FOREACH %name% (")) {
+ if (Token::Match(tok, "if|for|while %name% (")) {
if (Token::simpleMatch(tok, "for each")) {
- // 'for each ( )' -> 'asm ( )'
- tok->str("asm");
+ // 'for each (x in y )' -> 'for (x : y)'
+ if (Token* in = Token::findsimplematch(tok->tokAt(2), "in", tok->linkAt(2)))
+ in->str(":");
tok->deleteNext();
} else if (tok->strAt(1) == "constexpr") {
tok->deleteNext();
diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile
index 6ef1d053c54..6e9bf3025eb 100644
--- a/oss-fuzz/Makefile
+++ b/oss-fuzz/Makefile
@@ -44,7 +44,6 @@ LIBOBJ = $(libcppdir)/valueflow.o \
$(libcppdir)/checkassert.o \
$(libcppdir)/checkautovariables.o \
$(libcppdir)/checkbool.o \
- $(libcppdir)/checkboost.o \
$(libcppdir)/checkbufferoverrun.o \
$(libcppdir)/checkclass.o \
$(libcppdir)/checkcondition.o \
@@ -178,9 +177,6 @@ $(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/addoninf
$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbool.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/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp
-$(libcppdir)/checkboost.o: ../lib/checkboost.cpp ../lib/check.h ../lib/checkboost.h ../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/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h
- $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkboost.cpp
-
$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/color.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.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/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h ../lib/xml.h
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp
diff --git a/test/cfg/boost.cpp b/test/cfg/boost.cpp
index 49ef2546444..771b3b964f6 100644
--- a/test/cfg/boost.cpp
+++ b/test/cfg/boost.cpp
@@ -19,6 +19,10 @@
#include
#include
#include
+#include
+
+#include
+#include
BOOST_FORCEINLINE void boost_forceinline_test()
{}
@@ -108,6 +112,56 @@ void lock_guard_finiteLifetime(boost::mutex& m)
boost::lock_guard{ m };
}
+void test_BOOST_FOREACH_1(std::vector data)
+{
+ BOOST_FOREACH(int i, data) {
+ // cppcheck-suppress invalidContainerLoop
+ data.push_back(123);
+ }
+}
+
+void test_BOOST_FOREACH_2(std::set data)
+{
+ BOOST_FOREACH(int i, data) {
+ // don't warn for std::set
+ data.insert(123);
+ }
+}
+
+void test_BOOST_FOREACH_3(std::vector data)
+{
+ BOOST_FOREACH(const int& i, data) {
+ // cppcheck-suppress invalidContainerLoop
+ data.erase(data.begin());
+ }
+}
+
+// Check single line usage
+void test_BOOST_FOREACH_4(std::vector data)
+{
+ BOOST_FOREACH(const int& i, data)
+ // cppcheck-suppress invalidContainerLoop
+ data.clear();
+}
+
+// Container returned as result of a function -> Be quiet
+std::vector get_data();
+void test_BOOST_FOREACH_5()
+{
+ std::set data;
+ BOOST_FOREACH(const int& i, get_data())
+ data.insert(i);
+}
+
+// Break after modification (#4788)
+void test_BOOST_FOREACH_6(std::vector data)
+{
+ BOOST_FOREACH(int i, data) {
+ data.push_back(123);
+ break;
+ }
+}
+
BOOST_AUTO_TEST_SUITE(my_auto_test_suite)
BOOST_AUTO_TEST_CASE(test_message_macros)
@@ -127,4 +181,4 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(my_tuple_test, T, test_types_w_tuples)
BOOST_TEST(sizeof(T) == 4U);
}
-BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/testboost.cpp b/test/testboost.cpp
deleted file mode 100644
index ff8b2a44655..00000000000
--- a/test/testboost.cpp
+++ /dev/null
@@ -1,101 +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 "checkboost.h"
-#include "errortypes.h"
-#include "fixture.h"
-#include "helpers.h"
-#include "settings.h"
-
-#include
-
-class TestBoost : public TestFixture {
-public:
- TestBoost() : TestFixture("TestBoost") {}
-
-private:
- const Settings settings = settingsBuilder().severity(Severity::style).severity(Severity::performance).build();
-
- void run() override {
- TEST_CASE(BoostForeachContainerModification);
- }
-
-#define check(code) check_(code, __FILE__, __LINE__)
- template
- void check_(const char (&code)[size], const char* file, int line) {
- // Tokenize..
- SimpleTokenizer tokenizer(settings, *this);
- ASSERT_LOC(tokenizer.tokenize(code), file, line);
-
- // Check..
- runChecks(tokenizer, this);
- }
-
- void BoostForeachContainerModification() {
- check("void f() {\n"
- " vector data;\n"
- " BOOST_FOREACH(int i, data) {\n"
- " data.push_back(123);\n"
- " }\n"
- "}");
- ASSERT_EQUALS("[test.cpp:4]: (error) BOOST_FOREACH caches the end() iterator. It's undefined behavior if you modify the container inside.\n", errout_str());
-
- check("void f() {\n"
- " set data;\n"
- " BOOST_FOREACH(int i, data) {\n"
- " data.insert(123);\n"
- " }\n"
- "}");
- ASSERT_EQUALS("[test.cpp:4]: (error) BOOST_FOREACH caches the end() iterator. It's undefined behavior if you modify the container inside.\n", errout_str());
-
- check("void f() {\n"
- " set data;\n"
- " BOOST_FOREACH(const int &i, data) {\n"
- " data.erase(123);\n"
- " }\n"
- "}");
- ASSERT_EQUALS("[test.cpp:4]: (error) BOOST_FOREACH caches the end() iterator. It's undefined behavior if you modify the container inside.\n", errout_str());
-
- // Check single line usage
- check("void f() {\n"
- " set data;\n"
- " BOOST_FOREACH(const int &i, data)\n"
- " data.clear();\n"
- "}");
- ASSERT_EQUALS("[test.cpp:4]: (error) BOOST_FOREACH caches the end() iterator. It's undefined behavior if you modify the container inside.\n", errout_str());
-
- // Container returned as result of a function -> Be quiet
- check("void f() {\n"
- " BOOST_FOREACH(const int &i, get_data())\n"
- " data.insert(i);\n"
- "}");
- ASSERT_EQUALS("", errout_str());
-
- // Break after modification (#4788)
- check("void f() {\n"
- " vector data;\n"
- " BOOST_FOREACH(int i, data) {\n"
- " data.push_back(123);\n"
- " break;\n"
- " }\n"
- "}");
- ASSERT_EQUALS("", errout_str());
- }
-};
-
-REGISTER_TEST(TestBoost)
diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj
index 07cb0e82847..02054bbbb2d 100755
--- a/test/testrunner.vcxproj
+++ b/test/testrunner.vcxproj
@@ -49,7 +49,6 @@
-
diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp
index bbebf933723..919f7087369 100644
--- a/test/testtokenize.cpp
+++ b/test/testtokenize.cpp
@@ -918,9 +918,9 @@ class TestTokenizer : public TestFixture {
void foreach () {
// #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("void f ( ) { for ( char c : MyString ) { Console :: Write ( c ) ; } }", tokenizeAndStringify(code));
ASSERT_EQUALS(
- "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable c\n",
+ "[test.cpp:1]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable MyString\n",
errout_str());
}
diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp
index e19ea083fbc..e8f53d1224b 100644
--- a/test/testuninitvar.cpp
+++ b/test/testuninitvar.cpp
@@ -2145,7 +2145,7 @@ class TestUninitVar : public TestFixture {
" static const struct ab {\n"
" int a,b;\n"
" int get_a() { return a; }"
- " } = { 0, 0 };\n"
+ " } x = { 0, 0 };\n"
"}", true, false);
ASSERT_EQUALS("", errout_str());