From 6997525eaa8fa6ea09e6a8c7a33908e81544ef1f Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 23 Sep 2015 22:14:21 +0000 Subject: 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 --- clang/test/SemaObjCXX/parameterized_classes_arc.mm | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 clang/test/SemaObjCXX/parameterized_classes_arc.mm (limited to 'clang/test/SemaObjCXX/parameterized_classes_arc.mm') 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 : 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 *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 *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 *obj) { + Forward2 *x = [obj get]; + [obj set: x]; +} + +typedef __strong Forward *StrongForward; +void test1h(PC1 *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 *obj) { // expected-error {{type argument 'const id' cannot be qualified with 'const'}} + id x = [obj get]; + [obj set: x]; +} + +void test1j(PC1 *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 PC1 *test2_temp(); +void test2a() { test2_temp(); } +void test2b() { test2_temp(); } +void test2c() { test2_temp(); } +void test2d() { test2_temp<__strong id>(); } +void test2e() { test2_temp<__weak id>(); } +void test2f() { test2_temp<__attribute__((address_space(256))) id>(); } + +template PC1 *test3a(); // expected-error {{type argument 'const T' cannot be qualified with 'const'}} +template PC1<__strong T> *test3b(); // expected-error {{type argument '__strong T' cannot be qualified with '__strong'}} + +// Tests for generic parameter bounds. + +@interface PC2 // expected-error {{type bound '__strong id' for type parameter 'T' cannot be qualified with '__strong'}} +@end + +@interface PC3 // expected-error {{type bound '__weak id' for type parameter 'T' cannot be qualified with '__weak'}} +@end + +@interface PC4 // expected-error {{type bound 'Forward *__strong' for type parameter 'T' cannot be qualified with '__strong'}} +@end + +@interface PC5 // expected-error {{type bound 'Forward *__weak' for type parameter 'T' cannot be qualified with '__weak'}} +@end + +@interface PC6 // expected-error {{type bound 'StrongID' (aka '__strong id') for type parameter 'T' cannot be qualified with '__strong'}} +@end + +@interface PC7 // 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 // expected-error {{type bound 'const id' for type parameter 'T' cannot be qualified with 'const'}} +@end + +@interface PC9 // expected-error {{type bound 'volatile id' for type parameter 'T' cannot be qualified with 'volatile'}} +@end + +@interface PC10 // expected-error {{type bound '__attribute__((address_space(256))) id' for type parameter 'T' cannot be qualified with '__attribute__((address_space(256)))'}} +@end -- cgit v1.2.3