Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #13550 Remove boostForeachError/checkboost.cpp #7198

Merged
merged 13 commits into from
Jan 13, 2025
7 changes: 4 additions & 3 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's C++11 code. Does that work if we are using C++03 as standard?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have any loop-handling code that is conditional on the standard. Also, the new simplification can only be an improvement on the asm hack.

Copy link
Collaborator

@firewave firewave Jan 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely - especially since we are handling asm so well. It also now matches what the library configurations are doing.

if (Token* in = Token::findsimplematch(tok->tokAt(2), "in", tok->linkAt(2)))
in->str(":");
tok->deleteNext();
} else if (tok->strAt(1) == "constexpr") {
tok->deleteNext();
Expand Down
59 changes: 58 additions & 1 deletion test/cfg/boost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include <boost/thread/lock_guard.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/core/scoped_enum.hpp>
#include <boost/foreach.hpp>

#include <set>
#include <vector>

BOOST_FORCEINLINE void boost_forceinline_test()
{}
Expand Down Expand Up @@ -108,6 +112,59 @@ void lock_guard_finiteLifetime(boost::mutex& m)
boost::lock_guard<boost::mutex>{ m };
}

void test_BOOST_FOREACH_1()
{
std::vector<int> data;
BOOST_FOREACH(int i, data) {
// cppcheck-suppress invalidContainerLoop
data.push_back(123);
}
}

void test_BOOST_FOREACH_2()
{
std::set<int> data;
BOOST_FOREACH(int i, data) {
// cppcheck-suppress invalidContainerLoop
data.insert(123);
}
}

void test_BOOST_FOREACH_3()
{
std::set<int> data;
BOOST_FOREACH(const int& i, data) {
// cppcheck-suppress invalidContainerLoop
data.erase(123);
}
}

// Check single line usage
void test_BOOST_FOREACH_4()
{
std::set<int> data;
BOOST_FOREACH(const int& i, data)
// cppcheck-suppress invalidContainerLoop
data.clear();
}

// Container returned as result of a function -> Be quiet
void test_BOOST_FOREACH_5()
{
BOOST_FOREACH(const int& i, get_data())
data.insert(i);
}

// Break after modification (#4788)
void test_BOOST_FOREACH_6()
{
std::vector<int> 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)
Expand All @@ -127,4 +184,4 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(my_tuple_test, T, test_types_w_tuples)
BOOST_TEST(sizeof(T) == 4U);
}

BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()
4 changes: 2 additions & 2 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

Expand Down
2 changes: 1 addition & 1 deletion test/testuninitvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down
Loading