This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] New g++ warning for inner-style forward class declarations
- From: Simon Baldwin <simonb at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 02 Jul 2007 14:09:58 -0700
- Subject: [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