diff options
author | Jason Merrill <jason@redhat.com> | 2017-03-10 12:35:54 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-03-10 12:35:54 -0500 |
commit | 0c942f3edab10854aecdf92e8bd79ca6bc33bc66 (patch) | |
tree | a7d2c35e72397be1b3912093862c526b9c8df377 | |
parent | 8e2c69b4893c96b373a55b6850dde4eafa484e46 (diff) | |
download | gcc-0c942f3edab10854aecdf92e8bd79ca6bc33bc66.zip gcc-0c942f3edab10854aecdf92e8bd79ca6bc33bc66.tar.gz gcc-0c942f3edab10854aecdf92e8bd79ca6bc33bc66.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alias-decl-57.C | 30 |
4 files changed, 59 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 69b49e6..92b430d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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> PR c++/79967 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 68f2722..5be5dfe 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6208,8 +6208,8 @@ extern int is_specialization_of (tree, tree); extern bool is_specialization_of_friend (tree, tree); extern tree get_pattern_parm (tree, tree); extern int comp_template_args (tree, tree, tree * = NULL, - tree * = NULL); -extern int template_args_equal (tree, tree); + tree * = NULL, bool = false); +extern int template_args_equal (tree, tree, bool = false); extern tree maybe_process_partial_specialization (tree); extern tree most_specialized_instantiation (tree); extern void print_candidates (tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 416f132..b8ce9fe 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8240,7 +8240,7 @@ coerce_innermost_template_parms (tree parms, /* Returns 1 if template args OT and NT are equivalent. */ int -template_args_equal (tree ot, tree nt) +template_args_equal (tree ot, tree nt, bool partial_order /* = false */) { if (nt == ot) return 1; @@ -8288,8 +8288,13 @@ template_args_equal (tree ot, tree nt) template argument; we need them to be distinct so that we substitute into the specialization arguments at instantiation time. And aliases can't be equivalent without being ==, so - we don't need to look any deeper. */ - if (TYPE_ALIAS_P (nt) || TYPE_ALIAS_P (ot)) + we don't need to look any deeper. + + 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; else return same_type_p (ot, nt); @@ -8321,7 +8326,8 @@ template_args_equal (tree ot, tree nt) int comp_template_args (tree oldargs, tree newargs, - tree *oldarg_ptr, tree *newarg_ptr) + tree *oldarg_ptr, tree *newarg_ptr, + bool partial_order) { int i; @@ -8339,7 +8345,7 @@ comp_template_args (tree oldargs, tree newargs, tree nt = TREE_VEC_ELT (newargs, 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) *oldarg_ptr = ot; @@ -8351,6 +8357,12 @@ comp_template_args (tree oldargs, tree newargs, return 1; } +inline bool +comp_template_args_porder (tree oargs, tree nargs) +{ + return comp_template_args (oargs, nargs, NULL, NULL, true); +} + static void 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 /* We only need to check the innermost arguments; the other arguments will always agree. */ - || !comp_template_args (INNERMOST_TEMPLATE_ARGS (spec_args), - INNERMOST_TEMPLATE_ARGS (args))) + || !comp_template_args_porder (INNERMOST_TEMPLATE_ARGS (spec_args), + INNERMOST_TEMPLATE_ARGS (args))) return NULL_TREE; /* Now that we have bindings for all of the template arguments, diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-57.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-57.C new file mode 100644 index 0000000..f257e62 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-57.C @@ -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 |