In gcc/objc/: 2010-12-28 Nicola Pero <nicola.pero@meta-innovation.com>
authorNicola Pero <nicola.pero@meta-innovation.com>
Wed, 29 Dec 2010 01:16:55 +0000 (01:16 +0000)
committerNicola Pero <nicola@gcc.gnu.org>
Wed, 29 Dec 2010 01:16:55 +0000 (01:16 +0000)
In gcc/objc/:
2010-12-28  Nicola Pero  <nicola.pero@meta-innovation.com>

PR objc/47076
* objc-act.c (lookup_protocol): Added 'definition_required'
argument.  If 'definition_required', and the protocol is not
defined, emit a warning.
(objc_declare_protocols): Updated call to lookup_protocol.
(start_protocol): Same change.
(check_protocol_recursively): Same change.
(objc_build_protocol_expr): Same change.
(lookup_and_install_protocols): Added definition_required argument.
Pass it to lookup_protocol.
(objc_get_protocol_qualified_type): Updated call to
lookup_and_install_protocols.
(start_class): Updated calls to lookup_and_install_protocols; pass
true to 'definition_required' to get the warnings.
(start_protocol): Updated calls to lookup_and_install_protocols.

In gcc/testsuite/:
2010-12-28  Nicola Pero  <nicola.pero@meta-innovation.com>

PR objc/47076
* objc.dg/protocol-forward-1.m: New.
* obj-c++.dg/protocol-forward-1.mm: New.
* objc.dg/attributes/proto-attribute-2.m: Updated.
* objc.dg/class-protocol-1.m: Updated.
* obj-c++.dg/attributes/proto-attribute-2.mm: Updated.
* obj-c++.dg/class-protocol-1.mm: Updated.

From-SVN: r168307

gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/attributes/proto-attribute-2.mm
gcc/testsuite/obj-c++.dg/class-protocol-1.mm
gcc/testsuite/obj-c++.dg/protocol-forward-1.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/attributes/proto-attribute-2.m
gcc/testsuite/objc.dg/class-protocol-1.m
gcc/testsuite/objc.dg/protocol-forward-1.m [new file with mode: 0644]

index c7efb54cb9395d5813cf2323417a5a84375426d2..34f34786f3880e87c2317e8750d48ec5396d2450 100644 (file)
@@ -1,3 +1,21 @@
+2010-12-28  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       PR objc/47076
+       * objc-act.c (lookup_protocol): Added 'definition_required'
+       argument.  If 'definition_required', and the protocol is not
+       defined, emit a warning.
+       (objc_declare_protocols): Updated call to lookup_protocol.
+       (start_protocol): Same change.
+       (check_protocol_recursively): Same change.
+       (objc_build_protocol_expr): Same change.
+       (lookup_and_install_protocols): Added definition_required argument.
+       Pass it to lookup_protocol.
+       (objc_get_protocol_qualified_type): Updated call to
+       lookup_and_install_protocols.
+       (start_class): Updated calls to lookup_and_install_protocols; pass
+       true to 'definition_required' to get the warnings.
+       (start_protocol): Updated calls to lookup_and_install_protocols.
+
 2010-12-28  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * objc-act.c (objc_start_category_interface): Produce an error if
index 1117967e71df81240b49dc7c791802881cf96e03..c7fd4a9a51162db964aceb285ea46dffb079d19c 100644 (file)
@@ -232,8 +232,8 @@ static void build_selector_table_decl (void);
 
 /* Protocols.  */
 
-static tree lookup_protocol (tree, bool);
-static tree lookup_and_install_protocols (tree);
+static tree lookup_protocol (tree, bool, bool);
+static tree lookup_and_install_protocols (tree, bool);
 
 /* Type encoding.  */
 
@@ -2923,7 +2923,8 @@ objc_get_protocol_qualified_type (tree interface, tree protocols)
 
       /* Look up protocols and install in lang specific list.  */
       DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
-      TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
+      TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols
+       (protocols, /* definition_required */ false);
 
       /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
         return the pointer to the new pointee variant.  */
@@ -2951,7 +2952,8 @@ check_protocol_recursively (tree proto, tree list)
       tree pp = TREE_VALUE (p);
 
       if (TREE_CODE (pp) == IDENTIFIER_NODE)
-       pp = lookup_protocol (pp, /* warn if deprecated */ false);
+       pp = lookup_protocol (pp, /* warn if deprecated */ false,
+                             /* definition_required */ false);
 
       if (pp == proto)
        fatal_error ("protocol %qE has circular dependency",
@@ -2963,10 +2965,13 @@ check_protocol_recursively (tree proto, tree list)
 
 /* Look up PROTOCOLS, and return a list of those that are found.  If
    none are found, return NULL.  Note that this function will emit a
-   warning if a protocol is found and is deprecated.  */
-
+   warning if a protocol is found and is deprecated.  If
+   'definition_required', then warn if the protocol is found but is
+   not defined (ie, if we only saw a forward-declaration of the
+   protocol (as in "@protocol NSObject;") not a real definition with
+   the list of methods).  */
 static tree
-lookup_and_install_protocols (tree protocols)
+lookup_and_install_protocols (tree protocols, bool definition_required)
 {
   tree proto;
   tree return_value = NULL_TREE;
@@ -2977,7 +2982,8 @@ lookup_and_install_protocols (tree protocols)
   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
     {
       tree ident = TREE_VALUE (proto);
-      tree p = lookup_protocol (ident, /* warn_if_deprecated */ true);
+      tree p = lookup_protocol (ident, /* warn_if_deprecated */ true,
+                               definition_required);
 
       if (p)
        return_value = chainon (return_value,
@@ -8417,7 +8423,8 @@ tree
 objc_build_protocol_expr (tree protoname)
 {
   tree expr;
-  tree p = lookup_protocol (protoname, /* warn if deprecated */ true);
+  tree p = lookup_protocol (protoname, /* warn if deprecated */ true,
+                           /* definition_required */ false);
 
   if (!p)
     {
@@ -9644,7 +9651,7 @@ start_class (enum tree_code code, tree class_name, tree super_name,
        
       if (protocol_list)
        CLASS_PROTOCOL_LIST (klass)
-         = lookup_and_install_protocols (protocol_list);
+         = lookup_and_install_protocols (protocol_list, /* definition_required */ true);
 
       /* Determine if 'deprecated', the only attribute we recognize
         for classes, was used.  Ignore all other attributes for now,
@@ -9695,7 +9702,9 @@ start_class (enum tree_code code, tree class_name, tree super_name,
                       list.  */
                    CLASS_PROTOCOL_LIST (klass)
                      = chainon (CLASS_PROTOCOL_LIST (klass),
-                                lookup_and_install_protocols (protocol_list));
+                                lookup_and_install_protocols
+                                (protocol_list,
+                                 /* definition_required */ true));
                  }
              }
            else
@@ -9704,7 +9713,8 @@ start_class (enum tree_code code, tree class_name, tree super_name,
                
                if (protocol_list)
                  CLASS_PROTOCOL_LIST (klass)
-                   = lookup_and_install_protocols (protocol_list);
+                   = lookup_and_install_protocols
+                   (protocol_list, /* definition_required */ true);
              }
          }
       }
@@ -10798,10 +10808,12 @@ add_protocol (tree protocol)
 }
 
 /* Looks up a protocol.  If 'warn_if_deprecated' is true, a warning is
-   emitted if the protocol is deprecated.  */
+   emitted if the protocol is deprecated.  If 'definition_required' is
+   true, a warning is emitted if a full @protocol definition has not
+   been seen.  */
 
 static tree
-lookup_protocol (tree ident, bool warn_if_deprecated)
+lookup_protocol (tree ident, bool warn_if_deprecated, bool definition_required)
 {
   tree chain;
 
@@ -10817,6 +10829,10 @@ lookup_protocol (tree ident, bool warn_if_deprecated)
                     PROTOCOL_NAME (chain));
          }
 
+       if (definition_required && !PROTOCOL_DEFINED (chain))
+         warning (0, "definition of protocol %qE not found",
+                  PROTOCOL_NAME (chain));
+
        return chain;
       }
 
@@ -10856,7 +10872,8 @@ objc_declare_protocols (tree names, tree attributes)
     {
       tree name = TREE_VALUE (list);
 
-      if (lookup_protocol (name, /* warn if deprecated */ false) == NULL_TREE)
+      if (lookup_protocol (name, /* warn if deprecated */ false,
+                          /* definition_required */ false) == NULL_TREE)
        {
          tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
 
@@ -10904,7 +10921,8 @@ start_protocol (enum tree_code code, tree name, tree list, tree attributes)
        }
     }
 
-  protocol = lookup_protocol (name, /* warn_if_deprecated */ false);
+  protocol = lookup_protocol (name, /* warn_if_deprecated */ false,
+                             /* definition_required */ false);
 
   if (!protocol)
     {
@@ -10912,7 +10930,7 @@ start_protocol (enum tree_code code, tree name, tree list, tree attributes)
       TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
 
       PROTOCOL_NAME (protocol) = name;
-      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
+      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, /* definition_required */ false);
       add_protocol (protocol);
       PROTOCOL_DEFINED (protocol) = 1;
       PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
@@ -10922,7 +10940,7 @@ start_protocol (enum tree_code code, tree name, tree list, tree attributes)
   else if (! PROTOCOL_DEFINED (protocol))
     {
       PROTOCOL_DEFINED (protocol) = 1;
-      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
+      PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list, /* definition_required */ false);
 
       check_protocol_recursively (protocol, list);
     }
index 29ffa842e21f87a8fa2edcb0aa75c046ad1c781e..45d4441c52ad24dc01404fc3b9a14db594bc2869 100644 (file)
@@ -1,3 +1,13 @@
+2010-12-28  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       PR objc/47076
+       * objc.dg/protocol-forward-1.m: New.
+       * obj-c++.dg/protocol-forward-1.mm: New.
+       * objc.dg/attributes/proto-attribute-2.m: Updated.
+       * objc.dg/class-protocol-1.m: Updated.
+       * obj-c++.dg/attributes/proto-attribute-2.mm: Updated.
+       * obj-c++.dg/class-protocol-1.mm: Updated.
+       
 2010-12-28  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/45827
index 5b2eecb2f13121ac8c82fa3c772b9590341f3ea8..1e81c0b7b690c9152149e34aa2f92f73782a4192 100644 (file)
@@ -13,19 +13,6 @@ __attribute__ ((deprecated))
 
 @protocol NonDeprecatedProtocol1;
 
-
-@interface Class1 <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
-@end
-
-@interface Class2 <NonDeprecatedProtocol1>
-@end
-
-@interface Class3 <NonDeprecatedProtocol1, DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
-@end
-
-@interface Class2 (Category1) <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
-@end
-
 void function1 (id <DeprecatedProtocol1> object); /* { dg-warning "is deprecated" } */
 void function2 (id <NonDeprecatedProtocol1> object);
 
index b8200d0c0b30c4c9f5b0fcf5f25a798610a05a7b..6391fda6f12b094d7aa2e60469940d3cb5517a88 100644 (file)
@@ -1,4 +1,3 @@
-
 /* Check Class <protocol> types */
 /* Author: David Ayers <d.ayers@inode.at> */
 /* { dg-do compile } */
@@ -176,7 +175,7 @@ testCategoryInherited(void)
 
 @protocol FwProto;
 
-@interface MyClass1 (Forward) <FwProto>
+@interface MyClass1 (Forward) <FwProto> /* { dg-warning "definition of protocol .FwProto. not found" } */
 @end
 
 Class <FwProto> clsP7 = 0;
@@ -188,9 +187,9 @@ testForwardeDeclared1(void)
   [cls doItInstance7];      /* { dg-warning "no .\\+doItInstance7. method found" } */
 
   [clsP7 doItClass7];       /* { dg-warning "not found in protocol" } */
-  /* { dg-warning "no .\\+doItClass7. method found" "" { target *-*-* } 190 } */
+  /* { dg-warning "no .\\+doItClass7. method found" "" { target *-*-* } 189 } */
   [clsP7 doItInstance7];    /* { dg-warning "not found in protocol" } */
-  /* { dg-warning "no .\\+doItInstance7. method found" "" { target *-*-* } 192 } */
+  /* { dg-warning "no .\\+doItInstance7. method found" "" { target *-*-* } 191 } */
 
   [MyClass1 doItClass7];    /* { dg-warning "may not respond" } */
   [MyClass1 doItInstance7]; /* { dg-warning "may not respond" } */
diff --git a/gcc/testsuite/obj-c++.dg/protocol-forward-1.mm b/gcc/testsuite/obj-c++.dg/protocol-forward-1.mm
new file mode 100644 (file)
index 0000000..17d9044
--- /dev/null
@@ -0,0 +1,30 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010.  */
+/* { dg-do compile } */
+
+/* Test that all protocols appearing in @interface declarations are
+   real (ie, we saw a full @protocol definition with list of methods),
+   and not just forward-references (ie, "@protocol NSObject;").  */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol;
+
+@protocol MyProtocol2
+- (int)method2;
+@end
+
+@interface MyClass <MyProtocol> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+@end
+
+@interface MyClass2 <MyProtocol2> /* Ok */
+@end
+
+@interface MyClass2 (Category) <MyProtocol>  /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+@end
+
+@protocol MyProtocol3 <MyProtocol> /* Ok */
+@end
+
+/* TODO: I guess if MyProtocol3 is now used in an @interface, we
+   should check that all the protocols it references are defined
+   too ?  */
index 5b2eecb2f13121ac8c82fa3c772b9590341f3ea8..1e81c0b7b690c9152149e34aa2f92f73782a4192 100644 (file)
@@ -13,19 +13,6 @@ __attribute__ ((deprecated))
 
 @protocol NonDeprecatedProtocol1;
 
-
-@interface Class1 <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
-@end
-
-@interface Class2 <NonDeprecatedProtocol1>
-@end
-
-@interface Class3 <NonDeprecatedProtocol1, DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
-@end
-
-@interface Class2 (Category1) <DeprecatedProtocol1> /* { dg-warning "is deprecated" } */
-@end
-
 void function1 (id <DeprecatedProtocol1> object); /* { dg-warning "is deprecated" } */
 void function2 (id <NonDeprecatedProtocol1> object);
 
index f97f2317962f19b648c9abf608aceba2e287ffeb..cf061cb8ed76b279175f623e75bce575fb3521be 100644 (file)
@@ -175,7 +175,7 @@ testCategoryInherited(void)
 
 @protocol FwProto;
 
-@interface MyClass1 (Forward) <FwProto>
+@interface MyClass1 (Forward) <FwProto> /* { dg-warning "definition of protocol .FwProto. not found" } */
 @end
 
 Class <FwProto> clsP7 = 0;
diff --git a/gcc/testsuite/objc.dg/protocol-forward-1.m b/gcc/testsuite/objc.dg/protocol-forward-1.m
new file mode 100644 (file)
index 0000000..17d9044
--- /dev/null
@@ -0,0 +1,30 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010.  */
+/* { dg-do compile } */
+
+/* Test that all protocols appearing in @interface declarations are
+   real (ie, we saw a full @protocol definition with list of methods),
+   and not just forward-references (ie, "@protocol NSObject;").  */
+
+#include <objc/objc.h>
+
+@protocol MyProtocol;
+
+@protocol MyProtocol2
+- (int)method2;
+@end
+
+@interface MyClass <MyProtocol> /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+@end
+
+@interface MyClass2 <MyProtocol2> /* Ok */
+@end
+
+@interface MyClass2 (Category) <MyProtocol>  /* { dg-warning "definition of protocol .MyProtocol. not found" } */
+@end
+
+@protocol MyProtocol3 <MyProtocol> /* Ok */
+@end
+
+/* TODO: I guess if MyProtocol3 is now used in an @interface, we
+   should check that all the protocols it references are defined
+   too ?  */