diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-12-08 06:27:22 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-12-08 06:27:22 +0000 |
commit | 9ba7a2f2926541d4db21c6df15acc783b73e1f4f (patch) | |
tree | 7ba5569ae3e14325934f7a9e8cdf809c494d4870 | |
parent | cf71109bd6749b28e07670d2cf8eb7d3c216f531 (diff) | |
download | gcc-9ba7a2f2926541d4db21c6df15acc783b73e1f4f.zip gcc-9ba7a2f2926541d4db21c6df15acc783b73e1f4f.tar.gz gcc-9ba7a2f2926541d4db21c6df15acc783b73e1f4f.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 11 | ||||
-rw-r--r-- | gcc/cp/parser.c | 20 | ||||
-rw-r--r-- | gcc/cp/pt.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash65.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/spec16.C | 2 |
7 files changed, 57 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2135508..1a8d126 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ae250bf..e59586b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a0a6a17..d7611ed 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index acaf6bc..2cfcce5 100644 --- a/gcc/cp/pt.c +++ b/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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c5ab9b5..d1e707c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/g++.dg/template/crash65.C b/gcc/testsuite/g++.dg/template/crash65.C new file mode 100644 index 0000000..4d49ecf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash65.C @@ -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" } +}; diff --git a/gcc/testsuite/g++.dg/template/spec16.C b/gcc/testsuite/g++.dg/template/spec16.C index c5bd5a9..881d7a0 100644 --- a/gcc/testsuite/g++.dg/template/spec16.C +++ b/gcc/testsuite/g++.dg/template/spec16.C @@ -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" } } |