https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78346
Bug ID: 78346 Summary: std::search with binary comparison predicate uses invalid reference Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: reagentoo at gmail dot com Target Milestone: --- When using std::search with binary comparison predicate, reference obtained from iterator outlives iterator itself which violates part 24.2.1 [iterator.requirements.general] of C++ standard: 10. Destruction of an iterator may invalidate pointers and references previously obtained from that iterator. The iterator is being dereferenced when converting binary predicate to unary for later use in std::find_if: template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> _ForwardIterator1 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __predicate) { ... __first1 = std::__find_if(__first1, __last1, __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); In this expression __first2 is passed to a _Iter_equals_iter wrapper (from bits/predefined_ops.h): template<typename _Iterator1> struct _Iter_equals_iter { typename std::iterator_traits<_Iterator1>::reference _M_ref; <-- reference obtained from iterator _Iter_equals_iter(_Iterator1 __it1) : _M_ref(*__it1) { } template<typename _Iterator2> bool operator()(_Iterator2 __it2) { return *__it2 == _M_ref; } }; Since _Iterator1 __it1 is passed to constructor by value, _M_ref can become invalid after iterator leaves the scope; This behavior can be observed when using std::search with boost::filesystem::path, since boost::filesystem::path::iterator::dereference returns reference to a local member: http://melpon.org/wandbox/permlink/58aIbfJWeGgMKMdF As a proposed solution, _Iter_equals_iter might store copy of iterator rather than dereferenced value.