aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-05-11 15:46:59 -0400
committerJason Merrill <jason@redhat.com>2020-05-11 16:19:53 -0400
commit52c5933f5838adb7bf6035e648b770b4958d137f (patch)
tree18c8454e7f9ca88cfe88f2eb42b7658ff1d0312c /gcc
parent0f50f6daa140186a048cbf33f54f4591eabf5f12 (diff)
downloadgcc-52c5933f5838adb7bf6035e648b770b4958d137f.zip
gcc-52c5933f5838adb7bf6035e648b770b4958d137f.tar.gz
gcc-52c5933f5838adb7bf6035e648b770b4958d137f.tar.bz2
c++: Fix specialization of constrained member template.
The resolution of comment CA104 clarifies that we need to do direct substitution of constraints in order to determine which member template corresponds to an explicit specialization. gcc/cp/ChangeLog 2020-05-11 Jason Merrill <jason@redhat.com> Resolve C++20 NB comment CA104 * pt.c (determine_specialization): Compare constraints for specialization of member template of class instantiation.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c28
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-spec1.C10
-rw-r--r--gcc/testsuite/g++.dg/template/nontype18.C2
4 files changed, 42 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5195a0a..5cf9dda 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2020-05-11 Jason Merrill <jason@redhat.com>
+ Resolve C++20 NB comment CA104
+ * pt.c (determine_specialization): Compare constraints for
+ specialization of member template of class instantiation.
+
+2020-05-11 Jason Merrill <jason@redhat.com>
+
PR c++/92583
PR c++/92654
* tree.c (cp_walk_subtrees): Stop at typedefs.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 86f1bb7..8486456 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2282,8 +2282,29 @@ determine_specialization (tree template_id,
below. */
if (tsk == tsk_template)
{
- if (compparms (fn_arg_types, decl_arg_types))
- candidates = tree_cons (NULL_TREE, fn, candidates);
+ if (!comp_template_parms (DECL_TEMPLATE_PARMS (fn),
+ current_template_parms))
+ continue;
+ if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
+ TREE_TYPE (TREE_TYPE (fn))))
+ continue;
+ if (!compparms (fn_arg_types, decl_arg_types))
+ continue;
+
+ tree freq = get_trailing_function_requirements (fn);
+ tree dreq = get_trailing_function_requirements (decl);
+ if (!freq != !dreq)
+ continue;
+ if (freq)
+ {
+ tree fargs = DECL_TI_ARGS (fn);
+ tsubst_flags_t complain = tf_none;
+ freq = tsubst_constraint (freq, fargs, complain, fn);
+ if (!cp_tree_equal (freq, dreq))
+ continue;
+ }
+
+ candidates = tree_cons (NULL_TREE, fn, candidates);
continue;
}
@@ -2472,7 +2493,8 @@ determine_specialization (tree template_id,
*targs_out = copy_node (DECL_TI_ARGS (fn));
/* Propagate the candidate's constraints to the declaration. */
- set_constraints (decl, get_constraints (fn));
+ if (tsk != tsk_template)
+ set_constraints (decl, get_constraints (fn));
/* DECL is a re-declaration or partial instantiation of a template
function. */
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-spec1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-spec1.C
new file mode 100644
index 0000000..5001813
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-spec1.C
@@ -0,0 +1,10 @@
+// Example from CA 104 proposal.
+// { dg-do compile { target concepts } }
+
+template <class T> concept C = sizeof(T) == 8;
+template <class T> struct A {
+ template <class U> U f(U) requires C<typename T::type>; // #1
+ template <class U> U f(U) requires C<T>; // #2
+};
+
+template <> template <class U> U A<int>::f(U) requires C<int> { } // OK, specializes #2
diff --git a/gcc/testsuite/g++.dg/template/nontype18.C b/gcc/testsuite/g++.dg/template/nontype18.C
index cbe0a1b..b68416d 100644
--- a/gcc/testsuite/g++.dg/template/nontype18.C
+++ b/gcc/testsuite/g++.dg/template/nontype18.C
@@ -5,4 +5,4 @@ template<int I> struct A
template<typename T> void foo();
};
-template<int I> template<typename T> void A<0>::foo() {} // { dg-error "template parameter" }
+template<int I> template<typename T> void A<0>::foo() {} // { dg-error "" }