https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105220
--- Comment #4 from Jason Merrill <jason at gcc dot gnu.org> --- Further discussion raised that the parameter mapping lives somewhere on the border. Consider https://godbolt.org/z/TEsWhd5oG template<bool B> concept C = B; struct A { template<typename T> void f() requires C<T::value>; }; struct B { template<typename T> void f() requires C<T::value>; }; class X { friend struct A; static constexpr bool value = true; }; void g() { A().f<X>(); // OK? B().f<X>(); // error, X::value is private? } Clang, EDG, and MSVC all agree with the comments. GCC sat_cache brokenly treats the two C<T::value> as equivalent, so either accepts both calls or rejects both, depending on which comes first. It's not yet clear whether 2589 will be resolved to follow the comments or reject both.