From 883a2bff66fbcba913f3c21427a0551d8624dc6b Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Thu, 28 Oct 2004 20:53:04 +0000 Subject: [PATCH] re PR c++/17132 (GCC fails to eliminate function template specialization when argument deduction fails) PR c++/17132 * pt.c (instantiate_class_template): Increment processing_template_decl when substituting into a member class template. PR c++/17132 * g++.dg/template/memclass3.C: New test. From-SVN: r89778 --- gcc/cp/ChangeLog | 7 ++++ gcc/cp/pt.c | 18 +++++++++-- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/template/memclass3.C | 39 +++++++++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/memclass3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ee2ae82a54a..2edaa402f21 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2004-10-28 Mark Mitchell + + PR c++/17132 + * pt.c (instantiate_class_template): Increment + processing_template_decl when substituting into a member class + template. + 2004-10-27 Mark Mitchell PR c++/17435 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 99f4e7b9602..eb44e64b9b9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5621,14 +5621,28 @@ instantiate_class_template (tree type) tree tag = t; tree name = TYPE_IDENTIFIER (tag); tree newtag; - + bool class_template_p; + + class_template_p = (TREE_CODE (tag) != ENUMERAL_TYPE + && TYPE_LANG_SPECIFIC (tag) + && CLASSTYPE_IS_TEMPLATE (tag)); + /* If the member is a class template, then -- even after + substituition -- there may be dependent types in the + template argument list for the class. We increment + PROCESSING_TEMPLATE_DECL so that dependent_type_p, as + that function will assume that no types are dependent + when outside of a template. */ + if (class_template_p) + ++processing_template_decl; newtag = tsubst (tag, args, tf_error, NULL_TREE); + if (class_template_p) + --processing_template_decl; if (newtag == error_mark_node) continue; if (TREE_CODE (newtag) != ENUMERAL_TYPE) { - if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag)) + if (class_template_p) /* Unfortunately, lookup_template_class sets CLASSTYPE_IMPLICIT_INSTANTIATION for a partial instantiation (i.e., for the type of a member diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b1378a661b..556d3301c25 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-10-28 Mark Mitchell + + PR c++/17132 + * g++.dg/template/memclass3.C: New test. + 2004-10-28 Adam Nemet PR middle-end/18160 diff --git a/gcc/testsuite/g++.dg/template/memclass3.C b/gcc/testsuite/g++.dg/template/memclass3.C new file mode 100644 index 00000000000..8230b94e5b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memclass3.C @@ -0,0 +1,39 @@ +// PR c++/17132 + +template +struct has_deref +{ + struct impl + { + template < + typename Type, + typename Type::reference (Type::*Func)(void) const> + struct func_tag; + + template + static char (& test( + Type *, + func_tag * = 0 + ))[2]; + static char test(void *); + }; + + static const bool value = (sizeof(impl::test((T *) 0)) == 2); +}; + +template +struct container +{ + struct iterator + { + typedef T & reference; + reference operator*() const; + }; +}; + +int main() +{ + typedef container::iterator iter; + int result = has_deref::value; + return result; +} -- 2.30.2