1// RUN: %clang_cc1 -x objective-c -fsyntax-only -verify -Wno-objc-root-class %s
2// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s
3// rdar://8843851
4
5@interface StopAccessingIvarsDirectlyExample
6@property(strong) id name, rank, serialNumber;
7@end
8
9@implementation StopAccessingIvarsDirectlyExample
10
11- (void)identifyYourSelf {
12    if (self.name && self.rank && self.serialNumber)
13      self.name = 0;
14}
15
16// @synthesize name, rank, serialNumber;
17// default synthesis allows direct access to property ivars.
18- (id)init {
19        _name = _rank = _serialNumber = 0;
20	return self;
21}
22
23- (void)dealloc {
24}
25@end
26
27
28// Test2
29@interface Test2
30@property(strong, nonatomic) id object;
31@end
32
33// object has user declared setter/getter so it won't be
34// default synthesized; thus causing user error.
35@implementation Test2
36- (id) bar { return object; } // expected-error {{use of undeclared identifier 'object'}}
37- (void)setObject:(id)newObject {}
38- (id)object { return 0; }
39@end
40
41// Test3
42@interface Test3
43{
44  id uid;  // expected-note {{instance variable is declared here}}
45}
46@property (readwrite, assign) id uid;  // expected-note {{property declared here}}
47@end
48
49// rdar://11671080
50@implementation Test3 // expected-warning {{autosynthesized property 'uid' will use synthesized instance variable '_uid', not existing instance variable 'uid'}}
51// Oops, forgot to write @synthesize! will be default synthesized
52- (void) myMethod {
53   self.uid = 0; // Use of the “setter”
54   uid = 0; // Use of the wrong instance variable
55   _uid = 0; // Use of the property instance variable
56}
57@end
58
59@interface Test4 {
60  id _var;
61}
62@property (readwrite, assign) id var;
63@end
64
65
66// default synthesize property named 'var'
67@implementation Test4
68- (id) myMethod {
69  return self->_var;  //  compiles because 'var' is synthesized by default
70}
71@end
72
73@interface Test5
74{
75  id _var;
76}
77@property (readwrite, assign) id var;
78@end
79
80// default synthesis of property 'var'
81@implementation Test5
82- (id) myMethod {
83  Test5 *foo = 0;
84  return foo->_var; // OK
85}
86@end
87
88@interface Test6
89{
90  id _var; // expected-note {{'_var' declared here}}
91}
92@property (readwrite, assign) id var;
93@end
94
95// no default synthesis. So error is expected.
96@implementation Test6
97- (id) myMethod
98{
99  return var; // expected-error {{use of undeclared identifier 'var'}}
100}
101@synthesize var = _var;
102@end
103
104int* _object;
105
106@interface Test7
107@property (readwrite, assign) id object;
108@end
109
110// With default synthesis, '_object' is be the synthesized ivar not the global
111// 'int*' object. So no error.
112@implementation Test7
113- (id) myMethod {
114  return _object;
115}
116@end
117
118// rdar://11671080
119@interface Test8
120{
121  id _y;
122  id y; // expected-note {{instance variable is declared here}}
123}
124@property(copy) id y; // expected-note {{property declared here}}
125@end
126
127
128@implementation Test8 @end // expected-warning {{autosynthesized property 'y' will use  instance variable '_y', not existing instance variable 'y'}}
129
130