This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: How to check that selectors exist
- From: Nicola Pero <nicola at brainstorm dot co dot uk>
- To: shebs at apple dot com
- Cc: Devang Patel <dpatel at apple dot com>, gnustep-dev at gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Thu, 8 Aug 2002 16:25:33 +0100 (BST)
- Subject: 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;
}