| 1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s |
| 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; |
| 9 | foo(foo&&) = default; |
| 10 | foo& operator = (const foo&) = default; |
| 11 | foo& operator = (foo&&) = default; |
| 12 | ~foo() = default; |
| 13 | }; |
| 14 | |
| 15 | struct bar { |
| 16 | bar(); |
| 17 | bar(const bar&); |
| 18 | bar(bar&&); |
| 19 | bar& operator = (const bar&); |
| 20 | bar& operator = (bar&&); |
| 21 | ~bar(); |
| 22 | }; |
| 23 | |
| 24 | bar::bar() = default; |
| 25 | bar::bar(const bar&) = default; |
| 26 | bar::bar(bar&&) = default; |
| 27 | bar& bar::operator = (const bar&) = default; |
| 28 | bar& bar::operator = (bar&&) = default; |
| 29 | bar::~bar() = default; |
| 30 | |
| 31 | static_assert(__is_trivial(foo), "foo should be trivial"); |
| 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 | |
| 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 |
| 54 | |
| 55 | struct Friends { |
| 56 | friend S<bar>::S(); |
| 57 | friend S<bar>::S(const S&); |
| 58 | friend S<bar>::S(S&&); |
| 59 | }; |
| 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 | void f() noexcept(T::error); |
| 91 | |
| 92 | Error() noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} expected-error {{type 'char'}} |
| 93 | Error(const Error&) noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} |
| 94 | Error(Error&&) noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} |
| 95 | Error &operator=(const Error&) noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} expected-error {{type 'double'}} |
| 96 | Error &operator=(Error&&) noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} |
| 97 | ~Error() noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} expected-error {{type 'char'}} |
| 98 | }; |
| 99 | |
| 100 | Error<char> c; // expected-note 2{{instantiation of}} |
| 101 | struct DelayImplicit { |
| 102 | Error<int> e; // expected-note 6{{instantiation of}} |
| 103 | }; |
| 104 | Error<float> *e; |
| 105 | |
| 106 | // An exception specification is needed if the exception specification for a |
| 107 | // a defaulted special member function that calls the function is needed. |
| 108 | // Use in an unevaluated operand still results in the exception spec being |
| 109 | // needed. |
| 110 | void test1(decltype(declval<DelayImplicit>() = DelayImplicit(DelayImplicit()))); // expected-note 4{{in evaluation of exception specification}} |
| 111 | void test2(decltype(declval<DelayImplicit>() = declval<const DelayImplicit>())); // expected-note {{in evaluation of exception specification}} |
| 112 | void test3(decltype(DelayImplicit(declval<const DelayImplicit>()))); // expected-note {{in evaluation of exception specification}} |
| 113 | |
| 114 | // Any odr-use needs the exception specification. |
| 115 | void f(Error<double> *p) { |
| 116 | *p = *p; // expected-note {{instantiation of}} |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | namespace PR13527 { |
| 121 | struct X { |
| 122 | X() = delete; // expected-note {{here}} |
| 123 | X(const X&) = delete; // expected-note {{here}} |
| 124 | X(X&&) = delete; // expected-note {{here}} |
| 125 | X &operator=(const X&) = delete; // expected-note {{here}} |
| 126 | X &operator=(X&&) = delete; // expected-note {{here}} |
| 127 | ~X() = delete; // expected-note {{here}} |
| 128 | }; |
| 129 | X::X() = default; // expected-error {{redefinition}} |
| 130 | X::X(const X&) = default; // expected-error {{redefinition}} |
| 131 | X::X(X&&) = default; // expected-error {{redefinition}} |
| 132 | X &X::operator=(const X&) = default; // expected-error {{redefinition}} |
| 133 | X &X::operator=(X&&) = default; // expected-error {{redefinition}} |
| 134 | X::~X() = default; // expected-error {{redefinition}} |
| 135 | |
| 136 | struct Y { |
| 137 | Y() = default; |
| 138 | Y(const Y&) = default; |
| 139 | Y(Y&&) = default; |
| 140 | Y &operator=(const Y&) = default; |
| 141 | Y &operator=(Y&&) = default; |
| 142 | ~Y() = default; |
| 143 | }; |
| 144 | Y::Y() noexcept = default; // expected-error {{definition of explicitly defaulted}} |
| 145 | Y::Y(const Y&) noexcept = default; // expected-error {{definition of explicitly defaulted}} |
| 146 | Y::Y(Y&&) noexcept = default; // expected-error {{definition of explicitly defaulted}} |
| 147 | Y &Y::operator=(const Y&) noexcept = default; // expected-error {{definition of explicitly defaulted}} |
| 148 | Y &Y::operator=(Y&&) noexcept = default; // expected-error {{definition of explicitly defaulted}} |
| 149 | Y::~Y() = default; // expected-error {{definition of explicitly defaulted}} |
| 150 | } |
| 151 | |
| 152 | namespace PR27699 { |
| 153 | struct X { |
| 154 | X(); |
| 155 | }; |
| 156 | X::X() = default; // expected-note {{here}} |
| 157 | X::X() = default; // expected-error {{redefinition of 'X'}} |
| 158 | } |
| 159 | |
| 160 | namespace PR14577 { |
| 161 | template<typename T> |
| 162 | struct Outer { |
| 163 | template<typename U> |
| 164 | struct Inner1 { |
| 165 | ~Inner1(); |
| 166 | }; |
| 167 | |
| 168 | template<typename U> |
| 169 | struct Inner2 { |
| 170 | ~Inner2(); |
| 171 | }; |
| 172 | }; |
| 173 | |
| 174 | template<typename T> |
| 175 | Outer<T>::Inner1<T>::~Inner1() = delete; // expected-error {{nested name specifier 'Outer<T>::Inner1<T>::' for declaration does not refer into a class, class template or class template partial specialization}} expected-error {{only functions can have deleted definitions}} |
| 176 | |
| 177 | template<typename T> |
| 178 | Outer<T>::Inner2<T>::~Inner2() = default; // expected-error {{nested name specifier 'Outer<T>::Inner2<T>::' for declaration does not refer into a class, class template or class template partial specialization}} expected-error {{only special member functions may be defaulted}} |
| 179 | } |
| 180 | |
| 181 | extern "C" { // expected-note {{extern "C" language linkage specification begins here}} |
| 182 | template<typename _Tp> // expected-error {{templates must have C++ linkage}} |
| 183 | void PR13573(const _Tp&) = delete; |
| 184 | } |
| 185 | |
| 186 | namespace PR15597 { |
| 187 | template<typename T> struct A { |
| 188 | A() noexcept(true) = default; |
| 189 | ~A() noexcept(true) = default; |
| 190 | }; |
| 191 | template<typename T> struct B { |
| 192 | B() noexcept(false) = default; // expected-error {{does not match the calculated one}} |
| 193 | ~B() noexcept(false) = default; // expected-error {{does not match the calculated one}} |
| 194 | }; |
| 195 | A<int> a; |
| 196 | B<int> b; // expected-note {{here}} |
| 197 | } |
| 198 | |
| 199 | namespace PR27941 { |
| 200 | struct ExplicitBool { |
| 201 | ExplicitBool &operator=(bool) = default; // expected-error{{only special member functions may be defaulted}} |
| 202 | int member; |
| 203 | }; |
| 204 | |
| 205 | int fn() { |
| 206 | ExplicitBool t; |
| 207 | t = true; |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | namespace dependent_classes { |
| 212 | template <bool B, typename X, typename Y> |
| 213 | struct conditional; |
| 214 | |
| 215 | template <typename X, typename Y> |
| 216 | struct conditional<true, X, Y> { typedef X type; }; |
| 217 | |
| 218 | template <typename X, typename Y> |
| 219 | struct conditional<false, X, Y> { typedef Y type; }; |
| 220 | |
| 221 | template<bool B> struct X { |
| 222 | X(); |
| 223 | |
| 224 | // B == false triggers error for = default. |
| 225 | using T = typename conditional<B, const X &, int>::type; |
| 226 | X(T) = default; // expected-error {{only special member functions}} |
| 227 | |
| 228 | // Either value of B creates a constructor that can be default |
| 229 | using U = typename conditional<B, X&&, const X&>::type; |
| 230 | X(U) = default; |
| 231 | }; |
| 232 | |
| 233 | X<true> x1; |
| 234 | X<false> x2; // expected-note {{in instantiation}} |
| 235 | |
| 236 | template <typename Type> |
| 237 | class E { |
| 238 | explicit E(const int &) = default; |
| 239 | }; |
| 240 | |
| 241 | template <typename Type> |
| 242 | E<Type>::E(const int&) {} // expected-error {{definition of explicitly defaulted function}} |
| 243 | |
| 244 | } |
| 245 | |