1 // RUN: %clang_cc1 -std=c++1z -verify -Wno-unused %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 
make(int kind=0)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 
take(Noncopyable nc)31 void take(Noncopyable nc) {}
32 
nrvo()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 
test_expressions(bool b)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}} expected-error {{you need to include <typeinfo>}}
110   typeid(make_indestructible()); // expected-error {{deleted}} \
111                                  // expected-error {{need to include <typeinfo>}}
112   typeid(make_incomplete()); // expected-error {{incomplete}} \
113                              // expected-error {{need to include <typeinfo>}}
114 
115   // FIXME: The first two cases here are now also valid in C++17 onwards.
116   using I = decltype(Indestructible()); // expected-error {{deleted}}
117   using I = decltype(Indestructible{}); // expected-error {{deleted}}
118   using I = decltype(make_indestructible());
119   using J = decltype(make_incomplete());
120 
121   Noncopyable cond1 = b ? Noncopyable() : make();
122   Noncopyable cond2 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}}
123   Noncopyable cond3 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}}
124   Noncopyable cond4 = b ? Noncopyable() : nc1; // expected-error {{deleted}}
125   Noncopyable cond5 = b ? nc1 : Noncopyable(); // expected-error {{deleted}}
126   // Could convert both to an xvalue of type Noncopyable here, but we're not
127   // permitted to consider that.
128   Noncopyable &&cond6 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}}
129   Noncopyable &&cond7 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}}
130   // Could convert both to a const lvalue of type Noncopyable here, but we're
131   // not permitted to consider that, either.
132   const Noncopyable cnc;
133   const Noncopyable &cond8 = b ? cnc : Derived(); // expected-error {{incompatible}}
134   const Noncopyable &cond9 = b ? Derived() : cnc; // expected-error {{incompatible}}
135 
136   extern const volatile Noncopyable make_cv();
137   Noncopyable cv_difference1 = make_cv();
138   const volatile Noncopyable cv_difference2 = make();
139 }
140 
141 template<typename T> struct ConversionFunction { operator T(); };
142 Noncopyable cf1 = ConversionFunction<Noncopyable>();
143 Noncopyable cf2 = ConversionFunction<Noncopyable&&>(); // expected-error {{deleted}}
144 Noncopyable cf3 = ConversionFunction<const volatile Noncopyable>();
145 const volatile Noncopyable cf4 = ConversionFunction<Noncopyable>();
146 Noncopyable cf5 = ConversionFunction<Derived>(); // expected-error {{deleted}}
147 
148 struct AsMember {
149   Noncopyable member;
AsMemberAsMember150   AsMember() : member(make()) {}
151 };
152 // FIXME: DR (no number yet): we still get a copy for base or delegating construction.
153 struct AsBase : Noncopyable {
AsBaseAsBase154   AsBase() : Noncopyable(make()) {} // expected-error {{deleted}}
155 };
156 struct AsDelegating final {
157   AsDelegating(const AsDelegating &) = delete; // expected-note {{deleted}}
158   static AsDelegating make(int);
159 
160   // The base constructor version of this is problematic; the complete object
161   // version would be OK. Perhaps we could allow copy omission here for final
162   // classes?
AsDelegatingAsDelegating163   AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}}
164 };
165 
166 namespace CtorTemplateBeatsNonTemplateConversionFn {
167   struct Foo { template <typename Derived> Foo(const Derived &); };
168   template <typename Derived> struct Base { operator Foo() const = delete; }; // expected-note {{deleted}}
169   struct Derived : Base<Derived> {};
170 
f(Derived d)171   Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}}
g(Derived d)172   Foo g(Derived d) { return Foo(d); } // ok, calls constructor
173 }
174