[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaObjCXX / arc-0x.mm
blobac788686a7374aa8d329b4df364dad8b8fe557b8
1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -fobjc-weak -verify -fblocks -fobjc-exceptions %s
3 // "Move" semantics, trivial version.
4 void move_it(__strong id &&from) {
5   id to = static_cast<__strong id&&>(from);
8 // Deduction with 'auto'.
9 @interface A
10 + alloc;
11 - init;
12 @end
14 // don't warn about this
15 extern "C" A* MakeA();
17 // Ensure that deduction works with lifetime qualifiers.
18 void deduction(id obj) {
19   auto a = [[A alloc] init];
20   __strong A** aPtr = &a;
22   auto a2([[A alloc] init]);
23   __strong A** aPtr2 = &a2;
25   __strong id *idp = new auto(obj);
27   __strong id array[17];
28   for (auto x : array) { // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}}
29     __strong id *xPtr = &x;
30   }
32   @try {
33   } @catch (auto e) { // expected-error {{'auto' not allowed in exception declaration}}
34   }
37 void test1a() {
38   __autoreleasing id p; // expected-note 2 {{'p' declared here}}
39   (void) [&p] {};
40   (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
41   (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
43 void test1b() {
44   __autoreleasing id v;
45   __autoreleasing id &p = v; // expected-note 2 {{'p' declared here}}
46   (void) [&p] {};
47   (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
48   (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
50 void test1c() {
51   __autoreleasing id v; // expected-note {{'v' declared here}}
52   __autoreleasing id &p = v;
53   (void) ^{ (void) p; };
54   (void) ^{ (void) v; }; // expected-error {{cannot capture __autoreleasing variable in a block}}
57 // warn when initializing an 'auto' variable with an 'id' initializer expression
59 void testAutoId(id obj) {
60   auto x = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}}
63 @interface Array
64 + (instancetype)new;
65 - (id)objectAtIndex:(int)index;
66 @end
68 // ...but don't warn if it's coming from a template parameter.
69 template<typename T, int N>
70 void autoTemplateFunction(T param, id obj, Array *arr) {
71   auto x = param; // no-warning
72   auto y = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'y'}}
73   auto z = [arr objectAtIndex:N]; // expected-warning{{'auto' deduced as 'id' in declaration of 'z'}}
76 void testAutoIdTemplate(id obj) {
77   autoTemplateFunction<id, 2>(obj, obj, [Array new]); // no-warning
80 @interface NSObject @end
81 typedef __builtin_va_list va_list;
82 @interface MyClass : NSObject
83 @end
85 @implementation MyClass
86 + (void)fooMethod:(id)firstArg, ... {
87     va_list args;
89     __builtin_va_arg(args, id);
91 @end
93 namespace rdar12078752 {
94   void f() {
95     NSObject* o =0;
96     __autoreleasing decltype(o) o2 = o;
97     __autoreleasing auto o3 = o;
98   }
101 namespace test_err_arc_array_param_no_ownership {
102   template <class T>
103   void func(T a) {}
105   void test() {
106     func([](A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
107     func(^(A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
108   }
111 namespace test_union {
112   // Implicitly-declared special functions of a union are deleted by default if
113   // ARC is enabled and the union has an ObjC pointer field.
114   union U0 {
115     id f0; // expected-note 6 {{'U0' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
116   };
118   union U1 {
119     __weak id f0; // expected-note 12 {{'U1' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
120     U1() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}} expected-note{{replace 'default'}}
121     ~U1() = default; // expected-warning {{explicitly defaulted destructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}} expected-note{{replace 'default'}}
122     U1(const U1 &) = default; // expected-warning {{explicitly defaulted copy constructor is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}} expected-note{{replace 'default'}}
123     U1(U1 &&) = default; // expected-warning {{explicitly defaulted move constructor is implicitly deleted}} expected-note{{replace 'default'}}
124     U1 & operator=(const U1 &) = default; // expected-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}} expected-note{{replace 'default'}}
125     U1 & operator=(U1 &&) = default; // expected-warning {{explicitly defaulted move assignment operator is implicitly deleted}} expected-note{{replace 'default'}}
126   };
128   id getStrong();
130   // If the ObjC pointer field of a union has a default member initializer, the
131   // implicitly-declared default constructor of the union is not deleted by
132   // default.
133   union U2 {
134     id f0 = getStrong(); // expected-note 4 {{'U2' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
135     ~U2();
136   };
138   // It's fine if the user has explicitly defined the special functions.
139   union U3 {
140     id f0;
141     U3();
142     ~U3();
143     U3(const U3 &);
144     U3(U3 &&);
145     U3 & operator=(const U3 &);
146     U3 & operator=(U3 &&);
147   };
149   // ObjC pointer fields in anonymous union fields delete the defaulted special
150   // functions of the containing class.
151   struct S0 {
152     union {
153       id f0; // expected-note-re 6 {{{{.*}} of '(anonymous union at {{.*}})' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
154       char f1;
155     };
156   };
158   struct S1 {
159     union {
160       union { // expected-note-re {{copy constructor of 'S1' is implicitly deleted because field 'test_union::S1::(anonymous union at {{.*}})' has a deleted copy constructor}} expected-note-re {{copy assignment operator of 'S1' is implicitly deleted because field 'test_union::S1::(anonymous union at {{.*}})' has a deleted copy assignment operator}} expected-note-re 4 {{'S1' is implicitly deleted because field 'test_union::S1::(anonymous union at {{.*}})' has a deleted}}
161         id f0; // expected-note-re 2 {{{{.*}} of '(anonymous union at {{.*}}' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
162         char f1;
163       };
164       int f2;
165     };
166   };
168   struct S2 {
169     union {
170       // FIXME: the note should say 'f0' is causing the special functions to be deleted.
171       struct { // expected-note-re 6 {{'S2' is implicitly deleted because variant field 'test_union::S2::(anonymous struct at {{.*}})' has a non-trivial}}
172         id f0;
173         int f1;
174       };
175       int f2;
176     };
177     int f3;
178   };
180   U0 *x0;
181   U1 *x1;
182   U2 *x2;
183   U3 *x3;
184   S0 *x4;
185   S1 *x5;
186   S2 *x6;
188   static union { // expected-error {{call to implicitly-deleted default constructor of}}
189     id g0; // expected-note-re {{default constructor of '(unnamed union at {{.*}}' is implicitly deleted because variant field 'g0' is an ObjC pointer}}
190   };
192   static union { // expected-error {{call to implicitly-deleted default constructor of}}
193     union { // expected-note-re {{default constructor of '(unnamed union at {{.*}}' is implicitly deleted because field 'test_union::(anonymous union at {{.*}})' has a deleted default constructor}}
194       union { // expected-note-re {{default constructor of '(anonymous union at {{.*}}' is implicitly deleted because field 'test_union::(anonymous union at {{.*}})' has a deleted default constructor}}
195         __weak id g1; // expected-note-re {{default constructor of '(anonymous union at {{.*}}' is implicitly deleted because variant field 'g1' is an ObjC pointer}}
196         int g2;
197       };
198       int g3;
199     };
200     int g4;
201   };
203   void testDefaultConstructor() {
204     U0 t0; // expected-error {{call to implicitly-deleted default constructor}}
205     U1 t1; // expected-error {{call to implicitly-deleted default constructor}}
206     U2 t2;
207     U3 t3;
208     S0 t4; // expected-error {{call to implicitly-deleted default constructor}}
209     S1 t5; // expected-error {{call to implicitly-deleted default constructor}}
210     S2 t6; // expected-error {{call to implicitly-deleted default constructor}}
211   }
213   void testDestructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
214     delete u0; // expected-error {{attempt to use a deleted function}}
215     delete u1; // expected-error {{attempt to use a deleted function}}
216     delete u2;
217     delete u3;
218     delete s0; // expected-error {{attempt to use a deleted function}}
219     delete s1; // expected-error {{attempt to use a deleted function}}
220     delete s2; // expected-error {{attempt to use a deleted function}}
221   }
223   void testCopyConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
224     U0 t0(*u0); // expected-error {{call to implicitly-deleted copy constructor}}
225     U1 t1(*u1); // expected-error {{call to implicitly-deleted copy constructor}}
226     U2 t2(*u2); // expected-error {{call to implicitly-deleted copy constructor}}
227     U3 t3(*u3);
228     S0 t4(*s0); // expected-error {{call to implicitly-deleted copy constructor}}
229     S1 t5(*s1); // expected-error {{call to implicitly-deleted copy constructor}}
230     S2 t6(*s2); // expected-error {{call to implicitly-deleted copy constructor}}
231   }
233   void testCopyAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
234     *x0 = *u0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
235     *x1 = *u1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
236     *x2 = *u2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
237     *x3 = *u3;
238     *x4 = *s0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
239     *x5 = *s1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
240     *x6 = *s2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
241   }
243   // The diagnostics below refer to the deleted copy constructors and assignment
244   // operators since defaulted move constructors and assignment operators that are
245   // defined as deleted are ignored by overload resolution.
247   void testMoveConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
248     U0 t0(static_cast<U0 &&>(*u0)); // expected-error {{call to implicitly-deleted copy constructor}}
249     U1 t1(static_cast<U1 &&>(*u1)); // expected-error {{call to implicitly-deleted copy constructor}}
250     U2 t2(static_cast<U2 &&>(*u2)); // expected-error {{call to implicitly-deleted copy constructor}}
251     U3 t3(static_cast<U3 &&>(*u3));
252     S0 t4(static_cast<S0 &&>(*s0)); // expected-error {{call to implicitly-deleted copy constructor}}
253     S1 t5(static_cast<S1 &&>(*s1)); // expected-error {{call to implicitly-deleted copy constructor}}
254     S2 t6(static_cast<S2 &&>(*s2)); // expected-error {{call to implicitly-deleted copy constructor}}
255   }
257   void testMoveAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
258     *x0 = static_cast<U0 &&>(*u0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
259     *x1 = static_cast<U1 &&>(*u1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
260     *x2 = static_cast<U2 &&>(*u2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
261     *x3 = static_cast<U3 &&>(*u3);
262     *x4 = static_cast<S0 &&>(*s0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
263     *x5 = static_cast<S1 &&>(*s1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
264     *x6 = static_cast<S2 &&>(*s2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
265   }