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]

[Committed] New g++ warning for inner-style forward class declarations


Committed as revision 126219.

Attached is a patch to add a new warning to g++ for inner-style forward
class declarations that the compiler has ignored.  For example:

 struct Foo::Bar;  // Error, class Foo is not complete
 struct Foo { struct Bar {}; };
 struct Foo::Bar;  // No error, but pointless since Foo is complete

This patch adds a warning for the second use of 'struct Foo::Bar;' for
contexts where it is not an error, only an irrelevance.  This matches a
similar message emitted by the EDG parser (in Comeau C++, for example).

The patch includes a new test, to verify that the warning is emitted by
g++ when required, and also that g++ finds no false positives.

Regression tested with bootstrap and with the full g++ testsuite.

...


Index: gcc/testsuite/g++.dg/warn/forward-inner.C
===================================================================
--- gcc/testsuite/g++.dg/warn/forward-inner.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/forward-inner.C	(revision 126219)
@@ -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
+};
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog	(revision 126218)
+++ gcc/cp/ChangeLog	(revision 126219)
@@ -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: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 126218)
+++ gcc/cp/parser.c	(revision 126219)
@@ -10913,6 +10913,23 @@
                 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

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