tree match = most_specialized_instantiation (matches);
if (match != error_mark_node)
- matches = tree_cons (TREE_PURPOSE (match),
- NULL_TREE,
- NULL_TREE);
+ {
+ matches = match;
+ TREE_CHAIN (match) = NULL_TREE;
+ }
}
}
+ else if (flag_concepts && TREE_CHAIN (matches))
+ if (tree match = most_constrained_function (matches))
+ {
+ matches = match;
+ TREE_CHAIN (match) = NULL_TREE;
+ }
/* Now we should have exactly one function in MATCHES. */
if (matches == NULL_TREE)
extern tree maybe_process_partial_specialization (tree);
extern tree most_specialized_instantiation (tree);
extern tree most_specialized_partial_spec (tree, tsubst_flags_t, bool = false);
+extern tree most_constrained_function (tree);
extern void print_candidates (tree);
extern void instantiate_pending_templates (int);
extern tree tsubst_default_argument (tree, int, tree, tree,
{
gcc_assert (TREE_CODE (list) == TREE_LIST);
tree f = TREE_VALUE (list);
+ if (f == NULL_TREE)
+ /* Also handle a list from resolve_address_of_overloaded_function with the
+ function in TREE_PURPOSE. */
+ f = TREE_PURPOSE (list);
if (tree ti = DECL_TEMPLATE_INFO (f))
return TI_TEMPLATE (ti);
return f;
Note that we don't compare constraints on the functions
themselves, but rather those of their templates. */
-static tree
+tree
most_constrained_function (tree candidates)
{
// Try to find the best candidate in a first pass.
tree fn = *iter;
if (flag_noexcept_type)
maybe_instantiate_noexcept (fn, tf_none);
- if (try_one_overload (tparms, targs, tempargs, parm, TREE_TYPE (fn),
+ if (TREE_CODE (fn) == FUNCTION_DECL && !constraints_satisfied_p (fn))
+ continue;
+ tree elem = TREE_TYPE (fn);
+ if (try_one_overload (tparms, targs, tempargs, parm, elem,
strict, sub_strict, addr_p, explain_p)
- && (!goodfn || !decls_match (goodfn, fn)))
+ && (!goodfn || !same_type_p (goodfn, elem)))
{
- goodfn = fn;
+ goodfn = elem;
++good;
}
}
overloaded functions does not contain function templates and at most
one of a set of overloaded functions provides a unique match.
+ CWG2918 allows multiple functions to match if they all have the same type,
+ so that we can choose the most constrained later.
+
So if we found multiple possibilities, we return success but don't
deduce anything. */
--- /dev/null
+// CWG 2918 makes this OK
+// { dg-do compile { target c++20 } }
+
+template<bool B> struct X {
+ static void f(short) requires B; // #1
+ static void f(short); // #2
+};
+void test() {
+ auto x = &X<true>::f; // OK, deduces void(*)(short), selects #1
+ auto y = &X<false>::f; // OK, deduces void(*)(short), selects #2
+}