https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112288
--- Comment #8 from Patrick Palka <ppalka at gcc dot gnu.org> --- The issue was probably latent before r6-6830. The testcase is kind of strange, e.g. 'slot_allocated' is defined within 'allocate_slot' instead of within 'slot', which would arguably be more natural given that its 'slot<T>' function parameter. And consecutive equivalent calls to 'next' apparently resolve to different overloads due to 'slot_allocated' being defined only after we instantiate the second 'next' overload. Reduced: template<class T> struct slot { template<class U> friend constexpr bool slot_allocated(slot<T>, U); }; template<class T> struct allocate_slot { template<class U> friend constexpr bool slot_allocated(slot<T>, U) { return true; } }; template<class T, bool = slot_allocated(slot<T>{}, 0)> constexpr int next(int) { return 0; } template<class T> constexpr int next(...) { allocate_slot<T> s; return 42; } // slot_allocated<slot<int>, int>() not defined yet static_assert(next<int>(0) == 42); // now it's defined static_assert(next<int>(0) == 0);