From 1ca939e5ec6e33f8016a99ffe673e647a06ed6f3 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 11 Oct 2004 22:50:00 +0000 Subject: [PATCH] re PR c++/17936 (Declaration of specialization rejected) PR c++/17936 * cp-tree.h (CLASSTYPE_TEMPLATE_SPECIALIZATION): Add a comment. * pt.c (optimize_specialization_lookup_p): Do not optimize lookups for members of partial or explicit specializations. PR c++/17936 * g++.dg/template/spec18.C: New test. From-SVN: r88905 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/cp-tree.h | 3 +++ gcc/cp/pt.c | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/spec18.C | 13 +++++++++++++ 5 files changed, 32 insertions(+) create mode 100644 gcc/testsuite/g++.dg/template/spec18.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5196df9db4f..44c6b70abe6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2004-10-11 Mark Mitchell + PR c++/17936 + * cp-tree.h (CLASSTYPE_TEMPLATE_SPECIALIZATION): Add a comment. + * pt.c (optimize_specialization_lookup_p): Do not optimize lookups + for members of partial or explicit specializations. + PR c++/17929 * decl2.c (finish_anon_union): Robustify. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 85d0aa6a791..6f777b195ef 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2713,6 +2713,9 @@ struct lang_decl GTY(()) #define DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) == 2) #define SET_DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) = 2) + +/* Returns true for an explicit or partial specialization of a class + template. */ #define CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \ (CLASSTYPE_USE_TEMPLATE (NODE) == 2) #define SET_CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c794e35bf4e..36ff89b2679 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -774,6 +774,12 @@ optimize_specialization_lookup_p (tree tmpl) /* DECL_CLASS_SCOPE_P holds of T::f even if T is a template parameter. */ && CLASS_TYPE_P (DECL_CONTEXT (tmpl)) + /* The optimized lookup depends on the fact that the + template arguments for the member function template apply + purely to the containing class, which is not true if the + containing class is an explicit or partial + specialization. */ + && !CLASSTYPE_TEMPLATE_SPECIALIZATION (DECL_CONTEXT (tmpl)) && !DECL_MEMBER_TEMPLATE_P (tmpl) && !DECL_CONV_FN_P (tmpl) /* It is possible to have a template that is not a member diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 624e57ef301..ac5fa076e42 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-10-11 Mark Mitchell + + PR c++/17936 + * g++.dg/template/spec18.C: New test. + 2004-10-11 Steve Ellcey * testsuite/gcc.dg/ia64-asm-1.c: Add prototype for abort diff --git a/gcc/testsuite/g++.dg/template/spec18.C b/gcc/testsuite/g++.dg/template/spec18.C new file mode 100644 index 00000000000..a22e8543d0e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec18.C @@ -0,0 +1,13 @@ +// PR c++/17936 + +template struct A +{ + void foo(); +}; + +template struct A<1, N> +{ + void foo(); +}; + +template<> void A<1, 2>::foo();