| // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -fobjc-weak -verify -fblocks -fobjc-exceptions %s |
| |
| // "Move" semantics, trivial version. |
| void move_it(__strong id &&from) { |
| id to = static_cast<__strong id&&>(from); |
| } |
| |
| // Deduction with 'auto'. |
| @interface A |
| + alloc; |
| - init; |
| @end |
| |
| // <rdar://problem/12031870>: don't warn about this |
| extern "C" A* MakeA(); |
| |
| // Ensure that deduction works with lifetime qualifiers. |
| void deduction(id obj) { |
| auto a = [[A alloc] init]; |
| __strong A** aPtr = &a; |
| |
| auto a2([[A alloc] init]); |
| __strong A** aPtr2 = &a2; |
| |
| __strong id *idp = new auto(obj); |
| |
| __strong id array[17]; |
| for (auto x : array) { // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}} |
| __strong id *xPtr = &x; |
| } |
| |
| @try { |
| } @catch (auto e) { // expected-error {{'auto' not allowed in exception declaration}} |
| } |
| } |
| |
| // rdar://problem/11068137 |
| void test1a() { |
| __autoreleasing id p; // expected-note 2 {{'p' declared here}} |
| (void) [&p] {}; |
| (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}} |
| (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}} |
| } |
| void test1b() { |
| __autoreleasing id v; |
| __autoreleasing id &p = v; // expected-note 2 {{'p' declared here}} |
| (void) [&p] {}; |
| (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}} |
| (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}} |
| } |
| void test1c() { |
| __autoreleasing id v; // expected-note {{'v' declared here}} |
| __autoreleasing id &p = v; |
| (void) ^{ (void) p; }; |
| (void) ^{ (void) v; }; // expected-error {{cannot capture __autoreleasing variable in a block}} |
| } |
| |
| |
| // <rdar://problem/11319689> |
| // warn when initializing an 'auto' variable with an 'id' initializer expression |
| |
| void testAutoId(id obj) { |
| auto x = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}} |
| } |
| |
| @interface Array |
| + (instancetype)new; |
| - (id)objectAtIndex:(int)index; |
| @end |
| |
| // ...but don't warn if it's coming from a template parameter. |
| template<typename T, int N> |
| void autoTemplateFunction(T param, id obj, Array *arr) { |
| auto x = param; // no-warning |
| auto y = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'y'}} |
| auto z = [arr objectAtIndex:N]; // expected-warning{{'auto' deduced as 'id' in declaration of 'z'}} |
| } |
| |
| void testAutoIdTemplate(id obj) { |
| autoTemplateFunction<id, 2>(obj, obj, [Array new]); // no-warning |
| } |
| |
| // rdar://12229679 |
| @interface NSObject @end |
| typedef __builtin_va_list va_list; |
| @interface MyClass : NSObject |
| @end |
| |
| @implementation MyClass |
| + (void)fooMethod:(id)firstArg, ... { |
| va_list args; |
| |
| __builtin_va_arg(args, id); |
| } |
| @end |
| |
| namespace rdar12078752 { |
| void f() { |
| NSObject* o =0; |
| __autoreleasing decltype(o) o2 = o; |
| __autoreleasing auto o3 = o; |
| } |
| } |
| |
| namespace test_err_arc_array_param_no_ownership { |
| template <class T> |
| void func(T a) {} |
| |
| void test() { |
| func([](A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}} |
| func(^(A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}} |
| } |
| } |
| |
| namespace test_union { |
| // Implicitly-declared special functions of a union are deleted by default if |
| // ARC is enabled and the union has an ObjC pointer field. |
| union U0 { |
| id f0; // expected-note 6 {{'U0' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| }; |
| |
| union U1 { |
| __weak id f0; // expected-note 12 {{'U1' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| U1() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}} |
| ~U1() = default; // expected-warning {{explicitly defaulted destructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}} |
| U1(const U1 &) = default; // expected-warning {{explicitly defaulted copy constructor is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}} |
| U1(U1 &&) = default; // expected-warning {{explicitly defaulted move constructor is implicitly deleted}} |
| 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}} |
| U1 & operator=(U1 &&) = default; // expected-warning {{explicitly defaulted move assignment operator is implicitly deleted}} |
| }; |
| |
| id getStrong(); |
| |
| // If the ObjC pointer field of a union has a default member initializer, the |
| // implicitly-declared default constructor of the union is not deleted by |
| // default. |
| union U2 { |
| id f0 = getStrong(); // expected-note 4 {{'U2' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| ~U2(); |
| }; |
| |
| // It's fine if the user has explicitly defined the special functions. |
| union U3 { |
| id f0; |
| U3(); |
| ~U3(); |
| U3(const U3 &); |
| U3(U3 &&); |
| U3 & operator=(const U3 &); |
| U3 & operator=(U3 &&); |
| }; |
| |
| // ObjC pointer fields in anonymous union fields delete the defaulted special |
| // functions of the containing class. |
| struct S0 { |
| union { |
| id f0; // expected-note 6 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| char f1; |
| }; |
| }; |
| |
| struct S1 { |
| union { |
| union { // expected-note {{copy constructor of 'S1' is implicitly deleted because field '' has a deleted copy constructor}} expected-note {{copy assignment operator of 'S1' is implicitly deleted because field '' has a deleted copy assignment operator}} expected-note 4 {{'S1' is implicitly deleted because field '' has a deleted}} |
| id f0; // expected-note 2 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}} |
| char f1; |
| }; |
| int f2; |
| }; |
| }; |
| |
| struct S2 { |
| union { |
| // FIXME: the note should say 'f0' is causing the special functions to be deleted. |
| struct { // expected-note 6 {{'S2' is implicitly deleted because variant field '' has a non-trivial}} |
| id f0; |
| int f1; |
| }; |
| int f2; |
| }; |
| int f3; |
| }; |
| |
| U0 *x0; |
| U1 *x1; |
| U2 *x2; |
| U3 *x3; |
| S0 *x4; |
| S1 *x5; |
| S2 *x6; |
| |
| static union { // expected-error {{call to implicitly-deleted default constructor of}} |
| id g0; // expected-note {{default constructor of '' is implicitly deleted because variant field 'g0' is an ObjC pointer}} |
| }; |
| |
| static union { // expected-error {{call to implicitly-deleted default constructor of}} |
| union { // expected-note {{default constructor of '' is implicitly deleted because field '' has a deleted default constructor}} |
| union { // expected-note {{default constructor of '' is implicitly deleted because field '' has a deleted default constructor}} |
| __weak id g1; // expected-note {{default constructor of '' is implicitly deleted because variant field 'g1' is an ObjC pointer}} |
| int g2; |
| }; |
| int g3; |
| }; |
| int g4; |
| }; |
| |
| void testDefaultConstructor() { |
| U0 t0; // expected-error {{call to implicitly-deleted default constructor}} |
| U1 t1; // expected-error {{call to implicitly-deleted default constructor}} |
| U2 t2; |
| U3 t3; |
| S0 t4; // expected-error {{call to implicitly-deleted default constructor}} |
| S1 t5; // expected-error {{call to implicitly-deleted default constructor}} |
| S2 t6; // expected-error {{call to implicitly-deleted default constructor}} |
| } |
| |
| void testDestructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| delete u0; // expected-error {{attempt to use a deleted function}} |
| delete u1; // expected-error {{attempt to use a deleted function}} |
| delete u2; |
| delete u3; |
| delete s0; // expected-error {{attempt to use a deleted function}} |
| delete s1; // expected-error {{attempt to use a deleted function}} |
| delete s2; // expected-error {{attempt to use a deleted function}} |
| } |
| |
| void testCopyConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| U0 t0(*u0); // expected-error {{call to implicitly-deleted copy constructor}} |
| U1 t1(*u1); // expected-error {{call to implicitly-deleted copy constructor}} |
| U2 t2(*u2); // expected-error {{call to implicitly-deleted copy constructor}} |
| U3 t3(*u3); |
| S0 t4(*s0); // expected-error {{call to implicitly-deleted copy constructor}} |
| S1 t5(*s1); // expected-error {{call to implicitly-deleted copy constructor}} |
| S2 t6(*s2); // expected-error {{call to implicitly-deleted copy constructor}} |
| } |
| |
| void testCopyAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| *x0 = *u0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x1 = *u1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x2 = *u2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x3 = *u3; |
| *x4 = *s0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x5 = *s1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x6 = *s2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| } |
| |
| // The diagnostics below refer to the deleted copy constructors and assignment |
| // operators since defaulted move constructors and assignment operators that are |
| // defined as deleted are ignored by overload resolution. |
| |
| void testMoveConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| U0 t0(static_cast<U0 &&>(*u0)); // expected-error {{call to implicitly-deleted copy constructor}} |
| U1 t1(static_cast<U1 &&>(*u1)); // expected-error {{call to implicitly-deleted copy constructor}} |
| U2 t2(static_cast<U2 &&>(*u2)); // expected-error {{call to implicitly-deleted copy constructor}} |
| U3 t3(static_cast<U3 &&>(*u3)); |
| S0 t4(static_cast<S0 &&>(*s0)); // expected-error {{call to implicitly-deleted copy constructor}} |
| S1 t5(static_cast<S1 &&>(*s1)); // expected-error {{call to implicitly-deleted copy constructor}} |
| S2 t6(static_cast<S2 &&>(*s2)); // expected-error {{call to implicitly-deleted copy constructor}} |
| } |
| |
| void testMoveAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) { |
| *x0 = static_cast<U0 &&>(*u0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x1 = static_cast<U1 &&>(*u1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x2 = static_cast<U2 &&>(*u2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x3 = static_cast<U3 &&>(*u3); |
| *x4 = static_cast<S0 &&>(*s0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x5 = static_cast<S1 &&>(*s1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| *x6 = static_cast<S2 &&>(*s2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} |
| } |
| } |