aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c510
1 files changed, 383 insertions, 127 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 29f4b50..b6011c1 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -175,17 +175,17 @@ static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
static bool any_strictly_viable (struct z_candidate *);
static struct z_candidate *add_template_candidate
(struct z_candidate **, tree, tree, tree, tree, const vec<tree, va_gc> *,
- tree, tree, tree, int, unification_kind_t, tsubst_flags_t);
+ tree, tree, tree, int, unification_kind_t, bool, tsubst_flags_t);
static struct z_candidate *add_template_candidate_real
(struct z_candidate **, tree, tree, tree, tree, const vec<tree, va_gc> *,
- tree, tree, tree, int, tree, unification_kind_t, tsubst_flags_t);
+ tree, tree, tree, int, tree, unification_kind_t, bool, tsubst_flags_t);
static bool is_complete (tree);
static struct z_candidate *add_conv_candidate
(struct z_candidate **, tree, tree, const vec<tree, va_gc> *, tree,
tree, tsubst_flags_t);
static struct z_candidate *add_function_candidate
(struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *, tree,
- tree, int, conversion**, tsubst_flags_t);
+ tree, int, conversion**, bool, tsubst_flags_t);
static conversion *implicit_conversion (tree, tree, tree, bool, int,
tsubst_flags_t);
static conversion *reference_binding (tree, tree, tree, bool, int,
@@ -455,8 +455,8 @@ struct rejection_reason {
int expected;
/* The actual number of arguments in the call. */
int actual;
- /* Whether the call was a varargs call. */
- bool call_varargs_p;
+ /* Whether EXPECTED should be treated as a lower bound. */
+ bool least_p;
} arity;
/* Information about an argument conversion mismatch. */
struct conversion_info conversion;
@@ -628,12 +628,13 @@ alloc_rejection (enum rejection_reason_code code)
}
static struct rejection_reason *
-arity_rejection (tree first_arg, int expected, int actual)
+arity_rejection (tree first_arg, int expected, int actual, bool least_p = false)
{
struct rejection_reason *r = alloc_rejection (rr_arity);
int adjust = first_arg != NULL_TREE;
r->u.arity.expected = expected - adjust;
r->u.arity.actual = actual - adjust;
+ r->u.arity.least_p = least_p;
return r;
}
@@ -1731,7 +1732,8 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
because A[] and A[2] are reference-related. But we don't do it
because grok_reference_init has deduced the array size (to 1), and
A[1] and A[2] aren't reference-related. */
- if (CONSTRUCTOR_NELTS (expr) == 1)
+ if (CONSTRUCTOR_NELTS (expr) == 1
+ && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
{
tree elt = CONSTRUCTOR_ELT (expr, 0)->value;
if (error_operand_p (elt))
@@ -2095,6 +2097,7 @@ implicit_conversion_1 (tree to, tree from, tree expr, bool c_cast_p,
{
if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& CONSTRUCTOR_NELTS (expr) == 1
+ && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr)
&& !is_list_ctor (cand->fn))
{
/* "If C is not an initializer-list constructor and the
@@ -2239,6 +2242,56 @@ conv_flags (int i, int nargs, tree fn, tree arg, int flags)
return lflags;
}
+/* Build an appropriate 'this' conversion for the method FN and class
+ type CTYPE from the value ARG (having type ARGTYPE) to the type PARMTYPE.
+ This function modifies PARMTYPE, ARGTYPE and ARG. */
+
+static conversion *
+build_this_conversion (tree fn, tree ctype,
+ tree& parmtype, tree& argtype, tree& arg,
+ int flags, tsubst_flags_t complain)
+{
+ gcc_assert (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn));
+
+ /* The type of the implicit object parameter ('this') for
+ overload resolution is not always the same as for the
+ function itself; conversion functions are considered to
+ be members of the class being converted, and functions
+ introduced by a using-declaration are considered to be
+ members of the class that uses them.
+
+ Since build_over_call ignores the ICS for the `this'
+ parameter, we can just change the parm type. */
+ parmtype = cp_build_qualified_type (ctype,
+ cp_type_quals (TREE_TYPE (parmtype)));
+ bool this_p = true;
+ if (FUNCTION_REF_QUALIFIED (TREE_TYPE (fn)))
+ {
+ /* If the function has a ref-qualifier, the implicit
+ object parameter has reference type. */
+ bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn));
+ parmtype = cp_build_reference_type (parmtype, rv);
+ /* The special handling of 'this' conversions in compare_ics
+ does not apply if there is a ref-qualifier. */
+ this_p = false;
+ }
+ else
+ {
+ parmtype = build_pointer_type (parmtype);
+ /* We don't use build_this here because we don't want to
+ capture the object argument until we've chosen a
+ non-static member function. */
+ arg = build_address (arg);
+ argtype = lvalue_type (arg);
+ }
+ flags |= LOOKUP_ONLYCONVERTING;
+ conversion *t = implicit_conversion (parmtype, argtype, arg,
+ /*c_cast_p=*/false, flags, complain);
+ t->this_p = this_p;
+ return t;
+}
+
/* Create an overload candidate for the function or method FN called
with the argument list FIRST_ARG/ARGS and add it to CANDIDATES.
FLAGS is passed on to implicit_conversion.
@@ -2246,7 +2299,14 @@ conv_flags (int i, int nargs, tree fn, tree arg, int flags)
This does not change ARGS.
CTYPE, if non-NULL, is the type we want to pretend this function
- comes from for purposes of overload resolution. */
+ comes from for purposes of overload resolution.
+
+ SHORTCUT_BAD_CONVS controls how we handle "bad" argument conversions.
+ If true, we stop computing conversions upon seeing the first bad
+ conversion. This is used by add_candidates to avoid computing
+ more conversions than necessary in the presence of a strictly viable
+ candidate, while preserving the defacto behavior of overload resolution
+ when it turns out there are only non-strictly viable candidates. */
static struct z_candidate *
add_function_candidate (struct z_candidate **candidates,
@@ -2254,6 +2314,7 @@ add_function_candidate (struct z_candidate **candidates,
const vec<tree, va_gc> *args, tree access_path,
tree conversion_path, int flags,
conversion **convs,
+ bool shortcut_bad_convs,
tsubst_flags_t complain)
{
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
@@ -2375,8 +2436,6 @@ add_function_candidate (struct z_candidate **candidates,
{
tree argtype, to_type;
tree arg;
- conversion *t;
- int is_this;
if (parmnode == void_list_node)
break;
@@ -2395,54 +2454,23 @@ add_function_candidate (struct z_candidate **candidates,
(*args)[i + skip - (first_arg != NULL_TREE ? 1 : 0)]);
argtype = lvalue_type (arg);
- is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
- && ! DECL_CONSTRUCTOR_P (fn));
-
+ conversion *t;
if (parmnode)
{
tree parmtype = TREE_VALUE (parmnode);
-
- parmnode = TREE_CHAIN (parmnode);
-
- /* The type of the implicit object parameter ('this') for
- overload resolution is not always the same as for the
- function itself; conversion functions are considered to
- be members of the class being converted, and functions
- introduced by a using-declaration are considered to be
- members of the class that uses them.
-
- Since build_over_call ignores the ICS for the `this'
- parameter, we can just change the parm type. */
- if (ctype && is_this)
+ if (i == 0
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn))
+ t = build_this_conversion (fn, ctype, parmtype, argtype, arg,
+ flags, complain);
+ else
{
- parmtype = cp_build_qualified_type
- (ctype, cp_type_quals (TREE_TYPE (parmtype)));
- if (FUNCTION_REF_QUALIFIED (TREE_TYPE (fn)))
- {
- /* If the function has a ref-qualifier, the implicit
- object parameter has reference type. */
- bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn));
- parmtype = cp_build_reference_type (parmtype, rv);
- /* The special handling of 'this' conversions in compare_ics
- does not apply if there is a ref-qualifier. */
- is_this = false;
- }
- else
- {
- parmtype = build_pointer_type (parmtype);
- /* We don't use build_this here because we don't want to
- capture the object argument until we've chosen a
- non-static member function. */
- arg = build_address (arg);
- argtype = lvalue_type (arg);
- }
+ int lflags = conv_flags (i, len-skip, fn, arg, flags);
+ t = implicit_conversion (parmtype, argtype, arg,
+ /*c_cast_p=*/false, lflags, complain);
}
-
- int lflags = conv_flags (i, len-skip, fn, arg, flags);
-
- t = implicit_conversion (parmtype, argtype, arg,
- /*c_cast_p=*/false, lflags, complain);
to_type = parmtype;
+ parmnode = TREE_CHAIN (parmnode);
}
else
{
@@ -2451,9 +2479,6 @@ add_function_candidate (struct z_candidate **candidates,
to_type = argtype;
}
- if (t && is_this)
- t->this_p = true;
-
convs[i] = t;
if (! t)
{
@@ -2468,7 +2493,8 @@ add_function_candidate (struct z_candidate **candidates,
viable = -1;
reason = bad_arg_conversion_rejection (first_arg, i, arg, to_type,
EXPR_LOCATION (arg));
-
+ if (shortcut_bad_convs)
+ break;
}
}
@@ -3352,7 +3378,9 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
This does not change ARGLIST. The RETURN_TYPE is the desired type
for conversion operators. If OBJ is NULL_TREE, FLAGS and CTYPE are
as for add_function_candidate. If an OBJ is supplied, FLAGS and
- CTYPE are ignored, and OBJ is as for add_conv_candidate. */
+ CTYPE are ignored, and OBJ is as for add_conv_candidate.
+
+ SHORTCUT_BAD_CONVS is as in add_function_candidate. */
static struct z_candidate*
add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
@@ -3360,7 +3388,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
const vec<tree, va_gc> *arglist, tree return_type,
tree access_path, tree conversion_path,
int flags, tree obj, unification_kind_t strict,
- tsubst_flags_t complain)
+ bool shortcut_bad_convs, tsubst_flags_t complain)
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_tree_vec (ntparms);
@@ -3450,9 +3478,73 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
}
gcc_assert (ia == nargs_without_in_chrg);
+ if (!obj && explicit_targs)
+ {
+ /* Check that there's no obvious arity mismatch before proceeding with
+ deduction. This avoids substituting explicit template arguments
+ into the template (which could result in an error outside the
+ immediate context) when the resulting candidate would be unviable
+ anyway. */
+ int min_arity = 0, max_arity = 0;
+ tree parms = TYPE_ARG_TYPES (TREE_TYPE (tmpl));
+ parms = skip_artificial_parms_for (tmpl, parms);
+ for (; parms != void_list_node; parms = TREE_CHAIN (parms))
+ {
+ if (!parms || PACK_EXPANSION_P (TREE_VALUE (parms)))
+ {
+ max_arity = -1;
+ break;
+ }
+ if (TREE_PURPOSE (parms))
+ /* A parameter with a default argument. */
+ ++max_arity;
+ else
+ ++min_arity, ++max_arity;
+ }
+ if (ia < (unsigned)min_arity)
+ {
+ /* Too few arguments. */
+ reason = arity_rejection (NULL_TREE, min_arity, ia,
+ /*least_p=*/(max_arity == -1));
+ goto fail;
+ }
+ else if (max_arity != -1 && ia > (unsigned)max_arity)
+ {
+ /* Too many arguments. */
+ reason = arity_rejection (NULL_TREE, max_arity, ia);
+ goto fail;
+ }
+ }
+
errs = errorcount+sorrycount;
if (!obj)
- convs = alloc_conversions (nargs);
+ {
+ convs = alloc_conversions (nargs);
+
+ if (shortcut_bad_convs
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl)
+ && !DECL_CONSTRUCTOR_P (tmpl))
+ {
+ /* Check the 'this' conversion before proceeding with deduction.
+ This is effectively an extension of the DR 1391 resolution
+ that we perform in check_non_deducible_conversions, though it's
+ convenient to do this extra check here instead of there. */
+ tree parmtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (tmpl)));
+ tree argtype = lvalue_type (first_arg);
+ tree arg = first_arg;
+ conversion *t = build_this_conversion (tmpl, ctype,
+ parmtype, argtype, arg,
+ flags, complain);
+ convs[0] = t;
+ if (t->bad_p)
+ {
+ reason = bad_arg_conversion_rejection (first_arg, 0,
+ arg, parmtype,
+ EXPR_LOCATION (arg));
+ goto fail;
+ }
+ }
+ }
fn = fn_type_unification (tmpl, explicit_targs, targs,
args_without_in_chrg,
nargs_without_in_chrg,
@@ -3499,7 +3591,8 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
else
cand = add_function_candidate (candidates, fn, ctype,
first_arg, arglist, access_path,
- conversion_path, flags, convs, complain);
+ conversion_path, flags, convs,
+ shortcut_bad_convs, complain);
if (DECL_TI_TEMPLATE (fn) != tmpl)
/* This situation can occur if a member template of a template
class is specialized. Then, instantiate_template might return
@@ -3525,8 +3618,9 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
return cand;
fail:
- return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL,
- access_path, conversion_path, 0, reason, flags);
+ int viable = (reason->code == rr_bad_arg_conversion ? -1 : 0);
+ return add_candidate (candidates, tmpl, first_arg, arglist, nargs, convs,
+ access_path, conversion_path, viable, reason, flags);
}
@@ -3535,13 +3629,15 @@ add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
tree explicit_targs, tree first_arg,
const vec<tree, va_gc> *arglist, tree return_type,
tree access_path, tree conversion_path, int flags,
- unification_kind_t strict, tsubst_flags_t complain)
+ unification_kind_t strict, bool shortcut_bad_convs,
+ tsubst_flags_t complain)
{
return
add_template_candidate_real (candidates, tmpl, ctype,
explicit_targs, first_arg, arglist,
return_type, access_path, conversion_path,
- flags, NULL_TREE, strict, complain);
+ flags, NULL_TREE, strict, shortcut_bad_convs,
+ complain);
}
/* Create an overload candidate for the conversion function template TMPL,
@@ -3567,7 +3663,7 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
NULL_TREE, arglist, return_type, access_path,
conversion_path, 0, obj, DEDUCE_CALL,
- complain);
+ /*shortcut_bad_convs=*/false, complain);
}
/* The CANDS are the set of candidates that were considered for
@@ -3723,12 +3819,19 @@ print_conversion_rejection (location_t loc, struct conversion_info *info,
HAVE. */
static void
-print_arity_information (location_t loc, unsigned int have, unsigned int want)
-{
- inform_n (loc, want,
- " candidate expects %d argument, %d provided",
- " candidate expects %d arguments, %d provided",
- want, have);
+print_arity_information (location_t loc, unsigned int have, unsigned int want,
+ bool least_p)
+{
+ if (least_p)
+ inform_n (loc, want,
+ " candidate expects at least %d argument, %d provided",
+ " candidate expects at least %d arguments, %d provided",
+ want, have);
+ else
+ inform_n (loc, want,
+ " candidate expects %d argument, %d provided",
+ " candidate expects %d arguments, %d provided",
+ want, have);
}
/* Print information about one overload candidate CANDIDATE. MSGSTR
@@ -3792,7 +3895,8 @@ print_z_candidate (location_t loc, const char *msgstr,
{
case rr_arity:
print_arity_information (cloc, r->u.arity.actual,
- r->u.arity.expected);
+ r->u.arity.expected,
+ r->u.arity.least_p);
break;
case rr_arg_conversion:
print_conversion_rejection (cloc, &r->u.conversion, fn);
@@ -4108,7 +4212,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
{
cand->second_conv = build_identity_conv (totype, NULL_TREE);
- /* If totype isn't a reference, and LOOKUP_NO_TEMP_BIND isn't
+ /* If totype isn't a reference, and LOOKUP_ONLYCONVERTING is
set, then this is copy-initialization. In that case, "The
result of the call is then used to direct-initialize the
object that is the destination of the copy-initialization."
@@ -4117,6 +4221,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
We represent this in the conversion sequence with an
rvalue conversion, which means a constructor call. */
if (!TYPE_REF_P (totype)
+ && cxx_dialect < cxx17
+ && (flags & LOOKUP_ONLYCONVERTING)
&& !(convflags & LOOKUP_NO_TEMP_BIND))
cand->second_conv
= build_conv (ck_rvalue, totype, cand->second_conv);
@@ -4484,6 +4590,9 @@ build_converted_constant_expr_internal (tree type, tree expr,
&& processing_template_decl)
conv = next_conversion (conv);
+ /* Issuing conversion warnings for value-dependent expressions is
+ likely too noisy. */
+ warning_sentinel w (warn_conversion);
conv->check_narrowing = true;
conv->check_narrowing_const_only = true;
expr = convert_like (conv, expr, complain);
@@ -4622,7 +4731,7 @@ perform_overload_resolution (tree fn,
functions. */
static void
-print_error_for_call_failure (tree fn, vec<tree, va_gc> *args,
+print_error_for_call_failure (tree fn, const vec<tree, va_gc> *args,
struct z_candidate *candidates)
{
tree targs = NULL_TREE;
@@ -4647,6 +4756,40 @@ print_error_for_call_failure (tree fn, vec<tree, va_gc> *args,
print_z_candidates (loc, candidates);
}
+/* Perform overload resolution on the set of deduction guides DGUIDES
+ using ARGS. Returns the selected deduction guide, or error_mark_node
+ if overload resolution fails. */
+
+tree
+perform_dguide_overload_resolution (tree dguides, const vec<tree, va_gc> *args,
+ tsubst_flags_t complain)
+{
+ z_candidate *candidates;
+ bool any_viable_p;
+ tree result;
+
+ gcc_assert (deduction_guide_p (OVL_FIRST (dguides)));
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ void *p = conversion_obstack_alloc (0);
+
+ z_candidate *cand = perform_overload_resolution (dguides, args, &candidates,
+ &any_viable_p, complain);
+ if (!cand)
+ {
+ if (complain & tf_error)
+ print_error_for_call_failure (dguides, args, candidates);
+ result = error_mark_node;
+ }
+ else
+ result = cand->fn;
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return result;
+}
+
/* Return an expression for a call to FN (a namespace-scope function,
or a static member function) with the ARGS. This may change
ARGS. */
@@ -4911,10 +5054,8 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
|| TYPE_REFFN_P (totype)
|| (TYPE_REF_P (totype)
&& TYPE_PTRFN_P (TREE_TYPE (totype))))
- for (ovl_iterator iter (TREE_VALUE (convs)); iter; ++iter)
+ for (tree fn : ovl_range (TREE_VALUE (convs)))
{
- tree fn = *iter;
-
if (DECL_NONCONVERTING_P (fn))
continue;
@@ -5798,7 +5939,8 @@ build_conditional_expr_1 (const op_location_t &loc,
warn here, because the COND_EXPR will be turned into ARG2. */
if (warn_duplicated_branches
&& (complain & tf_warning)
- && (arg2 == arg3 || operand_equal_p (arg2, arg3, 0)))
+ && (arg2 == arg3 || operand_equal_p (arg2, arg3,
+ OEP_ADDRESS_OF_SAME_FIELD)))
warning_at (EXPR_LOCATION (result), OPT_Wduplicated_branches,
"this condition has identical branches");
@@ -5874,6 +6016,9 @@ perfect_conversion_p (conversion *conv)
next_conversion (conv)->type))
return false;
}
+ if (conv->check_narrowing)
+ /* Brace elision is imperfect. */
+ return false;
return true;
}
@@ -5888,6 +6033,11 @@ perfect_candidate_p (z_candidate *cand)
{
if (cand->viable < 1)
return false;
+ /* CWG1402 makes an implicitly deleted move op worse than other
+ candidates. */
+ if (DECL_DELETED_FN (cand->fn) && DECL_DEFAULTED_FN (cand->fn)
+ && move_fn_p (cand->fn))
+ return false;
int len = cand->num_convs;
for (int i = 0; i < len; ++i)
if (!perfect_conversion_p (cand->convs[i]))
@@ -5965,6 +6115,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
/* Delay creating the implicit this parameter until it is needed. */
non_static_args = NULL;
+ bool seen_strictly_viable = any_strictly_viable (*candidates);
/* If there's a non-template perfect match, we don't need to consider
templates. So check non-templates first. This optimization is only
really needed for the defaulted copy constructor of tuple and the like
@@ -5976,11 +6127,22 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
else /*if (flags & LOOKUP_DEFAULTED)*/
which = non_templates;
+ /* During overload resolution, we first consider each function under the
+ assumption that we'll eventually find a strictly viable candidate.
+ This allows us to circumvent our defacto behavior when checking
+ argument conversions and shortcut consideration of the candidate
+ upon encountering the first bad conversion. If this assumption
+ turns out to be false, and all candidates end up being non-strictly
+ viable, then we reconsider such candidates under the defacto behavior.
+ This trick is important for pruning member function overloads according
+ to their const/ref-qualifiers (since all 'this' conversions are at
+ worst bad) without breaking -fpermissive. */
+ tree bad_fns = NULL_TREE;
+ bool shortcut_bad_convs = true;
+
again:
- for (lkp_iterator iter (fns); iter; ++iter)
+ for (tree fn : lkp_range (fns))
{
- fn = *iter;
-
if (check_converting && DECL_NONCONVERTING_P (fn))
continue;
if (check_list_ctor && !is_list_ctor (fn))
@@ -6024,18 +6186,22 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
}
if (TREE_CODE (fn) == TEMPLATE_DECL)
- add_template_candidate (candidates,
- fn,
- ctype,
- explicit_targs,
- fn_first_arg,
- fn_args,
- return_type,
- access_path,
- conversion_path,
- flags,
- strict,
- complain);
+ {
+ if (!add_template_candidate (candidates,
+ fn,
+ ctype,
+ explicit_targs,
+ fn_first_arg,
+ fn_args,
+ return_type,
+ access_path,
+ conversion_path,
+ flags,
+ strict,
+ shortcut_bad_convs,
+ complain))
+ continue;
+ }
else
{
add_function_candidate (candidates,
@@ -6047,16 +6213,47 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
conversion_path,
flags,
NULL,
+ shortcut_bad_convs,
complain);
if (perfect_candidate_p (*candidates))
seen_perfect = true;
}
+
+ z_candidate *cand = *candidates;
+ if (cand->viable == 1)
+ seen_strictly_viable = true;
+
+ if (cand->viable == -1
+ && shortcut_bad_convs
+ && !cand->convs[cand->reversed () ? 0 : cand->num_convs - 1])
+ {
+ /* This candidate has been tentatively marked non-strictly viable,
+ and we didn't compute all argument conversions for it (having
+ stopped at the first bad conversion). Add the function to BAD_FNS
+ to fully reconsider later if we don't find any strictly viable
+ candidates. */
+ bad_fns = lookup_add (fn, bad_fns);
+ *candidates = (*candidates)->next;
+ }
}
if (which == non_templates && !seen_perfect)
{
which = templates;
goto again;
}
+ else if (which == templates
+ && !seen_strictly_viable
+ && shortcut_bad_convs
+ && bad_fns)
+ {
+ /* None of the candidates are strictly viable, so consider again those
+ functions in BAD_FNS, this time without shortcutting bad conversions
+ so that all their argument conversions are computed. */
+ which = either;
+ fns = bad_fns;
+ shortcut_bad_convs = false;
+ goto again;
+ }
}
/* Returns 1 if P0145R2 says that the LHS of operator CODE is evaluated first,
@@ -7012,10 +7209,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
the usual deallocation function, so we shouldn't complain
about using the operator delete (void *, size_t). */
if (DECL_CLASS_SCOPE_P (fn))
- for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (fns));
- iter; ++iter)
+ for (tree elt : lkp_range (MAYBE_BASELINK_FUNCTIONS (fns)))
{
- tree elt = *iter;
if (usual_deallocation_fn_p (elt)
&& FUNCTION_ARG_CHAIN (elt) == void_list_node)
goto ok;
@@ -7058,9 +7253,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
allocation function. If the lookup finds a single matching
deallocation function, that function will be called; otherwise, no
deallocation function will be called." */
- for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (fns)); iter; ++iter)
+ for (tree elt : lkp_range (MAYBE_BASELINK_FUNCTIONS (fns)))
{
- tree elt = *iter;
dealloc_info di_elt;
if (usual_deallocation_fn_p (elt, &di_elt))
{
@@ -7202,8 +7396,10 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
treat that as an implicit delete-expression. This is also called for
the delete if the constructor throws in a new-expression, and for a
deleting destructor (which implements a delete-expression). */
+ /* But leave this flag off for destroying delete to avoid wrong
+ assumptions in the optimizers. */
tree call = extract_call_expr (ret);
- if (TREE_CODE (call) == CALL_EXPR)
+ if (TREE_CODE (call) == CALL_EXPR && !destroying_delete_p (fn))
CALL_FROM_NEW_OR_DELETE_P (call) = 1;
return ret;
@@ -7467,8 +7663,9 @@ maybe_warn_array_conv (location_t loc, conversion *c, tree expr)
|| TYPE_DOMAIN (type) == NULL_TREE)
return;
- if (conv_binds_to_array_of_unknown_bound (c))
- pedwarn (loc, OPT_Wpedantic, "conversions to arrays of unknown bound "
+ if (pedantic && conv_binds_to_array_of_unknown_bound (c))
+ pedwarn (loc, OPT_Wc__20_extensions,
+ "conversions to arrays of unknown bound "
"are only available with %<-std=c++20%> or %<-std=gnu++20%>");
}
@@ -7793,7 +7990,7 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
expr = convert_like (next_conversion (convs), expr, fn, argnum,
convs->kind == ck_ref_bind
? issue_conversion_warnings : false,
- c_cast_p, complain);
+ c_cast_p, complain & ~tf_no_cleanup);
if (expr == error_mark_node)
return error_mark_node;
@@ -7894,8 +8091,23 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
"lvalue of type %qI", totype, extype);
else if (!TYPE_REF_IS_RVALUE (ref_type) && !lvalue_p (expr)
&& !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
- error_at (loc, "cannot bind non-const lvalue reference of "
- "type %qH to an rvalue of type %qI", totype, extype);
+ {
+ conversion *next = next_conversion (convs);
+ if (next->kind == ck_std)
+ {
+ next = next_conversion (next);
+ error_at (loc, "cannot bind non-const lvalue reference of "
+ "type %qH to a value of type %qI",
+ totype, next->type);
+ }
+ else if (!CP_TYPE_CONST_P (TREE_TYPE (ref_type)))
+ error_at (loc, "cannot bind non-const lvalue reference of "
+ "type %qH to an rvalue of type %qI", totype, extype);
+ else // extype is volatile
+ error_at (loc, "cannot bind lvalue reference of type "
+ "%qH to an rvalue of type %qI", totype,
+ extype);
+ }
else if (!reference_compatible_p (TREE_TYPE (totype), extype))
{
/* If we're converting from T[] to T[N], don't talk
@@ -8048,6 +8260,27 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
return expr;
}
+/* Return true if converting FROM to TO is unsafe in a template. */
+
+static bool
+conv_unsafe_in_template_p (tree to, tree from)
+{
+ /* Converting classes involves TARGET_EXPR. */
+ if (CLASS_TYPE_P (to) || CLASS_TYPE_P (from))
+ return true;
+
+ /* Converting real to integer produces FIX_TRUNC_EXPR which tsubst
+ doesn't handle. */
+ if (SCALAR_FLOAT_TYPE_P (from) && INTEGRAL_OR_ENUMERATION_TYPE_P (to))
+ return true;
+
+ /* Converting integer to real isn't a trivial conversion, either. */
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (from) && SCALAR_FLOAT_TYPE_P (to))
+ return true;
+
+ return false;
+}
+
/* Wrapper for convert_like_internal that handles creating
IMPLICIT_CONV_EXPR. */
@@ -8064,7 +8297,7 @@ convert_like (conversion *convs, tree expr, tree fn, int argnum,
tree conv_expr = NULL_TREE;
if (processing_template_decl
&& convs->kind != ck_identity
- && (CLASS_TYPE_P (convs->type) || CLASS_TYPE_P (TREE_TYPE (expr))))
+ && conv_unsafe_in_template_p (convs->type, TREE_TYPE (expr)))
{
conv_expr = build1 (IMPLICIT_CONV_EXPR, convs->type, expr);
if (convs->kind != ck_ref_bind)
@@ -8137,7 +8370,10 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
{
arg = mark_rvalue_use (arg);
if (TREE_SIDE_EFFECTS (arg))
- arg = cp_build_compound_expr (arg, null_pointer_node, complain);
+ {
+ warning_sentinel w(warn_unused_result);
+ arg = cp_build_compound_expr (arg, null_pointer_node, complain);
+ }
else
arg = null_pointer_node;
}
@@ -8789,6 +9025,7 @@ immediate_invocation_p (tree fn, int nargs)
|| !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
&& (current_binding_level->kind != sk_function_parms
|| !current_binding_level->immediate_fn_ctx_p)
+ && !in_consteval_if_p
/* As an exception, we defer std::source_location::current ()
invocations until genericization because LWG3396 mandates
special behavior for it. */
@@ -8922,8 +9159,13 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
/* OK, we're actually calling this inherited constructor; set its deletedness
appropriately. We can get away with doing this here because calling is
the only way to refer to a constructor. */
- if (DECL_INHERITED_CTOR (fn))
- deduce_inheriting_ctor (fn);
+ if (DECL_INHERITED_CTOR (fn)
+ && !deduce_inheriting_ctor (fn))
+ {
+ if (complain & tf_error)
+ mark_used (fn);
+ return error_mark_node;
+ }
/* Make =delete work with SFINAE. */
if (DECL_DELETED_FN (fn))
@@ -9103,18 +9345,32 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
if (base_binfo == error_mark_node)
return error_mark_node;
}
- tree converted_arg = build_base_path (PLUS_EXPR, arg,
- base_binfo, 1, complain);
/* If we know the dynamic type of the object, look up the final overrider
in the BINFO. */
if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
&& resolves_to_fixed_type_p (arg))
{
- fn = lookup_vfn_in_binfo (DECL_VINDEX (fn), base_binfo);
- flags |= LOOKUP_NONVIRTUAL;
+ tree ov = lookup_vfn_in_binfo (DECL_VINDEX (fn), base_binfo);
+
+ /* And unwind base_binfo to match. If we don't find the type we're
+ looking for in BINFO_INHERITANCE_CHAIN, we're looking at diamond
+ inheritance; for now do a normal virtual call in that case. */
+ tree octx = DECL_CONTEXT (ov);
+ tree obinfo = base_binfo;
+ while (obinfo && !SAME_BINFO_TYPE_P (BINFO_TYPE (obinfo), octx))
+ obinfo = BINFO_INHERITANCE_CHAIN (obinfo);
+ if (obinfo)
+ {
+ fn = ov;
+ base_binfo = obinfo;
+ flags |= LOOKUP_NONVIRTUAL;
+ }
}
+ tree converted_arg = build_base_path (PLUS_EXPR, arg,
+ base_binfo, 1, complain);
+
argarray[j++] = converted_arg;
parm = TREE_CHAIN (parm);
if (first_arg != NULL_TREE)
@@ -9354,7 +9610,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
already_used = true;
}
else
- cp_warn_deprecated_use (fn, complain);
+ cp_handle_deprecated_or_unavailable (fn, complain);
if (eliding_temp && DECL_BASE_CONSTRUCTOR_P (fn)
&& !make_base_init_ok (arg))
@@ -9394,7 +9650,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
/* Avoid copying empty classes. */
val = build2 (COMPOUND_EXPR, type, arg, to);
- TREE_NO_WARNING (val) = 1;
+ suppress_warning (val, OPT_Wunused);
}
else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
{
@@ -9425,10 +9681,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
build2 (MEM_REF, array_type, arg0, alias_set),
build2 (MEM_REF, array_type, arg, alias_set));
val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to);
- TREE_NO_WARNING (val) = 1;
+ suppress_warning (val, OPT_Wunused);
}
- cp_warn_deprecated_use (fn, complain);
+ cp_handle_deprecated_or_unavailable (fn, complain);
return val;
}
@@ -9499,7 +9755,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
tree c = extract_call_expr (call);
if (TREE_CODE (c) == CALL_EXPR)
- TREE_NO_WARNING (c) = 1;
+ suppress_warning (c /* Suppress all warnings. */);
}
if (TREE_CODE (fn) == ADDR_EXPR)
{
@@ -9628,10 +9884,8 @@ has_trivial_copy_assign_p (tree type, bool access, bool *hasassign)
/* Iterate over overloads of the assignment operator, checking
accessible copy assignments for triviality. */
- for (ovl_iterator oi (fns); oi; ++oi)
+ for (tree f : ovl_range (fns))
{
- tree f = *oi;
-
/* Skip operators that aren't copy assignments. */
if (!copy_fn_p (f))
continue;
@@ -9674,10 +9928,8 @@ has_trivial_copy_p (tree type, bool access, bool hasctor[2])
tree fns = get_class_binding (type, complete_ctor_identifier);
bool all_trivial = true;
- for (ovl_iterator oi (fns); oi; ++oi)
+ for (tree f : ovl_range (fns))
{
- tree f = *oi;
-
/* Skip template constructors. */
if (TREE_CODE (f) != FUNCTION_DECL)
continue;
@@ -10159,6 +10411,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
if (BRACE_ENCLOSED_INITIALIZER_P (arg)
&& !TYPE_HAS_LIST_CTOR (class_type)
+ && !CONSTRUCTOR_IS_DESIGNATED_INIT (arg)
&& CONSTRUCTOR_NELTS (arg) == 1)
arg = CONSTRUCTOR_ELT (arg, 0)->value;
@@ -10752,7 +11005,8 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
tree a = instance;
if (TREE_THIS_VOLATILE (a))
a = build_this (a);
- call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call);
+ if (TREE_SIDE_EFFECTS (a))
+ call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call);
}
else if (call != error_mark_node
&& DECL_DESTRUCTOR_P (cand->fn)
@@ -12146,7 +12400,7 @@ can_convert (tree to, tree from, tsubst_flags_t complain)
/* implicit_conversion only considers user-defined conversions
if it has an expression for the call argument list. */
if (CLASS_TYPE_P (from) || CLASS_TYPE_P (to))
- arg = build1 (CAST_EXPR, from, NULL_TREE);
+ arg = build_stub_object (from);
return can_convert_arg (to, from, arg, LOOKUP_IMPLICIT, complain);
}
@@ -12447,13 +12701,15 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
VAR. */
if (TREE_CODE (expr) != TARGET_EXPR)
expr = get_target_expr (expr);
+ else if (TREE_ADDRESSABLE (expr))
+ TREE_ADDRESSABLE (var) = 1;
if (TREE_CODE (decl) == FIELD_DECL
- && extra_warnings && !TREE_NO_WARNING (decl))
+ && extra_warnings && !warning_suppressed_p (decl))
{
warning (OPT_Wextra, "a temporary bound to %qD only persists "
"until the constructor exits", decl);
- TREE_NO_WARNING (decl) = true;
+ suppress_warning (decl);
}
/* Recursively extend temps in this initializer. */