+2013-02-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/56395
+ * tree.c (strip_typedefs): Strip typedefs from TYPENAME_TYPE template
+ args.
+
2013-02-19 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
}
break;
case TYPENAME_TYPE:
- result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t)),
- TYPENAME_TYPE_FULLNAME (t),
- typename_type, tf_none);
+ {
+ tree fullname = TYPENAME_TYPE_FULLNAME (t);
+ if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR)
+ {
+ tree args = TREE_OPERAND (fullname, 1);
+ tree new_args = copy_node (args);
+ bool changed = false;
+ int i;
+ for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ {
+ tree arg = TREE_VEC_ELT (args, i);
+ tree strip_arg;
+ if (TYPE_P (arg))
+ strip_arg = strip_typedefs (arg);
+ else
+ strip_arg = strip_typedefs_expr (arg);
+ TREE_VEC_ELT (new_args, i) = strip_arg;
+ if (strip_arg != arg)
+ changed = true;
+ }
+ if (changed)
+ fullname = lookup_template_function (TREE_OPERAND (fullname, 0),
+ new_args);
+ else
+ ggc_free (new_args);
+ }
+ result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t)),
+ fullname, typename_type, tf_none);
+ }
break;
case DECLTYPE_TYPE:
result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t));
--- /dev/null
+// PR c++/56395
+
+struct A
+{
+ template <class T> struct B { };
+};
+
+template <class T> struct D { };
+
+template <class T, class U> struct C
+{
+ typedef T _Type;
+ typedef typename T::template B<_Type> _BType;
+ D<_BType> d;
+};
+
+template <class T> struct C<T,T>
+{
+ typedef T _Type;
+ typedef typename T::template B<_Type> _BType;
+ D<_BType> d;
+};
+
+C<A,A> c;