1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s
void fn() = default; // expected-error {{only special member}}
struct foo {
void fn() = default; // expected-error {{only special member}}
foo() = default;
foo(const foo&) = default;
foo(foo&&) = default;
foo& operator = (const foo&) = default;
foo& operator = (foo&&) = default;
~foo() = default;
};
struct bar {
bar();
bar(const bar&);
bar(bar&&);
bar& operator = (const bar&);
bar& operator = (bar&&);
~bar();
};
bar::bar() = default;
bar::bar(const bar&) = default;
bar::bar(bar&&) = default;
bar& bar::operator = (const bar&) = default;
bar& bar::operator = (bar&&) = default;
bar::~bar() = default;
static_assert(__is_trivial(foo), "foo should be trivial");
static_assert(!__has_trivial_destructor(bar), "bar's destructor isn't trivial");
static_assert(!__has_trivial_constructor(bar),
"bar's default constructor isn't trivial");
static_assert(!__has_trivial_copy(bar), "bar has no trivial copy");
static_assert(!__has_trivial_assign(bar), "bar has no trivial assign");
void tester() {
foo f, g(f);
bar b, c(b);
f = g;
b = c;
}
template<typename T> struct S : T {
constexpr S() = default;
constexpr S(const S&) = default;
constexpr S(S&&) = default;
};
struct lit { constexpr lit() {} };
S<lit> s_lit; // ok
S<bar> s_bar; // ok
struct Friends {
friend S<bar>::S();
friend S<bar>::S(const S&);
friend S<bar>::S(S&&);
};
namespace DefaultedFnExceptionSpec {
// DR1330: The exception-specification of an implicitly-declared special
// member function is evaluated as needed.
template<typename T> T &&declval();
template<typename T> struct pair {
pair(const pair&) noexcept(noexcept(T(declval<T>())));
};
struct Y;
struct X { X(); X(const Y&); };
struct Y { pair<X> p; };
template<typename T>
struct A {
pair<T> p;
};
struct B {
B();
B(const A<B>&);
};
// Don't crash here.
void f() {
X x = X();
(void)noexcept(B(declval<B>()));
}
template<typename T>
struct Error {
// FIXME: Type canonicalization causes all the errors to point at the first
// declaration which has the type 'void () noexcept (T::error)'. We should
// get one error for 'Error<int>::Error()' and one for 'Error<int>::~Error()'.
void f() noexcept(T::error); // expected-error 2{{has no members}}
Error() noexcept(T::error);
Error(const Error&) noexcept(T::error);
Error(Error&&) noexcept(T::error);
Error &operator=(const Error&) noexcept(T::error);
Error &operator=(Error&&) noexcept(T::error);
~Error() noexcept(T::error);
};
struct DelayImplicit {
Error<int> e;
};
// Don't instantiate the exception specification here.
void test1(decltype(declval<DelayImplicit>() = DelayImplicit(DelayImplicit())));
void test2(decltype(declval<DelayImplicit>() = declval<const DelayImplicit>()));
void test3(decltype(DelayImplicit(declval<const DelayImplicit>())));
// Any odr-use causes the exception specification to be evaluated.
struct OdrUse { // \
expected-note {{instantiation of exception specification for 'Error'}} \
expected-note {{instantiation of exception specification for '~Error'}}
Error<int> e;
};
OdrUse use; // expected-note {{implicit default constructor for 'DefaultedFnExceptionSpec::OdrUse' first required here}}
}
namespace PR13527 {
struct X {
X() = delete; // expected-note {{here}}
X(const X&) = delete; // expected-note {{here}}
X(X&&) = delete; // expected-note {{here}}
X &operator=(const X&) = delete; // expected-note {{here}}
X &operator=(X&&) = delete; // expected-note {{here}}
~X() = delete; // expected-note {{here}}
};
X::X() = default; // expected-error {{redefinition}}
X::X(const X&) = default; // expected-error {{redefinition}}
X::X(X&&) = default; // expected-error {{redefinition}}
X &X::operator=(const X&) = default; // expected-error {{redefinition}}
X &X::operator=(X&&) = default; // expected-error {{redefinition}}
X::~X() = default; // expected-error {{redefinition}}
struct Y {
Y() = default;
Y(const Y&) = default;
Y(Y&&) = default;
Y &operator=(const Y&) = default;
Y &operator=(Y&&) = default;
~Y() = default;
};
Y::Y() = default; // expected-error {{definition of explicitly defaulted}}
Y::Y(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
Y::Y(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
Y &Y::operator=(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
Y &Y::operator=(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
Y::~Y() = default; // expected-error {{definition of explicitly defaulted}}
}
namespace PR14577 {
template<typename T>
struct Outer {
template<typename U>
struct Inner1 {
~Inner1();
};
template<typename U>
struct Inner2 {
~Inner2();
};
};
template<typename T>
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}}
template<typename T>
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}}
}
extern "C" {
template<typename _Tp> // expected-error {{templates must have C++ linkage}}
void PR13573(const _Tp&) = delete;
}
namespace PR15597 {
template<typename T> struct A {
A() noexcept(true) = default;
~A() noexcept(true) = default;
};
template<typename T> struct B {
B() noexcept(false) = default; // expected-error {{does not match the calculated one}}
~B() noexcept(false) = default; // expected-error {{does not match the calculated one}}
};
A<int> a;
B<int> b; // expected-note {{here}}
}
|