1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wno-objc-root-class %s |
2 | |
3 | struct 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 |
30 | void 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 |
39 | void 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> |
45 | namespace std { |
46 | template<typename T> void count(); |
47 | } |
48 | |
49 | @interface Test4 |
50 | - (X&) prop; |
51 | @end |
52 | |
53 | void 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 | |
66 | void 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 | |
77 | void test6(Test6 *t6) { |
78 | Class x = t6.class; |
79 | Class x2 = Test6.class; |
80 | } |
81 | |
82 | template<typename T> |
83 | void test6_template(T *t6) { |
84 | Class x = t6.class; |
85 | } |
86 | |
87 | template void test6_template(Test6*); |
88 | |
89 | // rdar://problem/10965735 |
90 | struct 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 |
101 | void 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. |
113 | class NonTrivial1 { |
114 | public: |
115 | ~NonTrivial1(); |
116 | }; |
117 | class NonTrivial2 { |
118 | public: |
119 | NonTrivial2(); |
120 | NonTrivial2(const NonTrivial2&); |
121 | }; |
122 | @interface TestNonTrivial |
123 | @property(assign, nonatomic) NonTrivial1 p1; |
124 | @property(assign, nonatomic) NonTrivial2 p2; |
125 | @end |
126 | TestNonTrivial *TestNonTrivialObj; |
127 | |
128 | extern void* VoidType; |
129 | extern decltype(TestNonTrivialObj.p1 = NonTrivial1())* VoidType; |
130 | extern decltype(TestNonTrivialObj.p2 = NonTrivial2())* VoidType; |
131 | |
132 | // rdar://13332183 |
133 | namespace 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 |
142 | namespace test9 { |
143 | char test(Test9 *t) { |
144 | return t.name[0]; |
145 | } |
146 | } |
147 | |
148 | namespace 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 |
157 | namespace 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 |
177 | struct CGSize { |
178 | double width; |
179 | double height; |
180 | }; |
181 | typedef struct CGSize CGSize; |
182 | |
183 | struct CGRect { |
184 | CGSize origin; |
185 | CGSize size; |
186 | }; |
187 | typedef struct CGRect CGRect; |
188 | |
189 | typedef CGRect NSRect; |
190 | void 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 | |