Home | History | Annotate | Download | only in SemaObjCXX
      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