diff options
author | John McCall <rjmccall@apple.com> | 2015-09-23 22:14:21 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2015-09-23 22:14:21 +0000 |
commit | 6997525eaa8fa6ea09e6a8c7a33908e81544ef1f (patch) | |
tree | 1decae494592ba5218d515d64f5d37c14fe5756f /clang/test/SemaObjCXX/parameterized_classes_arc.mm | |
parent | d209967a68dc11e255c9794d77340dce080a84e6 (diff) | |
download | bcm5719-llvm-6997525eaa8fa6ea09e6a8c7a33908e81544ef1f.tar.gz bcm5719-llvm-6997525eaa8fa6ea09e6a8c7a33908e81544ef1f.zip |
Forbid qualifiers on ObjC generic parameters and arguments, but
silently ignore them on arguments when they're provided indirectly
(.e.g behind a template argument or typedef).
This is mostly just good language design --- specifying that a
generic argument is __weak doesn't actually do anything --- but
it also prevents assertions when trying to apply a different
ownership qualifier.
rdar://21612439
llvm-svn: 248436
Diffstat (limited to 'clang/test/SemaObjCXX/parameterized_classes_arc.mm')
-rw-r--r-- | clang/test/SemaObjCXX/parameterized_classes_arc.mm | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/clang/test/SemaObjCXX/parameterized_classes_arc.mm b/clang/test/SemaObjCXX/parameterized_classes_arc.mm new file mode 100644 index 00000000000..38ddd70986e --- /dev/null +++ b/clang/test/SemaObjCXX/parameterized_classes_arc.mm @@ -0,0 +1,119 @@ +// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak %s -verify + +// rdar://21612439 + +__attribute__((objc_root_class)) +@interface NSObject +@end + +@class Forward; +@class Forward2; + +// Tests for generic arguments. + +@interface PC1<T> : NSObject +- (T) get; +- (void) set: (T) v; +@end + +void test1a(PC1<__weak id> *obj) { // expected-error {{type argument '__weak id' cannot be qualified with '__weak'}} + id x = [obj get]; + [obj set: x]; +} + +void test1b(PC1<__strong id> *obj) { // expected-error {{type argument '__strong id' cannot be qualified with '__strong'}} + id x = [obj get]; + [obj set: x]; +} + +void test1c(PC1<id> *obj) { + id x = [obj get]; + [obj set: x]; +} + +// Test that this doesn't completely kill downstream type-checking. +void test1d(PC1<__weak Forward*> *obj) { // expected-error {{type argument 'Forward *__weak' cannot be qualified with '__weak'}} + Forward2 *x = [obj get]; // expected-error {{cannot initialize}} + [obj set: x]; +} + +void test1e(PC1<__strong Forward*> *obj) { // expected-error {{type argument 'Forward *__strong' cannot be qualified with '__strong'}} + Forward2 *x = [obj get]; // expected-error {{cannot initialize}} + [obj set: x]; +} + +void test1f(PC1<Forward*> *obj) { + Forward2 *x = [obj get]; // expected-error {{cannot initialize}} + [obj set: x]; +} + +// Typedefs are fine, just silently ignore them. +typedef __strong id StrongID; +void test1g(PC1<StrongID> *obj) { + Forward2 *x = [obj get]; + [obj set: x]; +} + +typedef __strong Forward *StrongForward; +void test1h(PC1<StrongForward> *obj) { + Forward2 *x = [obj get]; // expected-error {{cannot initialize}} + [obj set: x]; +} + +// These aren't really ARC-specific, but they're the same basic idea. +void test1i(PC1<const id> *obj) { // expected-error {{type argument 'const id' cannot be qualified with 'const'}} + id x = [obj get]; + [obj set: x]; +} + +void test1j(PC1<volatile id> *obj) { // expected-error {{type argument 'volatile id' cannot be qualified with 'volatile'}} + id x = [obj get]; + [obj set: x]; +} + +void test1k(PC1<__attribute__((address_space(256))) id> *obj) { // expected-error {{type argument '__attribute__((address_space(256))) id' cannot be qualified with '__attribute__((address_space(256)))'}} + id x = [obj get]; + [obj set: x]; +} + +// Template-specific tests. +template <class T> PC1<T> *test2_temp(); +void test2a() { test2_temp<id>(); } +void test2b() { test2_temp<const id>(); } +void test2c() { test2_temp<volatile id>(); } +void test2d() { test2_temp<__strong id>(); } +void test2e() { test2_temp<__weak id>(); } +void test2f() { test2_temp<__attribute__((address_space(256))) id>(); } + +template <class T> PC1<const T> *test3a(); // expected-error {{type argument 'const T' cannot be qualified with 'const'}} +template <class T> PC1<__strong T> *test3b(); // expected-error {{type argument '__strong T' cannot be qualified with '__strong'}} + +// Tests for generic parameter bounds. + +@interface PC2<T : __strong id> // expected-error {{type bound '__strong id' for type parameter 'T' cannot be qualified with '__strong'}} +@end + +@interface PC3<T : __weak id> // expected-error {{type bound '__weak id' for type parameter 'T' cannot be qualified with '__weak'}} +@end + +@interface PC4<T : __strong Forward*> // expected-error {{type bound 'Forward *__strong' for type parameter 'T' cannot be qualified with '__strong'}} +@end + +@interface PC5<T : __weak Forward*> // expected-error {{type bound 'Forward *__weak' for type parameter 'T' cannot be qualified with '__weak'}} +@end + +@interface PC6<T : StrongID> // expected-error {{type bound 'StrongID' (aka '__strong id') for type parameter 'T' cannot be qualified with '__strong'}} +@end + +@interface PC7<T : StrongForward> // expected-error {{type bound 'StrongForward' (aka 'Forward *__strong') for type parameter 'T' cannot be qualified with '__strong'}} +@end + +// These aren't really ARC-specific, but they're the same basic idea. +@interface PC8<T : const id> // expected-error {{type bound 'const id' for type parameter 'T' cannot be qualified with 'const'}} +@end + +@interface PC9<T : volatile id> // expected-error {{type bound 'volatile id' for type parameter 'T' cannot be qualified with 'volatile'}} +@end + +@interface PC10<T : __attribute__((address_space(256))) id> // expected-error {{type bound '__attribute__((address_space(256))) id' for type parameter 'T' cannot be qualified with '__attribute__((address_space(256)))'}} +@end |