aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Baldwin <simonb@google.com>2007-07-02 17:57:57 +0000
committerSimon Baldwin <simonb@gcc.gnu.org>2007-07-02 17:57:57 +0000
commit2a7b8343cb0372cc52db8b625297336130280b4e (patch)
tree3a99335dd999003cb987b005ffaed594727657ea
parentd49343266bbe24e86d772f2cf1513012e1fae90c (diff)
downloadgcc-2a7b8343cb0372cc52db8b625297336130280b4e.zip
gcc-2a7b8343cb0372cc52db8b625297336130280b4e.tar.gz
gcc-2a7b8343cb0372cc52db8b625297336130280b4e.tar.bz2
parser.c (cp_parser_elaborated_type_specifier): Added a warning for inner-style nested forward declarations that don't declare...
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. From-SVN: r126219
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c17
-rw-r--r--gcc/testsuite/g++.dg/warn/forward-inner.C81
3 files changed, 104 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b25e051..27f6dc5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 484c6b5..d6e6204 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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
index 0000000..dae9948
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/forward-inner.C
@@ -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
+};