// 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 // : 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}} } // // 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 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(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 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)); // expected-error {{call to implicitly-deleted copy constructor}} U1 t1(static_cast(*u1)); // expected-error {{call to implicitly-deleted copy constructor}} U2 t2(static_cast(*u2)); // expected-error {{call to implicitly-deleted copy constructor}} U3 t3(static_cast(*u3)); S0 t4(static_cast(*s0)); // expected-error {{call to implicitly-deleted copy constructor}} S1 t5(static_cast(*s1)); // expected-error {{call to implicitly-deleted copy constructor}} S2 t6(static_cast(*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); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} *x1 = static_cast(*u1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} *x2 = static_cast(*u2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} *x3 = static_cast(*u3); *x4 = static_cast(*s0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} *x5 = static_cast(*s1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} *x6 = static_cast(*s2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}} } }