1 | // RUN: %clang_cc1 -std=c++1z -verify %s |
2 | |
3 | struct Noncopyable { |
4 | Noncopyable(); |
5 | Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}} expected-note 1+ {{not viable}} |
6 | virtual ~Noncopyable(); |
7 | }; |
8 | struct Derived : Noncopyable {}; |
9 | struct NoncopyableAggr { // expected-note 3{{candidate}} |
10 | Noncopyable nc; |
11 | }; |
12 | struct Indestructible { |
13 | Indestructible(); |
14 | ~Indestructible() = delete; // expected-note 1+{{deleted}} |
15 | }; |
16 | struct Incomplete; // expected-note 1+{{declar}} |
17 | |
18 | Noncopyable make(int kind = 0) { |
19 | switch (kind) { |
20 | case 0: return {}; |
21 | case 1: return Noncopyable(); |
22 | case 2: return Noncopyable{}; |
23 | case 3: return make(); |
24 | } |
25 | __builtin_unreachable(); |
26 | } |
27 | |
28 | Indestructible make_indestructible(); |
29 | Incomplete make_incomplete(); // expected-note 1+{{here}} |
30 | |
31 | void take(Noncopyable nc) {} |
32 | |
33 | Noncopyable nrvo() { |
34 | Noncopyable nrvo; |
35 | return nrvo; // expected-error {{deleted constructor}} |
36 | } |
37 | |
38 | Noncopyable nc1 = make(); |
39 | Noncopyable nc2 = Noncopyable(); |
40 | Noncopyable nc3 = Derived(); // expected-error {{deleted constructor}} |
41 | Noncopyable nc4((Noncopyable())); |
42 | Noncopyable nc5 = {Noncopyable()}; |
43 | Noncopyable nc6{Noncopyable()}; |
44 | |
45 | NoncopyableAggr nca1 = NoncopyableAggr{}; |
46 | NoncopyableAggr nca2 = NoncopyableAggr{{}}; |
47 | NoncopyableAggr nca3 = NoncopyableAggr{NoncopyableAggr{Noncopyable()}}; |
48 | |
49 | template<typename T> struct Convert { operator T(); }; // expected-note 1+{{candidate}} |
50 | Noncopyable conv1 = Convert<Noncopyable>(); |
51 | Noncopyable conv2((Convert<Noncopyable>())); |
52 | Noncopyable conv3 = {Convert<Noncopyable>()}; |
53 | Noncopyable conv4{Convert<Noncopyable>()}; |
54 | |
55 | Noncopyable ref_conv1 = Convert<Noncopyable&>(); // expected-error {{deleted constructor}} |
56 | Noncopyable ref_conv2((Convert<Noncopyable&>())); // expected-error {{deleted constructor}} |
57 | Noncopyable ref_conv3 = {Convert<Noncopyable&>()}; // expected-error {{deleted constructor}} |
58 | Noncopyable ref_conv4{Convert<Noncopyable&>()}; // expected-error {{deleted constructor}} |
59 | |
60 | Noncopyable derived_conv1 = Convert<Derived>(); // expected-error {{deleted constructor}} |
61 | Noncopyable derived_conv2((Convert<Derived>())); // expected-error {{deleted constructor}} |
62 | Noncopyable derived_conv3 = {Convert<Derived>()}; // expected-error {{deleted constructor}} |
63 | Noncopyable derived_conv4{Convert<Derived>()}; // expected-error {{deleted constructor}} |
64 | |
65 | NoncopyableAggr nc_aggr1 = Convert<NoncopyableAggr>(); |
66 | NoncopyableAggr nc_aggr2((Convert<NoncopyableAggr>())); |
67 | NoncopyableAggr nc_aggr3 = {Convert<NoncopyableAggr>()}; // expected-error {{no viable conversion}} |
68 | NoncopyableAggr nc_aggr4{Convert<NoncopyableAggr>()}; // expected-error {{no viable conversion}} |
69 | NoncopyableAggr nc_aggr5 = Convert<Noncopyable>(); // expected-error {{no viable}} |
70 | NoncopyableAggr nc_aggr6((Convert<Noncopyable>())); // expected-error {{no matching constructor}} |
71 | NoncopyableAggr nc_aggr7 = {Convert<Noncopyable>()}; |
72 | NoncopyableAggr nc_aggr8{Convert<Noncopyable>()}; |
73 | |
74 | void test_expressions(bool b) { |
75 | auto lambda = [a = make()] {}; |
76 | |
77 | take({}); |
78 | take(Noncopyable()); |
79 | take(Noncopyable{}); |
80 | take(make()); |
81 | |
82 | Noncopyable &&dc1 = dynamic_cast<Noncopyable&&>(Noncopyable()); |
83 | Noncopyable &&dc2 = dynamic_cast<Noncopyable&&>(nc1); |
84 | Noncopyable &&dc3 = dynamic_cast<Noncopyable&&>(Derived()); |
85 | |
86 | Noncopyable sc1 = static_cast<Noncopyable>(Noncopyable()); |
87 | Noncopyable sc2 = static_cast<Noncopyable>(nc1); // expected-error {{deleted}} |
88 | Noncopyable sc3 = static_cast<Noncopyable&&>(Noncopyable()); // expected-error {{deleted}} |
89 | Noncopyable sc4 = static_cast<Noncopyable>(static_cast<Noncopyable&&>(Noncopyable())); // expected-error {{deleted}} |
90 | |
91 | Noncopyable cc1 = (Noncopyable)Noncopyable(); |
92 | Noncopyable cc2 = (Noncopyable)Derived(); // expected-error {{deleted}} |
93 | |
94 | Noncopyable fc1 = Noncopyable(Noncopyable()); |
95 | Noncopyable fc2 = Noncopyable(Derived()); // expected-error {{deleted}} |
96 | |
97 | // We must check for a complete type for every materialized temporary. (Note |
98 | // that in the special case of the top level of a decltype, no temporary is |
99 | // materialized.) |
100 | make_incomplete(); // expected-error {{incomplete}} |
101 | make_incomplete().a; // expected-error {{incomplete}} |
102 | make_incomplete().*(int Incomplete::*)nullptr; // expected-error {{incomplete}} |
103 | dynamic_cast<Incomplete&&>(make_incomplete()); // expected-error {{incomplete}} |
104 | const_cast<Incomplete&&>(make_incomplete()); // expected-error {{incomplete}} |
105 | |
106 | sizeof(Indestructible{}); // expected-error {{deleted}} |
107 | sizeof(make_indestructible()); // expected-error {{deleted}} |
108 | sizeof(make_incomplete()); // expected-error {{incomplete}} |
109 | typeid(Indestructible{}); // expected-error {{deleted}} |
110 | typeid(make_indestructible()); // expected-error {{deleted}} |
111 | typeid(make_incomplete()); // expected-error {{incomplete}} |
112 | |
113 | // FIXME: The first two cases here are now also valid in C++17 onwards. |
114 | using I = decltype(Indestructible()); // expected-error {{deleted}} |
115 | using I = decltype(Indestructible{}); // expected-error {{deleted}} |
116 | using I = decltype(make_indestructible()); |
117 | using J = decltype(make_incomplete()); |
118 | |
119 | Noncopyable cond1 = b ? Noncopyable() : make(); |
120 | Noncopyable cond2 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}} |
121 | Noncopyable cond3 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}} |
122 | Noncopyable cond4 = b ? Noncopyable() : nc1; // expected-error {{deleted}} |
123 | Noncopyable cond5 = b ? nc1 : Noncopyable(); // expected-error {{deleted}} |
124 | // Could convert both to an xvalue of type Noncopyable here, but we're not |
125 | // permitted to consider that. |
126 | Noncopyable &&cond6 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}} |
127 | Noncopyable &&cond7 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}} |
128 | // Could convert both to a const lvalue of type Noncopyable here, but we're |
129 | // not permitted to consider that, either. |
130 | const Noncopyable cnc; |
131 | const Noncopyable &cond8 = b ? cnc : Derived(); // expected-error {{incompatible}} |
132 | const Noncopyable &cond9 = b ? Derived() : cnc; // expected-error {{incompatible}} |
133 | |
134 | extern const volatile Noncopyable make_cv(); |
135 | Noncopyable cv_difference1 = make_cv(); |
136 | const volatile Noncopyable cv_difference2 = make(); |
137 | } |
138 | |
139 | template<typename T> struct ConversionFunction { operator T(); }; |
140 | Noncopyable cf1 = ConversionFunction<Noncopyable>(); |
141 | Noncopyable cf2 = ConversionFunction<Noncopyable&&>(); // expected-error {{deleted}} |
142 | Noncopyable cf3 = ConversionFunction<const volatile Noncopyable>(); |
143 | const volatile Noncopyable cf4 = ConversionFunction<Noncopyable>(); |
144 | Noncopyable cf5 = ConversionFunction<Derived>(); // expected-error {{deleted}} |
145 | |
146 | struct AsMember { |
147 | Noncopyable member; |
148 | AsMember() : member(make()) {} |
149 | }; |
150 | // FIXME: DR (no number yet): we still get a copy for base or delegating construction. |
151 | struct AsBase : Noncopyable { |
152 | AsBase() : Noncopyable(make()) {} // expected-error {{deleted}} |
153 | }; |
154 | struct AsDelegating final { |
155 | AsDelegating(const AsDelegating &) = delete; // expected-note {{deleted}} |
156 | static AsDelegating make(int); |
157 | |
158 | // The base constructor version of this is problematic; the complete object |
159 | // version would be OK. Perhaps we could allow copy omission here for final |
160 | // classes? |
161 | AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}} |
162 | }; |
163 | |
164 | namespace CtorTemplateBeatsNonTemplateConversionFn { |
165 | struct Foo { template <typename Derived> Foo(const Derived &); }; |
166 | template <typename Derived> struct Base { operator Foo() const = delete; }; // expected-note {{deleted}} |
167 | struct Derived : Base<Derived> {}; |
168 | |
169 | Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}} |
170 | Foo g(Derived d) { return Foo(d); } // ok, calls constructor |
171 | } |
172 | |