Commit 9ba7a2f2 by Mark Mitchell Committed by Mark Mitchell

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
parent cf71109b
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> 2006-12-07 Lee Millward <lee.millward@codesourcery.com>
PR c++/29980 PR c++/29980
......
...@@ -2879,8 +2879,14 @@ extern void decl_shadowed_for_var_insert (tree, tree); ...@@ -2879,8 +2879,14 @@ extern void decl_shadowed_for_var_insert (tree, tree);
indicates the type of specializations: indicates the type of specializations:
1=implicit instantiation 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 Note that NODE will be marked as a specialization even if the
template it is instantiating is not a primary template. For template it is instantiating is not a primary template. For
...@@ -4168,6 +4174,7 @@ extern tree build_non_dependent_expr (tree); ...@@ -4168,6 +4174,7 @@ extern tree build_non_dependent_expr (tree);
extern tree build_non_dependent_args (tree); extern tree build_non_dependent_args (tree);
extern bool reregister_specialization (tree, tree, tree); extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree); extern tree fold_non_dependent_expr (tree);
extern bool explicit_class_specialization_p (tree);
/* in repo.c */ /* in repo.c */
extern void init_repo (void); extern void init_repo (void);
......
...@@ -11144,6 +11144,10 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -11144,6 +11144,10 @@ cp_parser_init_declarator (cp_parser* parser,
if (declarator == cp_error_declarator) if (declarator == cp_error_declarator)
return error_mark_node; 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) if (declares_class_or_enum & 2)
cp_parser_check_for_definition_in_return_type (declarator, cp_parser_check_for_definition_in_return_type (declarator,
decl_specifiers->type); decl_specifiers->type);
...@@ -11263,10 +11267,6 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -11263,10 +11267,6 @@ cp_parser_init_declarator (cp_parser* parser,
/* Check to see whether or not this declaration is a friend. */ /* Check to see whether or not this declaration is a friend. */
friend_p = cp_parser_friend_p (decl_specifiers); 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 /* Enter the newly declared entry in the symbol table. If we're
processing a declaration in a class-specifier, we wait until processing a declaration in a class-specifier, we wait until
after processing the initializer. */ after processing the initializer. */
...@@ -15312,10 +15312,14 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ...@@ -15312,10 +15312,14 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
is correct; there shouldn't be a `template <>' for is correct; there shouldn't be a `template <>' for
the definition of `S<int>::f'. */ the definition of `S<int>::f'. */
if (CLASSTYPE_TEMPLATE_INFO (scope) if (!CLASSTYPE_TEMPLATE_INFO (scope))
&& (CLASSTYPE_TEMPLATE_INSTANTIATION (scope) /* If SCOPE does not have template information of any
|| uses_template_parms (CLASSTYPE_TI_ARGS (scope))) kind, then it is not a template, nor is it nested
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope))) within a template. */
break;
if (explicit_class_specialization_p (scope))
break;
if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
++num_templates; ++num_templates;
scope = TYPE_CONTEXT (scope); scope = TYPE_CONTEXT (scope);
......
...@@ -1316,6 +1316,17 @@ register_local_specialization (tree spec, tree tmpl) ...@@ -1316,6 +1316,17 @@ register_local_specialization (tree spec, tree tmpl)
*slot = build_tree_list (spec, 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. */ /* Print the list of candidate FNS in an error message. */
void void
......
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> 2006-12-07 Andrew Pinski <andrew_pinski@playstation.sony.com>
* gcc.target/spu: New directory. * gcc.target/spu: New directory.
// 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 { ...@@ -7,5 +7,5 @@ struct A {
template<int M> void B () ; template<int M> void B () ;
}; };
void A<0>::B<0>() { // { dg-error "explicit specialization" } void A<0>::B<0>() { // { dg-error "parameter-lists" }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment