llvm-project
266 строк · 11.7 Кб
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -fobjc-weak -verify -fblocks -fobjc-exceptions %s
2
3// "Move" semantics, trivial version.
4void move_it(__strong id &&from) {
5id to = static_cast<__strong id&&>(from);
6}
7
8// Deduction with 'auto'.
9@interface A
10+ alloc;
11- init;
12@end
13
14// don't warn about this
15extern "C" A* MakeA();
16
17// Ensure that deduction works with lifetime qualifiers.
18void deduction(id obj) {
19auto a = [[A alloc] init];
20__strong A** aPtr = &a;
21
22auto a2([[A alloc] init]);
23__strong A** aPtr2 = &a2;
24
25__strong id *idp = new auto(obj);
26
27__strong id array[17];
28for (auto x : array) { // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}}
29__strong id *xPtr = &x;
30}
31
32@try {
33} @catch (auto e) { // expected-error {{'auto' not allowed in exception declaration}}
34}
35}
36
37void 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}}
42}
43void 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}}
49}
50void 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}}
55}
56
57// warn when initializing an 'auto' variable with an 'id' initializer expression
58
59void testAutoId(id obj) {
60auto x = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}}
61}
62
63@interface Array
64+ (instancetype)new;
65- (id)objectAtIndex:(int)index;
66@end
67
68// ...but don't warn if it's coming from a template parameter.
69template<typename T, int N>
70void autoTemplateFunction(T param, id obj, Array *arr) {
71auto x = param; // no-warning
72auto y = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'y'}}
73auto z = [arr objectAtIndex:N]; // expected-warning{{'auto' deduced as 'id' in declaration of 'z'}}
74}
75
76void testAutoIdTemplate(id obj) {
77autoTemplateFunction<id, 2>(obj, obj, [Array new]); // no-warning
78}
79
80@interface NSObject @end
81typedef __builtin_va_list va_list;
82@interface MyClass : NSObject
83@end
84
85@implementation MyClass
86+ (void)fooMethod:(id)firstArg, ... {
87va_list args;
88
89__builtin_va_arg(args, id);
90}
91@end
92
93namespace rdar12078752 {
94void f() {
95NSObject* o =0;
96__autoreleasing decltype(o) o2 = o;
97__autoreleasing auto o3 = o;
98}
99}
100
101namespace test_err_arc_array_param_no_ownership {
102template <class T>
103void func(T a) {}
104
105void test() {
106func([](A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
107func(^(A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
108}
109}
110
111namespace 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.
114union U0 {
115id f0; // expected-note 6 {{'U0' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
116};
117
118union U1 {
119__weak id f0; // expected-note 12 {{'U1' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
120U1() = 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'}}
122U1(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'}}
123U1(U1 &&) = default; // expected-warning {{explicitly defaulted move constructor is implicitly deleted}} expected-note{{replace 'default'}}
124U1 & 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'}}
125U1 & operator=(U1 &&) = default; // expected-warning {{explicitly defaulted move assignment operator is implicitly deleted}} expected-note{{replace 'default'}}
126};
127
128id getStrong();
129
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.
133union U2 {
134id f0 = getStrong(); // expected-note 4 {{'U2' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
135~U2();
136};
137
138// It's fine if the user has explicitly defined the special functions.
139union U3 {
140id f0;
141U3();
142~U3();
143U3(const U3 &);
144U3(U3 &&);
145U3 & operator=(const U3 &);
146U3 & operator=(U3 &&);
147};
148
149// ObjC pointer fields in anonymous union fields delete the defaulted special
150// functions of the containing class.
151struct S0 {
152union {
153id f0; // expected-note-re 6 {{{{.*}} of '(anonymous union at {{.*}})' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
154char f1;
155};
156};
157
158struct S1 {
159union {
160union { // 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}}
161id f0; // expected-note-re 2 {{{{.*}} of '(anonymous union at {{.*}}' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
162char f1;
163};
164int f2;
165};
166};
167
168struct S2 {
169union {
170// FIXME: the note should say 'f0' is causing the special functions to be deleted.
171struct { // expected-note-re 6 {{'S2' is implicitly deleted because variant field 'test_union::S2::(anonymous struct at {{.*}})' has a non-trivial}}
172id f0;
173int f1;
174};
175int f2;
176};
177int f3;
178};
179
180U0 *x0;
181U1 *x1;
182U2 *x2;
183U3 *x3;
184S0 *x4;
185S1 *x5;
186S2 *x6;
187
188static union { // expected-error {{call to implicitly-deleted default constructor of}}
189id g0; // expected-note-re {{default constructor of '(unnamed union at {{.*}}' is implicitly deleted because variant field 'g0' is an ObjC pointer}}
190};
191
192static union { // expected-error {{call to implicitly-deleted default constructor of}}
193union { // expected-note-re {{default constructor of '(unnamed union at {{.*}}' is implicitly deleted because field 'test_union::(anonymous union at {{.*}})' has a deleted default constructor}}
194union { // 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}}
196int g2;
197};
198int g3;
199};
200int g4;
201};
202
203void testDefaultConstructor() {
204U0 t0; // expected-error {{call to implicitly-deleted default constructor}}
205U1 t1; // expected-error {{call to implicitly-deleted default constructor}}
206U2 t2;
207U3 t3;
208S0 t4; // expected-error {{call to implicitly-deleted default constructor}}
209S1 t5; // expected-error {{call to implicitly-deleted default constructor}}
210S2 t6; // expected-error {{call to implicitly-deleted default constructor}}
211}
212
213void testDestructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
214delete u0; // expected-error {{attempt to use a deleted function}}
215delete u1; // expected-error {{attempt to use a deleted function}}
216delete u2;
217delete u3;
218delete s0; // expected-error {{attempt to use a deleted function}}
219delete s1; // expected-error {{attempt to use a deleted function}}
220delete s2; // expected-error {{attempt to use a deleted function}}
221}
222
223void testCopyConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
224U0 t0(*u0); // expected-error {{call to implicitly-deleted copy constructor}}
225U1 t1(*u1); // expected-error {{call to implicitly-deleted copy constructor}}
226U2 t2(*u2); // expected-error {{call to implicitly-deleted copy constructor}}
227U3 t3(*u3);
228S0 t4(*s0); // expected-error {{call to implicitly-deleted copy constructor}}
229S1 t5(*s1); // expected-error {{call to implicitly-deleted copy constructor}}
230S2 t6(*s2); // expected-error {{call to implicitly-deleted copy constructor}}
231}
232
233void 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}
242
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.
246
247void testMoveConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
248U0 t0(static_cast<U0 &&>(*u0)); // expected-error {{call to implicitly-deleted copy constructor}}
249U1 t1(static_cast<U1 &&>(*u1)); // expected-error {{call to implicitly-deleted copy constructor}}
250U2 t2(static_cast<U2 &&>(*u2)); // expected-error {{call to implicitly-deleted copy constructor}}
251U3 t3(static_cast<U3 &&>(*u3));
252S0 t4(static_cast<S0 &&>(*s0)); // expected-error {{call to implicitly-deleted copy constructor}}
253S1 t5(static_cast<S1 &&>(*s1)); // expected-error {{call to implicitly-deleted copy constructor}}
254S2 t6(static_cast<S2 &&>(*s2)); // expected-error {{call to implicitly-deleted copy constructor}}
255}
256
257void 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}
266}
267