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
This commit is contained in:
Lee Millward 2006-09-25 19:58:10 +00:00 committed by Lee Millward
parent 60feef2c2d
commit 9b910171a0
7 changed files with 49 additions and 11 deletions

View file

@ -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 <mark@codesourcery.com>

View file

@ -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);

View file

@ -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))

View file

@ -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

View file

@ -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 <dvorakz@suse.cz>
Adam Nemet <anemet@caviumnetworks.com>

View file

@ -0,0 +1,7 @@
//PR c++/27667
struct A
{
template<int> static void foo () {}
template<> static void foo<0>() {} // { dg-error "explicit" }
};

View file

@ -10,7 +10,7 @@ struct S {
template <class U> void f(U);
template <> void f<int>(int); // { dg-error "" } invalid specialization
template <class V> struct I {};
template <class V> struct I<V*> {};
template <class V> struct I {}; // { dg-error "template" }
template <class V> struct I<V*> {}; // { dg-error "template" }
template <> struct I<int>; // { dg-error "" } invalid specialization
};