From 869b0af5c5c3790ef77ffcc0cddf351a99b6c762 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Sun, 20 Feb 2011 17:37:03 +0000 Subject: [PATCH] re PR c++/46394 ([C++0X] [4.6 Regression] no matching function with default template parameter) PR c++/46394 gcc/cp/ PR c++/46394 * pt.c (tsubst_pack_expansion): do not use cp_tree_equal/same_type_p to detect an expansion of a parameter pack. gcc/testsuite/ PR c++/46394 * g++.dg/template/typedef38.C: New test. From-SVN: r170341 --- gcc/cp/ChangeLog | 7 +++++ gcc/cp/pt.c | 46 ++++++++++++++++++++++++++----- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/template/typedef38.C | 27 ++++++++++++++++++ 4 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/typedef38.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 938d3f2..a40fd02 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2011-02-20 Dodji Seketeli + + PR c++/46394 + * pt.c (tsubst_pack_expansion): do not use + cp_tree_equal/same_type_p to detect an expansion of a parameter + pack. + 2011-02-19 Jason Merrill PR c++/47503 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4990636..8867225 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8711,19 +8711,51 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, return result; } + /* For clarity in the comments below let's use the + representation 'argument_pack' to denote an + argument pack and its elements. + + In the 'if' block below, we want to detect cases where + ARG_PACK is argument_pack. I.e, we want to + check if ARG_PACK is an argument pack which sole element is + the expansion of PARM_PACK. That argument pack is typically + created by template_parm_to_arg when passed a parameter + pack. */ if (arg_pack && TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack)) == 1 && PACK_EXPANSION_P (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0))) { tree expansion = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0); tree pattern = PACK_EXPANSION_PATTERN (expansion); - if ((TYPE_P (pattern) && same_type_p (pattern, parm_pack)) - || (!TYPE_P (pattern) && cp_tree_equal (parm_pack, pattern))) - /* The argument pack that the parameter maps to is just an - expansion of the parameter itself, such as one would - find in the implicit typedef of a class inside the - class itself. Consider this parameter "unsubstituted", - so that we will maintain the outer pack expansion. */ + /* So we have an argument_pack. We want to test if P + is actually PARM_PACK. We will not use cp_tree_equal to + test P and PARM_PACK because during type fixup (by + fixup_template_parm) P can be a pre-fixup version of a + type and PARM_PACK be its post-fixup version. + cp_tree_equal would consider them as different even + though we would want to consider them compatible for our + precise purpose here. + + Thus we are going to consider that P and PARM_PACK are + compatible if they have the same DECL. */ + if ((/* If ARG_PACK is a type parameter pack named by the + same DECL as parm_pack ... */ + (TYPE_P (pattern) + && TYPE_P (parm_pack) + && TYPE_NAME (pattern) == TYPE_NAME (parm_pack)) + /* ... or if ARG_PACK is a non-type parameter + named by the same DECL as parm_pack ... */ + || (TREE_CODE (pattern) == TEMPLATE_PARM_INDEX + && TREE_CODE (parm_pack) == PARM_DECL + && TEMPLATE_PARM_DECL (pattern) + == TEMPLATE_PARM_DECL (DECL_INITIAL (parm_pack)))) + && template_parameter_pack_p (pattern)) + /* ... then the argument pack that the parameter maps to + is just an expansion of the parameter itself, such as + one would find in the implicit typedef of a class + inside the class itself. Consider this parameter + "unsubstituted", so that we will maintain the outer + pack expansion. */ arg_pack = NULL_TREE; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 51f26e9..ff5650a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-02-20 Dodji Seketeli + + PR c++/46394 + * g++.dg/template/typedef38.C: New test. + 2011-02-20 Paul Thomas PR fortran/46818 diff --git a/gcc/testsuite/g++.dg/template/typedef38.C b/gcc/testsuite/g++.dg/template/typedef38.C new file mode 100644 index 0000000..1c76404 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef38.C @@ -0,0 +1,27 @@ +// Origin: PR c++/46394 +// { dg-options "-std=c++0x" } +// { dg-do "compile" } + +template +struct S0 +{ + typedef T type; +}; + +template +struct S1 +{ + typedef int I; +}; + +struct A +{ + template::type...>::I> + A(U...u); +}; + +int +main() +{ + A a(1, 2); +} -- 2.7.4