Richard Smith | 762bb9d | 2011-10-13 22:29:44 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 2 | |
| 3 | void fn() = default; // expected-error {{only special member}} |
| 4 | struct foo { |
| 5 | void fn() = default; // expected-error {{only special member}} |
| 6 | |
| 7 | foo() = default; |
| 8 | foo(const foo&) = default; |
Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 9 | foo(foo&&) = default; |
Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 10 | foo& operator = (const foo&) = default; |
Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 11 | foo& operator = (foo&&) = default; |
Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 12 | ~foo() = default; |
| 13 | }; |
| 14 | |
| 15 | struct bar { |
| 16 | bar(); |
| 17 | bar(const bar&); |
Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 18 | bar(bar&&); |
Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 19 | bar& operator = (const bar&); |
Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 20 | bar& operator = (bar&&); |
Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 21 | ~bar(); |
| 22 | }; |
| 23 | |
| 24 | bar::bar() = default; |
| 25 | bar::bar(const bar&) = default; |
Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 26 | bar::bar(bar&&) = default; |
Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 27 | bar& bar::operator = (const bar&) = default; |
Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 28 | bar& bar::operator = (bar&&) = default; |
Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 29 | bar::~bar() = default; |
| 30 | |
Richard Smith | eb273b7 | 2012-02-14 02:33:50 +0000 | [diff] [blame] | 31 | static_assert(__is_trivial(foo), "foo should be trivial"); |
Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 32 | |
| 33 | static_assert(!__has_trivial_destructor(bar), "bar's destructor isn't trivial"); |
| 34 | static_assert(!__has_trivial_constructor(bar), |
| 35 | "bar's default constructor isn't trivial"); |
| 36 | static_assert(!__has_trivial_copy(bar), "bar has no trivial copy"); |
| 37 | static_assert(!__has_trivial_assign(bar), "bar has no trivial assign"); |
| 38 | |
| 39 | void tester() { |
| 40 | foo f, g(f); |
| 41 | bar b, c(b); |
| 42 | f = g; |
| 43 | b = c; |
| 44 | } |
| 45 | |
Richard Smith | eb273b7 | 2012-02-14 02:33:50 +0000 | [diff] [blame] | 46 | template<typename T> struct S : T { |
| 47 | constexpr S() = default; |
| 48 | constexpr S(const S&) = default; |
| 49 | constexpr S(S&&) = default; |
| 50 | }; |
| 51 | struct lit { constexpr lit() {} }; |
| 52 | S<lit> s_lit; // ok |
| 53 | S<bar> s_bar; // ok |
Richard Smith | f4fe843 | 2012-06-08 01:30:54 +0000 | [diff] [blame] | 54 | |
| 55 | struct Friends { |
| 56 | friend S<bar>::S(); |
| 57 | friend S<bar>::S(const S&); |
| 58 | friend S<bar>::S(S&&); |
| 59 | }; |
Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 60 | |
| 61 | namespace DefaultedFnExceptionSpec { |
| 62 | // DR1330: The exception-specification of an implicitly-declared special |
| 63 | // member function is evaluated as needed. |
| 64 | template<typename T> T &&declval(); |
| 65 | template<typename T> struct pair { |
| 66 | pair(const pair&) noexcept(noexcept(T(declval<T>()))); |
| 67 | }; |
| 68 | |
| 69 | struct Y; |
| 70 | struct X { X(); X(const Y&); }; |
| 71 | struct Y { pair<X> p; }; |
| 72 | |
| 73 | template<typename T> |
| 74 | struct A { |
| 75 | pair<T> p; |
| 76 | }; |
| 77 | struct B { |
| 78 | B(); |
| 79 | B(const A<B>&); |
| 80 | }; |
| 81 | |
| 82 | // Don't crash here. |
| 83 | void f() { |
| 84 | X x = X(); |
| 85 | (void)noexcept(B(declval<B>())); |
| 86 | } |
| 87 | |
| 88 | template<typename T> |
| 89 | struct Error { |
| 90 | // FIXME: Type canonicalization causes all the errors to point at the first |
| 91 | // declaration which has the type 'void () noexcept (T::error)'. We should |
| 92 | // get one error for 'Error<int>::Error()' and one for 'Error<int>::~Error()'. |
| 93 | void f() noexcept(T::error); // expected-error 2{{has no members}} |
| 94 | |
| 95 | Error() noexcept(T::error); |
| 96 | Error(const Error&) noexcept(T::error); |
| 97 | Error(Error&&) noexcept(T::error); |
| 98 | Error &operator=(const Error&) noexcept(T::error); |
| 99 | Error &operator=(Error&&) noexcept(T::error); |
| 100 | ~Error() noexcept(T::error); |
| 101 | }; |
| 102 | |
| 103 | struct DelayImplicit { |
| 104 | Error<int> e; |
| 105 | }; |
| 106 | |
| 107 | // Don't instantiate the exception specification here. |
| 108 | void test1(decltype(declval<DelayImplicit>() = DelayImplicit(DelayImplicit()))); |
| 109 | void test2(decltype(declval<DelayImplicit>() = declval<const DelayImplicit>())); |
| 110 | void test3(decltype(DelayImplicit(declval<const DelayImplicit>()))); |
| 111 | |
| 112 | // Any odr-use causes the exception specification to be evaluated. |
| 113 | struct OdrUse { // \ |
| 114 | expected-note {{instantiation of exception specification for 'Error'}} \ |
| 115 | expected-note {{instantiation of exception specification for '~Error'}} |
| 116 | Error<int> e; |
| 117 | }; |
| 118 | OdrUse use; // expected-note {{implicit default constructor for 'DefaultedFnExceptionSpec::OdrUse' first required here}} |
| 119 | } |
Richard Smith | eef0029 | 2012-08-06 02:25:10 +0000 | [diff] [blame^] | 120 | |
| 121 | namespace PR13527 { |
| 122 | struct X { |
| 123 | X() = delete; // expected-note {{here}} |
| 124 | X(const X&) = delete; // expected-note {{here}} |
| 125 | X(X&&) = delete; // expected-note {{here}} |
| 126 | X &operator=(const X&) = delete; // expected-note {{here}} |
| 127 | X &operator=(X&&) = delete; // expected-note {{here}} |
| 128 | ~X() = delete; // expected-note {{here}} |
| 129 | }; |
| 130 | X::X() = default; // expected-error {{redefinition}} |
| 131 | X::X(const X&) = default; // expected-error {{redefinition}} |
| 132 | X::X(X&&) = default; // expected-error {{redefinition}} |
| 133 | X &X::operator=(const X&) = default; // expected-error {{redefinition}} |
| 134 | X &X::operator=(X&&) = default; // expected-error {{redefinition}} |
| 135 | X::~X() = default; // expected-error {{redefinition}} |
| 136 | |
| 137 | struct Y { |
| 138 | Y() = default; |
| 139 | Y(const Y&) = default; |
| 140 | Y(Y&&) = default; |
| 141 | Y &operator=(const Y&) = default; |
| 142 | Y &operator=(Y&&) = default; |
| 143 | ~Y() = default; |
| 144 | }; |
| 145 | Y::Y() = default; // expected-error {{definition of explicitly defaulted}} |
| 146 | Y::Y(const Y&) = default; // expected-error {{definition of explicitly defaulted}} |
| 147 | Y::Y(Y&&) = default; // expected-error {{definition of explicitly defaulted}} |
| 148 | Y &Y::operator=(const Y&) = default; // expected-error {{definition of explicitly defaulted}} |
| 149 | Y &Y::operator=(Y&&) = default; // expected-error {{definition of explicitly defaulted}} |
| 150 | Y::~Y() = default; // expected-error {{definition of explicitly defaulted}} |
| 151 | } |