[Bug libstdc++/125981] std::find_if/std::mismatch dereference the past-the-end iterator when the predicate result type has an ADL-reachable operator&&

"cvs-commit at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125981

--- Comment #13 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-16 branch has been updated by Jonathan Wakely
<[email protected]>:

https://gcc.gnu.org/g:8618618b466b819d27930bdb6cf1b765099a2c22

commit r16-9548-g8618618b466b819d27930bdb6cf1b765099a2c22
Author: Yan Churkin <[email protected]>
Date:   Fri Jun 26 22:45:31 2026 +0300

    libstdc++: Don't dereference past-the-end iterator with overloaded
operator&& [PR125981]

    std::__find_if, std::__mismatch and std::__push_heap drove their loops
    with a condition of the form

      while (__first != __last && PREDICATE_CALL(...))

    If the predicate/comparator result type has an ADL-reachable
    operator&&(bool, T), overload resolution selects that user-defined
    operator&& for the loop condition.  It does not short-circuit, so the
    operand that dereferences *__first is evaluated even when
    __first == __last, dereferencing the past-the-end iterator.

    Such a result type does not model boolean-testable, so this is undefined
    behaviour and not a conformance issue.  Handle it anyway as a QoI
    extension, consistent with std::equal, std::binary_search and
    std::__partition, by forcing the predicate result to bool so the
    built-in && is used.  This has no effect on well-behaved predicates; the
    ranges:: versions are unaffected because their wrappers already return
    bool.

            PR libstdc++/125981

    libstdc++-v3/ChangeLog:

            * include/bits/stl_algobase.h (__find_if): Force the predicate
            result to bool so that non-boolean_testable predicates cannot
            cause a past-the-end iterator to be dereferenced.
            (__mismatch): Likewise for both overloads.
            * include/bits/stl_heap.h (__push_heap): Likewise for the
            comparator result.
            * testsuite/25_algorithms/find_if/overloaded_logical_ops.cc: New
            test.
            * testsuite/25_algorithms/mismatch/overloaded_logical_ops.cc:
            New test.

    Signed-off-by: Yan Churkin <[email protected]>
    (cherry picked from commit a4ceb702480b9f46dd9b862c81ad7505ca344286)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.