In gcc/objc/: 2011-06-05 Nicola Pero <nicola.pero@meta-innovation.com>
authorNicola Pero <nicola.pero@meta-innovation.com>
Sun, 5 Jun 2011 17:37:06 +0000 (17:37 +0000)
committerNicola Pero <nicola@gcc.gnu.org>
Sun, 5 Jun 2011 17:37:06 +0000 (17:37 +0000)
In gcc/objc/:
2011-06-05  Nicola Pero  <nicola.pero@meta-innovation.com>

* objc-act.c (receiver_is_class_object): Expanded comment.
(objc_finish_message_expr): Likewise.

In gcc/testsuite/:
2011-06-05  Nicola Pero  <nicola.pero@meta-innovation.com>

PR testsuite/49287
* objc.dg/gnu-api-2-class.m: Updated testcase silencing compiler
warning.
* objc.dg/gnu-api-2-objc.m: Likewise.
* obj-c++.dg/gnu-api-2-class.mm: Likewise
* obj-c++.dg/gnu-api-2-objc.mm: Likewise.

From-SVN: r174657

gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm
gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm
gcc/testsuite/objc.dg/gnu-api-2-class.m
gcc/testsuite/objc.dg/gnu-api-2-objc.m

index 50c80b5c7cb91cba7cf0a0cd4908db976c1a63f4..208decc7c86e826df554ca607d92b0585f1b5ab7 100644 (file)
@@ -1,3 +1,8 @@
+2011-06-05  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc-act.c (receiver_is_class_object): Expanded comment.
+       (objc_finish_message_expr): Likewise.
+
 2011-06-02  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        PR objc/48539
index e7acb7f05b1034635664b8de710fc9eb1dbe617d..321d52aaf28f80457f26e4d086ca0f9db1db9b23 100644 (file)
@@ -5270,7 +5270,42 @@ receiver_is_class_object (tree receiver, int self, int super)
     return exp;
 
   /* The receiver is a function call that returns an id.  Check if
-     it is a call to objc_getClass, if so, pick up the class name.  */
+     it is a call to objc_getClass, if so, pick up the class name.
+
+     This is required by the GNU runtime, which compiles
+
+       [NSObject alloc]
+
+     into
+
+       [objc_get_class ("NSObject") alloc];
+
+     and then, to check that the receiver responds to the +alloc
+     method, needs to be able to determine that the objc_get_class()
+     call returns the NSObject class and not just a generic Class
+     pointer.
+
+     But, traditionally this is enabled for all runtimes, not just the
+     GNU one, which means that the compiler is smarter than you'd
+     expect when dealing with objc_getClass().  For example, with the
+     Apple runtime, in the code
+
+       [objc_getClass ("NSObject")  alloc];
+
+     the compiler will recognize the objc_getClass() call as special
+     (due to the code below) and so will know that +alloc is called on
+     the 'NSObject' class, and can perform the corresponding checks.
+
+     Programmers can disable this behaviour by casting the results of
+     objc_getClass() to 'Class' (this may seem weird because
+     objc_getClass() is already declared to return 'Class', but the
+     compiler treats it as a special function).  This may be useful if
+     the class is never declared, and the compiler would complain
+     about a missing @interface for it.  Then, you can do
+
+       [(Class)objc_getClass ("MyClassNeverDeclared")  alloc];
+
+     to silence the warnings.  */
   if (TREE_CODE (receiver) == CALL_EXPR
       && (exp = CALL_EXPR_FN (receiver))
       && TREE_CODE (exp) == ADDR_EXPR
@@ -5478,13 +5513,16 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params,
            {
              /* If 'rtype' is NULL_TREE at this point it means that
                 we have seen no @interface corresponding to that
-                class name, only a @class declaration.  So, we have a
-                class name (class_tree) but no actual details of the
-                class methods.  We won't be able to check that the
-                class responds to the method, and we will have to
-                guess the method prototype.  Emit a warning, then
-                keep going (this will use any method with a matching
-                name, as if the receiver was of type 'Class').  */
+                class name, only a @class declaration (alternatively,
+                this was a call such as [objc_getClass("SomeClass")
+                alloc], where we've never seen the @interface of
+                SomeClass).  So, we have a class name (class_tree)
+                but no actual details of the class methods.  We won't
+                be able to check that the class responds to the
+                method, and we will have to guess the method
+                prototype.  Emit a warning, then keep going (this
+                will use any method with a matching name, as if the
+                receiver was of type 'Class').  */
              warning (0, "@interface of class %qE not found", class_tree);
            }
        }
index 7194f87fac405ff4159653e88320e05151791626..7fdb2ae2a1d9177c3e796ed5cab0e9a1d74e17cc 100644 (file)
@@ -1,3 +1,12 @@
+2011-06-05  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       PR testsuite/49287
+       * objc.dg/gnu-api-2-class.m: Updated testcase silencing compiler
+       warning.
+       * objc.dg/gnu-api-2-objc.m: Likewise.
+       * obj-c++.dg/gnu-api-2-class.mm: Likewise
+       * obj-c++.dg/gnu-api-2-objc.mm: Likewise.
+       
 2011-06-05  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * objc.dg/gnu-api-2-objc.m: Fixed testcase.  Use log2 of the
index 1e79e9b95c69dd7fb7ef81e08201753c8c7206b4..6dc9dd3733c12bd811ab2a546c96b7b8db76db7e 100644 (file)
@@ -109,7 +109,7 @@ int main ()
     objc_registerClassPair (new_class);    
 
     {
-      MySubClass *o = [[objc_getClass ("MySubSubClass") alloc] init];
+      MySubClass *o = [[(Class)objc_getClass ("MySubSubClass") alloc] init];
       Ivar variable2 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable2_ivar");
       Ivar variable3 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable3_ivar");
       Ivar variable4 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable4_ivar");
@@ -178,7 +178,7 @@ int main ()
     /* Now, MySubClass2 is basically the same as MySubClass!  We'll
        use the variable and setVariable: methods on it.  */
     {
-      MySubClass *o = (MySubClass *)[[objc_getClass ("MySubClass2") alloc] init];
+      MySubClass *o = (MySubClass *)[[(Class)objc_getClass ("MySubClass2") alloc] init];
 
       [o setVariable: o];
 
index ce70c5e434f284dd96d2145647a46e7a75064c6c..e5b1a69ed042e36ae69d210a0b142d6f4b1e5af2 100644 (file)
@@ -93,7 +93,7 @@ int main ()
       abort ();
 
     {
-      MySubClass *o = [[objc_getClass ("MyNewSubClass") alloc] init];
+      MySubClass *o = [[(Class)objc_getClass ("MyNewSubClass") alloc] init];
       
       if (object_getClass (o) != objc_getClass ("MyNewSubClass"))
        abort ();
index f3469f6ede8aa21c259c631d35ec5e512f6852d9..f396a09fad8b6775fc84c05d87b9f89f78ca3289 100644 (file)
@@ -109,7 +109,7 @@ int main(int argc, void **args)
     objc_registerClassPair (new_class);    
 
     {
-      MySubClass *o = [[objc_getClass ("MySubSubClass") alloc] init];
+      MySubClass *o = [[(Class)objc_getClass ("MySubSubClass") alloc] init];
       Ivar variable2 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable2_ivar");
       Ivar variable3 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable3_ivar");
       Ivar variable4 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable4_ivar");
@@ -178,7 +178,7 @@ int main(int argc, void **args)
     /* Now, MySubClass2 is basically the same as MySubClass!  We'll
        use the variable and setVariable: methods on it.  */
     {
-      MySubClass *o = (MySubClass *)[[objc_getClass ("MySubClass2") alloc] init];
+      MySubClass *o = (MySubClass *)[[(Class)objc_getClass ("MySubClass2") alloc] init];
 
       [o setVariable: o];
 
index d1177d70e5330bbcaa52a46b57689642ce48ea34..d65c120455e4aa9b43397743e9eb388f26d1d560 100644 (file)
@@ -93,7 +93,7 @@ int main(int argc, void **args)
       abort ();
 
     {
-      MySubClass *o = [[objc_getClass ("MyNewSubClass") alloc] init];
+      MySubClass *o = [[(Class)objc_getClass ("MyNewSubClass") alloc] init];
       
       if (object_getClass (o) != objc_getClass ("MyNewSubClass"))
        abort ();