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.
This commit is contained in:
parent
0f50f6daa1
commit
52c5933f58
@ -1,3 +1,9 @@
|
||||
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
|
||||
|
28
gcc/cp/pt.c
28
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. */
|
||||
|
10
gcc/testsuite/g++.dg/cpp2a/concepts-spec1.C
Normal file
10
gcc/testsuite/g++.dg/cpp2a/concepts-spec1.C
Normal file
@ -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
|
@ -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 "" }
|
||||
|
Loading…
Reference in New Issue
Block a user