Detect container action and yield functions (#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 4f124a57de5c761ac757ebed83d9f047ef4a1328. * Add Yield::AT_INDEX * Add Yield::ITERATOR * Simplify
This commit is contained in:
parent
2beb46194f
commit
bd6c5318ad
34
cfg/std.cfg
34
cfg/std.cfg
|
@ -6600,12 +6600,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
|
|||
<not-uninit/>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- void clear(); // until C++11 -->
|
||||
<!-- void clear() noexcept; // since C++11 -->
|
||||
<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">
|
||||
<noreturn>false</noreturn>
|
||||
<returnValue type="void"/>
|
||||
</function>
|
||||
<!-- bool empty() const; // until C++11 -->
|
||||
<!-- constexpr bool empty() const noexcept; // since C++11 until C++20 -->
|
||||
<!-- [[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
|
|||
<not-uninit/>
|
||||
</arg>
|
||||
</function>
|
||||
<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">
|
||||
<use-retval/>
|
||||
<noreturn>false</noreturn>
|
||||
</function>
|
||||
<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">
|
||||
<use-retval/>
|
||||
<noreturn>false</noreturn>
|
||||
</function>
|
||||
<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">
|
||||
<use-retval/>
|
||||
<noreturn>false</noreturn>
|
||||
</function>
|
||||
<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">
|
||||
<use-retval/>
|
||||
<noreturn>false</noreturn>
|
||||
</function>
|
||||
<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">
|
||||
<use-retval/>
|
||||
<noreturn>false</noreturn>
|
||||
</function>
|
||||
<function name="std::vector::at,std::array::at,std::string::at,std::wstring::at,std::string_view::at,std::wstring_view::at">
|
||||
<use-retval/>
|
||||
<noreturn>false</noreturn>
|
||||
|
@ -6768,14 +6742,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
|
|||
<not-uninit/>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- T* std::vector<T,Allocator>::data() noexcept; -->
|
||||
<!-- const T* std::vector<T,Allocator>::data() const noexcept; -->
|
||||
<function name="std::array::data,std::vector::data,std::span::data">
|
||||
<use-retval/>
|
||||
<const/>
|
||||
<returnValue type="const T *"/>
|
||||
<noreturn>false</noreturn>
|
||||
</function>
|
||||
<!-- https://en.cppreference.com/w/cpp/container/deque/swap -->
|
||||
<!-- void std::deque::swap( deque& other ); -->
|
||||
<!-- https://en.cppreference.com/w/cpp/container/list/swap -->
|
||||
|
|
|
@ -622,6 +622,14 @@ void CheckFunctions::checkLibraryMatchFunctions()
|
|||
if (Token::simpleMatch(tok->astTop(), "throw"))
|
||||
continue;
|
||||
|
||||
if (Token::simpleMatch(tok->astParent(), ".")) {
|
||||
const Token* contTok = tok->astParent()->astOperand1();
|
||||
if (astContainerAction(contTok) != Library::Container::Action::NO_ACTION)
|
||||
continue;
|
||||
if (astContainerYield(contTok) != Library::Container::Yield::NO_YIELD)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mSettings->library.isNotLibraryFunction(tok))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1358,6 +1358,15 @@ const Library::NonOverlappingData* Library::getNonOverlappingData(const Token *f
|
|||
|
||||
Library::UseRetValType Library::getUseRetValType(const Token *ftok) const
|
||||
{
|
||||
if (Token::simpleMatch(ftok->astParent(), ".")) {
|
||||
using Yield = Library::Container::Yield;
|
||||
using Action = Library::Container::Action;
|
||||
const Yield yield = astContainerYield(ftok->astParent()->astOperand1());
|
||||
if (yield == Yield::START_ITERATOR || yield == Yield::END_ITERATOR || yield == Yield::AT_INDEX ||
|
||||
yield == Yield::SIZE || yield == Yield::EMPTY || yield == Yield::BUFFER || yield == Yield::BUFFER_NT ||
|
||||
((yield == Yield::ITEM || yield == Yield::ITERATOR) && astContainerAction(ftok->astParent()->astOperand1()) == Action::NO_ACTION))
|
||||
return Library::UseRetValType::DEFAULT;
|
||||
}
|
||||
if (isNotLibraryFunction(ftok))
|
||||
return Library::UseRetValType::NONE;
|
||||
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
|
||||
|
|
|
@ -4489,7 +4489,7 @@ void getline()
|
|||
in.close();
|
||||
}
|
||||
|
||||
// cppcheck-suppress passedByValue
|
||||
// TODO cppcheck-suppress passedByValue
|
||||
void stream_write(std::ofstream& s, std::vector<char> v) {
|
||||
if (v.empty()) {}
|
||||
s.write(v.data(), v.size());
|
||||
|
|
|
@ -1925,9 +1925,7 @@ private:
|
|||
" auto x = std::vector<int>(1);\n"
|
||||
" x.push_back(1);\n"
|
||||
"}\n", "test.cpp", &s);
|
||||
TODO_ASSERT_EQUALS("",
|
||||
"[test.cpp:7]: (information) --check-library: There is no matching configuration for function auto::push_back()\n",
|
||||
errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" auto p(std::make_shared<std::vector<int>>());\n"
|
||||
|
|
Loading…
Reference in New Issue