diff options
Diffstat (limited to 'test/SemaObjCXX')
-rw-r--r-- | test/SemaObjCXX/arc-0x.mm | 169 | ||||
-rw-r--r-- | test/SemaObjCXX/literals.mm | 8 | ||||
-rw-r--r-- | test/SemaObjCXX/no-crash-thread-safety-analysis.mm | 15 | ||||
-rw-r--r-- | test/SemaObjCXX/objc-weak.mm | 2 | ||||
-rw-r--r-- | test/SemaObjCXX/overload.mm | 6 | ||||
-rw-r--r-- | test/SemaObjCXX/thread-safety-analysis.h | 17 | ||||
-rw-r--r-- | test/SemaObjCXX/vararg-non-pod.mm | 6 | ||||
-rw-r--r-- | test/SemaObjCXX/warn-implicit-self-in-block.mm | 42 | ||||
-rw-r--r-- | test/SemaObjCXX/warn-thread-safety-analysis.mm | 18 |
9 files changed, 259 insertions, 24 deletions
diff --git a/test/SemaObjCXX/arc-0x.mm b/test/SemaObjCXX/arc-0x.mm index 391fc47f34..052c99ac13 100644 --- a/test/SemaObjCXX/arc-0x.mm +++ b/test/SemaObjCXX/arc-0x.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -verify -fblocks -fobjc-exceptions %s +// 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) { @@ -101,3 +101,170 @@ namespace rdar12078752 { __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 2 {{'S1' is implicitly deleted because variant field '' has a non-trivial}} 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}} + } +} diff --git a/test/SemaObjCXX/literals.mm b/test/SemaObjCXX/literals.mm index 6cdd207d57..b62ed05f15 100644 --- a/test/SemaObjCXX/literals.mm +++ b/test/SemaObjCXX/literals.mm @@ -50,6 +50,9 @@ void x() { + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(unsigned long)cnt; @end +@interface NSString +@end + template<typename T> struct ConvertibleTo { operator T(); @@ -185,3 +188,8 @@ id value; void test_dictionary_colon() { id dict = @{ key : value }; } + +void testConstExpr() { + constexpr NSString *t0 = @"abc"; + constexpr NSString *t1 = @("abc"); +} diff --git a/test/SemaObjCXX/no-crash-thread-safety-analysis.mm b/test/SemaObjCXX/no-crash-thread-safety-analysis.mm new file mode 100644 index 0000000000..6abd391dc2 --- /dev/null +++ b/test/SemaObjCXX/no-crash-thread-safety-analysis.mm @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -Wno-objc-root-class %s + +// Thread safety analysis used to crash when used with ObjC methods. + +#include "thread-safety-analysis.h" + +@interface MyInterface +- (void)doIt:(class Lock *)myLock; +@end + +@implementation MyInterface +- (void)doIt:(class Lock *)myLock { + AutoLock lock(*myLock); +} +@end diff --git a/test/SemaObjCXX/objc-weak.mm b/test/SemaObjCXX/objc-weak.mm index 93c6af1aa3..2671dc104c 100644 --- a/test/SemaObjCXX/objc-weak.mm +++ b/test/SemaObjCXX/objc-weak.mm @@ -13,7 +13,7 @@ struct S { }; union U { - __weak id a; // expected-error {{ARC forbids Objective-C objects in union}} + __weak id a; S b; // expected-error {{union member 'b' has a non-trivial copy constructor}} }; diff --git a/test/SemaObjCXX/overload.mm b/test/SemaObjCXX/overload.mm index 018afc9b42..f3c06b4f22 100644 --- a/test/SemaObjCXX/overload.mm +++ b/test/SemaObjCXX/overload.mm @@ -111,11 +111,11 @@ namespace test5 { // rdar://problem/8592139 namespace test6 { - void foo(id); // expected-note{{candidate function}} - void foo(A*) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}} + void foo(id); + void foo(A*) __attribute__((unavailable)); // expected-note {{marked unavailable here}} void test(B *b) { - foo(b); // expected-error {{call to unavailable function 'foo'}} + foo(b); // expected-error {{'foo' is unavailable}} } } diff --git a/test/SemaObjCXX/thread-safety-analysis.h b/test/SemaObjCXX/thread-safety-analysis.h new file mode 100644 index 0000000000..f657b7e50a --- /dev/null +++ b/test/SemaObjCXX/thread-safety-analysis.h @@ -0,0 +1,17 @@ +class __attribute__((lockable)) Lock { +public: + void Acquire() __attribute__((exclusive_lock_function())) {} + void Release() __attribute__((unlock_function())) {} +}; + +class __attribute__((scoped_lockable)) AutoLock { +public: + AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock))) + : lock_(lock) { + lock.Acquire(); + } + ~AutoLock() __attribute__((unlock_function())) { lock_.Release(); } + +private: + Lock &lock_; +}; diff --git a/test/SemaObjCXX/vararg-non-pod.mm b/test/SemaObjCXX/vararg-non-pod.mm index daf9aa92b5..58270aa2b9 100644 --- a/test/SemaObjCXX/vararg-non-pod.mm +++ b/test/SemaObjCXX/vararg-non-pod.mm @@ -2,6 +2,10 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-error=non-pod-varargs -std=c++98 // RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-error=non-pod-varargs -std=c++11 +#if __cplusplus > 199711L +// expected-no-diagnostics +#endif + extern char version[]; @protocol P; @@ -22,8 +26,6 @@ void t1(D *d) [d g:10, c]; #if __cplusplus <= 199711L // C++03 or earlier modes // expected-warning@-2{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} -#else - // expected-no-diagnostics@-4 #endif [d g:10, version]; } diff --git a/test/SemaObjCXX/warn-implicit-self-in-block.mm b/test/SemaObjCXX/warn-implicit-self-in-block.mm new file mode 100644 index 0000000000..4842b4b10b --- /dev/null +++ b/test/SemaObjCXX/warn-implicit-self-in-block.mm @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -x objective-c++ -std=c++11 -fobjc-arc -fblocks -Wimplicit-retain-self -verify %s +// rdar://11194874 + +typedef void (^BlockTy)(); + +void noescapeFunc(__attribute__((noescape)) BlockTy); +void escapeFunc(BlockTy); + +@interface Root @end + +@interface I : Root +{ + int _bar; +} +@end + +@implementation I + - (void)foo{ + ^{ + _bar = 3; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}} + }(); + } + + - (void)testNested{ + noescapeFunc(^{ + (void)_bar; + escapeFunc(^{ + (void)_bar; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}} + noescapeFunc(^{ + (void)_bar; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}} + }); + (void)_bar; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}} + }); + (void)_bar; + }); + } + + - (void)testLambdaInBlock{ + noescapeFunc(^{ [&](){ (void)_bar; }(); }); + escapeFunc(^{ [&](){ (void)_bar; }(); }); // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}} + } +@end diff --git a/test/SemaObjCXX/warn-thread-safety-analysis.mm b/test/SemaObjCXX/warn-thread-safety-analysis.mm index 262ab7d108..a50c6f2ee1 100644 --- a/test/SemaObjCXX/warn-thread-safety-analysis.mm +++ b/test/SemaObjCXX/warn-thread-safety-analysis.mm @@ -1,22 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s -class __attribute__((lockable)) Lock { -public: - void Acquire() __attribute__((exclusive_lock_function())) {} - void Release() __attribute__((unlock_function())) {} -}; - -class __attribute__((scoped_lockable)) AutoLock { -public: - AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock))) - : lock_(lock) { - lock.Acquire(); - } - ~AutoLock() __attribute__((unlock_function())) { lock_.Release(); } - -private: - Lock &lock_; -}; +#include "thread-safety-analysis.h" @interface MyInterface { @private |