diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
commit | e252b51ccde010cbd2a146485d8045103cd99533 (patch) | |
tree | e060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/cp/call.c | |
parent | f10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff) | |
parent | 104c05c5284b7822d770ee51a7d91946c7e56d50 (diff) | |
download | gcc-e252b51ccde010cbd2a146485d8045103cd99533.zip gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2 |
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r-- | gcc/cp/call.c | 510 |
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. */ |