1// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
2
3@interface I0
4@property(readonly) int x;
5@property(readonly) int y;
6@property(readonly) int z;
7-(void) setY: (int) y0;
8@end
9
10@interface I0 (Cat0)
11-(void) setX: (int) a0;
12@end
13
14@implementation I0
15@dynamic x;
16@dynamic y;
17@dynamic z;
18-(void) setY: (int) y0{}
19
20-(void) im0 {
21  self.x = 0;
22  self.y = 2;
23  self.z = 2; // expected-error {{assignment to readonly property}}
24}
25@end
26
27// Test when property is 'readonly' but it has a setter in
28// its implementation only.
29@interface I1  {
30}
31@property(readonly) int identifier;
32@end
33
34
35@implementation I1
36@dynamic identifier;
37- (void)setIdentifier:(int)ident {}
38
39- (id)initWithIdentifier:(int)Arg {
40    self.identifier = 0;
41}
42
43@end
44
45
46// Also in a category implementation
47@interface I1(CAT)
48@property(readonly) int rprop;
49@end
50
51
52@implementation I1(CAT)
53@dynamic rprop;
54- (void)setRprop:(int)ident {}
55
56- (id)initWithIdentifier:(int)Arg {
57    self.rprop = 0;
58}
59
60@end
61
62static int g_val;
63
64@interface Root
65+ alloc;
66- init;
67@end
68
69@interface Subclass : Root
70{
71    int setterOnly;
72}
73- (void) setSetterOnly:(int)value;
74@end
75
76@implementation Subclass
77- (void) setSetterOnly:(int)value {
78    setterOnly = value;
79    g_val = setterOnly;
80}
81@end
82
83@interface C {}
84// - (int)Foo;
85- (void)setFoo:(int)value;
86@end
87
88void g(int);
89
90void f(C *c) {
91    c.Foo = 17; // OK
92    g(c.Foo); // expected-error {{no getter method for read from property}}
93}
94
95
96void abort(void);
97int main (void) {
98    Subclass *x = [[Subclass alloc] init];
99
100    x.setterOnly = 4;   // OK
101    if (g_val != 4)
102      abort ();
103    return 0;
104}
105
106// rdar://11363363
107@interface rdar11363363
108{
109  id R;
110}
111@property (copy) id p;
112@property (copy) id r;
113@property (copy) id Q;
114@property (copy) id t; // expected-note 2 {{property declared here}}
115@property (copy) id T; // expected-note 2 {{property declared here}}
116@property (copy) id Pxyz; // expected-note 2 {{property declared here}}
117@property (copy) id pxyz; // expected-note 2 {{property declared here}}
118@end
119
120@implementation rdar11363363
121@synthesize p;
122@synthesize r;
123@synthesize Q;
124@synthesize t, T;
125@synthesize Pxyz, pxyz;
126- (id) Meth {
127  self.P = 0; // expected-warning {{property 'P' not found on object of type 'rdar11363363 *'; did you mean to access property p?}}
128  self.q = 0; // expected-warning {{property 'q' not found on object of type 'rdar11363363 *'; did you mean to access property Q?}}
129// rdar://11528439
130  self.t = 0; // expected-error {{synthesized properties 't' and 'T' both claim setter 'setT:'}}
131  self.T = 0; // expected-error {{synthesized properties 'T' and 't' both claim setter 'setT:'}}
132  self.Pxyz = 0; // expected-error {{synthesized properties 'Pxyz' and 'pxyz' both claim setter 'setPxyz:'}}
133  self.pxyz = 0; // expected-error {{synthesized properties 'pxyz' and 'Pxyz' both claim setter 'setPxyz:'}}
134  self.r = 0;
135  return self.R; // expected-error {{no getter method for read from property}} \
136                 // expected-warning {{property 'R' not found on object of type 'rdar11363363 *'; did you mean to access property r?}}
137}
138@end
139
140// rdar://11499742
141@class BridgeFormatter;
142
143@interface FMXBridgeFormatter
144
145@property(assign, readwrite, getter=formatter, setter=setFormatter:) BridgeFormatter* cppFormatter;
146
147@end
148
149@implementation FMXBridgeFormatter
150@synthesize cppFormatter;
151
152- (void) dealloc
153{
154 self.formatter = 0;
155}
156@end
157
158