https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117293
--- Comment #8 from m.cencora at gmail dot com --- (In reply to Patrick Palka from comment #7) > 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. I think the reduced test-cases is not a valid representation of the bug I reported. The deprecated attribute should trigger a warning when "program refers to a name or entity other than to declare it". https://eel.is/c++draft/dcl.attr.deprecated And in my original test case, the deprecated constructor is not referred to or used. It is just taken into consideration during overload resolution, but another func wins - Bar(const string&).