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

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
This commit is contained in:
Nicola Pero 2011-06-05 17:37:06 +00:00 committed by Nicola Pero
parent b74b757924
commit 419b55d0f9
7 changed files with 66 additions and 14 deletions

View 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

View 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);
}
}

View 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

View 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];

View 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 ();

View 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];

View 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 ();