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