https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109680
--- Comment #5 from Marek Polacek <mpolacek at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #4) > template <typename T, typename U = T&&> > U __declval (int); > template <typename T> > T __declval (long); > template <typename T> > auto declval () noexcept -> decltype (__declval <T> (0)); > using To = int () const; > using From = int (*) (); > To foo () { return declval <From> (); } > From bar () { return declval <To> (); } > static_assert (!__is_convertible (To, From), ""); > static_assert (!__is_convertible (From, To), ""); > should show that both assertions should succeed. Thanks. > Dunno if in this case the > reason why it isn't convertible is simply the fact that functions can't be > declared to return function/method/array types or some other reason as well. Yeah, I'm also not sure, so I think this should fix it: --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -2245,6 +2245,8 @@ is_convertible_helper (tree from, tree to) { if (VOID_TYPE_P (from) && VOID_TYPE_P (to)) return integer_one_node; + if (FUNC_OR_METHOD_TYPE_P (from) || FUNC_OR_METHOD_TYPE_P (to)) + return error_mark_node; cp_unevaluated u; tree expr = build_stub_object (from); deferring_access_check_sentinel acs (dk_no_deferred); Since static_assert (!__is_convertible (int[3], int[3]), ""); already passes, arrays are handled correctly I think.