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)
