https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106026
Bug ID: 106026 Summary: ICE: error reporting routines re-entered. Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ldalessandro at gmail dot com Target Milestone: --- Created attachment 53163 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53163&action=edit Eric's tag_invoke implementation. Triggered with complicated tag_invoke + concepts. This code is erroneous (the friend function with "requires requires" in cpos::extent and the free function with "concepts::has_static_extent" should not both be possible. This requires Eric Niebler's tag_invoke gist, which is somewhat complex, so I left it in as an #include. I attached an actual copy as tag_invoke.hpp to this PR as well. https://godbolt.org/z/fzqEG6bnW #include <https://gist.githubusercontent.com/ericniebler/056f5459cf259da526d9ea2279c386bb/raw/6c63fa81442e811fea8bd6920a95c0b8229dca6c/tag_invoke.hpp> #include <array> #include <concepts> #define FWD(x) static_cast<decltype(x)&&>(x) namespace traits { template <class T> inline constexpr auto extents_v = not defined(extents_v<T>); } namespace cpos { struct extents { template <class T> requires requires { { traits::extents_v<std::remove_cvref_t<T>> }; } constexpr friend auto tag_invoke(extents, T&&) { return traits::extents_v<std::remove_cvref_t<T>>; } constexpr auto operator()(auto&& x) const { return tag_invoke(*this, FWD(x)); } }; } constexpr cpos::extents extents; namespace concepts { template <class T> concept has_extents = requires (T t) { { extents(t) }; }; template <class T> concept has_static_extents = has_extents<T> and requires { { traits::extents_v<std::remove_cvref_t<T>> }; }; } template <concepts::has_static_extents T> constexpr auto tag_invoke(cpos::extents, T&&) { return traits::extents_v<std::remove_cvref_t<T>>; } template <auto _shape> struct static_tensor { }; namespace traits { template <auto _shape> inline constexpr auto extents_v<static_tensor<_shape>> = _shape; } constexpr std::array matrix_shape = { 3, 3 }; auto x = static_tensor<matrix_shape>{}; static_assert(concepts::has_static_extents<decltype(x)>);