https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110580
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Reduced all the way: ``` template <typename _Tp> struct remove_reference { using type = __remove_reference(_Tp); }; template <typename _Tp> using remove_reference_t = typename remove_reference<_Tp>::type; template <typename _Tp, typename _Up> inline constexpr bool is_same_v = __is_same(_Tp, _Up); template <typename _Key> class s3 { public: template <typename _Up, typename _Vp = remove_reference_t<_Up>> static constexpr bool __usable_key = is_same_v<const _Vp, const _Key>; template <typename _Args> void f(_Args __args, int t) { if constexpr (__usable_key<_Args>) { const _Key &__k = __args; } } }; struct s0 {}; struct s1 {}; s1 g(); void createMember(int member, s3<s0> &children) { children.f(g(), member); } ``` Or if using the internal type_traits is bad idea here is better testcase: ``` #include <type_traits> using namespace std; template <typename _Key> class s3 { public: template <typename _Up, typename _Vp = remove_reference_t<_Up>> static constexpr bool __usable_key = is_same_v<const _Vp, const _Key>; template <typename _Args> void f(_Args __args, int t) { if constexpr (__usable_key<_Args>) { const _Key &__k = __args; } } }; struct s0 {}; struct s1 {}; s1 g(); void createMember(int member, s3<s0> &children) { children.f(g(), member); } ``` Here is a testcase using static assert rather than if constexpr: ``` #include <type_traits> using namespace std; template <typename _Key> class s3 { public: template <typename _Up, typename _Vp = remove_reference_t<_Up>> static constexpr bool __usable_key = is_same_v<const _Vp, const _Key>; template <typename _Args> void f(_Args __args, int t) { static_assert(!__usable_key<_Args>); } }; struct s0 {}; struct s1 {}; s1 g(); void createMember(int member, s3<s0> &children) { children.f(g(), member); } ```