1 // RUN: %clang_cc1 -std=c++1z -verify %s 2 3 template<typename T, bool B> using Fn = T () noexcept(B); 4 5 // - If the original A is a function pointer type, A can be "pointer to 6 // function" even if the deduced A is "pointer to noexcept function". 7 struct A { 8 template<typename T> operator Fn<T, false>*(); // expected-note {{candidate}} 9 }; 10 struct B { 11 template<typename T> operator Fn<T, true>*(); 12 }; 13 void (*p1)() = A(); 14 void (*p2)() = B(); 15 void (*p3)() noexcept = A(); // expected-error {{no viable conversion}} 16 void (*p4)() noexcept = B(); 17 18 // - If the original A is a pointer to member function type, A can be "pointer 19 // to member of type function" even if the deduced A is "pointer to member of 20 // type noexcept function". 21 struct C { 22 template<typename T> operator Fn<T, false> A::*(); // expected-note {{candidate}} 23 }; 24 struct D { 25 template<typename T> operator Fn<T, true> A::*(); 26 }; 27 void (A::*q1)() = C(); 28 void (A::*q2)() = D(); 29 void (A::*q3)() noexcept = C(); // expected-error {{no viable conversion}} 30 void (A::*q4)() noexcept = D(); 31 32 // There is no corresponding rule for references. 33 // FIXME: This seems like a defect. 34 // FIXME: We don't actually implement the final check for equal types at all! 35 // Instead, we handle the matching via [over.ics.user]p3: 36 // "If the user-defined conversion is specified by a specialization of a 37 // conversion function template, the second standard conversion sequence 38 // shall have exact match rank." 39 // Note that this *does* allow discarding noexcept, since that conversion has 40 // Exact Match rank. 41 struct E { 42 template<typename T> operator Fn<T, false>&(); // expected-note {{candidate}} 43 }; 44 struct F { 45 template<typename T> operator Fn<T, true>&(); 46 }; 47 void (&r1)() = E(); 48 void (&r2)() = F(); 49 void (&r3)() noexcept = E(); // expected-error {{no viable conversion}} 50 void (&r4)() noexcept = F(); 51 52 // FIXME: We reject this for entirely the wrong reason. We incorrectly succeed 53 // in deducing T = void, U = G::B, and only fail due to [over.ics.user]p3. 54 struct G { 55 template<typename, typename> struct A {}; 56 template<typename U> struct A<U, int> : A<U, void> {}; 57 struct B { typedef int type; }; 58 59 template<typename T, typename U = B> operator A<T, typename U::type> *(); // expected-note {{candidate function [with T = void, U = G::B]}} 60 }; 61 G::A<void, void> *g = G(); // expected-error {{no viable conversion}} 62