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
This commit is contained in:
parent
d49343266b
commit
2a7b8343cb
3 changed files with 104 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
81
gcc/testsuite/g++.dg/warn/forward-inner.C
Normal file
81
gcc/testsuite/g++.dg/warn/forward-inner.C
Normal file
|
@ -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
|
||||
};
|
Loading…
Add table
Reference in a new issue