diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-12-04 07:04:01 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-12-04 07:04:01 +0000 |
commit | afb0918a9b127a64098a1267f328908acc7e4d1d (patch) | |
tree | e0f05bad020e9fd6c620b6e6dec6e478ffafd699 /gcc/cp/parser.c | |
parent | aedec8ddd22c81f7afec5423accb4175cad874b0 (diff) | |
download | gcc-afb0918a9b127a64098a1267f328908acc7e4d1d.zip gcc-afb0918a9b127a64098a1267f328908acc7e4d1d.tar.gz gcc-afb0918a9b127a64098a1267f328908acc7e4d1d.tar.bz2 |
re PR c++/9127 (Confusing diagnostic on specialization not introduced by "template<>")
PR c++/9127
* cp-tree.h (at_namespace_scope_p): New function.
* parser.c (cp_parser_class_head): Handle invalid explicit
specializations.
* search.c (at_namespace_scope_p): New function.
PR c++/9127
* g++.dg/template/error6.C: New test.
From-SVN: r74274
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9ec128c..1ce8cd78 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11584,6 +11584,7 @@ cp_parser_class_head (cp_parser* parser, bool template_id_p = false; bool qualified_p = false; bool invalid_nested_name_p = false; + bool invalid_explicit_specialization_p = false; unsigned num_templates; /* Assume no nested-name-specifier will be present. */ @@ -11732,12 +11733,31 @@ cp_parser_class_head (cp_parser* parser, else if (invalid_nested_name_p) cp_parser_error (parser, "qualified name does not name a class"); + /* An explicit-specialization must be preceded by "template <>". If + it is not, try to recover gracefully. */ + if (at_namespace_scope_p () + && parser->num_template_parameter_lists == 0 + && num_templates == 1) + { + error ("an explicit specialization must be preceded by 'template <>'"); + invalid_explicit_specialization_p = true; + /* Take the same action that would have been taken by + cp_parser_explicit_specialization. */ + ++parser->num_template_parameter_lists; + begin_specialization (); + } + /* There must be no "return" statements between this point and the + end of this function; set "type "to the correct return value and + use "goto done;" to return. */ /* Make sure that the right number of template parameters were present. */ if (!cp_parser_check_template_parameters (parser, num_templates)) - /* If something went wrong, there is no point in even trying to - process the class-definition. */ - return NULL_TREE; + { + /* If something went wrong, there is no point in even trying to + process the class-definition. */ + type = NULL_TREE; + goto done; + } /* Look up the type. */ if (template_id_p) @@ -11789,7 +11809,8 @@ cp_parser_class_head (cp_parser* parser, { error ("declaration of `%D' in `%D' which does not " "enclose `%D'", type, scope, nested_name_specifier); - return NULL_TREE; + type = NULL_TREE; + goto done; } /* [dcl.meaning] @@ -11848,6 +11869,12 @@ cp_parser_class_head (cp_parser* parser, if (nested_name_specifier) pop_scope (nested_name_specifier); + done: + if (invalid_explicit_specialization_p) + { + end_specialization (); + --parser->num_template_parameter_lists; + } return type; } |