https://gcc.gnu.org/g:659f32ea9de57661f8a37dcfb0b9a01bfe29acce
commit r14-10696-g659f32ea9de57661f8a37dcfb0b9a01bfe29acce Author: Patrick Palka <ppa...@redhat.com> Date: Fri Sep 20 17:37:03 2024 -0400 c++: CWG 2789 and usings [PR116492] For GCC 14, narrowly fix this PR by implementing the missing - if they are member functions, both are direct members of the same class, and part of CWG 2789 for constructors only. PR c++/116492 DR 2789 gcc/cp/ChangeLog: * call.cc (cand_parms_match): Return false for constructors that come from different classes. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-inherit-ctor12.C: New test. Reviewed-by: Jason Merrill <ja...@redhat.com> Diff: --- gcc/cp/call.cc | 8 ++++++++ gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 0f4eeeb53951..492d17b17446 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -12826,6 +12826,14 @@ cand_parms_match (z_candidate *c1, z_candidate *c2, pmatch match_kind) && DECL_FUNCTION_MEMBER_P (fn2))) /* Early escape. */; + else if ((DECL_INHERITED_CTOR (fn1) || DECL_INHERITED_CTOR (fn2)) + && (DECL_CONTEXT (strip_inheriting_ctors (fn1)) + != DECL_CONTEXT (strip_inheriting_ctors (fn2)))) + /* This should really be checked for all member functions as per + CWG2789, but for GCC 14 we check this only for constructors since + without r15-3740 doing so would result in inconsistent handling + of object parameters (such as in concepts-memfun4.C). */ + return false; /* CWG2789 is not adequate, it should specify corresponding object parameters, not same typed object parameters. */ else if (!object_parms_correspond (c1, fn1, c2, fn2)) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C new file mode 100644 index 000000000000..3e5dbfc37ad0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C @@ -0,0 +1,16 @@ +// PR c++/116492 +// CWG 2789 +// { dg-do compile { target c++20 } } + +template<class T> +struct A { + A() requires true = delete; +}; + +struct B : A<int> { + B(); + using A<int>::A; +}; + +B b; // OK, selects the non-inherited constructor over the more constrained + // inherited constructor.