Commit 31cb2db0 by Jason Merrill Committed by Jason Merrill

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
parent 967064a1
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.
......
......@@ -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);
......
......@@ -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
......
......@@ -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:
......
// DR 1558 still applies when using void_t as a template-argument.
// { dg-do compile { target c++11 } }
template<typename...> using void_t = void;
template<class T> struct A { };
struct B { typedef int foo; };
template<typename T> A<void_t<typename T::foo>> f(); // { dg-error "int" }
template<typename T> A<void> g();
int main()
{
f<B>();
g<int>();
f<int>(); // { dg-error "no match" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment