1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s |
2 | |
3 | // An explicitly-defaulted function may be declared constexpr only if it would |
4 | // have been implicitly declared as constexpr. |
5 | struct S1 { |
6 | constexpr S1() = default; // expected-error {{defaulted definition of default constructor is not constexpr}} |
7 | constexpr S1(const S1&) = default; |
8 | constexpr S1(S1&&) = default; |
9 | constexpr S1 &operator=(const S1&) const = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}} |
10 | constexpr S1 &operator=(S1&&) const = default; // expected-error {{explicitly-defaulted move assignment operator may not have}} |
11 | constexpr ~S1() = default; // expected-error {{destructor cannot be marked constexpr}} |
12 | int n; |
13 | }; |
14 | struct NoCopyMove { |
15 | constexpr NoCopyMove() {} |
16 | NoCopyMove(const NoCopyMove&); |
17 | NoCopyMove(NoCopyMove&&); |
18 | }; |
19 | struct S2 { |
20 | constexpr S2() = default; |
21 | constexpr S2(const S2&) = default; // expected-error {{defaulted definition of copy constructor is not constexpr}} |
22 | constexpr S2(S2&&) = default; // expected-error {{defaulted definition of move constructor is not constexpr}} |
23 | NoCopyMove ncm; |
24 | }; |
25 | |
26 | // If a function is explicitly defaulted on its first declaration |
27 | // -- it is implicitly considered to be constexpr if the implicit declaration |
28 | // would be |
29 | struct S3 { |
30 | S3() = default; |
31 | S3(const S3&) = default; |
32 | S3(S3&&) = default; |
33 | constexpr S3(int n) : n(n) {} |
34 | int n; |
35 | }; |
36 | constexpr S3 s3a = S3(0); |
37 | constexpr S3 s3b = s3a; |
38 | constexpr S3 s3c = S3(); |
39 | constexpr S3 s3d; // expected-error {{default initialization of an object of const type 'const S3' without a user-provided default constructor}} |
40 | |
41 | struct S4 { |
42 | S4() = default; |
43 | S4(const S4&) = default; // expected-note {{here}} |
44 | S4(S4&&) = default; // expected-note {{here}} |
45 | NoCopyMove ncm; |
46 | }; |
47 | constexpr S4 s4a{}; // ok |
48 | constexpr S4 s4b = S4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} |
49 | constexpr S4 s4c = s4a; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} |
50 | |
51 | struct S5 { |
52 | constexpr S5(); |
53 | int n = 1, m = n + 3; |
54 | }; |
55 | constexpr S5::S5() = default; |
56 | static_assert(S5().m == 4, ""); |
57 | |
58 | |
59 | // An explicitly-defaulted function may have an exception specification only if |
60 | // it is compatible with the exception specification on an implicit declaration. |
61 | struct E1 { |
62 | E1() noexcept = default; |
63 | E1(const E1&) noexcept = default; |
64 | E1(E1&&) noexcept = default; |
65 | E1 &operator=(const E1&) noexcept = default; |
66 | E1 &operator=(E1&&) noexcept = default; |
67 | ~E1() noexcept = default; |
68 | }; |
69 | struct E2 { |
70 | E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}} |
71 | E2(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy constructor does not match the calculated one}} |
72 | E2(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move constructor does not match the calculated one}} |
73 | E2 &operator=(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy assignment operator does not match the calculated one}} |
74 | E2 &operator=(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move assignment operator does not match the calculated one}} |
75 | ~E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted destructor does not match the calculated one}} |
76 | }; |
77 | |
78 | // If a function is explicitly defaulted on its first declaration |
79 | // -- it is implicitly considered to have the same exception-specification as |
80 | // if it had been implicitly declared |
81 | struct E3 { |
82 | E3() = default; |
83 | E3(const E3&) = default; |
84 | E3(E3&&) = default; |
85 | E3 &operator=(const E3&) = default; |
86 | E3 &operator=(E3&&) = default; |
87 | ~E3() = default; |
88 | }; |
89 | E3 e3; |
90 | static_assert(noexcept(E3(), E3(E3()), E3(e3), e3 = E3(), e3 = e3), ""); |
91 | struct E4 { |
92 | E4() noexcept(false); |
93 | E4(const E4&) noexcept(false); |
94 | E4(E4&&) noexcept(false); |
95 | E4 &operator=(const E4&) noexcept(false); |
96 | E4 &operator=(E4&&) noexcept(false); |
97 | ~E4() noexcept(false); |
98 | }; |
99 | struct E5 { |
100 | E5() = default; |
101 | E5(const E5&) = default; |
102 | E5(E5&&) = default; |
103 | E5 &operator=(const E5&) = default; |
104 | E5 &operator=(E5&&) = default; |
105 | ~E5() = default; |
106 | |
107 | E4 e4; |
108 | }; |
109 | E5 e5; |
110 | static_assert(!noexcept(E5()), ""); |
111 | static_assert(!noexcept(E5(static_cast<E5&&>(e5))), ""); |
112 | static_assert(!noexcept(E5(e5)), ""); |
113 | static_assert(!noexcept(e5 = E5()), ""); |
114 | static_assert(!noexcept(e5 = e5), ""); |
115 | |
116 | namespace PR13492 { |
117 | struct B { |
118 | B() = default; |
119 | int field; |
120 | }; |
121 | |
122 | void f() { |
123 | const B b; // expected-error {{default initialization of an object of const type 'const PR13492::B' without a user-provided default constructor}} |
124 | } |
125 | } |
126 | |