return true;
}
+/* True iff one of CAND's argument conversions is NULL. */
+
+static bool
+missing_conversion_p (const z_candidate *cand)
+{
+ for (unsigned i = 0; i < cand->num_convs; ++i)
+ if (!cand->convs[i])
+ return true;
+ return false;
+}
+
/* Add each of the viable functions in FNS (a FUNCTION_DECL or
OVERLOAD) to the CANDIDATES, returning an updated list of
CANDIDATES. The ARGS are the arguments provided to the call;
if (cand->viable == -1
&& shortcut_bad_convs
- && !cand->convs[cand->reversed () ? 0 : cand->num_convs - 1])
+ && missing_conversion_p (cand))
{
/* This candidate has been tentatively marked non-strictly viable,
and we didn't compute all argument conversions for it (having
bool, bool);
static void tsubst_enum (tree, tree, tree);
static bool check_instantiated_args (tree, tree, tsubst_flags_t);
-static int check_non_deducible_conversion (tree, tree, int, int,
+static int check_non_deducible_conversion (tree, tree, unification_kind_t, int,
struct conversion **, bool);
static int maybe_adjust_types_for_deduction (tree, unification_kind_t,
tree*, tree*, tree);
unify_one_argument. */
static int
-check_non_deducible_conversion (tree parm, tree arg, int strict,
+check_non_deducible_conversion (tree parm, tree arg, unification_kind_t strict,
int flags, struct conversion **conv_p,
bool explain_p)
{
if (can_convert_arg (type, parm, NULL_TREE, flags, complain))
return unify_success (explain_p);
}
- else if (strict != DEDUCE_EXACT)
+ else if (strict == DEDUCE_CALL)
{
bool ok = false;
tree conv_arg = TYPE_P (arg) ? NULL_TREE : arg;
--- /dev/null
+// PR c++/104622
+// { dg-additional-options "-fpermissive" }
+
+template<class T>
+struct type_identity {
+ typedef T type;
+};
+
+template<class T> void f(typename type_identity<T>::type*, T, int*);
+
+int main() {
+ const int p = 0;
+ f(&p, 0, 0); // { dg-warning "invalid conversion" }
+}