aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2011-02-20 17:37:03 +0000
committerDodji Seketeli <dodji@redhat.com>2011-02-20 17:37:03 +0000
commitfa6d1adb2065ea55664f012dda413ff37a89c6ab (patch)
tree57dd167d0699fc05779ecc1add424c426cb2f953
parentf3ed78c048e856534a501fc17b1b5bb09af4b49a (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@170341 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/pt.c46
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/typedef38.C27
4 files changed, 78 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 938d3f2c40b..a40fd02141b 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 49906361a61..8867225bc4d 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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 51f26e9f26c..ff5650a0815 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-02-20 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/46394
+ * g++.dg/template/typedef38.C: New test.
+
2011-02-20 Paul Thomas <pault@gcc.gnu.org>
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 00000000000..1c764042946
--- /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<class T>
+struct S0
+{
+ typedef T type;
+};
+
+template<class... X>
+struct S1
+{
+ typedef int I;
+};
+
+struct A
+{
+ template<class...U, class V=typename S1<typename S0<U>::type...>::I>
+ A(U...u);
+};
+
+int
+main()
+{
+ A a(1, 2);
+}