Skip to content

Commit bd6c531

Browse files
Detect container action and yield functions (cppcheck-opensource#5117)
* Detect container action and yield functions * Fix test * Adapt getUseRetValType() to handle container yield functions Add TODO * Handle combined action/yield * Add Yield::BUFFER * Remove redundant functions * Revert "Remove redundant functions" This reverts commit 4f124a5. * Add Yield::AT_INDEX * Add Yield::ITERATOR * Simplify
1 parent 2beb461 commit bd6c531

5 files changed

Lines changed: 19 additions & 38 deletions

File tree

cfg/std.cfg

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6600,12 +6600,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
66006600
<not-uninit/>
66016601
</arg>
66026602
</function>
6603-
<!-- void clear(); // until C++11 -->
6604-
<!-- void clear() noexcept; // since C++11 -->
6605-
<function name="std::deque::clear,std::list::clear,std::forward_list::clear,std::map::clear,std::unordered_map::clear,std::queue::clear,std::set::clear,std::unordered_set::clear,std::stack::clear,std::string::clear,std::wstring::clear,std::basic_string::clear,std::vector::clear">
6606-
<noreturn>false</noreturn>
6607-
<returnValue type="void"/>
6608-
</function>
66096603
<!-- bool empty() const; // until C++11 -->
66106604
<!-- constexpr bool empty() const noexcept; // since C++11 until C++20 -->
66116605
<!-- [[nodiscard]] constexpr bool empty() const noexcept; // since C++20 -->
@@ -6703,26 +6697,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
67036697
<not-uninit/>
67046698
</arg>
67056699
</function>
6706-
<function name="std::list::back,std::list::front,std::forward_list::front,std::queue::back,std::queue::front,std::deque::back,std::deque::front,std::vector::back,std::vector::front,std::array::front,std::array::back,std::string::front,std::string::back,std::wstring::front,std::wstring::back,std::string_view::front,std::string_view::back,std::wstring_view::front,std::wstring_view::back,std::span::back,std::span::front">
6707-
<use-retval/>
6708-
<noreturn>false</noreturn>
6709-
</function>
6710-
<function name="std::list::begin,std::list::end,std::forward_list::begin,std::forward_list::end,std::deque::begin,std::deque::end,std::vector::begin,std::vector::end,std::array::begin,std::array::end,std::string::begin,std::string::end,std::wstring::begin,std::wstring::end,std::string_view::begin,std::string_view::end,std::wstring_view::begin,std::wstring_view::end,std::span::begin,std::span::end,std::set::begin,std::set::end,std::unordered_set::begin,std::unordered_set::end,std::map::begin,std::map::end,std::unordered_map::begin,std::unordered_map::end">
6711-
<use-retval/>
6712-
<noreturn>false</noreturn>
6713-
</function>
6714-
<function name="std::list::cbegin,std::list::cend,std::forward_list::cbegin,std::forward_list::cend,std::deque::cbegin,std::deque::cend,std::vector::cbegin,std::vector::cend,std::array::cbegin,std::array::cend,std::string::cbegin,std::string::cend,std::wstring::cbegin,std::wstring::cend,std::string_view::cbegin,std::string_view::cend,std::wstring_view::cbegin,std::wstring_view::cend,std::span::cbegin,std::span::cend,std::set::cbegin,std::set::cend,std::unordered_set::cbegin,std::unordered_set::cend,std::map::cbegin,std::map::cend,std::unordered_map::cbegin,std::unordered_map::cend">
6715-
<use-retval/>
6716-
<noreturn>false</noreturn>
6717-
</function>
6718-
<function name="std::list::rbegin,std::list::rend,std::deque::rbegin,std::deque::rend,std::vector::rbegin,std::vector::rend,std::array::rbegin,std::array::rend,std::string::rbegin,std::string::rend,std::wstring::rbegin,std::wstring::rend,std::string_view::rbegin,std::string_view::rend,std::wstring_view::rbegin,std::wstring_view::rend,std::span::rbegin,std::span::rend,std::set::rbegin,std::set::rend,std::map::rbegin,std::map::rend">
6719-
<use-retval/>
6720-
<noreturn>false</noreturn>
6721-
</function>
6722-
<function name="std::list::crbegin,std::list::crend,std::deque::crbegin,std::deque::crend,std::vector::crbegin,std::vector::crend,std::array::crbegin,std::array::crend,std::string::crbegin,std::string::crend,std::wstring::crbegin,std::wstring::crend,std::string_view::crbegin,std::string_view::crend,std::wstring_view::crbegin,std::wstring_view::crend,std::span::crbegin,std::span::crend,std::set::crbegin,std::set::crend,std::map::crbegin,std::map::crend">
6723-
<use-retval/>
6724-
<noreturn>false</noreturn>
6725-
</function>
67266700
<function name="std::vector::at,std::array::at,std::string::at,std::wstring::at,std::string_view::at,std::wstring_view::at">
67276701
<use-retval/>
67286702
<noreturn>false</noreturn>
@@ -6768,14 +6742,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
67686742
<not-uninit/>
67696743
</arg>
67706744
</function>
6771-
<!-- T* std::vector<T,Allocator>::data() noexcept; -->
6772-
<!-- const T* std::vector<T,Allocator>::data() const noexcept; -->
6773-
<function name="std::array::data,std::vector::data,std::span::data">
6774-
<use-retval/>
6775-
<const/>
6776-
<returnValue type="const T *"/>
6777-
<noreturn>false</noreturn>
6778-
</function>
67796745
<!-- https://en.cppreference.com/w/cpp/container/deque/swap -->
67806746
<!-- void std::deque::swap( deque& other ); -->
67816747
<!-- https://en.cppreference.com/w/cpp/container/list/swap -->

lib/checkfunctions.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,14 @@ void CheckFunctions::checkLibraryMatchFunctions()
622622
if (Token::simpleMatch(tok->astTop(), "throw"))
623623
continue;
624624

625+
if (Token::simpleMatch(tok->astParent(), ".")) {
626+
const Token* contTok = tok->astParent()->astOperand1();
627+
if (astContainerAction(contTok) != Library::Container::Action::NO_ACTION)
628+
continue;
629+
if (astContainerYield(contTok) != Library::Container::Yield::NO_YIELD)
630+
continue;
631+
}
632+
625633
if (!mSettings->library.isNotLibraryFunction(tok))
626634
continue;
627635

lib/library.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,15 @@ const Library::NonOverlappingData* Library::getNonOverlappingData(const Token *f
13581358

13591359
Library::UseRetValType Library::getUseRetValType(const Token *ftok) const
13601360
{
1361+
if (Token::simpleMatch(ftok->astParent(), ".")) {
1362+
using Yield = Library::Container::Yield;
1363+
using Action = Library::Container::Action;
1364+
const Yield yield = astContainerYield(ftok->astParent()->astOperand1());
1365+
if (yield == Yield::START_ITERATOR || yield == Yield::END_ITERATOR || yield == Yield::AT_INDEX ||
1366+
yield == Yield::SIZE || yield == Yield::EMPTY || yield == Yield::BUFFER || yield == Yield::BUFFER_NT ||
1367+
((yield == Yield::ITEM || yield == Yield::ITERATOR) && astContainerAction(ftok->astParent()->astOperand1()) == Action::NO_ACTION))
1368+
return Library::UseRetValType::DEFAULT;
1369+
}
13611370
if (isNotLibraryFunction(ftok))
13621371
return Library::UseRetValType::NONE;
13631372
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));

test/cfg/std.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4489,7 +4489,7 @@ void getline()
44894489
in.close();
44904490
}
44914491

4492-
// cppcheck-suppress passedByValue
4492+
// TODO cppcheck-suppress passedByValue
44934493
void stream_write(std::ofstream& s, std::vector<char> v) {
44944494
if (v.empty()) {}
44954495
s.write(v.data(), v.size());

test/testfunctions.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,9 +1925,7 @@ class TestFunctions : public TestFixture {
19251925
" auto x = std::vector<int>(1);\n"
19261926
" x.push_back(1);\n"
19271927
"}\n", "test.cpp", &s);
1928-
TODO_ASSERT_EQUALS("",
1929-
"[test.cpp:7]: (information) --check-library: There is no matching configuration for function auto::push_back()\n",
1930-
errout.str());
1928+
ASSERT_EQUALS("", errout.str());
19311929

19321930
check("void f() {\n"
19331931
" auto p(std::make_shared<std::vector<int>>());\n"

0 commit comments

Comments
 (0)