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); // expected-note {{passing argument to parameter here}} 89 90void f(C *c) { 91 c.Foo = 17; // OK 92 g(c.Foo); // expected-error {{expected getter method not found on object of type 'C *'}} 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