1 // RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s 2 3 struct A { 4 static constexpr bool x = true; 5 }; 6 7 namespace N0 { 8 9 template<typename T, typename U> 10 void f(T, U) noexcept(T::y); // #1 11 12 template<typename T, typename U> // #2 13 void f(T, U*) noexcept(T::x); 14 15 // Deduction should succeed for both candidates, and #2 should be selected as the primary template. 16 // Only the exception specification of #2 should be instantiated. 17 template<> 18 void f(A, int*) noexcept; 19 20 } 21 22 namespace N1 { 23 24 template<typename T, typename U> 25 void f(T, U) noexcept(T::x); // #1 26 27 template<typename T, typename U> 28 void f(T, U*) noexcept(T::y); // #2 29 // expected-error@-1 {{no member named 'y' in 'A'}} 30 31 // Deduction should succeed for both candidates, and #2 should be selected as the primary template. 32 // Only the exception specification of #2 should be instantiated. 33 template<> 34 void f(A, int*) noexcept; // expected-error {{exception specification in declaration does not match previous declaration}} 35 // expected-note@-1 {{in instantiation of exception specification for 'f<A, int>' requested here}} 36 // expected-note@-2 {{previous declaration is here}} 37 } 38 39 namespace N2 { 40 41 template<typename T, typename U> 42 void f(T, U) noexcept(T::x); 43 44 template<typename T, typename U> 45 void f(T, U*) noexcept(T::x); 46 47 template<typename T, typename U> 48 void f(T, U**) noexcept(T::y); // expected-error {{no member named 'y' in 'A'}} 49 50 template<typename T, typename U> 51 void f(T, U***) noexcept(T::x); 52 53 template<> 54 void f(A, int*) noexcept; // expected-note {{previous declaration is here}} 55 56 template<> 57 void f(A, int*); // expected-error {{'f<A, int>' is missing exception specification 'noexcept'}} 58 59 template<> 60 void f(A, int**) noexcept; // expected-error {{exception specification in declaration does not match previous declaration}} 61 // expected-note@-1 {{in instantiation of exception specification for 'f<A, int>' requested here}} 62 // expected-note@-2 {{previous declaration is here}} 63 64 // FIXME: Exception specification is currently set to EST_None if instantiation fails. 65 template<> 66 void f(A, int**); 67 68 template<> 69 void f(A, int***) noexcept; // expected-note {{previous declaration is here}} 70 71 template<> 72 void f(A, int***); // expected-error {{'f<A, int>' is missing exception specification 'noexcept'}} 73 74 } 75 76 namespace N3 { 77 78 template<typename T, typename U> 79 void f(T, U) noexcept(T::y); // #1 80 81 template<typename T, typename U> // #2 82 void f(T, U*) noexcept(T::x); 83 84 // Deduction should succeed for both candidates, and #2 should be selected by overload resolution. 85 // Only the exception specification of #2 should be instantiated. 86 void (*x)(A, int*) = f; 87 } 88 89 namespace N4 { 90 91 template<typename T, typename U> 92 void f(T, U) noexcept(T::x); // #1 93 94 template<typename T, typename U> 95 void f(T, U*) noexcept(T::y); // #2 96 // expected-error@-1 {{no member named 'y' in 'A'}} 97 98 // Deduction should succeed for both candidates, and #2 should be selected by overload resolution. 99 // Only the exception specification of #2 should be instantiated. 100 void (*x)(A, int*) = f; // expected-note {{in instantiation of exception specification for 'f<A, int>' requested here}} 101 } 102