https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108636
--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> --- Yes, that's explained above: (In reply to GCC Commits from comment #3) > On trunk there is a second problem, which is that the new equality > operators for comparing directory iterators with default_sentinel use > the shared_ptr::operator bool() conversion operator. The shared_ptr > specializations used by directory iterators are explicitly instantiated > in the library, but the bool conversion operators are not exported. This > causes linker errors at -O0 or with -fkeep-inline-functions. That just > requires the conversion operators to be exported. That was fixed by this part: > * config/abi/pre/gnu.ver (GLIBCXX_3.4.31): Export shared_ptr > conversion operators for directory iterator comparisons with > std::default_sentinel_t. But that can't be backported to the gcc-12 branch as it would change the ABI of the libstdc++.so.6.0.30 shared library. I think this would solve the problem with -fkeep-inline-functions: --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1666,6 +1666,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_ptr; } /// Return true if the stored pointer is not null. +#if __cplusplus >= 202002L + [[__gnu__::__always_inline__]] +#endif explicit operator bool() const noexcept { return _M_ptr != nullptr; } We would only need that on the gcc-12 branch, since it works elsewhere.