1// RUN: %clang_cc1 -fsyntax-only -fblocks -fobjc-arc -verify -Wno-objc-root-class %s
2
3// rdar://8843524
4
5struct A {
6  id x[4];
7  id y;
8};
9
10union u {
11  id u;
12};
13
14// Volatile fields are fine.
15struct C {
16  volatile int x[4];
17  volatile int y;
18};
19
20union u_trivial_c {
21  volatile int b;
22  struct C c;
23};
24
25@interface I {
26   struct A a;
27   struct B {
28    id y[10][20];
29    id z;
30   } b;
31
32   union u c;
33};
34@end
35
36// rdar://10260525
37struct r10260525 {
38  id (^block) ();
39};
40
41struct S {
42    id __attribute__((objc_ownership(none))) i;
43    void * vp;
44    int i1;
45};
46
47// rdar://9046528
48
49@class NSError;
50
51__autoreleasing id X; // expected-error {{global variables cannot have __autoreleasing ownership}}
52__autoreleasing NSError *E; // expected-error {{global variables cannot have __autoreleasing ownership}}
53
54
55extern id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}}
56
57void func()
58{
59    id X;
60    static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}}
61    extern id __autoreleasing E; // expected-error {{global variables cannot have __autoreleasing ownership}}
62
63}
64
65// rdar://9157348
66// rdar://15757510
67
68@interface J
69@property (retain) id newFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-newFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
70@property (strong) id copyBar;  // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-copyBar' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
71@property (copy) id allocBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-allocBaz' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
72@property (copy, nonatomic) id new;
73@property (retain) id newDFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-newDFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
74@property (strong) id copyDBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-copyDBar' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
75@property (copy) id allocDBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-allocDBaz' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
76@end
77
78@implementation J
79@synthesize newFoo;
80@synthesize copyBar;
81@synthesize allocBaz;
82@synthesize new;
83- new {return 0; };
84
85@dynamic newDFoo;
86@dynamic copyDBar;
87@dynamic allocDBaz;
88@end
89
90
91@interface MethodFamilyDiags
92@property (retain) id newFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
93- (id)newFoo; // expected-note {{explicitly declare getter '-newFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
94
95#define OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
96- (id)newBar; // expected-note {{explicitly declare getter '-newBar' with 'OBJC_METHOD_FAMILY_NONE' to return an 'unowned' object}}
97@property (retain) id newBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
98
99@property (retain) id newBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note {{explicitly declare getter '-newBaz' with 'OBJC_METHOD_FAMILY_NONE' to return an 'unowned' object}}
100#undef OBJC_METHOD_FAMILY_NONE
101
102@property (retain, readonly) id newGarply; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note {{explicitly declare getter '-newGarply' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}}
103@end
104
105@interface MethodFamilyDiags (Redeclarations)
106- (id)newGarply; // no note here
107@end
108
109@implementation MethodFamilyDiags
110@synthesize newGarply;
111@end
112
113
114// rdar://10187884
115@interface Super
116- (void)bar:(id)b; // expected-note {{parameter declared here}}
117- (void)bar1:(id) __attribute((ns_consumed)) b;
118- (void)ok:(id) __attribute((ns_consumed)) b;
119- (id)ns_non; // expected-note {{method declared here}}
120- (id)not_ret:(id) b __attribute((ns_returns_not_retained)); // expected-note {{method declared here}}
121- (id)both__returns_not_retained:(id) b __attribute((ns_returns_not_retained));
122@end
123
124@interface Sub : Super
125- (void)bar:(id) __attribute((ns_consumed)) b; // expected-error {{overriding method has mismatched ns_consumed attribute on its parameter}}
126- (void)bar1:(id)b;
127- (void)ok:(id) __attribute((ns_consumed)) b;
128- (id)ns_non __attribute((ns_returns_not_retained)); // expected-error {{overriding method has mismatched ns_returns_not_retained attributes}}
129- (id)not_ret:(id) b __attribute((ns_returns_retained)); // expected-error {{overriding method has mismatched ns_returns_retained attributes}}
130- (id)both__returns_not_retained:(id) b __attribute((ns_returns_not_retained));
131// rdar://12173491
132@property (copy, nonatomic) __attribute__((ns_returns_retained)) id (^fblock)(void);
133@end
134
135// Test that we give a good diagnostic here that mentions the missing
136// ownership qualifier.  We don't want this to get suppressed because
137// of an invalid conversion.
138void test7(void) {
139  id x;
140  id *px = &x; // expected-error {{pointer to non-const type 'id' with no explicit ownership}}
141
142  I *y;
143  J **py = &y; // expected-error {{pointer to non-const type 'J *' with no explicit ownership}} expected-warning {{incompatible pointer types initializing}}
144}
145
146void func(void) __attribute__((objc_ownership(none)));  // expected-warning {{'objc_ownership' only applies to Objective-C object or block pointer types; type here is 'void (void)'}}
147struct __attribute__((objc_ownership(none))) S2 {}; // expected-error {{'objc_ownership' attribute only applies to variables}}
148@interface I2
149    @property __attribute__((objc_ownership(frob))) id i; // expected-warning {{'objc_ownership' attribute argument not supported: 'frob'}}
150@end
151
152// rdar://15304886
153@interface NSObject @end
154
155@interface ControllerClass : NSObject @end
156
157@interface SomeClassOwnedByController
158@property (readonly) ControllerClass *controller; // expected-note {{property declared here}}
159
160// rdar://15465916
161@property (readonly, weak) ControllerClass *weak_controller;
162@end
163
164@interface SomeClassOwnedByController ()
165@property (readwrite, weak) ControllerClass *controller; // expected-warning {{primary property declaration is implicitly strong while redeclaration in class extension is weak}}
166
167@property (readwrite, weak) ControllerClass *weak_controller;
168@end
169
170@interface I3
171@end
172
173@interface D3 : I3
174@end
175
176@interface D3 (Cat1)
177- (id)method;
178@end
179
180@interface I3 (Cat2)
181// FIXME: clang should diagnose mismatch between methods in D3(Cat1) and
182//        I3(Cat2).
183- (id)method __attribute__((ns_returns_retained));
184@end
185
186@implementation D3
187- (id)method {
188  return (id)0;
189}
190@end
191