From 7c82a41e7f18796040b3e6effbf6c483b7beb915 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 14 Jun 2004 15:58:54 +0000 Subject: [PATCH] re PR c++/15096 (parse error with templates and pointer to const member) PR c++/15096 * decl.c (grokdeclarator): Ignore pointer-to-members when computing template depth. PR c++/14930 * name-lookup.c (pushtag): Do not try to put class declarations in explicit specialization scopes. PR c++/15096 * g++.dg/template/ptrmem10.C: New test. PR c++/14930 * g++.dg/template/friend30.C: New test. From-SVN: r83112 --- gcc/cp/ChangeLog | 10 +++++++ gcc/cp/decl.c | 37 ++++++++++++------------ gcc/cp/name-lookup.c | 11 ++++++- gcc/testsuite/ChangeLog | 8 +++++ gcc/testsuite/g++.dg/template/friend30.C | 15 ++++++++++ gcc/testsuite/g++.dg/template/ptrmem10.C | 21 ++++++++++++++ 6 files changed, 83 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/friend30.C create mode 100644 gcc/testsuite/g++.dg/template/ptrmem10.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cb18209818f..d99aef0a8fd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2004-06-14 Mark Mitchell + + PR c++/15096 + * decl.c (grokdeclarator): Ignore pointer-to-members when + computing template depth. + + PR c++/14930 + * name-lookup.c (pushtag): Do not try to put class declarations in + explicit specialization scopes. + 2004-06-11 Andrew Pinski * decl.c (grokdeclarator): Do not depend on C99's _Bool's behavior. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 950bac10b73..417171e760c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7599,27 +7599,28 @@ grokdeclarator (tree declarator, ctype = TREE_OPERAND (declarator, 0); t = ctype; - while (t != NULL_TREE && CLASS_TYPE_P (t)) - { - /* You're supposed to have one `template <...>' - for every template class, but you don't need one - for a full specialization. For example: - + if (TREE_CODE (TREE_OPERAND (declarator, 1)) != INDIRECT_REF) + while (t != NULL_TREE && CLASS_TYPE_P (t)) + { + /* You're supposed to have one `template <...>' + for every template class, but you don't need one + for a full specialization. For example: + template struct S{}; template <> struct S { void f(); }; void S::f () {} - - is correct; there shouldn't be a `template <>' for - the definition of `S::f'. */ - if (CLASSTYPE_TEMPLATE_INFO (t) - && (CLASSTYPE_TEMPLATE_INSTANTIATION (t) - || uses_template_parms (CLASSTYPE_TI_ARGS (t))) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))) - template_count += 1; - - t = TYPE_MAIN_DECL (t); - t = DECL_CONTEXT (t); - } + + is correct; there shouldn't be a `template <>' for + the definition of `S::f'. */ + if (CLASSTYPE_TEMPLATE_INFO (t) + && (CLASSTYPE_TEMPLATE_INSTANTIATION (t) + || uses_template_parms (CLASSTYPE_TI_ARGS (t))) + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))) + template_count += 1; + + t = TYPE_MAIN_DECL (t); + t = DECL_CONTEXT (t); + } if (sname == NULL_TREE) goto done_scoping; diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index d470251d317..3e42f3b5dce 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4635,7 +4635,16 @@ pushtag (tree name, tree type, int globalize) timevar_push (TV_NAME_LOOKUP); b = current_binding_level; - while (b->kind == sk_cleanup + while (/* Cleanup scopes are not scopes from the point of view of + the language. */ + b->kind == sk_cleanup + /* Neither are the scopes used to hold template parameters + for an explicit specialization. For an ordinary template + declaration, these scopes are not scopes from the point of + view of the language -- but we need a place to stash + things that will go in the containing namespace when the + template is instantiated. */ + || (b->kind == sk_template_parms && b->explicit_spec_p) || (b->kind == sk_class && (globalize /* We may be defining a new type in the initializer diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 02da20e3509..0bff3abb8de 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2004-06-14 Mark Mitchell + + PR c++/15096 + * g++.dg/template/ptrmem10.C: New test. + + PR c++/14930 + * g++.dg/template/friend30.C: New test. + 2004-06-14 Tobias Schlueter PR fortran/14928 diff --git a/gcc/testsuite/g++.dg/template/friend30.C b/gcc/testsuite/g++.dg/template/friend30.C new file mode 100644 index 00000000000..055fc8d89ec --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend30.C @@ -0,0 +1,15 @@ +// PR c++/14930 + +template class Point; + +template<> class Point { + friend class Plane; + double v; +}; + +struct Plane { + double get(const Point& p); +}; + +double Plane::get(const Point &p) { return p.v; } + diff --git a/gcc/testsuite/g++.dg/template/ptrmem10.C b/gcc/testsuite/g++.dg/template/ptrmem10.C new file mode 100644 index 00000000000..b76d5e80a5a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem10.C @@ -0,0 +1,21 @@ +// PR c++/15096 + +template +class C1 +{ +public: + C1 (); + ~C1 (); + const int C1::* getPtr () const; + +private: + int x; + T_ y; +}; + + +template +const int C1::* C1::getPtr () const +{ return &C1::x; } + +