Home | History | Annotate | Download | only in SemaObjC
      1 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
      2 
      3 #define nil (void *)0;
      4 #define Nil (void *)0;
      5 
      6 extern void foo();
      7 
      8 @protocol MyProtocol
      9 - (void) foo;
     10 @end
     11 
     12 @interface MyClass
     13 @end
     14 
     15 @interface MyOtherClass <MyProtocol>
     16 - (void) foo;
     17 @end
     18 
     19 int main()
     20 {
     21   id obj = nil;
     22   id<MyProtocol> obj_p = nil;
     23   MyClass *obj_c = nil;
     24   MyOtherClass *obj_cp = nil;
     25   Class obj_C = Nil;
     26 
     27   /* Assigning to an 'id' variable should never
     28      generate a warning.  */
     29   obj = obj_p;  /* Ok  */
     30   obj = obj_c;  /* Ok  */
     31   obj = obj_cp; /* Ok  */
     32   obj = obj_C;  /* Ok  */
     33   
     34   /* Assigning to a 'MyClass *' variable should always generate a
     35      warning, unless done from an 'id'.  */
     36   obj_c = obj;    /* Ok */
     37   obj_c = obj_cp; // // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'MyOtherClass *'}}
     38   obj_c = obj_C;  // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'Class'}}
     39 
     40   /* Assigning to an 'id<MyProtocol>' variable should generate a
     41      warning if done from a 'MyClass *' (which doesn't implement
     42      MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
     43      (which implements MyProtocol).  */
     44   obj_p = obj;    /* Ok */
     45   obj_p = obj_c;  // expected-warning {{assigning to 'id<MyProtocol>' from incompatible type 'MyClass *'}}
     46   obj_p = obj_cp; /* Ok  */
     47   obj_p = obj_C;  // expected-warning {{incompatible pointer types assigning to 'id<MyProtocol>' from 'Class'}}
     48 
     49   /* Assigning to a 'MyOtherClass *' variable should always generate
     50      a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
     51      MyOtherClass implements MyProtocol).  */
     52   obj_cp = obj;    /* Ok */
     53   obj_cp = obj_c;  // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'MyClass *'}}
     54   obj_cp = obj_p;  /* Ok */
     55   obj_cp = obj_C;  // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class'}}
     56 
     57   /* Any comparison involving an 'id' must be without warnings.  */
     58   if (obj == obj_p) foo() ;  /* Ok  */ /*Bogus warning here in 2.95.4*/
     59   if (obj_p == obj) foo() ;  /* Ok  */
     60   if (obj == obj_c) foo() ;  /* Ok  */
     61   if (obj_c == obj) foo() ;  /* Ok  */
     62   if (obj == obj_cp) foo() ; /* Ok  */
     63   if (obj_cp == obj) foo() ; /* Ok  */
     64   if (obj == obj_C) foo() ;  /* Ok  */
     65   if (obj_C == obj) foo() ;  /* Ok  */
     66 
     67   /* Any comparison between 'MyClass *' and anything which is not an 'id'
     68      must generate a warning.  */
     69   if (obj_p == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}}
     70 
     71   if (obj_c == obj_cp) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}} 
     72   if (obj_cp == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}}
     73 
     74   if (obj_c == obj_C) foo() ;
     75   if (obj_C == obj_c) foo() ;
     76 
     77   /* Any comparison between 'MyOtherClass *' (which implements
     78      MyProtocol) and an 'id' implementing MyProtocol are Ok.  */
     79   if (obj_cp == obj_p) foo() ; /* Ok */
     80   if (obj_p == obj_cp) foo() ; /* Ok */
     81 
     82 
     83   if (obj_p == obj_C) foo() ;  
     84   if (obj_C == obj_p) foo() ;
     85   if (obj_cp == obj_C) foo() ;  
     86   if (obj_C == obj_cp) foo() ;
     87 
     88   return 0;
     89 }
     90