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:
parent
8e2c69b489
commit
0c942f3eda
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
26
gcc/cp/pt.c
26
gcc/cp/pt.c
|
@ -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,
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue