OSDN Git Service

2007-07-02 Simon Baldwin <simonb@google.com>
authorsimonb <simonb@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Jul 2007 17:57:57 +0000 (17:57 +0000)
committersimonb <simonb@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Jul 2007 17:57:57 +0000 (17:57 +0000)
        * parser.c (cp_parser_elaborated_type_specifier): Added a warning
        for inner-style nested forward declarations that don't declare
        anything useful.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126219 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/g++.dg/warn/forward-inner.C [new file with mode: 0644]

index b25e051..27f6dc5 100644 (file)
@@ -1,3 +1,9 @@
+2007-07-02  Simon Baldwin  <simonb@google.com>
+
+       * parser.c (cp_parser_elaborated_type_specifier): Added a warning
+       for inner-style nested forward declarations that don't declare
+       anything useful.
+
 2007-07-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/31748
index 484c6b5..d6e6204 100644 (file)
@@ -10913,6 +10913,23 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
                 return error_mark_node;
             }
 
+          /* Forward declarations of nested types, such as
+
+               class C1::C2;
+               class C1::C2::C3;
+
+             are invalid unless all components preceding the final '::'
+             are complete.  If all enclosing types are complete, these
+             declarations become merely pointless.
+
+             Invalid forward declarations of nested types are errors
+             caught elsewhere in parsing.  Those that are pointless arrive
+             here.  */
+
+          if (cp_parser_declares_only_class_p (parser)
+              && !is_friend && !processing_explicit_instantiation)
+            warning (0, "declaration %qD does not declare anything", decl);
+
          type = TREE_TYPE (decl);
        }
       else
diff --git a/gcc/testsuite/g++.dg/warn/forward-inner.C b/gcc/testsuite/g++.dg/warn/forward-inner.C
new file mode 100644 (file)
index 0000000..dae9948
--- /dev/null
@@ -0,0 +1,81 @@
+// Check that the compiler warns about inner-style forward declarations in
+// contexts where they're not actually illegal, but merely useless.
+
+// Verify warnings for and within classes, and by extension, struct and union.
+class C1;
+class C1::C2;      // { dg-error "does not name a type" }
+class C1::C2::C3;  // { dg-error "has not been declared" }
+
+class C1 {
+ public:
+  class C2;
+  class C2::C3;    // { dg-error "does not name a type" }
+  class C2 {
+   public:
+    class C3;
+    class C3 { };
+    class C3;
+  };
+  class C2;
+  class C2::C3;    // { dg-warning "declaration 'class C1::C2::C3' does not declare anything" }
+};
+
+class C1;
+class C1::C2;      // { dg-warning "declaration 'class C1::C2' does not declare anything" }
+class C1::C2::C3;  // { dg-warning "declaration 'class C1::C2::C3' does not declare anything" }
+
+
+// Verify warnings for namespace scopes.
+class N1::C4;      // { dg-error "has not been declared" }
+class N1::N2::C5;  // { dg-error "has not been declared" }
+
+namespace N1 {
+  class C4;
+  class C4 { };
+  class C4;
+
+  class N2::C5;    // { dg-error "has not been declared" }
+  namespace N2 {
+    class C5;
+    class C5 { };
+    class C5;
+  }
+  class N2::C5;    // { dg-warning "declaration 'class N1::N2::C5' does not declare anything" }
+}
+
+class N1::C4;      // { dg-warning "declaration 'class N1::C4' does not declare anything" }
+class N1::N2::C5;  // { dg-warning "declaration 'class N1::N2::C5' does not declare anything" }
+
+
+// Verify that using declarations related to namespaces don't generate a
+// warning.
+using namespace N1;
+using namespace N1::N2;
+
+namespace N3 {
+  using N1::C4;      // Valid using declaration, no warning
+  using N1::N2::C5;  // Valid using declaration, no warning
+}
+
+
+// Verify that explicit template instantiations, easy to confuse with
+// forward declarations, don't generate a warning.
+template<class C>
+class TC6 {
+ public:
+  class TC7 { };
+};
+
+template class TC6<int>::TC7;  // Valid explicit instantiation, no warning
+
+
+// Verify that friend declarations, also easy to confuse with forward
+// declrations, are similarly not warned about.
+class C8 {
+ public:
+  class C9 { };
+};
+class C10 {
+ public:
+  friend class C8::C9;         // Valid friend declaration, no warning
+};