diff options
author | Dodji Seketeli <dodji@redhat.com> | 2011-02-20 17:37:03 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2011-02-20 18:37:03 +0100 |
commit | 869b0af5c5c3790ef77ffcc0cddf351a99b6c762 (patch) | |
tree | 57dd167d0699fc05779ecc1add424c426cb2f953 /gcc/cp | |
parent | 67ad6c8252dad5b26708db00ec1fda7c573af397 (diff) | |
download | gcc-869b0af5c5c3790ef77ffcc0cddf351a99b6c762.zip gcc-869b0af5c5c3790ef77ffcc0cddf351a99b6c762.tar.gz gcc-869b0af5c5c3790ef77ffcc0cddf351a99b6c762.tar.bz2 |
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
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 46 |
2 files changed, 46 insertions, 7 deletions
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 <dodji@redhat.com> + + 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 <jason@redhat.com> 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<elements>' to denote an + argument pack and its elements. + + In the 'if' block below, we want to detect cases where + ARG_PACK is argument_pack<PARM_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<P...>. 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; } |