Commit 3a3589b4 by Ziemowit Laski

c-common.h: Remove RID_ID.

[gcc/ChangeLog]
2004-10-25  David Ayers  <d.ayers@inode.at>

	* c-common.h: Remove RID_ID.
	* c-parse.in: Remove OBJECTNAME and references to RID_ID.
	(typespec_reserved_attr): Add rule for TYPENAME
	non_empty_protocolrefs.
	(yylexname): Remove special handling of RID_ID.

[gcc/objc/ChangeLog]
2004-10-25  Ziemowit Laski  <zlaski@apple.com>
	    David Ayers  <d.ayers@inode.at>

	* objc-act.c (objc_comptypes): Use IS_PROTOCOL_QUALIFIED_UNTYPED
	instead of IS_PROTOCOL_QUALIFIED_ID; add comparisons for:
	'Class <Protocol> != id <Protocol>'; 'Class <Protocol> != <class> *';
	'Class <Protocol> == id' and 'Class <Protocol> == Class'.
	(objc_is_id): Add test for 'super'.
	(objc_finish_message_expr): Allow for messaging of 'Class <Proto>'
	receivers; if class methods are not found in protocol lists, search
	for instance methods therein and warn if one is found.  Look in
	global hash tables for suitable method as a last resort when messaging
	'id <Proto>', 'Class <Proto>' and invalid receiver types.
	(objc_add_method): Insert instance methods listed in protocols into
	the global class method hash table.
	* objc-act.h (IS_PROTOCOL_QUALIFIED_ID): Rename to
	IS_PROTOCOL_QUALIFIED_UNTYPED and allow for 'Class <Proto>' in
	addition to 'id <Proto>'.

[gcc/testsuite/ChangeLog]
2004-10-25  David Ayers  <d.ayers@inode.at>
	    Ziemowit Laski  <zlaski@apple.com>

	* objc.dg/call-super-2.m: Add messages to 'Class <Proto>'; update
	diagnostics when messaging 'id <Proto>'.
	* objc.dg/class-protocol-1.m: New test.
	* objc.dg/desig-init-1.m: Add message to an invalid receiver using
	a non-existent method signature.
	* objc.dg/method-5.m, objc.dg/method-6.m, objc.dg/proto-hier-1.m:
	Update diagnostics when messaging with non-existent method signature.
	* objc.dg/proto-hier-2.m: Adjust wording of diagnostic.
	* objc.dg/proto-lossage-1.m, objc.dg/proto-lossage-4.m: Messages to
	invalid receivers are now resolved as if messaging 'id'; remove
	extraneous diagnostics.

From-SVN: r89562
parent 53071270
2004-10-25 David Ayers <d.ayers@inode.at>
* c-common.h: Remove RID_ID.
* c-parse.in: Remove OBJECTNAME and references to RID_ID.
(typespec_reserved_attr): Add rule for TYPENAME
non_empty_protocolrefs.
(yylexname): Remove special handling of RID_ID.
2004-10-25 James E Wilson <wilson@specifixinc.com> 2004-10-25 James E Wilson <wilson@specifixinc.com>
* doc/invoke.texi (-fcrossjumping): Not enabled at -O. * doc/invoke.texi (-fcrossjumping): Not enabled at -O.
......
...@@ -92,7 +92,7 @@ enum rid ...@@ -92,7 +92,7 @@ enum rid
RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST,
/* Objective-C */ /* Objective-C */
RID_ID, RID_AT_ENCODE, RID_AT_END, RID_AT_ENCODE, RID_AT_END,
RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS, RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS,
RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC, RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC,
RID_AT_PROTOCOL, RID_AT_SELECTOR, RID_AT_PROTOCOL, RID_AT_SELECTOR,
......
...@@ -178,7 +178,7 @@ do { \ ...@@ -178,7 +178,7 @@ do { \
Objective C, so that the token codes are the same in both. */ Objective C, so that the token codes are the same in both. */
%token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS AT_ENCODE %token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS AT_ENCODE
%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL %token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL
%token OBJECTNAME AT_CLASS AT_ALIAS %token AT_CLASS AT_ALIAS
%token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED %token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
%token OBJC_STRING %token OBJC_STRING
...@@ -259,7 +259,7 @@ do { \ ...@@ -259,7 +259,7 @@ do { \
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
%type <ttype> non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr %type <ttype> non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING OBJC_TYPE_QUAL %type <ttype> CLASSNAME OBJC_STRING OBJC_TYPE_QUAL
%type <ttype> superclass objc_quals objc_qual objc_typename %type <ttype> superclass objc_quals objc_qual objc_typename
%type <itype> objc_try_catch_stmt optellipsis %type <itype> objc_try_catch_stmt optellipsis
...@@ -472,7 +472,6 @@ identifier: ...@@ -472,7 +472,6 @@ identifier:
IDENTIFIER IDENTIFIER
| TYPENAME | TYPENAME
@@ifobjc @@ifobjc
| OBJECTNAME
| CLASSNAME | CLASSNAME
@@end_ifobjc @@end_ifobjc
; ;
...@@ -1281,7 +1280,7 @@ typespec_nonreserved_nonattr: ...@@ -1281,7 +1280,7 @@ typespec_nonreserved_nonattr:
| CLASSNAME protocolrefs | CLASSNAME protocolrefs
{ $$.kind = ctsk_objc; { $$.kind = ctsk_objc;
$$.spec = objc_get_protocol_qualified_type ($1, $2); } $$.spec = objc_get_protocol_qualified_type ($1, $2); }
| OBJECTNAME protocolrefs | TYPENAME non_empty_protocolrefs
{ $$.kind = ctsk_objc; { $$.kind = ctsk_objc;
$$.spec = objc_get_protocol_qualified_type ($1, $2); } $$.spec = objc_get_protocol_qualified_type ($1, $2); }
...@@ -1567,10 +1566,6 @@ after_type_declarator: ...@@ -1567,10 +1566,6 @@ after_type_declarator:
{ $$ = make_pointer_declarator ($2, $3); } { $$ = make_pointer_declarator ($2, $3); }
| TYPENAME | TYPENAME
{ $$ = build_id_declarator ($1); } { $$ = build_id_declarator ($1); }
@@ifobjc
| OBJECTNAME
{ $$ = build_id_declarator ($1); }
@@end_ifobjc
; ;
/* Kinds of declarator that can appear in a parameter list /* Kinds of declarator that can appear in a parameter list
...@@ -1589,10 +1584,6 @@ parm_declarator_starttypename: ...@@ -1589,10 +1584,6 @@ parm_declarator_starttypename:
{ $$ = set_array_declarator_inner ($2, $1, false); } { $$ = set_array_declarator_inner ($2, $1, false); }
| TYPENAME | TYPENAME
{ $$ = build_id_declarator ($1); } { $$ = build_id_declarator ($1); }
@@ifobjc
| OBJECTNAME
{ $$ = build_id_declarator ($1); }
@@end_ifobjc
; ;
parm_declarator_nostarttypename: parm_declarator_nostarttypename:
...@@ -2884,7 +2875,6 @@ selector: ...@@ -2884,7 +2875,6 @@ selector:
IDENTIFIER IDENTIFIER
| TYPENAME | TYPENAME
| CLASSNAME | CLASSNAME
| OBJECTNAME
| reservedwords | reservedwords
; ;
...@@ -3144,7 +3134,6 @@ static const struct resword reswords[] = ...@@ -3144,7 +3134,6 @@ static const struct resword reswords[] =
{ "while", RID_WHILE, 0 }, { "while", RID_WHILE, 0 },
@@ifobjc @@ifobjc
{ "id", RID_ID, D_OBJC },
/* These objc keywords are recognized only immediately after /* These objc keywords are recognized only immediately after
an '@'. */ an '@'. */
...@@ -3287,7 +3276,6 @@ static const short rid_to_yy[RID_MAX] = ...@@ -3287,7 +3276,6 @@ static const short rid_to_yy[RID_MAX] =
/* RID_STATCAST */ 0, /* RID_STATCAST */ 0,
/* Objective C */ /* Objective C */
/* RID_ID */ OBJECTNAME,
/* RID_AT_ENCODE */ AT_ENCODE, /* RID_AT_ENCODE */ AT_ENCODE,
/* RID_AT_END */ AT_END, /* RID_AT_END */ AT_END,
/* RID_AT_CLASS */ AT_CLASS, /* RID_AT_CLASS */ AT_CLASS,
...@@ -3356,15 +3344,6 @@ yylexname (void) ...@@ -3356,15 +3344,6 @@ yylexname (void)
enum rid rid_code = C_RID_CODE (yylval.ttype); enum rid rid_code = C_RID_CODE (yylval.ttype);
@@ifobjc @@ifobjc
/* Turn non-typedefed refs to "id" into plain identifiers; this
allows constructs like "void foo(id id);" to work. */
if (rid_code == RID_ID)
{
decl = lookup_name (yylval.ttype);
if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
return IDENTIFIER;
}
if (!OBJC_IS_AT_KEYWORD (rid_code) if (!OBJC_IS_AT_KEYWORD (rid_code)
&& (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context)) && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
@@end_ifobjc @@end_ifobjc
...@@ -3527,7 +3506,6 @@ yyprint (FILE *file, int yychar, YYSTYPE yyl) ...@@ -3527,7 +3506,6 @@ yyprint (FILE *file, int yychar, YYSTYPE yyl)
{ {
case IDENTIFIER: case IDENTIFIER:
case TYPENAME: case TYPENAME:
case OBJECTNAME:
case TYPESPEC: case TYPESPEC:
case TYPE_QUAL: case TYPE_QUAL:
case SCSPEC: case SCSPEC:
......
2004-10-25 Ziemowit Laski <zlaski@apple.com>
David Ayers <d.ayers@inode.at>
* objc-act.c (objc_comptypes): Use IS_PROTOCOL_QUALIFIED_UNTYPED
instead of IS_PROTOCOL_QUALIFIED_ID; add comparisons for:
'Class <Protocol> != id <Protocol>'; 'Class <Protocol> != <class> *';
'Class <Protocol> == id' and 'Class <Protocol> == Class'.
(objc_is_id): Add test for 'super'.
(objc_finish_message_expr): Allow for messaging of 'Class <Proto>'
receivers; if class methods are not found in protocol lists, search
for instance methods therein and warn if one is found. Look in
global hash tables for suitable method as a last resort when messaging
'id <Proto>', 'Class <Proto>' and invalid receiver types.
(objc_add_method): Insert instance methods listed in protocols into
the global class method hash table.
* objc-act.h (IS_PROTOCOL_QUALIFIED_ID): Rename to
IS_PROTOCOL_QUALIFIED_UNTYPED and allow for 'Class <Proto>' in
addition to 'id <Proto>'.
2004-10-21 Andrew Pinski <pinskia@physics.uc.edu> 2004-10-21 Andrew Pinski <pinskia@physics.uc.edu>
PR objc/17923 PR objc/17923
......
...@@ -866,8 +866,8 @@ objc_comptypes (tree lhs, tree rhs, int reflexive) ...@@ -866,8 +866,8 @@ objc_comptypes (tree lhs, tree rhs, int reflexive)
&& TREE_CODE (rhs) == POINTER_TYPE && TREE_CODE (rhs) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE) && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
{ {
int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs); int lhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (lhs);
int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs); int rhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (rhs);
if (lhs_is_proto) if (lhs_is_proto)
{ {
...@@ -878,6 +878,11 @@ objc_comptypes (tree lhs, tree rhs, int reflexive) ...@@ -878,6 +878,11 @@ objc_comptypes (tree lhs, tree rhs, int reflexive)
/* <Protocol> = <Protocol> */ /* <Protocol> = <Protocol> */
if (rhs_is_proto) if (rhs_is_proto)
{ {
/* Class <Protocol> != id <Protocol>;
id <Protocol> != Class <Protocol> */
if (IS_ID (lhs) != IS_ID (rhs))
return 0;
rproto_list = TYPE_PROTOCOL_LIST (rhs); rproto_list = TYPE_PROTOCOL_LIST (rhs);
if (!reflexive) if (!reflexive)
...@@ -942,6 +947,10 @@ objc_comptypes (tree lhs, tree rhs, int reflexive) ...@@ -942,6 +947,10 @@ objc_comptypes (tree lhs, tree rhs, int reflexive)
tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs)); tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
tree rinter; tree rinter;
/* Class <Protocol> != <class> * */
if (IS_CLASS (lhs))
return 0;
/* Make sure the protocol is supported by the object on /* Make sure the protocol is supported by the object on
the rhs. */ the rhs. */
for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
...@@ -985,15 +994,15 @@ objc_comptypes (tree lhs, tree rhs, int reflexive) ...@@ -985,15 +994,15 @@ objc_comptypes (tree lhs, tree rhs, int reflexive)
} }
return 1; return 1;
} }
/* <Protocol> = id */ /* id <Protocol> = id; Class <Protocol> = id */
else if (objc_is_object_id (TREE_TYPE (rhs))) else if (objc_is_object_id (TREE_TYPE (rhs)))
{ {
return 1; return 1;
} }
/* <Protocol> = Class */ /* id <Protocol> != Class; Class <Protocol> = Class */
else if (objc_is_class_id (TREE_TYPE (rhs))) else if (objc_is_class_id (TREE_TYPE (rhs)))
{ {
return 0; return IS_CLASS (lhs);
} }
/* <Protocol> = ?? : let comptypes decide. */ /* <Protocol> = ?? : let comptypes decide. */
return -1; return -1;
...@@ -1003,6 +1012,10 @@ objc_comptypes (tree lhs, tree rhs, int reflexive) ...@@ -1003,6 +1012,10 @@ objc_comptypes (tree lhs, tree rhs, int reflexive)
/* <class> * = <Protocol> */ /* <class> * = <Protocol> */
if (TYPED_OBJECT (TREE_TYPE (lhs))) if (TYPED_OBJECT (TREE_TYPE (lhs)))
{ {
/* <class> * != Class <Protocol> */
if (IS_CLASS (rhs))
return 0;
if (reflexive) if (reflexive)
{ {
tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs)); tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
...@@ -1062,15 +1075,15 @@ objc_comptypes (tree lhs, tree rhs, int reflexive) ...@@ -1062,15 +1075,15 @@ objc_comptypes (tree lhs, tree rhs, int reflexive)
else else
return 0; return 0;
} }
/* id = <Protocol> */ /* id = id <Protocol>; id = Class <Protocol> */
else if (objc_is_object_id (TREE_TYPE (lhs))) else if (objc_is_object_id (TREE_TYPE (lhs)))
{ {
return 1; return 1;
} }
/* Class = <Protocol> */ /* Class != id <Protocol>; Class = Class <Protocol> */
else if (objc_is_class_id (TREE_TYPE (lhs))) else if (objc_is_class_id (TREE_TYPE (lhs)))
{ {
return 0; return IS_CLASS (rhs);
} }
/* ??? = <Protocol> : let comptypes decide */ /* ??? = <Protocol> : let comptypes decide */
else else
...@@ -2714,7 +2727,8 @@ objc_is_id (tree type) ...@@ -2714,7 +2727,8 @@ objc_is_id (tree type)
/* NB: This function may be called before the ObjC front-end has /* NB: This function may be called before the ObjC front-end has
been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */ been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
return (objc_object_type && type && (IS_ID (type) || IS_CLASS (type)) return (objc_object_type && type
&& (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
? type ? type
: NULL_TREE); : NULL_TREE);
} }
...@@ -5567,25 +5581,35 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params) ...@@ -5567,25 +5581,35 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
{ {
if (!rtype) if (!rtype)
rtype = xref_tag (RECORD_TYPE, class_tree); rtype = xref_tag (RECORD_TYPE, class_tree);
else if (IS_ID (rtype)) else
{ {
class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
rprotos = TYPE_PROTOCOL_LIST (rtype); rprotos = TYPE_PROTOCOL_LIST (rtype);
rtype = NULL_TREE; rtype = NULL_TREE;
} }
else
{
class_tree = objc_class_name;
OBJC_SET_TYPE_NAME (rtype, class_tree);
}
if (rprotos) if (rprotos)
{
/* If messaging 'id <Protos>' or 'Class <Proto>', first search
in protocols themselves for the method prototype. */
method_prototype method_prototype
= lookup_method_in_protocol_list (rprotos, sel_name, = lookup_method_in_protocol_list (rprotos, sel_name,
class_tree != NULL_TREE); class_tree != NULL_TREE);
if (!method_prototype && !rprotos)
/* If messaging 'Class <Proto>' but did not find a class method
prototype, search for an instance method instead, and warn
about having done so. */
if (!method_prototype && !rtype && class_tree != NULL_TREE)
{
method_prototype method_prototype
= lookup_method_in_hash_lists (sel_name, = lookup_method_in_protocol_list (rprotos, sel_name, 0);
class_tree != NULL_TREE);
if (method_prototype)
warning ("found `-%s' instead of `+%s' in protocol(s)",
IDENTIFIER_POINTER (sel_name),
IDENTIFIER_POINTER (sel_name));
}
}
} }
else else
{ {
...@@ -5642,10 +5666,28 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params) ...@@ -5642,10 +5666,28 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
{ {
warning ("invalid receiver type `%s'", warning ("invalid receiver type `%s'",
gen_type_name (orig_rtype)); gen_type_name (orig_rtype));
/* After issuing the "invalid receiver" warning, perform method
lookup as if we were messaging 'id'. */
rtype = rprotos = NULL_TREE; rtype = rprotos = NULL_TREE;
} }
} }
/* For 'id' or 'Class' receivers, search in the global hash table
as a last resort. For all receivers, warn if protocol searches
have failed. */
if (!method_prototype)
{
if (rprotos)
warning ("`%c%s' not found in protocol(s)",
(class_tree ? '+' : '-'),
IDENTIFIER_POINTER (sel_name));
if (!rtype)
method_prototype
= lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
}
if (!method_prototype) if (!method_prototype)
{ {
static bool warn_missing_methods = false; static bool warn_missing_methods = false;
...@@ -5655,10 +5697,14 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params) ...@@ -5655,10 +5697,14 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)), IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
(class_tree ? '+' : '-'), (class_tree ? '+' : '-'),
IDENTIFIER_POINTER (sel_name)); IDENTIFIER_POINTER (sel_name));
if (rprotos) /* If we are messaging an 'id' or 'Class' object and made it here,
warning ("`%c%s' not implemented by protocol(s)", then we have failed to find _any_ instance or class method,
respectively. */
else
warning ("no `%c%s' method found",
(class_tree ? '+' : '-'), (class_tree ? '+' : '-'),
IDENTIFIER_POINTER (sel_name)); IDENTIFIER_POINTER (sel_name));
if (!warn_missing_methods) if (!warn_missing_methods)
{ {
warning ("(Messages without a matching method signature"); warning ("(Messages without a matching method signature");
...@@ -6160,13 +6206,16 @@ objc_add_method (tree class, tree method, int is_class) ...@@ -6160,13 +6206,16 @@ objc_add_method (tree class, tree method, int is_class)
add_method_to_hash_list (nst_method_hash_list, method); add_method_to_hash_list (nst_method_hash_list, method);
/* Instance methods in root classes (and categories thereof) /* Instance methods in root classes (and categories thereof)
may acts as class methods as a last resort. */ may act as class methods as a last resort. We also add
instance methods listed in @protocol declarations to
the class hash table, on the assumption that @protocols
may be adopted by root classes or categories. */
if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
|| TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE) || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
class = lookup_interface (CLASS_NAME (class)); class = lookup_interface (CLASS_NAME (class));
if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
&& !CLASS_SUPER_NAME (class)) || !CLASS_SUPER_NAME (class))
add_method_to_hash_list (cls_method_hash_list, method); add_method_to_hash_list (cls_method_hash_list, method);
} }
......
...@@ -277,8 +277,8 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX]; ...@@ -277,8 +277,8 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX];
(POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE (objc_object_type)) (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE (objc_object_type))
#define IS_CLASS(TYPE) \ #define IS_CLASS(TYPE) \
(POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE (objc_class_type)) (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE (objc_class_type))
#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \ #define IS_PROTOCOL_QUALIFIED_UNTYPED(TYPE) \
(IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE)) ((IS_ID (TYPE) || IS_CLASS (TYPE)) && TYPE_PROTOCOL_LIST (TYPE))
#define IS_SUPER(TYPE) \ #define IS_SUPER(TYPE) \
(POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == objc_super_template) (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == objc_super_template)
......
2004-10-25 David Ayers <d.ayers@inode.at>
Ziemowit Laski <zlaski@apple.com>
* objc.dg/call-super-2.m: Add messages to 'Class <Proto>'; update
diagnostics when messaging 'id <Proto>'.
* objc.dg/class-protocol-1.m: New test.
* objc.dg/desig-init-1.m: Add message to an invalid receiver using
a non-existent method signature.
* objc.dg/method-5.m, objc.dg/method-6.m, objc.dg/proto-hier-1.m:
Update diagnostics when messaging with non-existent method signature.
* objc.dg/proto-hier-2.m: Adjust wording of diagnostic.
* objc.dg/proto-lossage-1.m, objc.dg/proto-lossage-4.m: Messages to
invalid receivers are now resolved as if messaging 'id'; remove
extraneous diagnostics.
2004-10-25 Joseph S. Myers <jsm@polyomino.org.uk> 2004-10-25 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/16667 PR c/16667
......
...@@ -46,15 +46,14 @@ ...@@ -46,15 +46,14 @@
+ (int) class_func1 + (int) class_func1
{ {
int i = (size_t)[self class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */ int i = (size_t)[self class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 48 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 48 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 48 } */
return i + (size_t)[super class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */ return i + (size_t)[super class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
} }
+ (int) class_func2 + (int) class_func2
{ {
int i = [(id <Func>)self class_func0]; int i = [(id <Func>)self class_func0]; /* { dg-warning ".\\-class_func0. not found in protocol" } */
return i + [(id <Func>)super class_func0]; i += [(id <Func>)super class_func0]; /* { dg-warning ".\\-class_func0. not found in protocol" } */
i += [(Class <Func>)self class_func0];
return i + [(Class <Func>)super class_func0];
} }
+ (int) class_func3 + (int) class_func3
{ {
...@@ -120,16 +119,18 @@ ...@@ -120,16 +119,18 @@
} }
+ (int) categ_class_func2 + (int) categ_class_func2
{ {
int i = [(id <Func>)self class_func0]; int i = [(id <Func>)self class_func0]; /* { dg-warning ".\\-class_func0. not found in protocol" } */
return i + [(id <Func>)super class_func0]; i += [(id <Func>)super class_func0]; /* { dg-warning ".\\-class_func0. not found in protocol" } */
i += [(Class <Func>)self class_func0];
return i + [(Class <Func>)super class_func0];
} }
- (int) categ_instance_func1 - (int) categ_instance_func1
{ {
int i = (size_t)[self instance_func0]; /* { dg-warning ".Derived. may not respond to .\\-instance_func0." } */ int i = (size_t)[self instance_func0]; /* { dg-warning ".Derived. may not respond to .\\-instance_func0." } */
i += [(Derived <Func> *)self categ_instance_func2]; i += [(Derived <Func> *)self categ_instance_func2];
i += (size_t)[(Object <Func> *)self categ_instance_func2]; /* { dg-warning ".Object. may not respond to .\\-categ_instance_func2." } */ i += (size_t)[(Object <Func> *)self categ_instance_func2]; /* { dg-warning ".Object. may not respond to .\\-categ_instance_func2." } */
/* { dg-warning ".\\-categ_instance_func2. not implemented by protocol" "" { target *-*-* } 130 } */ /* { dg-warning ".\\-categ_instance_func2. not found in protocol" "" { target *-*-* } 131 } */
i += (size_t)[(id <Func>)self categ_instance_func2]; /* { dg-warning ".\\-categ_instance_func2. not implemented by protocol" } */ i += (size_t)[(id <Func>)self categ_instance_func2]; /* { dg-warning ".\\-categ_instance_func2. not found in protocol" } */
i += [(id)self categ_instance_func2]; i += [(id)self categ_instance_func2];
return i + (size_t)[super instance_func0]; /* { dg-warning ".Object. may not respond to .\\-instance_func0." } */ return i + (size_t)[super instance_func0]; /* { dg-warning ".Object. may not respond to .\\-instance_func0." } */
} }
...@@ -138,3 +139,7 @@ ...@@ -138,3 +139,7 @@
return [(id <Func>)super instance_func0]; return [(id <Func>)super instance_func0];
} }
@end @end
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
/* { dg-do run } */ /* { dg-do run } */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <objc/objc.h> #include <objc/objc.h>
#include <objc/Object.h> #include <objc/Object.h>
...@@ -18,19 +19,20 @@ ...@@ -18,19 +19,20 @@
+ (int) meth1 { return 45; } + (int) meth1 { return 45; }
+ (int) meth2 { return 21; } + (int) meth2 { return 21; }
+ (void) doTests { + (void) doTests {
int arr[6] = { int arr[7] = {
0, 0,
[Cls meth1], [Cls meth1],
[2 + 1] = 3, [2 + 1] = 3,
[2 * 2 ... 5] = (size_t)[0 meth2], /* { dg-warning "invalid receiver type" } */ [2 * 2 ... 5] = (size_t)[0 meth4], /* { dg-warning "invalid receiver type" } */
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */ /* { dg-warning "no .\\-meth4. method found" "" { target *-*-* } 26 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */ [2] [Cls meth2],
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */ /* Since invalid receivers are treated as 'id' for purposes of message
[2] [Cls meth2] lookup, we _should_ find a meth2 to call below. */
[6] = (int)[0 meth2] /* { dg-warning "invalid receiver type" } */
}; };
if (arr[0] != 0 || arr[1] != 45 || arr[2] != 21 || arr[3] != 3) if (arr[0] != 0 || arr[1] != 45 || arr[2] != 21 || arr[3] != 3)
abort (); /* { dg-warning "implicit declaration" } */ abort ();
printf ("%s\n", [super name]); printf ("%s\n", [super name]);
printf ("%d %d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]); printf ("%d %d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]);
...@@ -41,3 +43,7 @@ int main(void) { ...@@ -41,3 +43,7 @@ int main(void) {
[Cls doTests]; [Cls doTests];
return 0; return 0;
} }
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
...@@ -9,10 +9,12 @@ typedef struct NotAClass { ...@@ -9,10 +9,12 @@ typedef struct NotAClass {
void foo(UnderSpecified *u, NotAClass *n) { void foo(UnderSpecified *u, NotAClass *n) {
[n nonexistent_method]; /* { dg-warning "invalid receiver type" } */ [n nonexistent_method]; /* { dg-warning "invalid receiver type" } */
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 11 } */ /* { dg-warning "no .\\-nonexistent_method. method found" "" { target *-*-* } 11 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 11 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 11 } */
[NotAClass nonexistent_method]; /* { dg-error ".NotAClass. is not an Objective\\-C class name or alias" } */ [NotAClass nonexistent_method]; /* { dg-error ".NotAClass. is not an Objective\\-C class name or alias" } */
[u nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\-nonexistent_method." } */ [u nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\-nonexistent_method." } */
[UnderSpecified nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\+nonexistent_method." } */ [UnderSpecified nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\+nonexistent_method." } */
} }
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
...@@ -22,7 +22,7 @@ void foo(void) { ...@@ -22,7 +22,7 @@ void foo(void) {
/* { dg-warning "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 9 } */ /* { dg-warning "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 9 } */
/* { dg-warning "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 14 } */ /* { dg-warning "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 14 } */
[receiver starboard]; /* { dg-warning ".Class. may not respond to .\\+starboard." } */ [receiver starboard]; /* { dg-warning "no .\\+starboard. method found" } */
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */
......
...@@ -48,9 +48,11 @@ int foo(void) { ...@@ -48,9 +48,11 @@ int foo(void) {
id<Booing, Fooing> stupidVar; id<Booing, Fooing> stupidVar;
[stupidVar boo]; [stupidVar boo];
[stupidVar foo]; [stupidVar foo];
[stupidVar anotherMsg]; /* { dg-warning ".\-anotherMsg. not implemented by protocol" } */ [stupidVar anotherMsg]; /* { dg-warning ".\\-anotherMsg. not found in protocol" } */
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 51 } */ /* { dg-warning "no .\\-anotherMsg. method found" "" { target *-*-* } 51 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 51 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 51 } */
return 0; return 0;
} }
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
...@@ -41,7 +41,7 @@ typedef struct ...@@ -41,7 +41,7 @@ typedef struct
id one = [self anotherDataSource]; id one = [self anotherDataSource];
i = i - 1; i = i - 1;
// Do not issue warning about my_method not implemented by protocol // Do not issue warning about my_method not found in protocol
return [(one ? [self mainDataSource] : one) my_method:i]; return [(one ? [self mainDataSource] : one) my_method:i];
} }
......
...@@ -35,14 +35,10 @@ typedef struct objc_object { struct objc_class *class_pointer; } *id; ...@@ -35,14 +35,10 @@ typedef struct objc_object { struct objc_class *class_pointer; } *id;
return (id <NSObject>)plate1; /* { dg-bogus "does not conform" } */ return (id <NSObject>)plate1; /* { dg-bogus "does not conform" } */
} }
- (int) getValue { - (int) getValue {
int i = [plate1 someValue]; /* { dg-warning ".\\-someValue. not implemented by protocol\\(s\\)" } */ int i = [plate1 someValue]; /* { dg-warning ".\\-someValue. not found in protocol\\(s\\)" } */
/* { dg-warning "\\(Messages without a matching method signature" "" { target *-*-* } 38 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 38 } */
/* { dg-warning ".\.\.\.. as arguments\.\\)" "" { target *-*-* } 38 } */
/* { dg-warning "initialization makes integer from pointer without a cast" "" { target *-*-* } 38 } */
int j = [(id <NSObject>)plate1 someValue]; /* { dg-bogus "not implemented by protocol" } */ int j = [(id <NSObject>)plate1 someValue]; /* { dg-bogus "not found in protocol" } */
int k = [(id)plate1 someValue]; /* { dg-bogus "not implemented by protocol" } */ int k = [(id)plate1 someValue]; /* { dg-bogus "not found in protocol" } */
return i + j + k; return i + j + k;
} }
@end @end
...@@ -19,23 +19,20 @@ long foo(void) { ...@@ -19,23 +19,20 @@ long foo(void) {
Obj *objrcvr; Obj *objrcvr;
Obj <Proto> *objrcvr2; Obj <Proto> *objrcvr2;
receiver += [receiver someValue]; /* { dg-warning "invalid receiver type .long int." } */ /* NB: Since 'receiver' is an invalid ObjC message receiver, the compiler
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 22 } */ should warn but then search for methods as if we were messaging 'id'. */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 22 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 22 } */
/* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 22 } */
receiver += [receiver someValue]; /* { dg-warning "invalid receiver type .long int." } */
receiver += [receiver anotherValue]; /* { dg-warning "invalid receiver type .long int." } */ receiver += [receiver anotherValue]; /* { dg-warning "invalid receiver type .long int." } */
/* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 28 } */
receiver += [(Obj *)receiver someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */ receiver += [(Obj *)receiver someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
/* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 31 } */ /* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 28 } */
receiver += [(Obj *)receiver anotherValue]; receiver += [(Obj *)receiver anotherValue];
receiver += [(Obj <Proto> *)receiver someValue]; receiver += [(Obj <Proto> *)receiver someValue];
receiver += [(Obj <Proto> *)receiver anotherValue]; receiver += [(Obj <Proto> *)receiver anotherValue];
receiver += [objrcvr someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */ receiver += [objrcvr someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
/* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 37 } */ /* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 34 } */
receiver += [objrcvr anotherValue]; receiver += [objrcvr anotherValue];
receiver += [(Obj <Proto> *)objrcvr someValue]; receiver += [(Obj <Proto> *)objrcvr someValue];
...@@ -43,9 +40,13 @@ long foo(void) { ...@@ -43,9 +40,13 @@ long foo(void) {
receiver += [objrcvr2 someValue]; receiver += [objrcvr2 someValue];
receiver += [objrcvr2 anotherValue]; receiver += [objrcvr2 anotherValue];
receiver += [(Obj *)objrcvr2 someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */ receiver += [(Obj *)objrcvr2 someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
/* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 45 } */ /* { dg-warning "assignment makes integer from pointer without a cast" "" { target *-*-* } 42 } */
receiver += [(Obj *)objrcvr2 anotherValue]; receiver += [(Obj *)objrcvr2 anotherValue];
return receiver; return receiver;
} }
/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment