1 // PR c++/48468
2 // { dg-do compile { target c++11 } }
3 // { dg-prune-output "note" }
4 
5 template<class T>
6 T&& declval() noexcept;
7 
8 template< class T >
f1(T & x)9 inline void f1( T& x ) noexcept( noexcept( declval<T&>().foo() ) ) // { dg-error "Z" }
10 {
11   x.foo();
12 }
13 
14 template< class T,
15   bool Noexcept = noexcept( declval<T&>().foo() ) // { dg-error "no member|not convert" }
16 
17 >
f2(T & x)18 inline void f2( T& x ) noexcept( Noexcept )
19 {
20   x.foo();
21 }
22 
23 // a common and trivial mistake
24 template< class T >
f3(T & x)25 inline void f3( T& x ) noexcept( declval<T&>().foo() ) // { dg-error "Z" }
26 {
27   x.foo();
28 }
29 
30 struct X
31 {
32   void foo();
33 };
34 
35 struct Y
36 {
37   void foo() noexcept;
38 };
39 
40 struct Z {};
41 
main()42 int main()
43 {
44   X x; Y y; Z z;
45 
46   static_assert( !noexcept( f1(x) ), "OK." );
47   static_assert( !noexcept( f2(x) ), "OK." );
48   // static_assert( !noexcept( f3(x) ), "shall be ill-formed(OK)." );
49 
50   static_assert(  noexcept( f1(y) ), "OK." );
51   static_assert(  noexcept( f2(y) ), "OK." );
52   // static_assert(  noexcept( f3(y) ), "shall be ill-formed(OK)." );
53 
54   noexcept( f1(z) );		// { dg-message "required" }
55   static_assert(  noexcept( f2(z) ), "shall be ill-formed." ); // { dg-error "no match" }
56   noexcept( f3(z) );		// { dg-message "required" }
57 }
58