https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117293
--- Comment #4 from m.cencora at gmail dot com --- (In reply to Andrew Pinski from comment #2) > (In reply to Andrew Pinski from comment #1) > > I am not sure this is related to SFINAE though. > > > > Rather it is in an unevaluated context where the diagnostic of deprecated > > should not happen. > > But it is even odder than that. > > The problem is you need to match decltype(void(Dst{declval<Src>()})) to void > which it does. > > Note if I comment out: > ``` > Bar(const string&); > ``` > > then the template overload is selected. And I would have expected a warning > from clang/EDG/MSVC for the deprecated constructor but nothing. FWIW this is just due to reduction. In original code, the overload set of Bar constructors is such that removing the Bar(const string&) overload results (as expected) in ill-formed code with 'no viable overload' diagnostic (and the "deprecated" diagnostic as well). > > I am not 100% sure this if this warning is expected or not. > So I don't think there is a leak here either since you need to see if which > of the constructors is valid or not and then select based on which one is > more specialized or not. I'd say that warning is not expected, because user's code didn't (directly or indirectly) call the deprecated constructor. Also changing the SFINAE to something like this doesn't trigger the warning: template <typename U, decltype(void(Dst{declval<Src>()}))* = nullptr> Bar(const U&); > > Note using C++ 20 concepts does not warn.