1 // PR c++/51222
2 // { dg-do compile { target c++11 } }
3 
4 template<class T>
5 struct add_rref {
6   typedef T&& type;
7 };
8 
9 template<>
10 struct add_rref<void> {
11   typedef void type;
12 };
13 
14 template<class T>
15 typename add_rref<T>::type declval();
16 
17 template<class T, class U, class =
18   decltype(::delete ::new T(declval<U>()))
19 >
20 auto f(int) -> char;
21 
22 template<class, class>
23 auto f(...) -> char(&)[2];
24 
25 template<class T, class =
26   decltype(::delete ::new T())
27 >
28 auto g(int) -> char;
29 
30 template<class>
31 auto g(...) -> char(&)[2];
32 
33 template<class T, class U>
34 auto f2(int) -> decltype(::delete ::new T(declval<U>()), char());
35 
36 template<class, class>
37 auto f2(...) -> char(&)[2];
38 
39 template<class T>
40 auto g2(int) -> decltype(::delete ::new T(), char());
41 
42 template<class>
43 auto g2(...) -> char(&)[2];
44 
45 struct C { };
46 
47 struct A {
48   virtual ~A() = 0;
49 };
50 
51 struct D1 {
52   D1() = delete;
53 };
54 
55 struct D2 {
56   ~D2() = delete;
57 };
58 
59 static_assert(sizeof(g<void>(0)) == 2, "Ouch");
60 static_assert(sizeof(g<void()>(0)) == 2, "Ouch");
61 static_assert(sizeof(g<void() const>(0)) == 2, "Ouch");
62 static_assert(sizeof(g<A>(0)) == 2, "Ouch");
63 static_assert(sizeof(g<D1>(0)) == 2, "Ouch");
64 static_assert(sizeof(g<D2>(0)) == 2, "Ouch");
65 static_assert(sizeof(g<int&>(0)) == 2, "Ouch");
66 static_assert(sizeof(g<int&&>(0)) == 2, "Ouch");
67 static_assert(sizeof(g<void(&)()>(0)) == 2, "Ouch");
68 static_assert(sizeof(g<void(&&)()>(0)) == 2, "Ouch");
69 static_assert(sizeof(f<void, void>(0)) == 2, "Ouch");
70 static_assert(sizeof(f<void(), void()>(0)) == 2, "Ouch");
71 //static_assert(sizeof(f<void() const, void() const>(0)) == 2, "Ouch");
72 static_assert(sizeof(f<int, void>(0)) == 2, "Ouch");
73 static_assert(sizeof(f<void, int>(0)) == 2, "Ouch");
74 static_assert(sizeof(f<C, void>(0)) == 2, "Ouch");
75 static_assert(sizeof(f<C, int>(0)) == 2, "Ouch");
76 static_assert(sizeof(f<int&, int&>(0)) == 2, "Ouch");
77 static_assert(sizeof(f<int&&, int&&>(0)) == 2, "Ouch");
78 static_assert(sizeof(f<void(&)(), void(&)()>(0)) == 2, "Ouch");
79 static_assert(sizeof(f<void(&&)(), void(&&)()>(0)) == 2, "Ouch");
80 
81 static_assert(sizeof(g2<void>(0)) == 2, "Ouch");
82 static_assert(sizeof(g2<void()>(0)) == 2, "Ouch");
83 static_assert(sizeof(g2<void() const>(0)) == 2, "Ouch");
84 static_assert(sizeof(g2<A>(0)) == 2, "Ouch");
85 static_assert(sizeof(g2<D1>(0)) == 2, "Ouch");
86 static_assert(sizeof(g2<D2>(0)) == 2, "Ouch");
87 static_assert(sizeof(g2<int&>(0)) == 2, "Ouch");
88 static_assert(sizeof(g2<int&&>(0)) == 2, "Ouch");
89 static_assert(sizeof(g2<void(&)()>(0)) == 2, "Ouch");
90 static_assert(sizeof(g2<void(&&)()>(0)) == 2, "Ouch");
91 static_assert(sizeof(f2<void, void>(0)) == 2, "Ouch");
92 static_assert(sizeof(f2<void(), void()>(0)) == 2, "Ouch");
93 //static_assert(sizeof(f2<void() const, void() const>(0)) == 2, "Ouch");
94 static_assert(sizeof(f2<int, void>(0)) == 2, "Ouch");
95 static_assert(sizeof(f2<void, int>(0)) == 2, "Ouch");
96 static_assert(sizeof(f2<C, void>(0)) == 2, "Ouch");
97 static_assert(sizeof(f2<C, int>(0)) == 2, "Ouch");
98 static_assert(sizeof(f2<int&, int&>(0)) == 2, "Ouch");
99 static_assert(sizeof(f2<int&&, int&&>(0)) == 2, "Ouch");
100 static_assert(sizeof(f2<void(&)(), void(&)()>(0)) == 2, "Ouch");
101 static_assert(sizeof(f2<void(&&)(), void(&&)()>(0)) == 2, "Ouch");
102