blob: a7133d79b463f0e1cc00f891a2aed993378a850a [file] [log] [blame]
Richard Smith122f88d2016-12-06 23:52:28 +00001// RUN: %clang_cc1 -std=c++1z -verify %s
2
3struct Noncopyable {
4 Noncopyable();
Richard Smith67ef14f2017-09-26 18:37:55 +00005 Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}} expected-note 1+ {{not viable}}
Richard Smith122f88d2016-12-06 23:52:28 +00006 virtual ~Noncopyable();
7};
8struct Derived : Noncopyable {};
Richard Smith67ef14f2017-09-26 18:37:55 +00009struct NoncopyableAggr { // expected-note 3{{candidate}}
Richard Smith122f88d2016-12-06 23:52:28 +000010 Noncopyable nc;
11};
12struct Indestructible {
13 Indestructible();
14 ~Indestructible() = delete; // expected-note 1+{{deleted}}
15};
16struct Incomplete; // expected-note 1+{{declar}}
17
18Noncopyable 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
28Indestructible make_indestructible();
29Incomplete make_incomplete(); // expected-note 1+{{here}}
30
31void take(Noncopyable nc) {}
32
33Noncopyable nrvo() {
34 Noncopyable nrvo;
35 return nrvo; // expected-error {{deleted constructor}}
36}
37
38Noncopyable nc1 = make();
39Noncopyable nc2 = Noncopyable();
40Noncopyable nc3 = Derived(); // expected-error {{deleted constructor}}
Richard Smith67ef14f2017-09-26 18:37:55 +000041Noncopyable nc4((Noncopyable()));
42Noncopyable nc5 = {Noncopyable()};
43Noncopyable nc6{Noncopyable()};
Richard Smith122f88d2016-12-06 23:52:28 +000044
45NoncopyableAggr nca1 = NoncopyableAggr{};
46NoncopyableAggr nca2 = NoncopyableAggr{{}};
47NoncopyableAggr nca3 = NoncopyableAggr{NoncopyableAggr{Noncopyable()}};
48
Richard Smith67ef14f2017-09-26 18:37:55 +000049template<typename T> struct Convert { operator T(); }; // expected-note 1+{{candidate}}
50Noncopyable conv1 = Convert<Noncopyable>();
51Noncopyable conv2((Convert<Noncopyable>()));
52Noncopyable conv3 = {Convert<Noncopyable>()};
53Noncopyable conv4{Convert<Noncopyable>()};
54
55Noncopyable ref_conv1 = Convert<Noncopyable&>(); // expected-error {{deleted constructor}}
56Noncopyable ref_conv2((Convert<Noncopyable&>())); // expected-error {{deleted constructor}}
57Noncopyable ref_conv3 = {Convert<Noncopyable&>()}; // expected-error {{deleted constructor}}
58Noncopyable ref_conv4{Convert<Noncopyable&>()}; // expected-error {{deleted constructor}}
59
60Noncopyable derived_conv1 = Convert<Derived>(); // expected-error {{deleted constructor}}
61Noncopyable derived_conv2((Convert<Derived>())); // expected-error {{deleted constructor}}
62Noncopyable derived_conv3 = {Convert<Derived>()}; // expected-error {{deleted constructor}}
63Noncopyable derived_conv4{Convert<Derived>()}; // expected-error {{deleted constructor}}
64
65NoncopyableAggr nc_aggr1 = Convert<NoncopyableAggr>();
66NoncopyableAggr nc_aggr2((Convert<NoncopyableAggr>()));
67NoncopyableAggr nc_aggr3 = {Convert<NoncopyableAggr>()}; // expected-error {{no viable conversion}}
68NoncopyableAggr nc_aggr4{Convert<NoncopyableAggr>()}; // expected-error {{no viable conversion}}
69NoncopyableAggr nc_aggr5 = Convert<Noncopyable>(); // expected-error {{no viable}}
70NoncopyableAggr nc_aggr6((Convert<Noncopyable>())); // expected-error {{no matching constructor}}
71NoncopyableAggr nc_aggr7 = {Convert<Noncopyable>()};
72NoncopyableAggr nc_aggr8{Convert<Noncopyable>()};
73
Richard Smith122f88d2016-12-06 23:52:28 +000074void 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
139template<typename T> struct ConversionFunction { operator T(); };
140Noncopyable cf1 = ConversionFunction<Noncopyable>();
141Noncopyable cf2 = ConversionFunction<Noncopyable&&>(); // expected-error {{deleted}}
142Noncopyable cf3 = ConversionFunction<const volatile Noncopyable>();
143const volatile Noncopyable cf4 = ConversionFunction<Noncopyable>();
144Noncopyable cf5 = ConversionFunction<Derived>(); // expected-error {{deleted}}
145
146struct 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.
151struct AsBase : Noncopyable {
152 AsBase() : Noncopyable(make()) {} // expected-error {{deleted}}
153};
154struct AsDelegating final {
Richard Smith60a6bbe2016-12-07 00:24:40 +0000155 AsDelegating(const AsDelegating &) = delete; // expected-note {{deleted}}
Richard Smith122f88d2016-12-06 23:52:28 +0000156 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};
Richard Smith51731362017-11-01 01:37:11 +0000163
164namespace 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}