1// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak %s -verify
2
3// rdar://21612439
4
5__attribute__((objc_root_class))
6@interface NSObject
7@end
8
9@class Forward;
10@class Forward2;
11
12// Tests for generic arguments.
13
14@interface PC1<T> : NSObject
15- (T) get;
16- (void) set: (T) v; // expected-note 4 {{parameter}}
17@end
18
19void test1a(PC1<__weak id> *obj) { // expected-error {{type argument '__weak id' cannot be qualified with '__weak'}}
20  id x = [obj get];
21  [obj set: x];
22}
23
24void test1b(PC1<__strong id> *obj) { // expected-error {{type argument '__strong id' cannot be qualified with '__strong'}}
25  id x = [obj get];
26  [obj set: x];
27}
28
29void test1c(PC1<id> *obj) {
30  id x = [obj get];
31  [obj set: x];
32}
33
34// Test that this doesn't completely kill downstream type-checking.
35void test1d(PC1<__weak Forward*> *obj) { // expected-error {{type argument 'Forward *__weak' cannot be qualified with '__weak'}}
36  Forward2 *x = [obj get]; // expected-warning {{incompatible}}
37  [obj set: x]; // expected-warning {{incompatible}}
38}
39
40void test1e(PC1<__strong Forward*> *obj) { // expected-error {{type argument 'Forward *__strong' cannot be qualified with '__strong'}}
41  Forward2 *x = [obj get]; // expected-warning {{incompatible}}
42  [obj set: x]; // expected-warning {{incompatible}}
43}
44
45void test1f(PC1<Forward*> *obj) {
46  Forward2 *x = [obj get]; // expected-warning {{incompatible}}
47  [obj set: x]; // expected-warning {{incompatible}}
48}
49
50// Typedefs are fine, just silently ignore them.
51typedef __strong id StrongID;
52void test1g(PC1<StrongID> *obj) {
53  Forward2 *x = [obj get];
54  [obj set: x];
55}
56
57typedef __strong Forward *StrongForward;
58void test1h(PC1<StrongForward> *obj) {
59  Forward2 *x = [obj get]; // expected-warning {{incompatible}}
60  [obj set: x]; // expected-warning {{incompatible}}
61}
62
63// These aren't really ARC-specific, but they're the same basic idea.
64void test1i(PC1<const id> *obj) { // expected-error {{type argument 'const id' cannot be qualified with 'const'}}
65  id x = [obj get];
66  [obj set: x];
67}
68
69void test1j(PC1<volatile id> *obj) { // expected-error {{type argument 'volatile id' cannot be qualified with 'volatile'}}
70  id x = [obj get];
71  [obj set: x];
72}
73
74void 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)))'}}
75  id x = [obj get];
76  [obj set: x];
77}
78
79// Tests for generic parameter bounds.
80
81@interface PC2<T : __strong id> // expected-error {{type bound '__strong id' for type parameter 'T' cannot be qualified with '__strong'}}
82@end
83
84@interface PC3<T : __weak id> // expected-error {{type bound '__weak id' for type parameter 'T' cannot be qualified with '__weak'}}
85@end
86
87@interface PC4<T : __strong Forward*> // expected-error {{type bound 'Forward *__strong' for type parameter 'T' cannot be qualified with '__strong'}}
88@end
89
90@interface PC5<T : __weak Forward*> // expected-error {{type bound 'Forward *__weak' for type parameter 'T' cannot be qualified with '__weak'}}
91@end
92
93@interface PC6<T : StrongID> // expected-error {{type bound 'StrongID' (aka '__strong id') for type parameter 'T' cannot be qualified with '__strong'}}
94@end
95
96@interface PC7<T : StrongForward> // expected-error {{type bound 'StrongForward' (aka 'Forward *__strong') for type parameter 'T' cannot be qualified with '__strong'}}
97@end
98
99// These aren't really ARC-specific, but they're the same basic idea.
100@interface PC8<T : const id> // expected-error {{type bound 'const id' for type parameter 'T' cannot be qualified with 'const'}}
101@end
102
103@interface PC9<T : volatile id> // expected-error {{type bound 'volatile id' for type parameter 'T' cannot be qualified with 'volatile'}}
104@end
105
106@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)))'}}
107@end