/* True if the defining declarations of the two candidates have equivalent
parameters. */
-bool
+static bool
cand_parms_match (z_candidate *c1, z_candidate *c2)
{
tree fn1 = c1->fn;
fn1 = DECL_TEMPLATE_RESULT (t1);
fn2 = DECL_TEMPLATE_RESULT (t2);
}
- return compparms (TYPE_ARG_TYPES (TREE_TYPE (fn1)),
- TYPE_ARG_TYPES (TREE_TYPE (fn2)));
+ 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)
+ && (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn1)
+ != DECL_NONSTATIC_MEMBER_FUNCTION_P (fn2)))
+ {
+ /* Ignore 'this' when comparing the parameters of a static member
+ function with those of a non-static one. */
+ parms1 = skip_artificial_parms_for (fn1, parms1);
+ parms2 = skip_artificial_parms_for (fn2, parms2);
+ }
+ return compparms (parms1, parms2);
}
/* Compare two candidates for overloading as described in
--- /dev/null
+// PR c++/103783
+// { dg-do compile { target c++20 } }
+
+template<bool B>
+struct A {
+ template<class...> void f1() = delete;
+ template<class...> static void f1() requires B;
+
+ template<class...> void f2() requires B;
+ template<class...> static void f2() = delete;
+
+ void g1() = delete;
+ static void g1() requires B;
+
+ void g2() requires B;
+ static void g2() = delete;
+};
+
+int main() {
+ A<true> a;
+ a.f1(); // OK
+ a.f2(); // OK
+ a.g1(); // OK, previously rejected as ambiguous
+ a.g2(); // OK, previously rejected as ambiguous
+}