aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-03-10 12:35:54 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-03-10 12:35:54 -0500
commit0c942f3edab10854aecdf92e8bd79ca6bc33bc66 (patch)
treea7d2c35e72397be1b3912093862c526b9c8df377
parent8e2c69b4893c96b373a55b6850dde4eafa484e46 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/pt.c26
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-57.C30
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