aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2011-02-20 17:37:03 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2011-02-20 18:37:03 +0100
commit869b0af5c5c3790ef77ffcc0cddf351a99b6c762 (patch)
tree57dd167d0699fc05779ecc1add424c426cb2f953 /gcc/cp
parent67ad6c8252dad5b26708db00ec1fda7c573af397 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/pt.c46
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;
}