Bootstrapped anh regtested on x86_64-pc-linux-gnu, does this look OK for trunk and 15?
-- >8 -- When a using refers to a member from a partial specialization, we need to substitute the arguments relative to partial specialization into the constraints, not those relative to the primary template. Otherwise we incorrectly reject e.g. the below testcase as ambiguous since we substitute T=int* instead of T=int into #1's constraints and fail to notice the correspondence. This patch corrects the recent r16-2771-gb9f1cc4e119da9 fix by using outer_template_args instead of TI_ARGS of the DECL_CONTEXT, which should always return the correct arguments. PR c++/121351 gcc/cp/ChangeLog: * class.cc (add_method): Use outer_template_args when we need to substitute outer template arguments into constraints. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-using7.C: New test. --- gcc/cp/class.cc | 8 +++---- gcc/testsuite/g++.dg/cpp2a/concepts-using7.C | 23 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-using7.C diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index 14acb9c23c01..cf58f652fc1d 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -1365,14 +1365,14 @@ add_method (tree type, tree method, bool via_using) { if (TREE_CODE (fn) == TEMPLATE_DECL) ++processing_template_decl; - if (tree ti = CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (fn))) + if (tree outer_args = outer_template_args (fn)) fn_constraints = tsubst_constraint_info (fn_constraints, - TI_ARGS (ti), + outer_args, tf_warning_or_error, fn); - if (tree ti = CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (method))) + if (tree outer_args = outer_template_args (method)) method_constraints = tsubst_constraint_info (method_constraints, - TI_ARGS (ti), + outer_args, tf_warning_or_error, method); if (TREE_CODE (fn) == TEMPLATE_DECL) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-using7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-using7.C new file mode 100644 index 000000000000..ffb7cc58d2bd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-using7.C @@ -0,0 +1,23 @@ +// PR c++/121351 +// { dg-do compile { target c++20 } } + +template<class T> concept C = true; + +template<class T> +struct A; + +template<class T> +struct A<T*> { + template<class U> void f(U) requires C<T>; // #1 +}; + +template<class T> +struct B : A<T*> { + using A<T*>::f; + template<class U> void f(U) requires C<int>; // #2 +}; + +int main() { + B<int> b; + b.f(42); // OK, #2 corresponds to and therefore hides #1 +} -- 2.51.0.rc1