@@ -8717,13 +8717,24 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
{
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. */
+ 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;
}
new file mode 100644
@@ -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);
+}