re PR c++/29732 (ICE on invalid friend declaration)
PR c++/29732 * cp-tree.h (DECL_USE_TEMPLATE): Mention partial specializations. (explicit_class_specialization_p): Declare. * pt.c (explicit_class_specialization_p): New function. * parser.c (cp_parser_init_declarator): Check correct number of template parameters for in-class function definitions. (cp_parser_check_declrator_template_parameters): Stop looking for template classes when we find an explicit specialization. PR c++/29732 * g++.dg/template/crash65.C: New test. * g++.dg/template/spec16.C: Tweak error markers. From-SVN: r119649
This commit is contained in:
parent
cf71109bd6
commit
9ba7a2f292
7 changed files with 57 additions and 11 deletions
|
@ -1,3 +1,14 @@
|
|||
2006-12-07 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/29732
|
||||
* cp-tree.h (DECL_USE_TEMPLATE): Mention partial specializations.
|
||||
(explicit_class_specialization_p): Declare.
|
||||
* pt.c (explicit_class_specialization_p): New function.
|
||||
* parser.c (cp_parser_init_declarator): Check correct number of
|
||||
template parameters for in-class function definitions.
|
||||
(cp_parser_check_declrator_template_parameters): Stop looking for
|
||||
template classes when we find an explicit specialization.
|
||||
|
||||
2006-12-07 Lee Millward <lee.millward@codesourcery.com>
|
||||
|
||||
PR c++/29980
|
||||
|
|
|
@ -2879,8 +2879,14 @@ extern void decl_shadowed_for_var_insert (tree, tree);
|
|||
indicates the type of specializations:
|
||||
|
||||
1=implicit instantiation
|
||||
2=explicit specialization, e.g. int min<int> (int, int);
|
||||
3=explicit instantiation, e.g. template int min<int> (int, int);
|
||||
|
||||
2=partial or explicit specialization, e.g.:
|
||||
|
||||
template <> int min<int> (int, int),
|
||||
|
||||
3=explicit instantiation, e.g.:
|
||||
|
||||
template int min<int> (int, int);
|
||||
|
||||
Note that NODE will be marked as a specialization even if the
|
||||
template it is instantiating is not a primary template. For
|
||||
|
@ -4168,6 +4174,7 @@ extern tree build_non_dependent_expr (tree);
|
|||
extern tree build_non_dependent_args (tree);
|
||||
extern bool reregister_specialization (tree, tree, tree);
|
||||
extern tree fold_non_dependent_expr (tree);
|
||||
extern bool explicit_class_specialization_p (tree);
|
||||
|
||||
/* in repo.c */
|
||||
extern void init_repo (void);
|
||||
|
|
|
@ -11144,6 +11144,10 @@ cp_parser_init_declarator (cp_parser* parser,
|
|||
if (declarator == cp_error_declarator)
|
||||
return error_mark_node;
|
||||
|
||||
/* Check that the number of template-parameter-lists is OK. */
|
||||
if (!cp_parser_check_declarator_template_parameters (parser, declarator))
|
||||
return error_mark_node;
|
||||
|
||||
if (declares_class_or_enum & 2)
|
||||
cp_parser_check_for_definition_in_return_type (declarator,
|
||||
decl_specifiers->type);
|
||||
|
@ -11263,10 +11267,6 @@ cp_parser_init_declarator (cp_parser* parser,
|
|||
/* Check to see whether or not this declaration is a friend. */
|
||||
friend_p = cp_parser_friend_p (decl_specifiers);
|
||||
|
||||
/* Check that the number of template-parameter-lists is OK. */
|
||||
if (!cp_parser_check_declarator_template_parameters (parser, declarator))
|
||||
return error_mark_node;
|
||||
|
||||
/* Enter the newly declared entry in the symbol table. If we're
|
||||
processing a declaration in a class-specifier, we wait until
|
||||
after processing the initializer. */
|
||||
|
@ -15312,10 +15312,14 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
|
|||
|
||||
is correct; there shouldn't be a `template <>' for
|
||||
the definition of `S<int>::f'. */
|
||||
if (CLASSTYPE_TEMPLATE_INFO (scope)
|
||||
&& (CLASSTYPE_TEMPLATE_INSTANTIATION (scope)
|
||||
|| uses_template_parms (CLASSTYPE_TI_ARGS (scope)))
|
||||
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
|
||||
if (!CLASSTYPE_TEMPLATE_INFO (scope))
|
||||
/* If SCOPE does not have template information of any
|
||||
kind, then it is not a template, nor is it nested
|
||||
within a template. */
|
||||
break;
|
||||
if (explicit_class_specialization_p (scope))
|
||||
break;
|
||||
if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
|
||||
++num_templates;
|
||||
|
||||
scope = TYPE_CONTEXT (scope);
|
||||
|
|
11
gcc/cp/pt.c
11
gcc/cp/pt.c
|
@ -1316,6 +1316,17 @@ register_local_specialization (tree spec, tree tmpl)
|
|||
*slot = build_tree_list (spec, tmpl);
|
||||
}
|
||||
|
||||
/* TYPE is a class type. Returns true if TYPE is an explicitly
|
||||
specialized class. */
|
||||
|
||||
bool
|
||||
explicit_class_specialization_p (tree type)
|
||||
{
|
||||
if (!CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
|
||||
return false;
|
||||
return !uses_template_parms (CLASSTYPE_TI_ARGS (type));
|
||||
}
|
||||
|
||||
/* Print the list of candidate FNS in an error message. */
|
||||
|
||||
void
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2006-12-07 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/29732
|
||||
* g++.dg/template/crash65.C: New test.
|
||||
* g++.dg/template/spec16.C: Tweak error markers.
|
||||
|
||||
2006-12-07 Andrew Pinski <andrew_pinski@playstation.sony.com>
|
||||
|
||||
* gcc.target/spu: New directory.
|
||||
|
|
7
gcc/testsuite/g++.dg/template/crash65.C
Normal file
7
gcc/testsuite/g++.dg/template/crash65.C
Normal file
|
@ -0,0 +1,7 @@
|
|||
// PR c++/29732
|
||||
|
||||
struct A
|
||||
{
|
||||
template<int> template<typename T> friend void foo(T) {} // { dg-error "parameter" }
|
||||
void bar() { foo(0); } // { dg-error "foo" }
|
||||
};
|
|
@ -7,5 +7,5 @@ struct A {
|
|||
template<int M> void B () ;
|
||||
};
|
||||
|
||||
void A<0>::B<0>() { // { dg-error "explicit specialization" }
|
||||
void A<0>::B<0>() { // { dg-error "parameter-lists" }
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue