blob: e2b8fd7961740915db8bbb3ee52395962d022e66 [file] [log] [blame]
Richard Smith122f88d2016-12-06 23:52:28 +00001// RUN: %clang_cc1 -std=c++1z -verify %s
2
3struct Noncopyable {
4 Noncopyable();
5 Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}}
6 virtual ~Noncopyable();
7};
8struct Derived : Noncopyable {};
9struct NoncopyableAggr {
10 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}}
41
42NoncopyableAggr nca1 = NoncopyableAggr{};
43NoncopyableAggr nca2 = NoncopyableAggr{{}};
44NoncopyableAggr nca3 = NoncopyableAggr{NoncopyableAggr{Noncopyable()}};
45
46void test_expressions(bool b) {
47 auto lambda = [a = make()] {};
48
49 take({});
50 take(Noncopyable());
51 take(Noncopyable{});
52 take(make());
53
54 Noncopyable &&dc1 = dynamic_cast<Noncopyable&&>(Noncopyable());
55 Noncopyable &&dc2 = dynamic_cast<Noncopyable&&>(nc1);
56 Noncopyable &&dc3 = dynamic_cast<Noncopyable&&>(Derived());
57
58 Noncopyable sc1 = static_cast<Noncopyable>(Noncopyable());
59 Noncopyable sc2 = static_cast<Noncopyable>(nc1); // expected-error {{deleted}}
60 Noncopyable sc3 = static_cast<Noncopyable&&>(Noncopyable()); // expected-error {{deleted}}
61 Noncopyable sc4 = static_cast<Noncopyable>(static_cast<Noncopyable&&>(Noncopyable())); // expected-error {{deleted}}
62
63 Noncopyable cc1 = (Noncopyable)Noncopyable();
64 Noncopyable cc2 = (Noncopyable)Derived(); // expected-error {{deleted}}
65
66 Noncopyable fc1 = Noncopyable(Noncopyable());
67 Noncopyable fc2 = Noncopyable(Derived()); // expected-error {{deleted}}
68
69 // We must check for a complete type for every materialized temporary. (Note
70 // that in the special case of the top level of a decltype, no temporary is
71 // materialized.)
72 make_incomplete(); // expected-error {{incomplete}}
73 make_incomplete().a; // expected-error {{incomplete}}
74 make_incomplete().*(int Incomplete::*)nullptr; // expected-error {{incomplete}}
75 dynamic_cast<Incomplete&&>(make_incomplete()); // expected-error {{incomplete}}
76 const_cast<Incomplete&&>(make_incomplete()); // expected-error {{incomplete}}
77
78 sizeof(Indestructible{}); // expected-error {{deleted}}
79 sizeof(make_indestructible()); // expected-error {{deleted}}
80 sizeof(make_incomplete()); // expected-error {{incomplete}}
81 typeid(Indestructible{}); // expected-error {{deleted}}
82 typeid(make_indestructible()); // expected-error {{deleted}}
83 typeid(make_incomplete()); // expected-error {{incomplete}}
84
85 // FIXME: The first two cases here are now also valid in C++17 onwards.
86 using I = decltype(Indestructible()); // expected-error {{deleted}}
87 using I = decltype(Indestructible{}); // expected-error {{deleted}}
88 using I = decltype(make_indestructible());
89 using J = decltype(make_incomplete());
90
91 Noncopyable cond1 = b ? Noncopyable() : make();
92 Noncopyable cond2 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}}
93 Noncopyable cond3 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}}
94 Noncopyable cond4 = b ? Noncopyable() : nc1; // expected-error {{deleted}}
95 Noncopyable cond5 = b ? nc1 : Noncopyable(); // expected-error {{deleted}}
96 // Could convert both to an xvalue of type Noncopyable here, but we're not
97 // permitted to consider that.
98 Noncopyable &&cond6 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}}
99 Noncopyable &&cond7 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}}
100 // Could convert both to a const lvalue of type Noncopyable here, but we're
101 // not permitted to consider that, either.
102 const Noncopyable cnc;
103 const Noncopyable &cond8 = b ? cnc : Derived(); // expected-error {{incompatible}}
104 const Noncopyable &cond9 = b ? Derived() : cnc; // expected-error {{incompatible}}
105
106 extern const volatile Noncopyable make_cv();
107 Noncopyable cv_difference1 = make_cv();
108 const volatile Noncopyable cv_difference2 = make();
109}
110
111template<typename T> struct ConversionFunction { operator T(); };
112Noncopyable cf1 = ConversionFunction<Noncopyable>();
113Noncopyable cf2 = ConversionFunction<Noncopyable&&>(); // expected-error {{deleted}}
114Noncopyable cf3 = ConversionFunction<const volatile Noncopyable>();
115const volatile Noncopyable cf4 = ConversionFunction<Noncopyable>();
116Noncopyable cf5 = ConversionFunction<Derived>(); // expected-error {{deleted}}
117
118struct AsMember {
119 Noncopyable member;
120 AsMember() : member(make()) {}
121};
122// FIXME: DR (no number yet): we still get a copy for base or delegating construction.
123struct AsBase : Noncopyable {
124 AsBase() : Noncopyable(make()) {} // expected-error {{deleted}}
125};
126struct AsDelegating final {
Richard Smith60a6bbe2016-12-07 00:24:40 +0000127 AsDelegating(const AsDelegating &) = delete; // expected-note {{deleted}}
Richard Smith122f88d2016-12-06 23:52:28 +0000128 static AsDelegating make(int);
129
130 // The base constructor version of this is problematic; the complete object
131 // version would be OK. Perhaps we could allow copy omission here for final
132 // classes?
133 AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}}
134};