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