From: Lee Millward Date: Mon, 25 Sep 2006 19:58:10 +0000 (+0000) Subject: re PR c++/27667 (ICE with in-class specialization) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9b910171a09f1ea69821c0c8a7f53cc0c33401f7;p=gcc.git re PR c++/27667 (ICE with in-class specialization) PR c++/27667 * cp-tree.h (begin_specialization): Return bool instead of void. * pt.c (check_specialization_scope): Likwise. Adjust comment. Return false if a specialization isn't permitted in the current scope,. (begin_specialization): Use the return value of check_specialization_scope. * parser.c (cp_parser_explicit_specialization): If begin_specialization returned false, skip the rest of the specialization. * g++.dg/template/spec33.C: New test. * g++.old-deja/g++.pt/spec20.C: Adjust error markers. From-SVN: r117206 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a41714cdcd1..46bfeb876d3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -8,6 +8,18 @@ Return false on error. * decl.c (xref_tag): Return error_mark_node if redeclare_class_template returned false. + + PR c++/27667 + * cp-tree.h (begin_specialization): Return bool + instead of void. + * pt.c (check_specialization_scope): Likwise. + Adjust comment. Return false if a specialization + isn't permitted in the current scope. + (begin_specialization): Use the return value of + check_specialization_scope. + * parser.c (cp_parser_explicit_specialization): If + begin_specialization returned false, skip the rest + of the specialization. 2006-09-21 Mark Mitchell diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 227fc9dfdec..93c4053ccd6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4086,7 +4086,7 @@ extern void maybe_begin_member_template_processing (tree); extern void maybe_end_member_template_processing (void); extern tree finish_member_template_decl (tree); extern void begin_template_parm_list (void); -extern void begin_specialization (void); +extern bool begin_specialization (void); extern void reset_specialization (void); extern void end_specialization (void); extern void begin_explicit_instantiation (void); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d0205208eb3..0b7dd3cde47 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -9455,7 +9455,13 @@ cp_parser_explicit_specialization (cp_parser* parser) else need_lang_pop = false; /* Let the front end know that we are beginning a specialization. */ - begin_specialization (); + if (!begin_specialization ()) + { + end_specialization (); + cp_parser_skip_to_end_of_block_or_statement (parser); + return; + } + /* If the next keyword is `template', we need to figure out whether or not we're looking a template-declaration. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index daee2522047..4e8fad66e5c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -142,7 +142,7 @@ static tree most_specialized_class (tree, tree); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); -static void check_specialization_scope (void); +static bool check_specialization_scope (void); static tree process_partial_specialization (tree); static void set_current_access_from_decl (tree); static void check_default_tmpl_args (tree, tree, int, int); @@ -535,9 +535,10 @@ begin_template_parm_list (void) } /* This routine is called when a specialization is declared. If it is - invalid to declare a specialization here, an error is reported. */ + invalid to declare a specialization here, an error is reported and + false is returned, otherwise this routine will return true. */ -static void +static bool check_specialization_scope (void) { tree scope = current_scope (); @@ -552,7 +553,10 @@ check_specialization_scope (void) shall be declared in the namespace of which the class template is a member. */ if (scope && TREE_CODE (scope) != NAMESPACE_DECL) - error ("explicit specialization in non-namespace scope %qD", scope); + { + error ("explicit specialization in non-namespace scope %qD", scope); + return false; + } /* [temp.expl.spec] @@ -563,17 +567,22 @@ check_specialization_scope (void) explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. */ if (current_template_parms) - error ("enclosing class templates are not explicitly specialized"); + { + error ("enclosing class templates are not explicitly specialized"); + return false; + } + + return true; } /* We've just seen template <>. */ -void +bool begin_specialization (void) { begin_scope (sk_template_spec, NULL); note_template_header (1); - check_specialization_scope (); + return check_specialization_scope (); } /* Called at then end of processing a declaration preceded by diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a511e562536..4fc16e5f23d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -9,6 +9,10 @@ PR c++/27329 * g++.dg/template/crash59.C: New test. + + PR c++/27667 + * g++.dg/template/spec33.C: New test. + * g++.old-deja/g++.pt/spec20.C: Adjust error markers. 2006-09-24 Zdenek Dvorak Adam Nemet diff --git a/gcc/testsuite/g++.dg/template/spec33.C b/gcc/testsuite/g++.dg/template/spec33.C new file mode 100644 index 00000000000..809d4f012c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec33.C @@ -0,0 +1,7 @@ +//PR c++/27667 + +struct A +{ + template static void foo () {} + template<> static void foo<0>() {} // { dg-error "explicit" } +}; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec20.C b/gcc/testsuite/g++.old-deja/g++.pt/spec20.C index 064ce1423a7..b6148e5ded9 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/spec20.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/spec20.C @@ -10,7 +10,7 @@ struct S { template void f(U); template <> void f(int); // { dg-error "" } invalid specialization - template struct I {}; - template struct I {}; + template struct I {}; // { dg-error "template" } + template struct I {}; // { dg-error "template" } template <> struct I; // { dg-error "" } invalid specialization };