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:
parent
60feef2c2d
commit
9b910171a0
7 changed files with 49 additions and 11 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
23
gcc/cp/pt.c
23
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
|
||||
|
|
|
@ -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>
|
||||
|
|
7
gcc/testsuite/g++.dg/template/spec33.C
Normal file
7
gcc/testsuite/g++.dg/template/spec33.C
Normal file
|
@ -0,0 +1,7 @@
|
|||
//PR c++/27667
|
||||
|
||||
struct A
|
||||
{
|
||||
template<int> static void foo () {}
|
||||
template<> static void foo<0>() {} // { dg-error "explicit" }
|
||||
};
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue