aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-08-03 16:32:08 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-08-03 16:32:08 -0400
commit45d765871b6744d2fe519a61a1d15ff4d613388f (patch)
tree9218647d81212608b0e192ef6ad5cce3a8330fe0 /gcc/cp
parent9e356571d442ca5241117b05428fb5055b55d0aa (diff)
downloadgcc-45d765871b6744d2fe519a61a1d15ff4d613388f.zip
gcc-45d765871b6744d2fe519a61a1d15ff4d613388f.tar.gz
gcc-45d765871b6744d2fe519a61a1d15ff4d613388f.tar.bz2
DR 1286
DR 1286 * pt.c (get_underlying_template): New. (convert_template_argument, lookup_template_class_1): Use it. From-SVN: r201470
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c38
2 files changed, 42 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8b9b997..5587ac1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2013-08-03 Jason Merrill <jason@redhat.com>
+ DR 1286
+ * pt.c (get_underlying_template): New.
+ (convert_template_argument, lookup_template_class_1): Use it.
+
DR 1430
PR c++/51239
* pt.c (pack_expansion_args_count): Rename from
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bbaeb7d..d03c1cf 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5111,6 +5111,34 @@ alias_template_specialization_p (const_tree t)
&& DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t)));
}
+/* Return either TMPL or another template that it is equivalent to under DR
+ 1286: An alias that just changes the name of a template is equivalent to
+ the other template. */
+
+static tree
+get_underlying_template (tree tmpl)
+{
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
+ while (DECL_ALIAS_TEMPLATE_P (tmpl))
+ {
+ tree result = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
+ if (TYPE_TEMPLATE_INFO (result))
+ {
+ tree sub = TYPE_TI_TEMPLATE (result);
+ if (PRIMARY_TEMPLATE_P (sub)
+ && same_type_p (result, TREE_TYPE (sub)))
+ {
+ /* The alias type is equivalent to the pattern of the
+ underlying template, so strip the alias. */
+ tmpl = sub;
+ continue;
+ }
+ }
+ break;
+ }
+ return tmpl;
+}
+
/* Subroutine of convert_nontype_argument. Converts EXPR to TYPE, which
must be a function or a pointer-to-function type, as specified
in [temp.arg.nontype]: disambiguate EXPR if it is an overload set,
@@ -6319,6 +6347,9 @@ convert_template_argument (tree parm,
tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
tree argparm;
+ /* Strip alias templates that are equivalent to another
+ template. */
+ arg = get_underlying_template (arg);
argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
if (coerce_template_template_parms (parmparm, argparm,
@@ -7177,6 +7208,13 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
complain &= ~tf_user;
+ /* An alias that just changes the name of a template is equivalent to the
+ other template, so if any of the arguments are pack expansions, strip
+ the alias to avoid problems with a pack expansion passed to a non-pack
+ alias template parameter (DR 1430). */
+ if (pack_expansion_args_count (INNERMOST_TEMPLATE_ARGS (arglist)))
+ templ = get_underlying_template (templ);
+
if (DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
{
/* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store