On 9/18/24 10:59 PM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this
look OK for trunk?  I'm not sure this is worth backporting
without the previous CWG 2273 tweak since it'll mean inconsistent
behavior between implict vs explicit object members in GCC 14: the call
to S<>{}.f() in concepts-memfun4.C would now return 10 (due to the CWG
2273 tiebreaker incorrectly triggering), while the g() and h() calls
would be ambiguous (since that tiebreaker doesn't consider object
correspondence).

Agreed, I wouldn't backport.

Also I'm not 100% sure if I'm interpreting "both are direct members of
the same class" correctly here to mean ruling out using'd vs non-using'd
members, since https://eel.is/c++draft/namespace.udecl#note-5 says
using'd members are "treated as though they were direct members of the
derived class"...?

Looking back at the CWG wiki notes, I see that ruling out using vs non-using was intended.

+++ b/gcc/cp/call.cc
@@ -12893,16 +12872,19 @@ cand_parms_match (z_candidate *c1, z_candidate *c2, 
pmatch match_kind)
    tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn1));
    tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (fn2));
+ if (DECL_FUNCTION_MEMBER_P (fn1)
+      && DECL_FUNCTION_MEMBER_P (fn2))
      {
+      tree base1 = DECL_CONTEXT (strip_inheriting_ctors (fn1));
+      tree base2 = DECL_CONTEXT (strip_inheriting_ctors (fn2));
+      if (base1 != base2)
+       return false;
+
+      /* CWG2789 is not adequate, it should specify corresponding object
+        parameters, not same typed object parameters.  */

With this change, the difference is no longer significant; the comment should change to something like

/* Use object_parms_correspond to simplify comparing iobj/xobj/static
   member functions.  */

+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C
@@ -20,12 +23,14 @@ struct S : B<> {
    constexpr operator int () const { return 10; }
    constexpr int g() { return 10; }
    constexpr int h(this S&&) { return 10; }
+  // { dg-warning "explicit object" "" { target c++20_only } .-1 }
  };
-// implicit object parms match, B::f is more constrained
-static_assert(S<>{}.f() == 5);
-static_assert(S<>{}.g() == 5);
-static_assert(S<>{}.h() == 5);
+// ambiguous, constraints aren't considered since the candidates
+// are defined from different classes

"defined in" or "come from"

OK with these two tweaks.

Jason

Reply via email to