Index: gcc/objc/ChangeLog
===================================================================
--- gcc/objc/ChangeLog  (revision 174624)
+++ gcc/objc/ChangeLog  (working copy)
@@ -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: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c (revision 174624)
+++ gcc/objc/objc-act.c (working copy)
@@ -5270,7 +5270,42 @@ receiver_is_class_object (tree receiver, int self,
     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_
            {
              /* 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: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog     (revision 174656)
+++ gcc/testsuite/ChangeLog     (working copy)
@@ -1,5 +1,14 @@
 2011-06-05  Nicola Pero  <nicola.pero@meta-innovation.com>
 
+       PR objc/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
        alignment, not the alignment, when calling class_addIvar().  Add
        an 'isa' instance variable to the test root class.
Index: gcc/testsuite/objc.dg/gnu-api-2-class.m
===================================================================
--- gcc/testsuite/objc.dg/gnu-api-2-class.m     (revision 174655)
+++ gcc/testsuite/objc.dg/gnu-api-2-class.m     (working copy)
@@ -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: gcc/testsuite/objc.dg/gnu-api-2-objc.m
===================================================================
--- gcc/testsuite/objc.dg/gnu-api-2-objc.m      (revision 174656)
+++ gcc/testsuite/objc.dg/gnu-api-2-objc.m      (working copy)
@@ -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 ();
Index: gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm  (revision 174656)
+++ gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm  (working copy)
@@ -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: gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm (revision 174655)
+++ gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm (working copy)
@@ -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];
 
