My initial implementation of alias template equivalence failed to handle
the case here, of a nested alias being equivalent to its enclosing class
template. Fixed by implementing the rules in the standard more directly.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit f7c8a08b6ee7f9229be75efa909d6673c77a4fd3
Author: Jason Merrill <ja...@redhat.com>
Date: Tue Feb 25 11:15:36 2014 -0500
DR 1286
PR c++/60328
* pt.c (get_underlying_template): Fix equivalence calculation.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bd59142..4a9fa71 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5185,9 +5185,12 @@ get_underlying_template (tree tmpl)
tree sub = TYPE_TI_TEMPLATE (result);
if (PRIMARY_TEMPLATE_P (sub)
&& (num_innermost_template_parms (tmpl)
- == num_innermost_template_parms (sub))
- && same_type_p (result, TREE_TYPE (sub)))
+ == num_innermost_template_parms (sub)))
{
+ tree alias_args = INNERMOST_TEMPLATE_ARGS
+ (template_parms_to_args (DECL_TEMPLATE_PARMS (tmpl)));
+ if (!comp_template_args (TYPE_TI_ARGS (result), alias_args))
+ break;
/* The alias type is equivalent to the pattern of the
underlying template, so strip the alias. */
tmpl = sub;
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286b.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286b.C
new file mode 100644
index 0000000..fef9818
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286b.C
@@ -0,0 +1,12 @@
+// PR c++/60328
+// { dg-require-effective-target c++11 }
+
+template <class _T, class... _Rest>
+struct Foo
+{
+ template <class _TT, class... _RR>
+ using Bar = Foo<_TT, _RR...>;
+
+ using Normal = Foo<_Rest...>;
+ using Fail = Bar<_Rest...>;
+};