summaryrefslogtreecommitdiffstats
path: root/test/SemaObjCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaObjCXX')
-rw-r--r--test/SemaObjCXX/arc-0x.mm169
-rw-r--r--test/SemaObjCXX/literals.mm8
-rw-r--r--test/SemaObjCXX/no-crash-thread-safety-analysis.mm15
-rw-r--r--test/SemaObjCXX/objc-weak.mm2
-rw-r--r--test/SemaObjCXX/overload.mm6
-rw-r--r--test/SemaObjCXX/thread-safety-analysis.h17
-rw-r--r--test/SemaObjCXX/vararg-non-pod.mm6
-rw-r--r--test/SemaObjCXX/warn-implicit-self-in-block.mm42
-rw-r--r--test/SemaObjCXX/warn-thread-safety-analysis.mm18
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