This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: Objective-c prototype search cleanups


Hey Alex,

I've started looking at your patch, and generally it looks great, but I do
have two "issues" with it.


First, the documentation states:
+ @item -Wno-conflicting-prototypes
+ @opindex Wno-conflicting-prototypes
+ When sending a message to a receiver whose type is known, that type is
+ searched for a method prototype for the message. If multiple conflicting
+ prototypes are found, a warning is issued. This can happen if, e.g., a class
+ and its superclass both declare a method, but with different return or
+ argument types. If you use the @code{Wno-conflicting-prototypes} option, no
+ warnings are issued.
+


My question is, if a class declares a method, why even look in the superclass (or
any of its categories)? It is very clear which one the runtime will use. Furthermore,
the current approach (i.e., allowing superclass method prototypes to differ) allows for
at least an "appearance" of covariant return type support. :-)


Secondly, if no matching method prototype is found, you put in a last-ditch attempt
to find it in the hash tables. This sometimes succeeds and sometimes fails, leading
to an inconsistent failure mode. Furthermore, whenever you do find a selector in a
hash table, you do not appear to check for duplicates. If one is to consult the hash
tables at all, I think it should be done in the same way as when messaging 'id' or 'Class'
(and preferrably in the same place in the code).


I'm sure we're all going to have a meaningful discussion on this, as always. :-) In the meantime,
is it OK if I just commit the 'instance methods of root class considered class methods' part
of your patch? I'd like to label the patch with your name, but I'm not sure what your copyright
assignment status is. Please let me know,


Thanks,

--Zem


On Monday, Sep 29, 2003, at 13:02 US/Pacific, Alexander Malmberg wrote:


Alexander Malmberg wrote:
Hi,

Here is the message sending prototype search patch again, now against
mainline.
[...]

And of course, I send an old diff. Sorry about that. A correct version
of the diff is attached. (The test cases were correct in the previous
mail.)

- Alexander Malmberg? gcc/testsuite/objc.dg/missing-interface.m
? gcc/testsuite/objc.dg/prototype-1.m
? gcc/testsuite/objc.dg/prototype-2.m
? gcc/testsuite/objc.dg/prototype-3.m
? gcc/testsuite/objc.dg/prototype-4.m
? gcc/testsuite/objc.dg/prototype-5.m
Index: gcc/c-common.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.461
diff -u -r1.461 c-common.c
--- gcc/c-common.c	25 Sep 2003 01:25:43 -0000	1.461
+++ gcc/c-common.c	29 Sep 2003 19:48:25 -0000
@@ -497,6 +497,11 @@

int warn_protocol = 1;

+/* Warn if multiple prototypes are found when sending a message to a receiver
+ with a known type. */
+
+int warn_conflicting_prototypes = 1;
+


/* C++ language option variables. */

Index: gcc/c-common.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.209
diff -u -r1.209 c-common.h
--- gcc/c-common.h	25 Sep 2003 01:25:45 -0000	1.209
+++ gcc/c-common.h	29 Sep 2003 19:48:25 -0000
@@ -660,6 +660,11 @@

extern int warn_protocol;

+/* Warn if multiple prototypes are found when sending a message to a receiver
+ with a known type. */
+
+extern int warn_conflicting_prototypes;
+


/* C++ language option variables. */

Index: gcc/c-opts.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.90
diff -u -r1.90 c-opts.c
--- gcc/c-opts.c	25 Sep 2003 01:25:46 -0000	1.90
+++ gcc/c-opts.c	29 Sep 2003 19:48:27 -0000
@@ -406,6 +406,10 @@
       cpp_opts->warn_comments = value;
       break;

+    case OPT_Wconflicting_prototypes:
+      warn_conflicting_prototypes = value;
+      break;
+
     case OPT_Wconversion:
       warn_conversion = value;
       break;
Index: gcc/c.opt
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c.opt,v
retrieving revision 1.17
diff -u -r1.17 c.opt
--- gcc/c.opt	25 Sep 2003 01:25:50 -0000	1.17
+++ gcc/c.opt	29 Sep 2003 19:48:29 -0000
@@ -172,6 +172,10 @@
 C ObjC C++ ObjC++
 Synonym for -Wcomment

+Wconflicting-prototypes
+ObjC ObjC++
+Warn if multiple conflicting prototypes are found for a message to a typed receiver
+
Wconversion
C ObjC C++ ObjC++
Warn about possibly confusing type conversions
Index: gcc/doc/invoke.texi
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.339
diff -u -r1.339 invoke.texi
--- gcc/doc/invoke.texi 25 Sep 2003 01:25:52 -0000 1.339
+++ gcc/doc/invoke.texi 29 Sep 2003 19:48:37 -0000
@@ -1954,6 +1954,15 @@
compilation. This also enforces the coding style convention
that methods and selectors must be declared before being used.


+@item -Wno-conflicting-prototypes
+@opindex Wno-conflicting-prototypes
+When sending a message to a receiver whose type is known, that type is
+searched for a method prototype for the message. If multiple conflicting
+prototypes are found, a warning is issued. This can happen if, e.g., a class
+and its superclass both declare a method, but with different return or
+argument types. If you use the @code{Wno-conflicting-prototypes} option, no
+warnings are issued.
+
@c not documented because only avail via -Wp
@c @item -print-objc-runtime-info


Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.194
diff -u -r1.194 objc-act.c
--- gcc/objc/objc-act.c	25 Sep 2003 17:53:41 -0000	1.194
+++ gcc/objc/objc-act.c	29 Sep 2003 19:48:41 -0000
@@ -182,7 +182,6 @@
 static hash hash_lookup (hash *, tree);
 static void hash_add_attr (hash, tree);
 static tree lookup_method (tree, tree);
-static tree lookup_method_static (tree, tree, int);
 static tree add_class (tree);
 static void add_category (tree, tree);

@@ -198,6 +197,29 @@
 static tree build_objc_string_decl (enum string_section);
 static tree build_selector_reference_decl (void);

+/* Searching for a prototype for a selector. */
+
+/* These methods are used to search for a suitable prototype for a receiver
+ of a known type. Currently, these are used in finish_message_expr() and
+ really_start_method(). */
+
+/* The prototype found in the prototype search. If multiple prototypes
+ were found, this will be the first found prototype. */
+static GTY(()) tree current_found_prototype;
+static int num_found_prototypes;
+
+/* If warnings about conflicting prototypes are turned off, this will be set
+ to 1 as soon as a prototype is found, indicating that the search does not
+ need to proceed. (Finding additional prototypes does no harm, but it's
+ a waste of time.) */
+static int prototype_search_done;
+
+static void prototype_search_start (const char *);
+static void prototype_search_end (void);
+static void prototype_found (tree);
+static void lookup_method_static (tree, tree, int);
+static void lookup_method_in_protocol_list (tree, tree, int);
+
/* Protocol additions. */


 static tree add_protocol (tree);
@@ -239,7 +261,6 @@
 /* Everything else.  */

 static tree define_decl (tree, tree);
-static tree lookup_method_in_protocol_list (tree, tree, int);
 static tree lookup_protocol_in_reflist (tree, tree);
 static tree create_builtin_decl (enum tree_code, tree, const char *);
 static void setup_string_decl (void);
@@ -559,39 +580,6 @@
 }

 static tree
-lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
-				int class_meth)
-{
-   tree rproto, p;
-   tree fnd = 0;
-
-   for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
-     {
-        p = TREE_VALUE (rproto);
-
-	if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
-	  {
-	    if ((fnd = lookup_method (class_meth
-				      ? PROTOCOL_CLS_METHODS (p)
-				      : PROTOCOL_NST_METHODS (p), sel_name)))
-	      ;
-	    else if (PROTOCOL_LIST (p))
-	      fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
-						    sel_name, class_meth);
-	  }
-	else
-          {
-	    ; /* An identifier...if we could not find a protocol.  */
-          }
-
-	if (fnd)
-	  return fnd;
-     }
-
-   return 0;
-}
-
-static tree
 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
 {
   tree rproto, p;
@@ -5663,6 +5651,10 @@
   tree selector, retval, is_class;
   int self, super, have_cast;

+  /* A description of the receiver's type we use when reporting
+     errors/warnings. Currently, will always point at errbuf.  */
+  char *report_type;
+
   /* Extract the receiver of the message, as well as its type
      (where the latter may take the form of a cast or be inferred
      from the implementation context).  */
@@ -5680,15 +5672,25 @@
 		   && !IS_SUPER (rtype)));

/* If the receiver is a class object, retrieve the corresponding
- @interface, if one exists. */
+ @interface, if one exists. */
is_class = receiver_is_class_object (receiver, self, super);
-
- /* Now determine the receiver type (if an explicit cast has not been
- provided). */
- if (!have_cast)
+
+ /* Now determine the receiver type if an explicit cast has not been
+ provided. Generate a description of the receiver's type and place
+ it in report_type. */
+ if (!have_cast)
{
if (is_class)
- rtype = lookup_interface (is_class);
+ {
+ rtype = lookup_interface (is_class);
+ if (!rtype)
+ warning ("no interface seen for `%s'",
+ IDENTIFIER_POINTER (is_class));
+
+ report_type = errbuf;
+ sprintf (report_type, "%s",
+ IDENTIFIER_POINTER (is_class));
+ }
/* Handle `self' and `super'. */
else if (super)
{
@@ -5699,40 +5701,51 @@
return error_mark_node;
}
rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
+
+ report_type = errbuf;
+ sprintf (report_type, "%s",
+ IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)));
}
else if (self)
- rtype = lookup_interface (CLASS_NAME (implementation_template));
- }
-
- /* If receiver is of type `id' or `Class' (or if the @interface for a
- class is not visible), we shall be satisfied with the existence of
- any instance or class method. */
- if (!rtype || IS_ID (rtype)
- || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
- {
- if (!rtype)
- rtype = xref_tag (RECORD_TYPE, is_class);
- else if (IS_ID (rtype))
{
- rprotos = TYPE_PROTOCOL_LIST (rtype);
- rtype = NULL_TREE;
+ rtype = lookup_interface (CLASS_NAME (implementation_template));
+
+ report_type = errbuf;
+ sprintf (report_type, "%s",
+ IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
}
else
- is_class = TYPE_NAME (rtype) = get_identifier ("Class");
-
- if (rprotos)
- method_prototype
- = lookup_method_in_protocol_list (rprotos, sel_name,
- is_class != NULL_TREE);
- if (!method_prototype && !rprotos)
- method_prototype
- = (is_class
- ? check_duplicates (hash_lookup (cls_method_hash_list, sel_name), 1)
- : lookup_method_in_hash_lists (sel_name));
+ report_type = gen_declaration (rtype, errbuf);
}
else
+ report_type = gen_declaration (rtype, errbuf);
+
+ /* Search for a suitable prototype. If we can't find one, we use our
+ fallback prototype: id (*)(id,SEL,...).
+
+ First we check if the type information known for the receiver gives any
+ prototypes. If this gives us a unique prototype, we use it. If it gives
+ several prototypes, we warn and use the "derived-most" prototype.
+
+ If the type information does not provide any prototypes, we search for
+ one among all known prototypes. However, if the receiver is a class
+ object according to the type information, we only search among prototypes
+ for class methods, and instance methods in root classes.
+
+ If this gives us one unique prototype, we use it. If the receiver wasn't
+ of type 'id' or 'Class', we issue a warning.
+
+ If this gives us more than one prototype, or no prototype, we issue an
+ appropriate warning and use one of them. */
+
+ prototype_search_start (report_type);
+
+ /* Search for a prototype given by the class part of the receiver's type,
+ if any. */
+ if (rtype && !IS_ID (rtype)
+ && TREE_TYPE (rtype) != TREE_TYPE (objc_class_type))
{
- tree orig_rtype = rtype, saved_rtype;
+ tree saved_rtype;


       if (TREE_CODE (rtype) == POINTER_TYPE)
 	rtype = TREE_TYPE (rtype);
@@ -5741,73 +5754,141 @@
 	     && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
 	     && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
 	rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
+
       saved_rtype = rtype;
       if (TYPED_OBJECT (rtype))
 	{
 	  rprotos = TYPE_PROTOCOL_LIST (rtype);
 	  rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
 	}
+
       /* If we could not find an @interface declaration, we must have
 	 only seen a @class declaration; so, we cannot say anything
 	 more intelligent about which methods the receiver will
 	 understand. */
       if (!rtype)
-	rtype = saved_rtype;
+ 	{
+	  rtype = saved_rtype;
+	  warning ("no interface seen for `%s'",
+		   IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)));
+	}
       else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
 	  || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
 	{
 	  /* We have a valid ObjC class name.  Look up the method name
-	     in the published @interface for the class (and its
+	     in the published @interface(s) for the class (and its
 	     superclasses). */
-	  method_prototype
-	    = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
+	  lookup_method_static (rtype, sel_name, is_class != NULL_TREE);

-	  /* If the method was not found in the @interface, it may still
-	     exist locally as part of the @implementation.  */
-	  if (!method_prototype && objc_implementation_context
+	  /* The method may also exist locally as part of the
+	     @implementation.  */
+	  if (!prototype_search_done
+	     && objc_implementation_context
 	     && CLASS_NAME (objc_implementation_context)
-		== OBJC_TYPE_NAME (rtype))			
-	    method_prototype
-	      = lookup_method
-		((is_class
-		  ? CLASS_CLS_METHODS (objc_implementation_context)
-		  : CLASS_NST_METHODS (objc_implementation_context)),
-		  sel_name);
-
-	  /* If we haven't found a candidate method by now, try looking for
-	     it in the protocol list.  */
-	  if (!method_prototype && rprotos)
-	    method_prototype
-	      = lookup_method_in_protocol_list (rprotos, sel_name,
-						is_class != NULL_TREE);
+		== OBJC_TYPE_NAME (rtype))
+	    {
+	      tree possible_prototype;
+
+	      if (is_class)
+		{
+		  possible_prototype
+		    = lookup_method
+		      (CLASS_CLS_METHODS (objc_implementation_context),
+		       sel_name);
+		  if (possible_prototype)
+		    prototype_found (possible_prototype);
+
+		  /* If we are a root class, the instance methods also apply
+		     to the class.  */
+		  if (!prototype_search_done && !CLASS_SUPER_NAME (rtype))
+		    {
+		      possible_prototype
+			= lookup_method
+			  (CLASS_NST_METHODS (objc_implementation_context),
+			   sel_name);
+		      if (possible_prototype)
+			prototype_found (possible_prototype);
+		    }
+		}
+	      else
+		{
+		  possible_prototype
+		    = lookup_method
+		      (CLASS_NST_METHODS (objc_implementation_context),
+		       sel_name);
+		  if (possible_prototype)
+		    prototype_found (possible_prototype);
+		}
+	    }
 	}
       else
 	{
-	  warning ("invalid receiver type `%s'",
-		   gen_declaration (orig_rtype, errbuf));
-	  rtype = rprotos = NULL_TREE;
+	  warning ("invalid receiver type `%s'", report_type);
+	  rtype = rprotos = is_class = NULL_TREE;
 	}
-    }	
+    }
+  else if (rtype && IS_ID (rtype))
+    {
+      rprotos = TYPE_PROTOCOL_LIST (rtype);
+    }

- if (!method_prototype)
+ /* Now look in the protocol list. */
+ if (!prototype_search_done && rprotos)
+ lookup_method_in_protocol_list (rprotos, sel_name,
+ is_class != NULL_TREE);
+
+ prototype_search_end ();
+
+ if (num_found_prototypes == 1)
+ {
+ /* We found exactly one. Use it. */
+ method_prototype = current_found_prototype;
+ }
+ else if (num_found_prototypes > 1)
+ {
+ /* We found more than one. prototype_found() will already have issued
+ warnings. We set method_prototype to the first one, which will
+ be the "derived-most" prototype. */
+ method_prototype = current_found_prototype;
+ }
+ else
{
- static bool warn_missing_methods = false;
+ /* The type information didn't give us any prototypes. Thus, we check
+ if there are any known prototypes at all. */


- if (rtype)
- warning ("`%s' may not respond to `%c%s'",
- IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
- (is_class ? '+' : '-'),
- IDENTIFIER_POINTER (sel_name));
- if (rprotos)
- warning ("`%c%s' not implemented by protocol(s)",
- (is_class ? '+' : '-'),
+ if (rtype && TREE_TYPE (rtype) == TREE_TYPE (objc_class_type)
+ && !IS_ID (rtype))
+ is_class = get_identifier ("Class");
+
+ /* If the object is "typed", ie. not just 'id' or 'Class', issue a
+ warning. */
+ if (rprotos || !rtype
+ || (!IS_ID (rtype)
+ && TREE_TYPE (rtype) != TREE_TYPE (objc_class_type)))
+ warning ("receiver of type `%s' may not respond to `%c%s'",
+ report_type, (is_class ? '+' : '-'),
IDENTIFIER_POINTER (sel_name));
- if (!warn_missing_methods)
+
+ method_prototype
+ = (is_class
+ ? check_duplicates (hash_lookup (cls_method_hash_list, sel_name), 1)
+ : lookup_method_in_hash_lists (sel_name));
+
+ if (!method_prototype)
{
- warning ("(Messages without a matching method signature");
- warning ("will be assumed to return `id' and accept");
- warning ("`...' as arguments.)");
- warn_missing_methods = true;
+ static bool warn_missing_methods = false;
+
+ warning ("no prototype found for `%c%s'",
+ (is_class ? '+' : '-'),
+ IDENTIFIER_POINTER (sel_name));
+
+ if (!warn_missing_methods)
+ {
+ warning ("(Messages without a matching method prototype");
+ warning ("will be assumed to return `id' and accept");
+ warning ("`...' as arguments.)");
+ warn_missing_methods = true;
+ }
}
}


@@ -6177,27 +6258,74 @@
entry->list = obj; /* append to front */
}

-static tree
-lookup_method (tree mchain, tree method)
+static GTY(()) const char *prototype_search_type;
+
+/* Start a prototype search. type is a string describing the receiver's
+ type, and is used when issuing warnings. */
+static void
+prototype_search_start (const char *type)
{
- tree key;
+ prototype_search_type = type;
+ num_found_prototypes = 0;
+ current_found_prototype = 0;
+ prototype_search_done = 0;
+}


-  if (TREE_CODE (method) == IDENTIFIER_NODE)
-    key = method;
-  else
-    key = METHOD_SEL_NAME (method);
+static void
+prototype_search_end (void)
+{
+  prototype_search_type = 0;
+}

- while (mchain)
+/* Called when a prototype is found. Will check if it's compatible with
+ the prototype already found, issue warnings if necessary, and update
+ current_found_prototype and num_found_prototypes as necessary. */
+static void
+prototype_found (tree prototype)
+{
+ if (!warn_conflicting_prototypes)
{
- if (METHOD_SEL_NAME (mchain) == key)
- return mchain;
+ /* This might be called several times even if warnings are turned off.
+ If so, we ignore all calls except the first. */
+ if (num_found_prototypes == 0)
+ current_found_prototype = prototype;
+ num_found_prototypes = 1;
+ prototype_search_done = 1;
+ return;
+ }


- mchain = TREE_CHAIN (mchain);
+ /* If we've found exactly one prototype, and the new prototype is
+ compatible, do nothing. */
+ if (num_found_prototypes == 1
+ && comp_proto_with_proto (prototype, current_found_prototype))
+ return;
+
+ num_found_prototypes++;
+ if (num_found_prototypes > 1)
+ {
+ char type = (TREE_CODE (prototype) == INSTANCE_METHOD_DECL) ? '-' : '+';
+
+ if (num_found_prototypes == 2)
+ {
+ warning ("multiple methods named `%c%s' found for receiver of type `%s'",
+ type,
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (prototype)),
+ prototype_search_type);
+ warn_with_method ("using", type,
+ current_found_prototype);
+ warn_with_method ("instead of", type, prototype);
+ }
+ else
+ warn_with_method ("or", type, prototype);
}
- return NULL_TREE;
+ else
+ current_found_prototype = prototype;
}


-static tree
+/* Look for prototypes for a selector in an interface (including all
+ categories and protocols, and then all superclasses, for that interface).
+ Any prototypes found are passed to prototype_found(). */
+static void
lookup_method_static (tree interface, tree ident, int is_class)
{
tree meth = NULL_TREE, root_inter = NULL_TREE;
@@ -6208,54 +6336,144 @@
tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
tree category = inter;


-      /* First, look up the method in the class itself.  */
+      /* Look up the method in the class itself.  */
       if ((meth = lookup_method (chain, ident)))
-	return meth;
+	{
+	  prototype_found (meth);
+	  if (prototype_search_done)
+	    return;
+	}

- /* Failing that, look for the method in each category of the class. */
+ /* Look for the method in each category of the class. */
while ((category = CLASS_CATEGORY_LIST (category)))
{
chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);


 	  /* Check directly in each category.  */
 	  if ((meth = lookup_method (chain, ident)))
-	    return meth;
+	    {
+	      prototype_found (meth);
+	      if (prototype_search_done)
+		return;
+	    }

-	  /* Failing that, check in each category's protocols.  */
+	  /* Check in each category's protocols.  */
 	  if (CLASS_PROTOCOL_LIST (category))
 	    {
-	      if ((meth = (lookup_method_in_protocol_list
-			   (CLASS_PROTOCOL_LIST (category), ident, is_class))))
-		return meth;
+	      lookup_method_in_protocol_list
+		(CLASS_PROTOCOL_LIST (category), ident, is_class);
+	      if (prototype_search_done)
+		return;
 	    }
 	}

- /* If not found in categories, check in protocols of the main class. */
+ /* Check in protocols of the main class. */
if (CLASS_PROTOCOL_LIST (inter))
{
- if ((meth = (lookup_method_in_protocol_list
- (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
- return meth;
+ lookup_method_in_protocol_list
+ (CLASS_PROTOCOL_LIST (inter), ident, is_class);
+ if (prototype_search_done)
+ return;
}


-      /* Failing that, climb up the inheritance hierarchy.  */
+      /* Climb up the inheritance hierarchy.  */
       root_inter = inter;
       inter = lookup_interface (CLASS_SUPER_NAME (inter));
     }
   while (inter);

- /* If no class (factory) method was found, check if an _instance_
+ /* If the receiver is a class object, check if an _instance_
method of the same name exists in the root class. This is what
- the Objective-C runtime will do. If an instance method was not
- found, return 0. */
- return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
+ the Objective-C runtime will do. */
+ if (is_class)
+ lookup_method_static (root_inter, ident, 0);
+}
+
+/* Look for prototypes for a selector in a set of protocols (including
+ protocols the protocols inherit from). Any prototypes that are found
+ will be passed to prototype_found(). */
+static void
+lookup_method_in_protocol_list (tree rproto_list, tree sel_name, int class_meth)
+{
+ tree rproto, p;
+ tree fnd;
+
+ for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
+ {
+ p = TREE_VALUE (rproto);
+
+ if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
+ {
+ /* Check the protocol itself. */
+ if ((fnd = lookup_method (class_meth
+ ? PROTOCOL_CLS_METHODS (p)
+ : PROTOCOL_NST_METHODS (p), sel_name)))
+ {
+ prototype_found (fnd);
+ if (prototype_search_done)
+ return;
+ }
+ /* Check the protocols this protocol inherits from. */
+ if (PROTOCOL_LIST (p))
+ {
+ lookup_method_in_protocol_list (PROTOCOL_LIST (p),
+ sel_name, class_meth);
+ if (prototype_search_done)
+ return;
+ }
+ }
+ }
+}
+
+static tree
+lookup_method (tree mchain, tree method)
+{
+ tree key;
+
+ if (TREE_CODE (method) == IDENTIFIER_NODE)
+ key = method;
+ else
+ key = METHOD_SEL_NAME (method);
+
+ while (mchain)
+ {
+ if (METHOD_SEL_NAME (mchain) == key)
+ return mchain;
+
+ mchain = TREE_CHAIN (mchain);
+ }
+ return NULL_TREE;
+}
+
+
+/* Add the method to the hash list if it doesn't contain an identical
+ method already. */
+static void
+add_method_to_hash_list (hash *hash_list, tree method)
+{
+ hash hsh;
+
+ if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
+ {
+ /* Install on a global chain. */
+ hash_enter (hash_list, method);
+ }
+ else
+ {
+ /* Check types against those; if different, add to a list. */
+ attr loop;
+ int already_there = comp_proto_with_proto (method, hsh->key);
+ for (loop = hsh->list; !already_there && loop; loop = loop->next)
+ already_there |= comp_proto_with_proto (method, loop->value);
+ if (!already_there)
+ hash_add_attr (hsh, method);
+ }
}


 tree
 add_method (tree class, tree method, int is_class)
 {
   tree mth;
-  hash hsh;

if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
{
@@ -6273,10 +6491,11 @@
}
else
{
- /* When processing an @interface for a class or category, give hard errors on methods with
- identical selectors but differing argument and/or return types. We do not do this for
- @implementations, because C/C++ will do it for us (i.e., there will be
- duplicate function definition errors). */
+ /* When processing an @interface for a class or category, give hard
+ errors on methods with identical selectors but differing argument
+ and/or return types. We do not do this for @implementations, because
+ C/C++ will do it for us (i.e., there will be duplicate function
+ definition errors). */
if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
|| TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
&& !comp_proto_with_proto (method, mth))
@@ -6284,23 +6503,21 @@
is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
}


- if (!(hsh = hash_lookup (is_class
- ? cls_method_hash_list
- : nst_method_hash_list, METHOD_SEL_NAME (method))))
- {
- /* Install on a global chain. */
- hash_enter (is_class ? cls_method_hash_list : nst_method_hash_list, method);
- }
+ if (is_class)
+ add_method_to_hash_list (cls_method_hash_list, method);
else
{
- /* Check types against those; if different, add to a list. */
- attr loop;
- int already_there = comp_proto_with_proto (method, hsh->key);
- for (loop = hsh->list; !already_there && loop; loop = loop->next)
- already_there |= comp_proto_with_proto (method, loop->value);
- if (!already_there)
- hash_add_attr (hsh, method);
+ add_method_to_hash_list (nst_method_hash_list, method);
+
+ /* Instance methods in root classes are inherited by class objects,
+ so we add those methods to the class method list, too.
+
+ TODO: We should do this for categories of root classes as well. */
+ if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
+ && !CLASS_SUPER_NAME (class))
+ add_method_to_hash_list (cls_method_hash_list, method);
}
+
return method;
}


@@ -7768,17 +7985,24 @@

if (implementation_template != objc_implementation_context)
{
- tree proto
- = lookup_method_static (implementation_template,
- METHOD_SEL_NAME (method),
- TREE_CODE (method) == CLASS_METHOD_DECL);
-
- if (proto && ! comp_method_with_proto (method, proto))
+ prototype_search_start
+ (IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
+ lookup_method_static (implementation_template,
+ METHOD_SEL_NAME (method),
+ TREE_CODE (method) == CLASS_METHOD_DECL);
+ prototype_search_end ();
+
+ /* If we found exactly one prototype, check that the implementation
+ matches it (if there's more than one, warnings will already have
+ been issued during the search). */
+ if (num_found_prototypes == 1
+ && !comp_method_with_proto (method, current_found_prototype))
{
char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');


warn_with_method ("conflicting types for", type, method);
- warn_with_method ("previous declaration of", type, proto);
+ warn_with_method ("previous declaration of", type,
+ current_found_prototype);
}
}
}
Index: gcc/testsuite/objc.dg/call-super-2.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/call-super-2.m,v
retrieving revision 1.2
diff -u -r1.2 call-super-2.m
--- gcc/testsuite/objc.dg/call-super-2.m 25 Sep 2003 01:26:00 -0000 1.2
+++ gcc/testsuite/objc.dg/call-super-2.m 29 Sep 2003 19:48:48 -0000
@@ -44,11 +44,8 @@
@implementation Derived
+ (int) class_func1
{
- int i = (int)[self class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
- /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 47 } */
- /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 47 } */
- /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 47 } */
- return i + (int)[super class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+ int i = (int)[self class_func0]; /* { dg-warning "receiver of type .Derived. may not respond to .\\+class_func0." } */
+ return i + (int)[super class_func0]; /* { dg-warning "receiver of type .Object. may not respond to .\\+class_func0." } */
}
+ (int) class_func2
{
@@ -65,12 +62,12 @@
}
+ (int) class_func5
{
- int i = (int)[Derived class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
- return i + (int)[Object class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+ int i = (int)[Derived class_func0]; /* { dg-warning "receiver of type .Derived. may not respond to .\\+class_func0." } */
+ return i + (int)[Object class_func0]; /* { dg-warning "receiver of type .Object. may not respond to .\\+class_func0." } */
}
+ (int) class_func6
{
- return (int)[OBJC_GETCLASS("Object") class_func1]; /* { dg-warning ".Object. may not respond to .\\+class_func1." } */
+ return (int)[OBJC_GETCLASS("Object") class_func1]; /* { dg-warning "receiver of type .Object. may not respond to .\\+class_func1." } */
}
+ (int) class_func7
{
@@ -78,8 +75,8 @@
}
- (int) instance_func1
{
- int i = (int)[self instance_func0]; /* { dg-warning ".Derived. may not respond to .\\-instance_func0." } */
- return i + (int)[super instance_func0]; /* { dg-warning ".Object. may not respond to .\\-instance_func0." } */
+ int i = (int)[self instance_func0]; /* { dg-warning "receiver of type .Derived. may not respond to .\\-instance_func0." } */
+ return i + (int)[super instance_func0]; /* { dg-warning "receiver of type .Object. may not respond to .\\-instance_func0." } */
}
- (int) instance_func2
{
@@ -95,12 +92,17 @@
}
- (int) instance_func5
{
- int i = (int)[Derived instance_func1]; /* { dg-warning ".Derived. may not respond to .\\+instance_func1." } */
- return i + (int)[Object instance_func1]; /* { dg-warning ".Object. may not respond to .\\+instance_func1." } */
+ int i = (int)[Derived instance_func1]; /* { dg-warning "receiver of type .Derived. may not respond to .\\+instance_func1." } */
+ /* { dg-warning "no prototype found for .\\+instance_func1." "" { target *-*-* } 95 } */
+ /* { dg-warning "\\(Messages without a matching method prototype" "" { target *-*-* } 95 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 95 } */
+ /* { dg-warning ".\.\.\.. as arguments\.\\)" "" { target *-*-* } 95 } */
+ return i + (int)[Object instance_func1]; /* { dg-warning "receiver of type .Object. may not respond to .\\+instance_func1." } */
+ /* { dg-warning "no prototype found for .\\+instance_func1." "" { target *-*-* } 100 } */
}
- (int) instance_func6
{
- return (int)[OBJC_GETCLASS("Object") class_func1]; /* { dg-warning ".Object. may not respond to .\\+class_func1." } */
+ return (int)[OBJC_GETCLASS("Object") class_func1]; /* { dg-warning "receiver of type .Object. may not respond to .\\+class_func1." } */
}
- (int) instance_func7
{
@@ -111,11 +113,12 @@
@implementation Derived (Categ)
+ (int) categ_class_func1
{
- int i = (int)[self class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
+ int i = (int)[self class_func0]; /* { dg-warning "receiver of type .Derived. may not respond to .\\+class_func0." } */
i += [self class_func1];
i += [self categ_class_func2];
- i += (int)[self categ_instance_func1]; /* { dg-warning ".Derived. may not respond to .\\+categ_instance_func1." } */
- return i + (int)[super class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+ i += (int)[self categ_instance_func1]; /* { dg-warning "receiver of type .Derived. may not respond to .\\+categ_instance_func1." } */
+ /* { dg-warning "no prototype found for .\\+categ_instance_func1." "" { target *-*-* } 119 } */
+ return i + (int)[super class_func0]; /* { dg-warning "receiver of type .Object. may not respond to .\\+class_func0." } */
}
+ (int) categ_class_func2
{
@@ -124,13 +127,12 @@
}
- (int) categ_instance_func1
{
- int i = (int)[self instance_func0]; /* { dg-warning ".Derived. may not respond to .\\-instance_func0." } */
+ int i = (int)[self instance_func0]; /* { dg-warning "receiver of type .Derived. may not respond to .\\-instance_func0." } */
i += [(Derived <Func> *)self categ_instance_func2];
- i += (int)[(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 *-*-* } 129 } */
- i += (int)[(id <Func>)self categ_instance_func2]; /* { dg-warning ".\\-categ_instance_func2. not implemented by protocol" } */
+ i += (int)[(Object <Func> *)self categ_instance_func2]; /* { dg-warning "receiver of type .Object <Func> \\*. may not respond to .\\-categ_instance_func2." } */
+ i += (int)[(id <Func>)self categ_instance_func2]; /* { dg-warning "receiver of type .id <Func>. may not respond to .\\-categ_instance_func2." } */
i += [(id)self categ_instance_func2];
- return i + (int)[super instance_func0]; /* { dg-warning ".Object. may not respond to .\\-instance_func0." } */
+ return i + (int)[super instance_func0]; /* { dg-warning "receiver of type .Object. may not respond to .\\-instance_func0." } > */
}
- (int) categ_instance_func2
{
Index: gcc/testsuite/objc.dg/desig-init-1.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/desig-init-1.m,v
retrieving revision 1.2
diff -u -r1.2 desig-init-1.m
--- gcc/testsuite/objc.dg/desig-init-1.m 25 Sep 2003 01:26:00 -0000 1.2
+++ gcc/testsuite/objc.dg/desig-init-1.m 29 Sep 2003 19:48:48 -0000
@@ -22,10 +22,8 @@
0,
[Cls meth1],
[2 + 1] = 3,
- [2 * 2 ... 5] = (int)[0 meth2], /* { dg-warning "invalid receiver type" } */
- /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */
- /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */
- /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */
+ [2 * 2 ... 5] = (int)[0 meth2], /* { dg-warning "invalid receiver type .int ." } */
+ /* { dg-warning "receiver of type .int . may not respond to .\\-meth2." "" { target *-*-* } 25 } */
[2] [Cls meth2]
};


Index: gcc/testsuite/objc.dg/method-2.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/method-2.m,v
retrieving revision 1.2
diff -u -r1.2 method-2.m
--- gcc/testsuite/objc.dg/method-2.m 25 Sep 2003 01:26:01 -0000 1.2
+++ gcc/testsuite/objc.dg/method-2.m 29 Sep 2003 19:48:48 -0000
@@ -22,11 +22,13 @@
[self rootInstanceMethod]; /* class is searched for an instance method */
[MyIntermediate rootInstanceMethod]; /* with the same name. */


- [self instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */
- /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */
+ [self instanceMethod]; /* { dg-warning "receiver of type .MyDerived. may not respond to .\\+instanceMethod." } */
+ /* { dg-warning "no prototype found for .\\+instanceMethod." "" { target *-*-* } 25 } */
+ /* { dg-warning "\\(Messages without a matching method prototype" "" { 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 } */
[MyDerived instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */
+ /* { dg-warning "no prototype found for .\\+instanceMethod." "" { target *-*-* } 30 } */
}
@end


Index: gcc/testsuite/objc.dg/method-5.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/method-5.m,v
retrieving revision 1.2
diff -u -r1.2 method-5.m
--- gcc/testsuite/objc.dg/method-5.m	25 Sep 2003 01:26:01 -0000	1.2
+++ gcc/testsuite/objc.dg/method-5.m	29 Sep 2003 19:48:48 -0000
@@ -8,11 +8,17 @@
 } NotAClass;

void foo(UnderSpecified *u, NotAClass *n) {
- [n nonexistent_method]; /* { dg-warning "invalid receiver type" } */
- /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 11 } */
+ [n nonexistent_method]; /* { dg-warning "invalid receiver type .untagged struct \\*." } */
+ /* { dg-warning "receiver of type .untagged struct \\*. may not respond to .\\-nonexistent_method." "" { target *-*-* } 11 } */
+ /* { dg-warning "no prototype found for .\\-nonexistent_method." "" { target *-*-* } 11 } */
+ /* { dg-warning "\\(Messages without a matching method prototype" "" { target *-*-* } 11 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 11 } */
- /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 11 } */
+ /* { dg-warning ".\.\.\.. as arguments\\.\\)" "" { target *-*-* } 11 } */
[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." } */
- [UnderSpecified nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\+nonexistent_method." } */
+ [u nonexistent_method]; /* { dg-warning "no interface seen for .UnderSpecified." } */
+ /* { dg-warning "receiver of type .UnderSpecified \\*. may not respond to .\\-nonexistent_method." "" { target *-*-* } 18 } */
+ /* { dg-warning "no prototype found for .\\-nonexistent_method." "" { target *-*-* } 18 } */
+ [UnderSpecified nonexistent_method]; /* { dg-warning "no interface seen for .UnderSpecified." } */
+ /* { dg-warning "receiver of type .UnderSpecified. may not respond to .\\+nonexistent_method." "" { target *-*-* } 21 } */
+ /* { dg-warning "no prototype found for .\\+nonexistent_method." "" { target *-*-* } 21 } */
}
Index: gcc/testsuite/objc.dg/method-6.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/method-6.m,v
retrieving revision 1.2
diff -u -r1.2 method-6.m
--- gcc/testsuite/objc.dg/method-6.m 25 Sep 2003 01:26:01 -0000 1.2
+++ gcc/testsuite/objc.dg/method-6.m 29 Sep 2003 19:48:48 -0000
@@ -1,26 +1,38 @@
-/* Check that sending messages to variables of type 'Class' does not involve instance methods. */
+/* Check that sending messages to variables of type 'Class' does not involve instance methods not in root classes. */
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */


#include <objc/Protocol.h>

 @interface Base
-- (unsigned)port;
+- (unsigned)port1;
 - (id)starboard;
 @end

 @interface Derived: Base
-- (Object *)port;
-+ (Protocol *)port;
+- (Object *)port1;
++ (Protocol *)port1;
+- (Object *)port2;
++ (Protocol *)port2;
+- (Object *)port3;
 @end

id foo(void) {
Class receiver;
- id p = [receiver port]; /* there should be no warnings here! */
- p = [receiver starboard]; /* { dg-warning ".Class. may not respond to .\\+starboard." } */
- /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 20 } */
- /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 20 } */
- /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 20 } */
- p = [Class port]; /* { dg-error ".Class. is not an Objective\\-C class name or alias" } */
- return p;
+ id p1 = [receiver port1]; /* { dg-warning "multiple methods named .\\-port1. found" } */
+ /* { dg-warning "using .\\-\\(unsigned\\)port1." "" { target *-*-* } 8 } */
+ /* { dg-warning "also found .\\-\\(Protocol \\*\\)port1." "" { target *-*-* } 14 } */
+ /* { dg-warning "initialization makes pointer from integer without a cast" "" { target *-*-* } 22 } */
+ id p2 = [receiver port2]; /* there should be no warnings here! */
+ id p3 = [receiver port3]; /* { dg-warning "no prototype found for .\\+port3." } */
+ /* { dg-warning "\\(Messages without a matching method prototype" "" { target *-*-* } 27 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 27 } */
+ /* { dg-warning ".\.\.\.. as arguments\.\\)" "" { target *-*-* } 27 } */
+ p1 = [receiver starboard]; /* No warning here as Class is treated like id (i.e. all class methods are matched) */
+ p1 = [Base port1]; /* { dg-warning "assignment makes pointer from integer without a cast" } */
+ p1 = [Derived port1]; /* { dg-warning "multiple methods named .\\-port1. found for receiver of type .Derived." } */
+ /* { dg-warning "using .\\-\\(Protocol \\*\\)port1." "" { target *-*-* } 14 } */
+ /* { dg-warning "instead of .\\-\\(unsigned\\)port1." "" { target *-*-* } 8 } */
+ p2 = [Derived port2]; /* No warning, using class method */
+ return p1;
}
Index: gcc/testsuite/objc.dg/method-7.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/method-7.m,v
retrieving revision 1.2
diff -u -r1.2 method-7.m
--- gcc/testsuite/objc.dg/method-7.m 25 Sep 2003 01:26:01 -0000 1.2
+++ gcc/testsuite/objc.dg/method-7.m 29 Sep 2003 19:48:48 -0000
@@ -15,13 +15,11 @@
id foo(void) {
Object *obj = [[Object alloc] init];
id obj2 = obj;
- [obj setWindow:nil]; /* { dg-warning ".Object. may not respond to .\\-setWindow:." } */
- /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 18 } */
- /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 18 } */
- /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 18 } */
- [obj2 setWindow:nil]; /* { dg-warning "multiple methods named .\\-setWindow:. found" } */
+ [obj setWindow:nil]; /* { dg-warning "receiver of type .Object \\*. may not respond to .\\-setWindow:." } */
+ /* { dg-warning "multiple methods named .\\-setWindow:. found" "" { target *-*-* } 18 } */
/* { dg-warning "using .\\-\\(void\\)setWindow:\\(Object \\*\\)wdw." "" { target *-*-* } 8 } */
/* { dg-warning "also found .\\-\\(void\\)setWindow:\\(Class1 \\*\\)window." "" { target *-*-* } 12 } */
+ [obj2 setWindow:nil]; /* { dg-warning "multiple methods named .\\-setWindow:. found" } */


return obj;
}
Index: gcc/testsuite/objc.dg/proto-hier-1.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/proto-hier-1.m,v
retrieving revision 1.2
diff -u -r1.2 proto-hier-1.m
--- gcc/testsuite/objc.dg/proto-hier-1.m 25 Sep 2003 01:26:01 -0000 1.2
+++ gcc/testsuite/objc.dg/proto-hier-1.m 29 Sep 2003 19:48:49 -0000
@@ -48,8 +48,9 @@
id<Booing, Fooing> stupidVar;
[stupidVar boo];
[stupidVar foo];
- [stupidVar anotherMsg]; /* { dg-warning ".\-anotherMsg. not implemented by protocol" } */
- /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 51 } */
+ [stupidVar anotherMsg]; /* { dg-warning "receiver of type .id <Booing, Fooing>. may not respond to .\-anotherMsg." } */
+ /* { dg-warning "no prototype found for .\-anotherMsg." "" { target *-*-* } 51 } */
+ /* { dg-warning "Messages without a matching method prototype" "" { target *-*-* } 51 } */
/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 51 } */
/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 51 } */
return 0;
Index: gcc/testsuite/objc.dg/proto-lossage-1.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/proto-lossage-1.m,v
retrieving revision 1.2
diff -u -r1.2 proto-lossage-1.m
--- gcc/testsuite/objc.dg/proto-lossage-1.m 25 Sep 2003 01:26:01 -0000 1.2
+++ gcc/testsuite/objc.dg/proto-lossage-1.m 29 Sep 2003 19:48:49 -0000
@@ -35,11 +35,7 @@
return (id <NSObject>)plate1; /* { dg-bogus "does not conform" } */
}
- (int) getValue {
- int i = [plate1 someValue]; /* { dg-warning ".\\-someValue. not implemented by 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 i = [plate1 someValue]; /* { dg-warning "receiver of type .id <PlateMethods>. may not respond to .\\-someValue." } */


int j = [(id <NSObject>)plate1 someValue]; /* { dg-bogus "not implemented by protocol" } */
int k = [(id)plate1 someValue]; /* { dg-bogus "not implemented by protocol" } */


--------------------------------------------------------------
Ziemowit Laski                 1 Infinite Loop, MS 301-2K
Mac OS X Compiler Group        Cupertino, CA USA  95014-2083
Apple Computer, Inc.           +1.408.974.6229  Fax .5477


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]