1 // PR c++/51222 2 // { dg-options -std=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