1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wno-objc-root-class %s
2
3struct X {
4  void f() const;
5  ~X();
6};
7
8@interface A {
9  X x_;
10}
11
12- (const X&)x;
13- (void)setx:(const X&)other;
14@end
15
16@implementation A
17
18- (const X&)x { return x_; }
19- (void)setx:(const X&)other { x_ = other; }
20- (void)method {
21  self.x.f();
22}
23@end
24
25// rdar://problem/10444030
26@interface Test2
27- (void) setY: (int) y;
28- (int) z;
29@end
30void test2(Test2 *a) {
31  auto y = a.y; // expected-error {{no getter method for read from property}}
32  auto z = a.z;
33}
34
35// rdar://problem/10672108
36@interface Test3
37- (int) length;
38@end
39void test3(Test3 *t) {
40  char vla[t.length] = {}; // expected-error {{variable-sized object may not be initialized}}
41  char *heaparray = new char[t.length];
42}
43
44// <rdar://problem/10672501>
45namespace std {
46  template<typename T> void count();
47}
48
49@interface Test4
50- (X&) prop;
51@end
52
53void test4(Test4 *t) {
54  (void)const_cast<const X&>(t.prop);
55  (void)dynamic_cast<X&>(t.prop);
56  (void)reinterpret_cast<int&>(t.prop);
57}
58
59@interface Test5 {
60@public
61  int count;
62}
63@property int count;
64@end
65
66void test5(Test5* t5) {
67  if (t5.count < 2) { }
68  if (t5->count < 2) { }
69}
70
71
72@interface Test6
73+ (Class)class;
74- (Class)class;
75@end
76
77void test6(Test6 *t6) {
78  Class x = t6.class;
79  Class x2 = Test6.class;
80}
81
82template<typename T>
83void test6_template(T *t6) {
84  Class x = t6.class;
85}
86
87template void test6_template(Test6*);
88
89// rdar://problem/10965735
90struct Test7PointerMaker {
91  operator char *() const;
92};
93@interface Test7
94- (char*) implicit_property;
95- (char) bad_implicit_property;
96- (Test7PointerMaker) implicit_struct_property;
97@property int *explicit_property;
98@property int bad_explicit_property;
99@property Test7PointerMaker explicit_struct_property;
100@end
101void test7(Test7 *ptr) {
102  delete ptr.implicit_property;
103  delete ptr.bad_implicit_property; // expected-error {{cannot delete expression of type 'char'}}
104  delete ptr.explicit_property;
105  delete ptr.bad_explicit_property; // expected-error {{cannot delete expression of type 'int'}}
106  delete ptr.implicit_struct_property;
107  delete ptr.explicit_struct_property;
108}
109
110// Make sure the returned value from property assignment is void,
111// because there isn't any other viable way to handle it for
112// non-trivial classes.
113class NonTrivial1 {
114public:
115	~NonTrivial1();
116};
117class NonTrivial2 {
118public:
119	NonTrivial2();
120	NonTrivial2(const NonTrivial2&);
121};
122@interface TestNonTrivial
123@property(assign, nonatomic) NonTrivial1 p1;
124@property(assign, nonatomic) NonTrivial2 p2;
125@end
126TestNonTrivial *TestNonTrivialObj;
127
128extern void* VoidType;
129extern decltype(TestNonTrivialObj.p1 = NonTrivial1())* VoidType;
130extern decltype(TestNonTrivialObj.p2 = NonTrivial2())* VoidType;
131
132// rdar://13332183
133namespace test9 {
134  struct CString {
135    const char *_data;
136    char operator[](int i) const { return _data[i]; }
137  };
138}
139@interface Test9
140@property test9::CString name;
141@end
142namespace test9 {
143  char test(Test9 *t) {
144    return t.name[0];
145  }
146}
147
148namespace test10 {
149  struct A { operator const char*(); };
150  struct B { operator const char*(); };
151}
152@interface Test10
153@property test10::A a;
154@property test10::B b;
155@property int index;
156@end
157namespace test10 {
158  void test(Test10 *t) {
159    (void) t.a[6];
160    (void) 6[t.b];
161    (void) "help"[t.index];
162    (void) t.index["help"];
163    (void) t.a[t.index];
164    (void) t.index[t.b];
165  }
166}
167
168// <rdar://problem/14354144>
169@interface PropertyOfItself
170@property (readonly, nonatomic) PropertyOfItself x; // expected-error {{interface type cannot be statically allocated}}
171@end
172@implementation PropertyOfItself
173@synthesize x;
174@end
175
176// rdar://14654207
177struct CGSize {
178  double width;
179  double height;
180};
181typedef struct CGSize CGSize;
182
183struct CGRect {
184  CGSize origin;
185  CGSize size;
186};
187typedef struct CGRect CGRect;
188
189typedef CGRect NSRect;
190void HappySetFrame(NSRect frame) {}
191
192__attribute__((objc_root_class))
193@interface NSObject
194@property CGRect frame;
195@end
196
197@implementation NSObject
198- (void) nothing
199{
200	HappySetFrame({{0,0}, {13,14}});
201	[self setFrame: {{0,0}, {13,14}}];
202        self.frame = {{0,0}, {13,14}};
203        self.frame = (CGRect){{3,5}, {13,14}};
204}
205@end
206