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: How to check that selectors exist


> > So: -Wselector would perform checks on the whole selectors table at the
> > end of compilation, while -Wundeclared-selector would check, when a
> > @selector() is found, that is has been already declared (and only with 
> > a
> > single signature).
> > Would that be a reasonable agreement for you ?  If so, I'm happy with 
> > your
> > change going in, and I'll try to implement a -Wundeclared-selector and
> > submit a patch.  :-)
> 
> Sounds like a plan.  I will put my change in today evening.
> 

Here is a set of patches implementing -Wundeclared-selector as promised.

NB: I will be leaving for two weeks on saturday (holidays finally :-).  
If Stan approves it when I'm away, I'm happy with anyone else applying it
(including any sort of reformatting and improvements which might be
necessary).  Else, I'll apply it if approved before I leave (which I
doubt, given how slow Stan is in approving :-), or when I am back.


Thu Aug  8 17:06:44 2002  Nicola Pero  <n.pero@mi.flashnet.it>

	* c-common.c (warn_undeclared_selector): New variable.
	* c-common.h (warn_undeclared_selector): Idem.
	* c-opts.c (c_common_decode_option): Set warn_undeclared_selector
	to on when -Wundeclared-selector is found.
	(COMMAND_LINE_OPTIONS): Added -Wundeclared-selector.
	* objc/objc-act.c (build_selector_expr): If
	warn_undeclared_selector is set, check that the selector has
	already been defined, and emit a warning if not.
	

Index: objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.148
diff -u -r1.148 objc-act.c
--- objc-act.c	7 Aug 2002 18:32:11 -0000	1.148
+++ objc-act.c	8 Aug 2002 15:03:06 -0000
@@ -5124,6 +5124,11 @@
   return expr;
 }
 
+/*
+ * This function is called by the parser when a @selector() expression
+ * is found, in order to compile it.  It is only called by the parser
+ * and only to compile a @selector().
+ */
 tree
 build_selector_expr (selnamelist)
      tree selnamelist;
@@ -5139,6 +5144,36 @@
   else
     abort ();
 
+  /* If we are required to check @selector() expressions as they
+   * are found, check that the selector has been declared.  */
+  if (warn_undeclared_selector)
+    {
+      /* Look the selector up in the list of all known class and
+       * instance methods (up to this line) to check that the selector
+       * exists.  
+       */
+      hash hsh;
+
+      /* First try with instance methods.  */
+      hsh = hash_lookup (nst_method_hash_list, selname);
+      
+      /* If not found, try with class methods.  */
+      if (!hsh)
+	{
+	  hsh = hash_lookup (cls_method_hash_list, selname);
+	}
+      
+      /* If still not found, print out a warning.  */
+      if (!hsh)
+	{
+	  warning ("unknown (undeclared) selector `%s'", 
+		   IDENTIFIER_POINTER (selname));
+	}
+      /* TODO: Also check that the selector has not been declared in
+       * multiple methods with conflicting signatures.  */
+    }
+  
+
   if (flag_typed_selectors)
     return build_typed_selector_reference (selname, 0);
   else
@@ -5277,7 +5312,9 @@
   while (mchain)
     {
       if (METHOD_SEL_NAME (mchain) == key)
-	return mchain;
+	{
+	  return mchain;
+	}
       mchain = TREE_CHAIN (mchain);
     }
   return NULL_TREE;

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.362
diff -u -r1.362 c-common.c
--- c-common.c	7 Aug 2002 18:32:07 -0000	1.362
+++ c-common.c	8 Aug 2002 15:06:20 -0000
@@ -443,9 +443,17 @@
 const char *constant_string_class_name;
 
 /* Warn if multiple methods are seen for the same selector, but with
-   different argument types.  */
+   different argument types.  Performs the check on the whole selector
+   table at the end of compilation.  */
 
 int warn_selector;
+
+/* Warn if a @selector() is found, and no method with that selector
+   has been previously declared.  The check is done on each
+   @selector() as soon as it is found - so it warns about forward
+   declarations.  */
+
+int warn_undeclared_selector;
 
 /* Warn if methods required by a protocol are not implemented in the 
    class adopting it.  When turned off, methods inherited to that
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.148
diff -u -r1.148 c-common.h
--- c-common.h	7 Aug 2002 18:32:07 -0000	1.148
+++ c-common.h	8 Aug 2002 15:06:21 -0000
@@ -613,9 +613,17 @@
 const char *constant_string_class_name;
 
 /* Warn if multiple methods are seen for the same selector, but with
-   different argument types.  */
+   different argument types.  Performs the check on the whole selector
+   table at the end of compilation.  */
 
 extern int warn_selector;
+
+/* Warn if a @selector() is found, and no method with that selector
+   has been previously declared.  The check is done on each
+   @selector() as soon as it is found - so it warns about forward
+   declarations.  */
+
+extern int warn_undeclared_selector;
 
 /* Warn if methods required by a protocol are not implemented in the 
    class adopting it.  When turned off, methods inherited to that
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.2
diff -u -r1.2 c-opts.c
--- c-opts.c	8 Aug 2002 06:30:12 -0000	1.2
+++ c-opts.c	8 Aug 2002 15:06:21 -0000
@@ -133,6 +133,7 @@
   OPT("Wsystem-headers",	CL_ALL,   OPT_Wsystem_headers)		     \
   OPT("Wtraditional",		CL_C,     OPT_Wtraditional)		     \
   OPT("Wtrigraphs",		CL_ALL,   OPT_Wtrigraphs)		     \
+  OPT("Wundeclared-selector",	CL_OBJC,  OPT_Wundeclared_selector)	     \
   OPT("Wundef",			CL_ALL,   OPT_Wundef)			     \
   OPT("Wunknown-pragmas",	CL_ALL,   OPT_Wunknown_pragmas)		     \
   OPT("Wunused-macros",		CL_ALL,   OPT_Wunused_macros)		     \
@@ -734,6 +735,10 @@
 
     case OPT_Wtrigraphs:
       cpp_opts->warn_trigraphs = on;
+      break;
+
+    case OPT_Wundeclared_selector:
+      warn_undeclared_selector = on;
       break;
 
     case OPT_Wundef:


============================================
Finally, a testcase showing it working :-) :
testsuite/objc.dg/undeclared-selector.m

/* Test for -Wundeclared-selector.  */
/* Author: Nicola Pero <nicola@brainstorm.co.uk>.  */
/* { dg-do compile } */
/* { dg-options "-Wundeclared-selector" } */

#include <objc/objc.h>

@interface MyClass

+ (void) methodA;
- (void) methodB;
+ (void) methodD;
- (void) methodF;

@end

@implementation MyClass

+ (void) methodA {}
- (void) methodB {}
+ (void) methodD
{
  SEL d = @selector(methodD); /* Ok */
  /* The warning in the following line is a regexp, which is why dots
     are used.  */
  SEL e = @selector(methodE); /* { dg-warning "nknown .undeclared. selector" } */
}

- (void) methodE
{
  SEL e = @selector(methodE); /* Ok */
}

- (void) methodF
{
  SEL e = @selector(methodE); /* Ok */
}

@end

int main (void)
{
  SEL a = @selector(methodA); /* Ok */
  SEL b = @selector(methodB); /* Ok */
  SEL c = @selector(methodC); /* { dg-warning "nknown .undeclared. selector" } */
  SEL d = @selector(methodD); /* Ok */
  SEL e = @selector(methodE); /* Ok */
  return 0;
  
}


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