aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-11-08 01:06:42 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-11-08 01:06:42 -0500
commit31cb2db0b28fe254d07194fb68bd95f8372a0457 (patch)
treeab788b854793bedbd2a4f41bebb0a2e56b901e73 /gcc/cp
parent967064a13f94780b3a573ed953ff6b7968da4361 (diff)
downloadgcc-31cb2db0b28fe254d07194fb68bd95f8372a0457.zip
gcc-31cb2db0b28fe254d07194fb68bd95f8372a0457.tar.gz
gcc-31cb2db0b28fe254d07194fb68bd95f8372a0457.tar.bz2
DR 1558
DR 1558 * pt.c (dependent_alias_template_spec_p): New. (dependent_type_p_r): Handle dependent alias template specialization. (template_args_equal): A dependent alias template specializations is not equal to its underlying type as a template argument. * tree.c (strip_typedefs): Don't strip a dependent alias template-id. From-SVN: r217250
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c41
-rw-r--r--gcc/cp/tree.c5
4 files changed, 49 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 132b9e1..a831d62 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
2014-11-07 Jason Merrill <jason@redhat.com>
+ DR 1558
+ * pt.c (dependent_alias_template_spec_p): New.
+ (dependent_type_p_r): Handle dependent alias template specialization.
+ (template_args_equal): A dependent alias template specializations
+ is not equal to its underlying type as a template argument.
+ * tree.c (strip_typedefs): Don't strip a dependent alias
+ template-id.
+
* parser.c (cp_parser_unqualified_id): Handle __func__ here.
(cp_parser_primary_expression): Not here.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index abc3d6f..74636df 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5692,6 +5692,7 @@ extern tree fold_non_dependent_expr (tree);
extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t);
extern bool alias_type_or_template_p (tree);
extern bool alias_template_specialization_p (const_tree);
+extern bool dependent_alias_template_spec_p (const_tree);
extern bool explicit_class_specialization_p (tree);
extern bool push_tinst_level (tree);
extern bool push_tinst_level_loc (tree, location_t);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2cf10f4..fa9652f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5268,7 +5268,7 @@ alias_type_or_template_p (tree t)
|| DECL_ALIAS_TEMPLATE_P (t));
}
-/* Return TRUE iff is a specialization of an alias template. */
+/* Return TRUE iff T is a specialization of an alias template. */
bool
alias_template_specialization_p (const_tree t)
@@ -5282,6 +5282,16 @@ alias_template_specialization_p (const_tree t)
&& DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t)));
}
+/* Return TRUE iff T is a specialization of an alias template with
+ dependent template-arguments. */
+
+bool
+dependent_alias_template_spec_p (const_tree t)
+{
+ return (alias_template_specialization_p (t)
+ && any_dependent_template_arguments_p (TYPE_TI_ARGS (t)));
+}
+
/* Return the number of innermost template parameters in TMPL. */
static int
@@ -7217,7 +7227,24 @@ template_args_equal (tree ot, tree nt)
return template_args_equal (ot, nt);
}
else if (TYPE_P (nt))
- return TYPE_P (ot) && same_type_p (ot, nt);
+ {
+ if (!TYPE_P (ot))
+ return false;
+ /* Don't treat an alias template specialization with dependent
+ arguments as equivalent to its underlying type when used as a
+ template argument; we need them to hash differently. */
+ bool ndep = dependent_alias_template_spec_p (nt);
+ ++processing_template_decl;
+ bool odep = dependent_alias_template_spec_p (ot);
+ --processing_template_decl;
+ if (ndep != odep)
+ return false;
+ else if (ndep)
+ return (TYPE_TI_TEMPLATE (nt) == TYPE_TI_TEMPLATE (ot)
+ && template_args_equal (TYPE_TI_ARGS (nt), TYPE_TI_ARGS (ot)));
+ else
+ return same_type_p (ot, nt);
+ }
else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
return 0;
else
@@ -20719,8 +20746,10 @@ dependent_type_p_r (tree type)
if (TREE_CODE (type) == TYPENAME_TYPE)
return true;
/* -- a cv-qualified type where the cv-unqualified type is
- dependent. */
- type = TYPE_MAIN_VARIANT (type);
+ dependent.
+ No code is necessary for this bullet; the code below handles
+ cv-qualified types, and we don't want to strip aliases with
+ TYPE_MAIN_VARIANT because of DR 1558. */
/* -- a compound type constructed from any dependent type. */
if (TYPE_PTRMEM_P (type))
return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
@@ -20763,9 +20792,9 @@ dependent_type_p_r (tree type)
return true;
/* ... or any of the template arguments is a dependent type or
an expression that is type-dependent or value-dependent. */
- else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
+ else if (TYPE_TEMPLATE_INFO (type)
&& (any_dependent_template_arguments_p
- (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)))))
+ (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (type)))))
return true;
/* All TYPEOF_TYPEs, DECLTYPE_TYPEs, and UNDERLYING_TYPEs are
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 32e7bd54..e0c2af1 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1244,6 +1244,11 @@ strip_typedefs (tree t)
if (t == TYPE_CANONICAL (t))
return t;
+ if (dependent_alias_template_spec_p (t))
+ /* DR 1558: However, if the template-id is dependent, subsequent
+ template argument substitution still applies to the template-id. */
+ return t;
+
switch (TREE_CODE (t))
{
case POINTER_TYPE: