PR c++/79960 - alias templates and partial ordering

* pt.c (comp_template_args): Add partial_order parm.
	(template_args_equal): Likewise.
	(comp_template_args_porder): New.
	(get_partial_spec_bindings): Use it.

From-SVN: r246042
This commit is contained in:
Jason Merrill 2017-03-10 12:35:54 -05:00 committed by Jason Merrill
parent 8e2c69b489
commit 0c942f3eda
4 changed files with 59 additions and 9 deletions

View File

@ -1,3 +1,11 @@
2017-03-10 Jason Merrill <jason@redhat.com>
PR c++/79960 - alias templates and partial ordering
* pt.c (comp_template_args): Add partial_order parm.
(template_args_equal): Likewise.
(comp_template_args_porder): New.
(get_partial_spec_bindings): Use it.
2017-03-10 Marek Polacek <polacek@redhat.com> 2017-03-10 Marek Polacek <polacek@redhat.com>
PR c++/79967 PR c++/79967

View File

@ -6208,8 +6208,8 @@ extern int is_specialization_of (tree, tree);
extern bool is_specialization_of_friend (tree, tree); extern bool is_specialization_of_friend (tree, tree);
extern tree get_pattern_parm (tree, tree); extern tree get_pattern_parm (tree, tree);
extern int comp_template_args (tree, tree, tree * = NULL, extern int comp_template_args (tree, tree, tree * = NULL,
tree * = NULL); tree * = NULL, bool = false);
extern int template_args_equal (tree, tree); extern int template_args_equal (tree, tree, bool = false);
extern tree maybe_process_partial_specialization (tree); extern tree maybe_process_partial_specialization (tree);
extern tree most_specialized_instantiation (tree); extern tree most_specialized_instantiation (tree);
extern void print_candidates (tree); extern void print_candidates (tree);

View File

@ -8240,7 +8240,7 @@ coerce_innermost_template_parms (tree parms,
/* Returns 1 if template args OT and NT are equivalent. */ /* Returns 1 if template args OT and NT are equivalent. */
int int
template_args_equal (tree ot, tree nt) template_args_equal (tree ot, tree nt, bool partial_order /* = false */)
{ {
if (nt == ot) if (nt == ot)
return 1; return 1;
@ -8288,8 +8288,13 @@ template_args_equal (tree ot, tree nt)
template argument; we need them to be distinct so that we template argument; we need them to be distinct so that we
substitute into the specialization arguments at instantiation substitute into the specialization arguments at instantiation
time. And aliases can't be equivalent without being ==, so time. And aliases can't be equivalent without being ==, so
we don't need to look any deeper. */ we don't need to look any deeper.
if (TYPE_ALIAS_P (nt) || TYPE_ALIAS_P (ot))
During partial ordering, however, we need to treat them normally so
that we can order uses of the same alias with different
cv-qualification (79960). */
if (!partial_order
&& (TYPE_ALIAS_P (nt) || TYPE_ALIAS_P (ot)))
return false; return false;
else else
return same_type_p (ot, nt); return same_type_p (ot, nt);
@ -8321,7 +8326,8 @@ template_args_equal (tree ot, tree nt)
int int
comp_template_args (tree oldargs, tree newargs, comp_template_args (tree oldargs, tree newargs,
tree *oldarg_ptr, tree *newarg_ptr) tree *oldarg_ptr, tree *newarg_ptr,
bool partial_order)
{ {
int i; int i;
@ -8339,7 +8345,7 @@ comp_template_args (tree oldargs, tree newargs,
tree nt = TREE_VEC_ELT (newargs, i); tree nt = TREE_VEC_ELT (newargs, i);
tree ot = TREE_VEC_ELT (oldargs, i); tree ot = TREE_VEC_ELT (oldargs, i);
if (! template_args_equal (ot, nt)) if (! template_args_equal (ot, nt, partial_order))
{ {
if (oldarg_ptr != NULL) if (oldarg_ptr != NULL)
*oldarg_ptr = ot; *oldarg_ptr = ot;
@ -8351,6 +8357,12 @@ comp_template_args (tree oldargs, tree newargs,
return 1; return 1;
} }
inline bool
comp_template_args_porder (tree oargs, tree nargs)
{
return comp_template_args (oargs, nargs, NULL, NULL, true);
}
static void static void
add_pending_template (tree d) add_pending_template (tree d)
{ {
@ -21584,8 +21596,8 @@ get_partial_spec_bindings (tree tmpl, tree spec_tmpl, tree args)
if (spec_args == error_mark_node if (spec_args == error_mark_node
/* We only need to check the innermost arguments; the other /* We only need to check the innermost arguments; the other
arguments will always agree. */ arguments will always agree. */
|| !comp_template_args (INNERMOST_TEMPLATE_ARGS (spec_args), || !comp_template_args_porder (INNERMOST_TEMPLATE_ARGS (spec_args),
INNERMOST_TEMPLATE_ARGS (args))) INNERMOST_TEMPLATE_ARGS (args)))
return NULL_TREE; return NULL_TREE;
/* Now that we have bindings for all of the template arguments, /* Now that we have bindings for all of the template arguments,

View File

@ -0,0 +1,30 @@
// PR c++/79960
// { dg-do compile { target c++11 } }
using size_t = decltype(sizeof(0));
template<typename T> struct tuple_size;
template<typename T, size_t U = tuple_size<T>::value>
using __has_tuple_size = T;
template<typename T> struct tuple_size<const __has_tuple_size<T>> {
static constexpr size_t value = tuple_size<T>::value;
};
template<typename T> struct tuple_size<volatile __has_tuple_size<T>> {
static constexpr size_t value = tuple_size<T>::value;
};
template<typename T> struct tuple_size<const __has_tuple_size<volatile T>> {
static constexpr size_t value = tuple_size<T>::value;
};
template<typename... T> struct tuple { };
template<typename... T> struct tuple_size<tuple<T...>> {
static constexpr size_t value = sizeof...(T);
};
static_assert( tuple_size<const tuple<>>::value == 0, "" ); // OK
static_assert( tuple_size<volatile tuple<>>::value == 0, "" ); // OK
static_assert( tuple_size<const volatile tuple<>>::value == 0, "" ); // FAIL