From 8808159929f6f9b9a28975f8bddb400dcc83e6d2 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 5 Jan 2004 19:54:35 +0000 Subject: [PATCH] re PR c++/13451 (Wrong error message with qualified names for member declarations) PR c++/13451 * parser.c (cp_parser_class_head): Reorder logic to check for invalid qualification. PR c++/13451 * g++.dg/template/class2.C: New test. From-SVN: r75440 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/parser.c | 55 ++++++++++++++------------ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/template/class2.C | 7 ++++ 4 files changed, 47 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/class2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e3baeebd3df..79af88e2e98 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-01-05 Mark Mitchell + + PR c++/13451 + * parser.c (cp_parser_class_head): Reorder logic to check for + invalid qualification. + 2004-01-04 Mark Mitchell PR c++/13157 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 76de7a0817f..9a16f826d34 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11837,6 +11837,35 @@ cp_parser_class_head (cp_parser* parser, else if (invalid_nested_name_p) cp_parser_error (parser, "qualified name does not name a class"); + else if (nested_name_specifier) + { + tree scope; + /* Figure out in what scope the declaration is being placed. */ + scope = current_scope (); + if (!scope) + scope = current_namespace; + /* If that scope does not contain the scope in which the + class was originally declared, the program is invalid. */ + if (scope && !is_ancestor (scope, nested_name_specifier)) + { + error ("declaration of `%D' in `%D' which does not " + "enclose `%D'", type, scope, nested_name_specifier); + type = NULL_TREE; + goto done; + } + /* [dcl.meaning] + + A declarator-id shall not be qualified exception of the + definition of a ... nested class outside of its class + ... [or] a the definition or explicit instantiation of a + class member of a namespace outside of its namespace. */ + if (scope == nested_name_specifier) + { + pedwarn ("extra qualification ignored"); + nested_name_specifier = NULL_TREE; + num_templates = 0; + } + } /* An explicit-specialization must be preceded by "template <>". If it is not, try to recover gracefully. */ if (at_namespace_scope_p () @@ -11880,7 +11909,6 @@ cp_parser_class_head (cp_parser* parser, else { tree class_type; - tree scope; /* Given: @@ -11903,31 +11931,6 @@ cp_parser_class_head (cp_parser* parser, } } - /* Figure out in what scope the declaration is being placed. */ - scope = current_scope (); - if (!scope) - scope = current_namespace; - /* If that scope does not contain the scope in which the - class was originally declared, the program is invalid. */ - if (scope && !is_ancestor (scope, CP_DECL_CONTEXT (type))) - { - error ("declaration of `%D' in `%D' which does not " - "enclose `%D'", type, scope, nested_name_specifier); - type = NULL_TREE; - goto done; - } - /* [dcl.meaning] - - A declarator-id shall not be qualified exception of the - definition of a ... nested class outside of its class - ... [or] a the definition or explicit instantiation of a - class member of a namespace outside of its namespace. */ - if (scope == CP_DECL_CONTEXT (type)) - { - pedwarn ("extra qualification ignored"); - nested_name_specifier = NULL_TREE; - } - maybe_process_partial_specialization (TREE_TYPE (type)); class_type = current_class_type; /* Enter the scope indicated by the nested-name-specifier. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7e34508659c..fc4e462beb3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-01-05 Mark Mitchell + + PR c++/13451 + * g++.dg/template/class2.C: New test. + 2004-01-05 Nathan Sidwell Richard Sandiford diff --git a/gcc/testsuite/g++.dg/template/class2.C b/gcc/testsuite/g++.dg/template/class2.C new file mode 100644 index 00000000000..4144997fe16 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/class2.C @@ -0,0 +1,7 @@ +// PR c++/13451 + +template +struct A { + struct B; + struct A::B { }; // { dg-error "" } +}; -- 2.30.2