https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117293
Patrick Palka <ppalka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ppalka at gcc dot gnu.org --- Comment #7 from Patrick Palka <ppalka at gcc dot gnu.org> --- Substituting U=string into overload_set<const U&, Foo, void>::type during overload resolution certainly has the side effect of instantiating that class template specialization (which entails partial specialization selection). And the outcome of that instantiation should be independent of the context (otherwise the program is IFNDR via https://eel.is/c++draft/temp.point#7 IIUC). So the testcase can be simplified to: template <typename T> T declval(); template<typename Src, typename Dst, typename> struct overload_set; template<typename Src, typename Dst> struct overload_set<Src, Dst, decltype(void(Dst{declval<Src>()}))> // deprecated warning { using type = void; }; struct string {}; struct Foo { [[deprecated("dupa")]] Foo(const string&) {}; }; overload_set<const string&, Foo, void> x; Like with the original testcase GCC issues a deprecation warning, Clang doesn't.