| /* Functions related to invoking -*- C++ -*- methods and overloaded functions. |
| Copyright (C) 1987-2021 Free Software Foundation, Inc. |
| Contributed by Michael Tiemann (tiemann@cygnus.com) and |
| modified by Brendan Kehoe (brendan@cygnus.com). |
| |
| This file is part of GCC. |
| |
| GCC is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3, or (at your option) |
| any later version. |
| |
| GCC is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| |
| /* High-level class interface. */ |
| |
| #include "config.h" |
| #include "system.h" |
| #include "coretypes.h" |
| #include "target.h" |
| #include "cp-tree.h" |
| #include "timevar.h" |
| #include "stringpool.h" |
| #include "cgraph.h" |
| #include "stor-layout.h" |
| #include "trans-mem.h" |
| #include "flags.h" |
| #include "toplev.h" |
| #include "intl.h" |
| #include "convert.h" |
| #include "langhooks.h" |
| #include "c-family/c-objc.h" |
| #include "internal-fn.h" |
| #include "stringpool.h" |
| #include "attribs.h" |
| #include "gcc-rich-location.h" |
| |
| /* The various kinds of conversion. */ |
| |
| enum conversion_kind { |
| ck_identity, |
| ck_lvalue, |
| ck_fnptr, |
| ck_qual, |
| ck_std, |
| ck_ptr, |
| ck_pmem, |
| ck_base, |
| ck_ref_bind, |
| ck_user, |
| ck_ambig, |
| ck_list, |
| ck_aggr, |
| ck_rvalue |
| }; |
| |
| /* The rank of the conversion. Order of the enumerals matters; better |
| conversions should come earlier in the list. */ |
| |
| enum conversion_rank { |
| cr_identity, |
| cr_exact, |
| cr_promotion, |
| cr_std, |
| cr_pbool, |
| cr_user, |
| cr_ellipsis, |
| cr_bad |
| }; |
| |
| /* An implicit conversion sequence, in the sense of [over.best.ics]. |
| The first conversion to be performed is at the end of the chain. |
| That conversion is always a cr_identity conversion. */ |
| |
| struct conversion { |
| /* The kind of conversion represented by this step. */ |
| conversion_kind kind; |
| /* The rank of this conversion. */ |
| conversion_rank rank; |
| BOOL_BITFIELD user_conv_p : 1; |
| BOOL_BITFIELD ellipsis_p : 1; |
| BOOL_BITFIELD this_p : 1; |
| /* True if this conversion would be permitted with a bending of |
| language standards, e.g. disregarding pointer qualifiers or |
| converting integers to pointers. */ |
| BOOL_BITFIELD bad_p : 1; |
| /* If KIND is ck_ref_bind or ck_base, true to indicate that a |
| temporary should be created to hold the result of the |
| conversion. If KIND is ck_ambig or ck_user, true means force |
| copy-initialization. */ |
| BOOL_BITFIELD need_temporary_p : 1; |
| /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion |
| from a pointer-to-derived to pointer-to-base is being performed. */ |
| BOOL_BITFIELD base_p : 1; |
| /* If KIND is ck_ref_bind, true when either an lvalue reference is |
| being bound to an lvalue expression or an rvalue reference is |
| being bound to an rvalue expression. If KIND is ck_rvalue or ck_base, |
| true when we are treating an lvalue as an rvalue (12.8p33). If |
| ck_identity, we will be binding a reference directly or decaying to |
| a pointer. */ |
| BOOL_BITFIELD rvaluedness_matches_p: 1; |
| BOOL_BITFIELD check_narrowing: 1; |
| /* Whether check_narrowing should only check TREE_CONSTANTs; used |
| in build_converted_constant_expr. */ |
| BOOL_BITFIELD check_narrowing_const_only: 1; |
| /* True if this conversion is taking place in a copy-initialization context |
| and we should only consider converting constructors. Only set in |
| ck_base and ck_rvalue. */ |
| BOOL_BITFIELD copy_init_p : 1; |
| /* The type of the expression resulting from the conversion. */ |
| tree type; |
| union { |
| /* The next conversion in the chain. Since the conversions are |
| arranged from outermost to innermost, the NEXT conversion will |
| actually be performed before this conversion. This variant is |
| used only when KIND is neither ck_identity, ck_aggr, ck_ambig nor |
| ck_list. Please use the next_conversion function instead |
| of using this field directly. */ |
| conversion *next; |
| /* The expression at the beginning of the conversion chain. This |
| variant is used only if KIND is ck_identity, ck_aggr, or ck_ambig. |
| You can use conv_get_original_expr to get this expression. */ |
| tree expr; |
| /* The array of conversions for an initializer_list, so this |
| variant is used only when KIN D is ck_list. */ |
| conversion **list; |
| } u; |
| /* The function candidate corresponding to this conversion |
| sequence. This field is only used if KIND is ck_user. */ |
| struct z_candidate *cand; |
| }; |
| |
| #define CONVERSION_RANK(NODE) \ |
| ((NODE)->bad_p ? cr_bad \ |
| : (NODE)->ellipsis_p ? cr_ellipsis \ |
| : (NODE)->user_conv_p ? cr_user \ |
| : (NODE)->rank) |
| |
| #define BAD_CONVERSION_RANK(NODE) \ |
| ((NODE)->ellipsis_p ? cr_ellipsis \ |
| : (NODE)->user_conv_p ? cr_user \ |
| : (NODE)->rank) |
| |
| static struct obstack conversion_obstack; |
| static bool conversion_obstack_initialized; |
| struct rejection_reason; |
| |
| static struct z_candidate * tourney (struct z_candidate *, tsubst_flags_t); |
| static int equal_functions (tree, tree); |
| static int joust (struct z_candidate *, struct z_candidate *, bool, |
| tsubst_flags_t); |
| static int compare_ics (conversion *, conversion *); |
| static void maybe_warn_class_memaccess (location_t, tree, |
| const vec<tree, va_gc> *); |
| static tree build_over_call (struct z_candidate *, int, tsubst_flags_t); |
| static tree convert_like (conversion *, tree, tsubst_flags_t); |
| static tree convert_like_with_context (conversion *, tree, tree, int, |
| tsubst_flags_t); |
| static void op_error (const op_location_t &, enum tree_code, enum tree_code, |
| tree, tree, tree, bool); |
| static struct z_candidate *build_user_type_conversion_1 (tree, tree, int, |
| tsubst_flags_t); |
| static void print_z_candidate (location_t, const char *, struct z_candidate *); |
| static void print_z_candidates (location_t, struct z_candidate *); |
| static tree build_this (tree); |
| 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, 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, 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**, 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, |
| tsubst_flags_t); |
| static conversion *build_conv (conversion_kind, tree, conversion *); |
| static conversion *build_list_conv (tree, tree, int, tsubst_flags_t); |
| static conversion *next_conversion (conversion *); |
| static bool is_subseq (conversion *, conversion *); |
| static conversion *maybe_handle_ref_bind (conversion **); |
| static void maybe_handle_implicit_object (conversion **); |
| static struct z_candidate *add_candidate |
| (struct z_candidate **, tree, tree, const vec<tree, va_gc> *, size_t, |
| conversion **, tree, tree, int, struct rejection_reason *, int); |
| static tree source_type (conversion *); |
| static void add_warning (struct z_candidate *, struct z_candidate *); |
| static conversion *direct_reference_binding (tree, conversion *); |
| static bool promoted_arithmetic_type_p (tree); |
| static conversion *conditional_conversion (tree, tree, tsubst_flags_t); |
| static char *name_as_c_string (tree, tree, bool *); |
| static tree prep_operand (tree); |
| static void add_candidates (tree, tree, const vec<tree, va_gc> *, tree, tree, |
| bool, tree, tree, int, struct z_candidate **, |
| tsubst_flags_t); |
| static conversion *merge_conversion_sequences (conversion *, conversion *); |
| static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t); |
| static conversion *build_identity_conv (tree, tree); |
| static inline bool conv_binds_to_array_of_unknown_bound (conversion *); |
| static bool conv_is_prvalue (conversion *); |
| static tree prevent_lifetime_extension (tree); |
| |
| /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE. |
| NAME can take many forms... */ |
| |
| bool |
| check_dtor_name (tree basetype, tree name) |
| { |
| /* Just accept something we've already complained about. */ |
| if (name == error_mark_node) |
| return true; |
| |
| if (TREE_CODE (name) == TYPE_DECL) |
| name = TREE_TYPE (name); |
| else if (TYPE_P (name)) |
| /* OK */; |
| else if (identifier_p (name)) |
| { |
| if ((MAYBE_CLASS_TYPE_P (basetype) |
| || TREE_CODE (basetype) == ENUMERAL_TYPE) |
| && name == constructor_name (basetype)) |
| return true; |
| |
| /* Otherwise lookup the name, it could be an unrelated typedef |
| of the correct type. */ |
| name = lookup_name (name, LOOK_want::TYPE); |
| if (!name) |
| return false; |
| name = TREE_TYPE (name); |
| if (name == error_mark_node) |
| return false; |
| } |
| else |
| { |
| /* In the case of: |
| |
| template <class T> struct S { ~S(); }; |
| int i; |
| i.~S(); |
| |
| NAME will be a class template. */ |
| gcc_assert (DECL_CLASS_TEMPLATE_P (name)); |
| return false; |
| } |
| |
| return same_type_p (TYPE_MAIN_VARIANT (basetype), TYPE_MAIN_VARIANT (name)); |
| } |
| |
| /* We want the address of a function or method. We avoid creating a |
| pointer-to-member function. */ |
| |
| tree |
| build_addr_func (tree function, tsubst_flags_t complain) |
| { |
| tree type = TREE_TYPE (function); |
| |
| /* We have to do these by hand to avoid real pointer to member |
| functions. */ |
| if (TREE_CODE (type) == METHOD_TYPE) |
| { |
| if (TREE_CODE (function) == OFFSET_REF) |
| { |
| tree object = build_address (TREE_OPERAND (function, 0)); |
| return get_member_function_from_ptrfunc (&object, |
| TREE_OPERAND (function, 1), |
| complain); |
| } |
| function = build_address (function); |
| } |
| else if (TREE_CODE (function) == FUNCTION_DECL |
| && DECL_IMMEDIATE_FUNCTION_P (function)) |
| function = build_address (function); |
| else |
| function = decay_conversion (function, complain, /*reject_builtin=*/false); |
| |
| return function; |
| } |
| |
| /* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or |
| POINTER_TYPE to those. Note, pointer to member function types |
| (TYPE_PTRMEMFUNC_P) must be handled by our callers. There are |
| two variants. build_call_a is the primitive taking an array of |
| arguments, while build_call_n is a wrapper that handles varargs. */ |
| |
| tree |
| build_call_n (tree function, int n, ...) |
| { |
| if (n == 0) |
| return build_call_a (function, 0, NULL); |
| else |
| { |
| tree *argarray = XALLOCAVEC (tree, n); |
| va_list ap; |
| int i; |
| |
| va_start (ap, n); |
| for (i = 0; i < n; i++) |
| argarray[i] = va_arg (ap, tree); |
| va_end (ap); |
| return build_call_a (function, n, argarray); |
| } |
| } |
| |
| /* Update various flags in cfun and the call itself based on what is being |
| called. Split out of build_call_a so that bot_manip can use it too. */ |
| |
| void |
| set_flags_from_callee (tree call) |
| { |
| /* Handle both CALL_EXPRs and AGGR_INIT_EXPRs. */ |
| tree decl = cp_get_callee_fndecl_nofold (call); |
| |
| /* We check both the decl and the type; a function may be known not to |
| throw without being declared throw(). */ |
| bool nothrow = decl && TREE_NOTHROW (decl); |
| tree callee = cp_get_callee (call); |
| if (callee) |
| nothrow |= TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (callee))); |
| else if (TREE_CODE (call) == CALL_EXPR |
| && internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW) |
| nothrow = true; |
| |
| if (cfun && cp_function_chain && !cp_unevaluated_operand) |
| { |
| if (!nothrow && at_function_scope_p ()) |
| cp_function_chain->can_throw = 1; |
| |
| if (decl && TREE_THIS_VOLATILE (decl)) |
| current_function_returns_abnormally = 1; |
| } |
| |
| TREE_NOTHROW (call) = nothrow; |
| } |
| |
| tree |
| build_call_a (tree function, int n, tree *argarray) |
| { |
| tree decl; |
| tree result_type; |
| tree fntype; |
| int i; |
| |
| function = build_addr_func (function, tf_warning_or_error); |
| |
| gcc_assert (TYPE_PTR_P (TREE_TYPE (function))); |
| fntype = TREE_TYPE (TREE_TYPE (function)); |
| gcc_assert (FUNC_OR_METHOD_TYPE_P (fntype)); |
| result_type = TREE_TYPE (fntype); |
| /* An rvalue has no cv-qualifiers. */ |
| if (SCALAR_TYPE_P (result_type) || VOID_TYPE_P (result_type)) |
| result_type = cv_unqualified (result_type); |
| |
| function = build_call_array_loc (input_location, |
| result_type, function, n, argarray); |
| set_flags_from_callee (function); |
| |
| decl = get_callee_fndecl (function); |
| |
| if (decl && !TREE_USED (decl)) |
| { |
| /* We invoke build_call directly for several library |
| functions. These may have been declared normally if |
| we're building libgcc, so we can't just check |
| DECL_ARTIFICIAL. */ |
| gcc_assert (DECL_ARTIFICIAL (decl) |
| || !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), |
| "__", 2)); |
| mark_used (decl); |
| } |
| |
| require_complete_eh_spec_types (fntype, decl); |
| |
| TREE_HAS_CONSTRUCTOR (function) = (decl && DECL_CONSTRUCTOR_P (decl)); |
| |
| /* Don't pass empty class objects by value. This is useful |
| for tags in STL, which are used to control overload resolution. |
| We don't need to handle other cases of copying empty classes. */ |
| if (!decl || !fndecl_built_in_p (decl)) |
| for (i = 0; i < n; i++) |
| { |
| tree arg = CALL_EXPR_ARG (function, i); |
| if (is_empty_class (TREE_TYPE (arg)) |
| && simple_empty_class_p (TREE_TYPE (arg), arg, INIT_EXPR)) |
| { |
| while (TREE_CODE (arg) == TARGET_EXPR) |
| /* We're disconnecting the initializer from its target, |
| don't create a temporary. */ |
| arg = TARGET_EXPR_INITIAL (arg); |
| tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (arg)); |
| arg = build2 (COMPOUND_EXPR, TREE_TYPE (t), arg, t); |
| CALL_EXPR_ARG (function, i) = arg; |
| } |
| } |
| |
| return function; |
| } |
| |
| /* New overloading code. */ |
| |
| struct z_candidate; |
| |
| struct candidate_warning { |
| z_candidate *loser; |
| candidate_warning *next; |
| }; |
| |
| /* Information for providing diagnostics about why overloading failed. */ |
| |
| enum rejection_reason_code { |
| rr_none, |
| rr_arity, |
| rr_explicit_conversion, |
| rr_template_conversion, |
| rr_arg_conversion, |
| rr_bad_arg_conversion, |
| rr_template_unification, |
| rr_invalid_copy, |
| rr_inherited_ctor, |
| rr_constraint_failure |
| }; |
| |
| struct conversion_info { |
| /* The index of the argument, 0-based. */ |
| int n_arg; |
| /* The actual argument or its type. */ |
| tree from; |
| /* The type of the parameter. */ |
| tree to_type; |
| /* The location of the argument. */ |
| location_t loc; |
| }; |
| |
| struct rejection_reason { |
| enum rejection_reason_code code; |
| union { |
| /* Information about an arity mismatch. */ |
| struct { |
| /* The expected number of arguments. */ |
| int expected; |
| /* The actual number of arguments in the call. */ |
| int actual; |
| /* Whether EXPECTED should be treated as a lower bound. */ |
| bool least_p; |
| } arity; |
| /* Information about an argument conversion mismatch. */ |
| struct conversion_info conversion; |
| /* Same, but for bad argument conversions. */ |
| struct conversion_info bad_conversion; |
| /* Information about template unification failures. These are the |
| parameters passed to fn_type_unification. */ |
| struct { |
| tree tmpl; |
| tree explicit_targs; |
| int num_targs; |
| const tree *args; |
| unsigned int nargs; |
| tree return_type; |
| unification_kind_t strict; |
| int flags; |
| } template_unification; |
| /* Information about template instantiation failures. These are the |
| parameters passed to instantiate_template. */ |
| struct { |
| tree tmpl; |
| tree targs; |
| } template_instantiation; |
| } u; |
| }; |
| |
| struct z_candidate { |
| /* The FUNCTION_DECL that will be called if this candidate is |
| selected by overload resolution. */ |
| tree fn; |
| /* If not NULL_TREE, the first argument to use when calling this |
| function. */ |
| tree first_arg; |
| /* The rest of the arguments to use when calling this function. If |
| there are no further arguments this may be NULL or it may be an |
| empty vector. */ |
| const vec<tree, va_gc> *args; |
| /* The implicit conversion sequences for each of the arguments to |
| FN. */ |
| conversion **convs; |
| /* The number of implicit conversion sequences. */ |
| size_t num_convs; |
| /* If FN is a user-defined conversion, the standard conversion |
| sequence from the type returned by FN to the desired destination |
| type. */ |
| conversion *second_conv; |
| struct rejection_reason *reason; |
| /* If FN is a member function, the binfo indicating the path used to |
| qualify the name of FN at the call site. This path is used to |
| determine whether or not FN is accessible if it is selected by |
| overload resolution. The DECL_CONTEXT of FN will always be a |
| (possibly improper) base of this binfo. */ |
| tree access_path; |
| /* If FN is a non-static member function, the binfo indicating the |
| subobject to which the `this' pointer should be converted if FN |
| is selected by overload resolution. The type pointed to by |
| the `this' pointer must correspond to the most derived class |
| indicated by the CONVERSION_PATH. */ |
| tree conversion_path; |
| tree template_decl; |
| tree explicit_targs; |
| candidate_warning *warnings; |
| z_candidate *next; |
| int viable; |
| |
| /* The flags active in add_candidate. */ |
| int flags; |
| |
| bool rewritten () const { return (flags & LOOKUP_REWRITTEN); } |
| bool reversed () const { return (flags & LOOKUP_REVERSED); } |
| }; |
| |
| /* Returns true iff T is a null pointer constant in the sense of |
| [conv.ptr]. */ |
| |
| bool |
| null_ptr_cst_p (tree t) |
| { |
| tree type = TREE_TYPE (t); |
| |
| /* [conv.ptr] |
| |
| A null pointer constant is an integer literal ([lex.icon]) with value |
| zero or a prvalue of type std::nullptr_t. */ |
| if (NULLPTR_TYPE_P (type)) |
| return true; |
| |
| if (cxx_dialect >= cxx11) |
| { |
| STRIP_ANY_LOCATION_WRAPPER (t); |
| |
| /* Core issue 903 says only literal 0 is a null pointer constant. */ |
| if (TREE_CODE (t) == INTEGER_CST |
| && !TREE_OVERFLOW (t) |
| && TREE_CODE (type) == INTEGER_TYPE |
| && integer_zerop (t) |
| && !char_type_p (type)) |
| return true; |
| } |
| else if (CP_INTEGRAL_TYPE_P (type)) |
| { |
| t = fold_non_dependent_expr (t, tf_none); |
| STRIP_NOPS (t); |
| if (integer_zerop (t) && !TREE_OVERFLOW (t)) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /* Returns true iff T is a null member pointer value (4.11). */ |
| |
| bool |
| null_member_pointer_value_p (tree t) |
| { |
| tree type = TREE_TYPE (t); |
| if (!type) |
| return false; |
| else if (TYPE_PTRMEMFUNC_P (type)) |
| return (TREE_CODE (t) == CONSTRUCTOR |
| && CONSTRUCTOR_NELTS (t) |
| && integer_zerop (CONSTRUCTOR_ELT (t, 0)->value)); |
| else if (TYPE_PTRDATAMEM_P (type)) |
| return integer_all_onesp (t); |
| else |
| return false; |
| } |
| |
| /* Returns nonzero if PARMLIST consists of only default parms, |
| ellipsis, and/or undeduced parameter packs. */ |
| |
| bool |
| sufficient_parms_p (const_tree parmlist) |
| { |
| for (; parmlist && parmlist != void_list_node; |
| parmlist = TREE_CHAIN (parmlist)) |
| if (!TREE_PURPOSE (parmlist) |
| && !PACK_EXPANSION_P (TREE_VALUE (parmlist))) |
| return false; |
| return true; |
| } |
| |
| /* Allocate N bytes of memory from the conversion obstack. The memory |
| is zeroed before being returned. */ |
| |
| static void * |
| conversion_obstack_alloc (size_t n) |
| { |
| void *p; |
| if (!conversion_obstack_initialized) |
| { |
| gcc_obstack_init (&conversion_obstack); |
| conversion_obstack_initialized = true; |
| } |
| p = obstack_alloc (&conversion_obstack, n); |
| memset (p, 0, n); |
| return p; |
| } |
| |
| /* Allocate rejection reasons. */ |
| |
| static struct rejection_reason * |
| alloc_rejection (enum rejection_reason_code code) |
| { |
| struct rejection_reason *p; |
| p = (struct rejection_reason *) conversion_obstack_alloc (sizeof *p); |
| p->code = code; |
| return p; |
| } |
| |
| static struct rejection_reason * |
| 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; |
| } |
| |
| static struct rejection_reason * |
| arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to, |
| location_t loc) |
| { |
| struct rejection_reason *r = alloc_rejection (rr_arg_conversion); |
| int adjust = first_arg != NULL_TREE; |
| r->u.conversion.n_arg = n_arg - adjust; |
| r->u.conversion.from = from; |
| r->u.conversion.to_type = to; |
| r->u.conversion.loc = loc; |
| return r; |
| } |
| |
| static struct rejection_reason * |
| bad_arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to, |
| location_t loc) |
| { |
| struct rejection_reason *r = alloc_rejection (rr_bad_arg_conversion); |
| int adjust = first_arg != NULL_TREE; |
| r->u.bad_conversion.n_arg = n_arg - adjust; |
| r->u.bad_conversion.from = from; |
| r->u.bad_conversion.to_type = to; |
| r->u.bad_conversion.loc = loc; |
| return r; |
| } |
| |
| static struct rejection_reason * |
| explicit_conversion_rejection (tree from, tree to) |
| { |
| struct rejection_reason *r = alloc_rejection (rr_explicit_conversion); |
| r->u.conversion.n_arg = 0; |
| r->u.conversion.from = from; |
| r->u.conversion.to_type = to; |
| r->u.conversion.loc = UNKNOWN_LOCATION; |
| return r; |
| } |
| |
| static struct rejection_reason * |
| template_conversion_rejection (tree from, tree to) |
| { |
| struct rejection_reason *r = alloc_rejection (rr_template_conversion); |
| r->u.conversion.n_arg = 0; |
| r->u.conversion.from = from; |
| r->u.conversion.to_type = to; |
| r->u.conversion.loc = UNKNOWN_LOCATION; |
| return r; |
| } |
| |
| static struct rejection_reason * |
| template_unification_rejection (tree tmpl, tree explicit_targs, tree targs, |
| const tree *args, unsigned int nargs, |
| tree return_type, unification_kind_t strict, |
| int flags) |
| { |
| size_t args_n_bytes = sizeof (*args) * nargs; |
| tree *args1 = (tree *) conversion_obstack_alloc (args_n_bytes); |
| struct rejection_reason *r = alloc_rejection (rr_template_unification); |
| r->u.template_unification.tmpl = tmpl; |
| r->u.template_unification.explicit_targs = explicit_targs; |
| r->u.template_unification.num_targs = TREE_VEC_LENGTH (targs); |
| /* Copy args to our own storage. */ |
| memcpy (args1, args, args_n_bytes); |
| r->u.template_unification.args = args1; |
| r->u.template_unification.nargs = nargs; |
| r->u.template_unification.return_type = return_type; |
| r->u.template_unification.strict = strict; |
| r->u.template_unification.flags = flags; |
| return r; |
| } |
| |
| static struct rejection_reason * |
| template_unification_error_rejection (void) |
| { |
| return alloc_rejection (rr_template_unification); |
| } |
| |
| static struct rejection_reason * |
| invalid_copy_with_fn_template_rejection (void) |
| { |
| struct rejection_reason *r = alloc_rejection (rr_invalid_copy); |
| return r; |
| } |
| |
| static struct rejection_reason * |
| inherited_ctor_rejection (void) |
| { |
| struct rejection_reason *r = alloc_rejection (rr_inherited_ctor); |
| return r; |
| } |
| |
| /* Build a constraint failure record. */ |
| |
| static struct rejection_reason * |
| constraint_failure (void) |
| { |
| struct rejection_reason *r = alloc_rejection (rr_constraint_failure); |
| return r; |
| } |
| |
| /* Dynamically allocate a conversion. */ |
| |
| static conversion * |
| alloc_conversion (conversion_kind kind) |
| { |
| conversion *c; |
| c = (conversion *) conversion_obstack_alloc (sizeof (conversion)); |
| c->kind = kind; |
| return c; |
| } |
| |
| /* Make sure that all memory on the conversion obstack has been |
| freed. */ |
| |
| void |
| validate_conversion_obstack (void) |
| { |
| if (conversion_obstack_initialized) |
| gcc_assert ((obstack_next_free (&conversion_obstack) |
| == obstack_base (&conversion_obstack))); |
| } |
| |
| /* Dynamically allocate an array of N conversions. */ |
| |
| static conversion ** |
| alloc_conversions (size_t n) |
| { |
| return (conversion **) conversion_obstack_alloc (n * sizeof (conversion *)); |
| } |
| |
| /* True iff the active member of conversion::u for code CODE is NEXT. */ |
| |
| static inline bool |
| has_next (conversion_kind code) |
| { |
| return !(code == ck_identity |
| || code == ck_ambig |
| || code == ck_list |
| || code == ck_aggr); |
| } |
| |
| static conversion * |
| build_conv (conversion_kind code, tree type, conversion *from) |
| { |
| conversion *t; |
| conversion_rank rank = CONVERSION_RANK (from); |
| |
| /* Only call this function for conversions that use u.next. */ |
| gcc_assert (from == NULL || has_next (code)); |
| |
| /* Note that the caller is responsible for filling in t->cand for |
| user-defined conversions. */ |
| t = alloc_conversion (code); |
| t->type = type; |
| t->u.next = from; |
| |
| switch (code) |
| { |
| case ck_ptr: |
| case ck_pmem: |
| case ck_base: |
| case ck_std: |
| if (rank < cr_std) |
| rank = cr_std; |
| break; |
| |
| case ck_qual: |
| case ck_fnptr: |
| if (rank < cr_exact) |
| rank = cr_exact; |
| break; |
| |
| default: |
| break; |
| } |
| t->rank = rank; |
| t->user_conv_p = (code == ck_user || from->user_conv_p); |
| t->bad_p = from->bad_p; |
| t->base_p = false; |
| return t; |
| } |
| |
| /* Represent a conversion from CTOR, a braced-init-list, to TYPE, a |
| specialization of std::initializer_list<T>, if such a conversion is |
| possible. */ |
| |
| static conversion * |
| build_list_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) |
| { |
| tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type), 0); |
| unsigned len = CONSTRUCTOR_NELTS (ctor); |
| conversion **subconvs = alloc_conversions (len); |
| conversion *t; |
| unsigned i; |
| tree val; |
| |
| /* Within a list-initialization we can have more user-defined |
| conversions. */ |
| flags &= ~LOOKUP_NO_CONVERSION; |
| /* But no narrowing conversions. */ |
| flags |= LOOKUP_NO_NARROWING; |
| |
| /* Can't make an array of these types. */ |
| if (TYPE_REF_P (elttype) |
| || TREE_CODE (elttype) == FUNCTION_TYPE |
| || VOID_TYPE_P (elttype)) |
| return NULL; |
| |
| FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val) |
| { |
| conversion *sub |
| = implicit_conversion (elttype, TREE_TYPE (val), val, |
| false, flags, complain); |
| if (sub == NULL) |
| return NULL; |
| |
| subconvs[i] = sub; |
| } |
| |
| t = alloc_conversion (ck_list); |
| t->type = type; |
| t->u.list = subconvs; |
| t->rank = cr_exact; |
| |
| for (i = 0; i < len; ++i) |
| { |
| conversion *sub = subconvs[i]; |
| if (sub->rank > t->rank) |
| t->rank = sub->rank; |
| if (sub->user_conv_p) |
| t->user_conv_p = true; |
| if (sub->bad_p) |
| t->bad_p = true; |
| } |
| |
| return t; |
| } |
| |
| /* Return the next conversion of the conversion chain (if applicable), |
| or NULL otherwise. Please use this function instead of directly |
| accessing fields of struct conversion. */ |
| |
| static conversion * |
| next_conversion (conversion *conv) |
| { |
| if (conv == NULL |
| || !has_next (conv->kind)) |
| return NULL; |
| return conv->u.next; |
| } |
| |
| /* Strip to the first ck_user, ck_ambig, ck_list, ck_aggr or ck_identity |
| encountered. */ |
| |
| static conversion * |
| strip_standard_conversion (conversion *conv) |
| { |
| while (conv |
| && conv->kind != ck_user |
| && has_next (conv->kind)) |
| conv = next_conversion (conv); |
| return conv; |
| } |
| |
| /* Subroutine of build_aggr_conv: check whether FROM is a valid aggregate |
| initializer for array type ATYPE. */ |
| |
| static bool |
| can_convert_array (tree atype, tree from, int flags, tsubst_flags_t complain) |
| { |
| tree elttype = TREE_TYPE (atype); |
| unsigned i; |
| |
| if (TREE_CODE (from) == CONSTRUCTOR) |
| { |
| for (i = 0; i < CONSTRUCTOR_NELTS (from); ++i) |
| { |
| tree val = CONSTRUCTOR_ELT (from, i)->value; |
| bool ok; |
| if (TREE_CODE (elttype) == ARRAY_TYPE) |
| ok = can_convert_array (elttype, val, flags, complain); |
| else |
| ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags, |
| complain); |
| if (!ok) |
| return false; |
| } |
| return true; |
| } |
| |
| if (char_type_p (TYPE_MAIN_VARIANT (elttype)) |
| && TREE_CODE (tree_strip_any_location_wrapper (from)) == STRING_CST) |
| return array_string_literal_compatible_p (atype, from); |
| |
| /* No other valid way to aggregate initialize an array. */ |
| return false; |
| } |
| |
| /* Helper for build_aggr_conv. Return true if FIELD is in PSET, or if |
| FIELD has ANON_AGGR_TYPE_P and any initializable field in there recursively |
| is in PSET. */ |
| |
| static bool |
| field_in_pset (hash_set<tree, true> &pset, tree field) |
| { |
| if (pset.contains (field)) |
| return true; |
| if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) |
| for (field = TYPE_FIELDS (TREE_TYPE (field)); |
| field; field = DECL_CHAIN (field)) |
| { |
| field = next_initializable_field (field); |
| if (field == NULL_TREE) |
| break; |
| if (field_in_pset (pset, field)) |
| return true; |
| } |
| return false; |
| } |
| |
| /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an |
| aggregate class, if such a conversion is possible. */ |
| |
| static conversion * |
| build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) |
| { |
| unsigned HOST_WIDE_INT i = 0; |
| conversion *c; |
| tree field = next_initializable_field (TYPE_FIELDS (type)); |
| tree empty_ctor = NULL_TREE; |
| hash_set<tree, true> pset; |
| |
| /* We already called reshape_init in implicit_conversion. */ |
| |
| /* The conversions within the init-list aren't affected by the enclosing |
| context; they're always simple copy-initialization. */ |
| flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING; |
| |
| /* For designated initializers, verify that each initializer is convertible |
| to corresponding TREE_TYPE (ce->index) and mark those FIELD_DECLs as |
| visited. In the following loop then ignore already visited |
| FIELD_DECLs. */ |
| if (CONSTRUCTOR_IS_DESIGNATED_INIT (ctor)) |
| { |
| tree idx, val; |
| FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, idx, val) |
| { |
| if (idx && TREE_CODE (idx) == FIELD_DECL) |
| { |
| tree ftype = TREE_TYPE (idx); |
| bool ok; |
| |
| if (TREE_CODE (ftype) == ARRAY_TYPE) |
| ok = can_convert_array (ftype, val, flags, complain); |
| else |
| ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags, |
| complain); |
| |
| if (!ok) |
| return NULL; |
| /* For unions, there should be just one initializer. */ |
| if (TREE_CODE (type) == UNION_TYPE) |
| { |
| field = NULL_TREE; |
| i = 1; |
| break; |
| } |
| pset.add (idx); |
| } |
| else |
| return NULL; |
| } |
| } |
| |
| for (; field; field = next_initializable_field (DECL_CHAIN (field))) |
| { |
| tree ftype = TREE_TYPE (field); |
| tree val; |
| bool ok; |
| |
| if (!pset.is_empty () && field_in_pset (pset, field)) |
| continue; |
| if (i < CONSTRUCTOR_NELTS (ctor)) |
| { |
| val = CONSTRUCTOR_ELT (ctor, i)->value; |
| ++i; |
| } |
| else if (DECL_INITIAL (field)) |
| val = get_nsdmi (field, /*ctor*/false, complain); |
| else if (TYPE_REF_P (ftype)) |
| /* Value-initialization of reference is ill-formed. */ |
| return NULL; |
| else |
| { |
| if (empty_ctor == NULL_TREE) |
| empty_ctor = build_constructor (init_list_type_node, NULL); |
| val = empty_ctor; |
| } |
| |
| if (TREE_CODE (ftype) == ARRAY_TYPE) |
| ok = can_convert_array (ftype, val, flags, complain); |
| else |
| ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags, |
| complain); |
| |
| if (!ok) |
| return NULL; |
| |
| if (TREE_CODE (type) == UNION_TYPE) |
| break; |
| } |
| |
| if (i < CONSTRUCTOR_NELTS (ctor)) |
| return NULL; |
| |
| c = alloc_conversion (ck_aggr); |
| c->type = type; |
| c->rank = cr_exact; |
| c->user_conv_p = true; |
| c->check_narrowing = true; |
| c->u.expr = ctor; |
| return c; |
| } |
| |
| /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an |
| array type, if such a conversion is possible. */ |
| |
| static conversion * |
| build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) |
| { |
| conversion *c; |
| unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor); |
| tree elttype = TREE_TYPE (type); |
| unsigned i; |
| tree val; |
| bool bad = false; |
| bool user = false; |
| enum conversion_rank rank = cr_exact; |
| |
| /* We might need to propagate the size from the element to the array. */ |
| complete_type (type); |
| |
| if (TYPE_DOMAIN (type) |
| && !variably_modified_type_p (TYPE_DOMAIN (type), NULL_TREE)) |
| { |
| unsigned HOST_WIDE_INT alen = tree_to_uhwi (array_type_nelts_top (type)); |
| if (alen < len) |
| return NULL; |
| } |
| |
| flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING; |
| |
| FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val) |
| { |
| conversion *sub |
| = implicit_conversion (elttype, TREE_TYPE (val), val, |
| false, flags, complain); |
| if (sub == NULL) |
| return NULL; |
| |
| if (sub->rank > rank) |
| rank = sub->rank; |
| if (sub->user_conv_p) |
| user = true; |
| if (sub->bad_p) |
| bad = true; |
| } |
| |
| c = alloc_conversion (ck_aggr); |
| c->type = type; |
| c->rank = rank; |
| c->user_conv_p = user; |
| c->bad_p = bad; |
| c->u.expr = ctor; |
| return c; |
| } |
| |
| /* Represent a conversion from CTOR, a braced-init-list, to TYPE, a |
| complex type, if such a conversion is possible. */ |
| |
| static conversion * |
| build_complex_conv (tree type, tree ctor, int flags, |
| tsubst_flags_t complain) |
| { |
| conversion *c; |
| unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor); |
| tree elttype = TREE_TYPE (type); |
| unsigned i; |
| tree val; |
| bool bad = false; |
| bool user = false; |
| enum conversion_rank rank = cr_exact; |
| |
| if (len != 2) |
| return NULL; |
| |
| flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING; |
| |
| FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val) |
| { |
| conversion *sub |
| = implicit_conversion (elttype, TREE_TYPE (val), val, |
| false, flags, complain); |
| if (sub == NULL) |
| return NULL; |
| |
| if (sub->rank > rank) |
| rank = sub->rank; |
| if (sub->user_conv_p) |
| user = true; |
| if (sub->bad_p) |
| bad = true; |
| } |
| |
| c = alloc_conversion (ck_aggr); |
| c->type = type; |
| c->rank = rank; |
| c->user_conv_p = user; |
| c->bad_p = bad; |
| c->u.expr = ctor; |
| return c; |
| } |
| |
| /* Build a representation of the identity conversion from EXPR to |
| itself. The TYPE should match the type of EXPR, if EXPR is non-NULL. */ |
| |
| static conversion * |
| build_identity_conv (tree type, tree expr) |
| { |
| conversion *c; |
| |
| c = alloc_conversion (ck_identity); |
| c->type = type; |
| c->u.expr = expr; |
| |
| return c; |
| } |
| |
| /* Converting from EXPR to TYPE was ambiguous in the sense that there |
| were multiple user-defined conversions to accomplish the job. |
| Build a conversion that indicates that ambiguity. */ |
| |
| static conversion * |
| build_ambiguous_conv (tree type, tree expr) |
| { |
| conversion *c; |
| |
| c = alloc_conversion (ck_ambig); |
| c->type = type; |
| c->u.expr = expr; |
| |
| return c; |
| } |
| |
| tree |
| strip_top_quals (tree t) |
| { |
| if (TREE_CODE (t) == ARRAY_TYPE) |
| return t; |
| return cp_build_qualified_type (t, 0); |
| } |
| |
| /* Returns the standard conversion path (see [conv]) from type FROM to type |
| TO, if any. For proper handling of null pointer constants, you must |
| also pass the expression EXPR to convert from. If C_CAST_P is true, |
| this conversion is coming from a C-style cast. */ |
| |
| static conversion * |
| standard_conversion (tree to, tree from, tree expr, bool c_cast_p, |
| int flags, tsubst_flags_t complain) |
| { |
| enum tree_code fcode, tcode; |
| conversion *conv; |
| bool fromref = false; |
| tree qualified_to; |
| |
| to = non_reference (to); |
| if (TYPE_REF_P (from)) |
| { |
| fromref = true; |
| from = TREE_TYPE (from); |
| } |
| qualified_to = to; |
| to = strip_top_quals (to); |
| from = strip_top_quals (from); |
| |
| if (expr && type_unknown_p (expr)) |
| { |
| if (TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to)) |
| { |
| tsubst_flags_t tflags = tf_conv; |
| expr = instantiate_type (to, expr, tflags); |
| if (expr == error_mark_node) |
| return NULL; |
| from = TREE_TYPE (expr); |
| } |
| else if (TREE_CODE (to) == BOOLEAN_TYPE) |
| { |
| /* Necessary for eg, TEMPLATE_ID_EXPRs (c++/50961). */ |
| expr = resolve_nondeduced_context (expr, complain); |
| from = TREE_TYPE (expr); |
| } |
| } |
| |
| fcode = TREE_CODE (from); |
| tcode = TREE_CODE (to); |
| |
| conv = build_identity_conv (from, expr); |
| if (fcode == FUNCTION_TYPE || fcode == ARRAY_TYPE) |
| { |
| from = type_decays_to (from); |
| fcode = TREE_CODE (from); |
| /* Tell convert_like that we're using the address. */ |
| conv->rvaluedness_matches_p = true; |
| conv = build_conv (ck_lvalue, from, conv); |
| } |
| /* Wrapping a ck_rvalue around a class prvalue (as a result of using |
| obvalue_p) seems odd, since it's already a prvalue, but that's how we |
| express the copy constructor call required by copy-initialization. */ |
| else if (fromref || (expr && obvalue_p (expr))) |
| { |
| if (expr) |
| { |
| tree bitfield_type; |
| bitfield_type = is_bitfield_expr_with_lowered_type (expr); |
| if (bitfield_type) |
| { |
| from = strip_top_quals (bitfield_type); |
| fcode = TREE_CODE (from); |
| } |
| } |
| conv = build_conv (ck_rvalue, from, conv); |
| if (flags & LOOKUP_PREFER_RVALUE) |
| /* Tell convert_like to set LOOKUP_PREFER_RVALUE. */ |
| conv->rvaluedness_matches_p = true; |
| /* If we're performing copy-initialization, remember to skip |
| explicit constructors. */ |
| if (flags & LOOKUP_ONLYCONVERTING) |
| conv->copy_init_p = true; |
| } |
| |
| /* Allow conversion between `__complex__' data types. */ |
| if (tcode == COMPLEX_TYPE && fcode == COMPLEX_TYPE) |
| { |
| /* The standard conversion sequence to convert FROM to TO is |
| the standard conversion sequence to perform componentwise |
| conversion. */ |
| conversion *part_conv = standard_conversion |
| (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags, |
| complain); |
| |
| if (!part_conv) |
| conv = NULL; |
| else if (part_conv->kind == ck_identity) |
| /* Leave conv alone. */; |
| else |
| { |
| conv = build_conv (part_conv->kind, to, conv); |
| conv->rank = part_conv->rank; |
| } |
| |
| return conv; |
| } |
| |
| if (same_type_p (from, to)) |
| { |
| if (CLASS_TYPE_P (to) && conv->kind == ck_rvalue) |
| conv->type = qualified_to; |
| return conv; |
| } |
| |
| /* [conv.ptr] |
| A null pointer constant can be converted to a pointer type; ... A |
| null pointer constant of integral type can be converted to an |
| rvalue of type std::nullptr_t. */ |
| if ((tcode == POINTER_TYPE || TYPE_PTRMEM_P (to) |
| || NULLPTR_TYPE_P (to)) |
| && ((expr && null_ptr_cst_p (expr)) |
| || NULLPTR_TYPE_P (from))) |
| conv = build_conv (ck_std, to, conv); |
| else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE) |
| || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE)) |
| { |
| /* For backwards brain damage compatibility, allow interconversion of |
| pointers and integers with a pedwarn. */ |
| conv = build_conv (ck_std, to, conv); |
| conv->bad_p = true; |
| } |
| else if (UNSCOPED_ENUM_P (to) && fcode == INTEGER_TYPE) |
| { |
| /* For backwards brain damage compatibility, allow interconversion of |
| enums and integers with a pedwarn. */ |
| conv = build_conv (ck_std, to, conv); |
| conv->bad_p = true; |
| } |
| else if ((tcode == POINTER_TYPE && fcode == POINTER_TYPE) |
| || (TYPE_PTRDATAMEM_P (to) && TYPE_PTRDATAMEM_P (from))) |
| { |
| tree to_pointee; |
| tree from_pointee; |
| |
| if (tcode == POINTER_TYPE) |
| { |
| to_pointee = TREE_TYPE (to); |
| from_pointee = TREE_TYPE (from); |
| |
| /* Since this is the target of a pointer, it can't have function |
| qualifiers, so any TYPE_QUALS must be for attributes const or |
| noreturn. Strip them. */ |
| if (TREE_CODE (to_pointee) == FUNCTION_TYPE |
| && TYPE_QUALS (to_pointee)) |
| to_pointee = build_qualified_type (to_pointee, TYPE_UNQUALIFIED); |
| if (TREE_CODE (from_pointee) == FUNCTION_TYPE |
| && TYPE_QUALS (from_pointee)) |
| from_pointee = build_qualified_type (from_pointee, TYPE_UNQUALIFIED); |
| } |
| else |
| { |
| to_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (to); |
| from_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (from); |
| } |
| |
| if (tcode == POINTER_TYPE |
| && same_type_ignoring_top_level_qualifiers_p (from_pointee, |
| to_pointee)) |
| ; |
| else if (VOID_TYPE_P (to_pointee) |
| && !TYPE_PTRDATAMEM_P (from) |
| && TREE_CODE (from_pointee) != FUNCTION_TYPE) |
| { |
| tree nfrom = TREE_TYPE (from); |
| /* Don't try to apply restrict to void. */ |
| int quals = cp_type_quals (nfrom) & ~TYPE_QUAL_RESTRICT; |
| from_pointee = cp_build_qualified_type (void_type_node, quals); |
| from = build_pointer_type (from_pointee); |
| conv = build_conv (ck_ptr, from, conv); |
| } |
| else if (TYPE_PTRDATAMEM_P (from)) |
| { |
| tree fbase = TYPE_PTRMEM_CLASS_TYPE (from); |
| tree tbase = TYPE_PTRMEM_CLASS_TYPE (to); |
| |
| if (same_type_p (fbase, tbase)) |
| /* No base conversion needed. */; |
| else if (DERIVED_FROM_P (fbase, tbase) |
| && (same_type_ignoring_top_level_qualifiers_p |
| (from_pointee, to_pointee))) |
| { |
| from = build_ptrmem_type (tbase, from_pointee); |
| conv = build_conv (ck_pmem, from, conv); |
| } |
| else |
| return NULL; |
| } |
| else if (CLASS_TYPE_P (from_pointee) |
| && CLASS_TYPE_P (to_pointee) |
| /* [conv.ptr] |
| |
| An rvalue of type "pointer to cv D," where D is a |
| class type, can be converted to an rvalue of type |
| "pointer to cv B," where B is a base class (clause |
| _class.derived_) of D. If B is an inaccessible |
| (clause _class.access_) or ambiguous |
| (_class.member.lookup_) base class of D, a program |
| that necessitates this conversion is ill-formed. |
| Therefore, we use DERIVED_FROM_P, and do not check |
| access or uniqueness. */ |
| && DERIVED_FROM_P (to_pointee, from_pointee)) |
| { |
| from_pointee |
| = cp_build_qualified_type (to_pointee, |
| cp_type_quals (from_pointee)); |
| from = build_pointer_type (from_pointee); |
| conv = build_conv (ck_ptr, from, conv); |
| conv->base_p = true; |
| } |
| |
| if (same_type_p (from, to)) |
| /* OK */; |
| else if (c_cast_p && comp_ptr_ttypes_const (to, from, bounds_either)) |
| /* In a C-style cast, we ignore CV-qualification because we |
| are allowed to perform a static_cast followed by a |
| const_cast. */ |
| conv = build_conv (ck_qual, to, conv); |
| else if (!c_cast_p && comp_ptr_ttypes (to_pointee, from_pointee)) |
| conv = build_conv (ck_qual, to, conv); |
| else if (expr && string_conv_p (to, expr, 0)) |
| /* converting from string constant to char *. */ |
| conv = build_conv (ck_qual, to, conv); |
| else if (fnptr_conv_p (to, from)) |
| conv = build_conv (ck_fnptr, to, conv); |
| /* Allow conversions among compatible ObjC pointer types (base |
| conversions have been already handled above). */ |
| else if (c_dialect_objc () |
| && objc_compare_types (to, from, -4, NULL_TREE)) |
| conv = build_conv (ck_ptr, to, conv); |
| else if (ptr_reasonably_similar (to_pointee, from_pointee)) |
| { |
| conv = build_conv (ck_ptr, to, conv); |
| conv->bad_p = true; |
| } |
| else |
| return NULL; |
| |
| from = to; |
| } |
| else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from)) |
| { |
| tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from)); |
| tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to)); |
| tree fbase = class_of_this_parm (fromfn); |
| tree tbase = class_of_this_parm (tofn); |
| |
| /* If FBASE and TBASE are equivalent but incomplete, DERIVED_FROM_P |
| yields false. But a pointer to member of incomplete class is OK. */ |
| if (!same_type_p (fbase, tbase) && !DERIVED_FROM_P (fbase, tbase)) |
| return NULL; |
| |
| tree fstat = static_fn_type (fromfn); |
| tree tstat = static_fn_type (tofn); |
| if (same_type_p (tstat, fstat) |
| || fnptr_conv_p (tstat, fstat)) |
| /* OK */; |
| else |
| return NULL; |
| |
| if (!same_type_p (fbase, tbase)) |
| { |
| from = build_memfn_type (fstat, |
| tbase, |
| cp_type_quals (tbase), |
| type_memfn_rqual (tofn)); |
| from = build_ptrmemfunc_type (build_pointer_type (from)); |
| conv = build_conv (ck_pmem, from, conv); |
| conv->base_p = true; |
| } |
| if (fnptr_conv_p (tstat, fstat)) |
| conv = build_conv (ck_fnptr, to, conv); |
| } |
| else if (tcode == BOOLEAN_TYPE) |
| { |
| /* [conv.bool] |
| |
| A prvalue of arithmetic, unscoped enumeration, pointer, or pointer |
| to member type can be converted to a prvalue of type bool. ... |
| For direct-initialization (8.5 [dcl.init]), a prvalue of type |
| std::nullptr_t can be converted to a prvalue of type bool; */ |
| if (ARITHMETIC_TYPE_P (from) |
| || UNSCOPED_ENUM_P (from) |
| || fcode == POINTER_TYPE |
| || TYPE_PTRMEM_P (from) |
| || NULLPTR_TYPE_P (from)) |
| { |
| conv = build_conv (ck_std, to, conv); |
| if (fcode == POINTER_TYPE |
| || TYPE_PTRDATAMEM_P (from) |
| || (TYPE_PTRMEMFUNC_P (from) |
| && conv->rank < cr_pbool) |
| || NULLPTR_TYPE_P (from)) |
| conv->rank = cr_pbool; |
| if (NULLPTR_TYPE_P (from) && (flags & LOOKUP_ONLYCONVERTING)) |
| conv->bad_p = true; |
| if (flags & LOOKUP_NO_NARROWING) |
| conv->check_narrowing = true; |
| return conv; |
| } |
| |
| return NULL; |
| } |
| /* We don't check for ENUMERAL_TYPE here because there are no standard |
| conversions to enum type. */ |
| /* As an extension, allow conversion to complex type. */ |
| else if (ARITHMETIC_TYPE_P (to)) |
| { |
| if (! (INTEGRAL_CODE_P (fcode) |
| || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL))) |
| || SCOPED_ENUM_P (from)) |
| return NULL; |
| |
| /* If we're parsing an enum with no fixed underlying type, we're |
| dealing with an incomplete type, which renders the conversion |
| ill-formed. */ |
| if (!COMPLETE_TYPE_P (from)) |
| return NULL; |
| |
| conv = build_conv (ck_std, to, conv); |
| |
| tree underlying_type = NULL_TREE; |
| if (TREE_CODE (from) == ENUMERAL_TYPE |
| && ENUM_FIXED_UNDERLYING_TYPE_P (from)) |
| underlying_type = ENUM_UNDERLYING_TYPE (from); |
| |
| /* Give this a better rank if it's a promotion. |
| |
| To handle CWG 1601, also bump the rank if we are converting |
| an enumeration with a fixed underlying type to the underlying |
| type. */ |
| if ((same_type_p (to, type_promotes_to (from)) |
| || (underlying_type && same_type_p (to, underlying_type))) |
| && next_conversion (conv)->rank <= cr_promotion) |
| conv->rank = cr_promotion; |
| } |
| else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE |
| && vector_types_convertible_p (from, to, false)) |
| return build_conv (ck_std, to, conv); |
| else if (MAYBE_CLASS_TYPE_P (to) && MAYBE_CLASS_TYPE_P (from) |
| && is_properly_derived_from (from, to)) |
| { |
| if (conv->kind == ck_rvalue) |
| conv = next_conversion (conv); |
| conv = build_conv (ck_base, to, conv); |
| /* The derived-to-base conversion indicates the initialization |
| of a parameter with base type from an object of a derived |
| type. A temporary object is created to hold the result of |
| the conversion unless we're binding directly to a reference. */ |
| conv->need_temporary_p = !(flags & LOOKUP_NO_TEMP_BIND); |
| if (flags & LOOKUP_PREFER_RVALUE) |
| /* Tell convert_like to set LOOKUP_PREFER_RVALUE. */ |
| conv->rvaluedness_matches_p = true; |
| /* If we're performing copy-initialization, remember to skip |
| explicit constructors. */ |
| if (flags & LOOKUP_ONLYCONVERTING) |
| conv->copy_init_p = true; |
| } |
| else |
| return NULL; |
| |
| if (flags & LOOKUP_NO_NARROWING) |
| conv->check_narrowing = true; |
| |
| return conv; |
| } |
| |
| /* Returns nonzero if T1 is reference-related to T2. */ |
| |
| bool |
| reference_related_p (tree t1, tree t2) |
| { |
| if (t1 == error_mark_node || t2 == error_mark_node) |
| return false; |
| |
| t1 = TYPE_MAIN_VARIANT (t1); |
| t2 = TYPE_MAIN_VARIANT (t2); |
| |
| /* [dcl.init.ref] |
| |
| Given types "cv1 T1" and "cv2 T2," "cv1 T1" is reference-related |
| to "cv2 T2" if T1 is similar to T2, or T1 is a base class of T2. */ |
| return (similar_type_p (t1, t2) |
| || (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2) |
| && DERIVED_FROM_P (t1, t2))); |
| } |
| |
| /* Returns nonzero if T1 is reference-compatible with T2. */ |
| |
| bool |
| reference_compatible_p (tree t1, tree t2) |
| { |
| /* [dcl.init.ref] |
| |
| "cv1 T1" is reference compatible with "cv2 T2" if |
| a prvalue of type "pointer to cv2 T2" can be converted to the type |
| "pointer to cv1 T1" via a standard conversion sequence. */ |
| tree ptype1 = build_pointer_type (t1); |
| tree ptype2 = build_pointer_type (t2); |
| conversion *conv = standard_conversion (ptype1, ptype2, NULL_TREE, |
| /*c_cast_p=*/false, 0, tf_none); |
| if (!conv || conv->bad_p) |
| return false; |
| return true; |
| } |
| |
| /* Return true if converting FROM to TO would involve a qualification |
| conversion. */ |
| |
| static bool |
| involves_qualification_conversion_p (tree to, tree from) |
| { |
| /* If we're not convering a pointer to another one, we won't get |
| a qualification conversion. */ |
| if (!((TYPE_PTR_P (to) && TYPE_PTR_P (from)) |
| || (TYPE_PTRDATAMEM_P (to) && TYPE_PTRDATAMEM_P (from)))) |
| return false; |
| |
| conversion *conv = standard_conversion (to, from, NULL_TREE, |
| /*c_cast_p=*/false, 0, tf_none); |
| for (conversion *t = conv; t; t = next_conversion (t)) |
| if (t->kind == ck_qual) |
| return true; |
| |
| return false; |
| } |
| |
| /* A reference of the indicated TYPE is being bound directly to the |
| expression represented by the implicit conversion sequence CONV. |
| Return a conversion sequence for this binding. */ |
| |
| static conversion * |
| direct_reference_binding (tree type, conversion *conv) |
| { |
| tree t; |
| |
| gcc_assert (TYPE_REF_P (type)); |
| gcc_assert (!TYPE_REF_P (conv->type)); |
| |
| t = TREE_TYPE (type); |
| |
| if (conv->kind == ck_identity) |
| /* Mark the identity conv as to not decay to rvalue. */ |
| conv->rvaluedness_matches_p = true; |
| |
| /* [over.ics.rank] |
| |
| When a parameter of reference type binds directly |
| (_dcl.init.ref_) to an argument expression, the implicit |
| conversion sequence is the identity conversion, unless the |
| argument expression has a type that is a derived class of the |
| parameter type, in which case the implicit conversion sequence is |
| a derived-to-base Conversion. |
| |
| If the parameter binds directly to the result of applying a |
| conversion function to the argument expression, the implicit |
| conversion sequence is a user-defined conversion sequence |
| (_over.ics.user_), with the second standard conversion sequence |
| either an identity conversion or, if the conversion function |
| returns an entity of a type that is a derived class of the |
| parameter type, a derived-to-base conversion. */ |
| if (is_properly_derived_from (conv->type, t)) |
| { |
| /* Represent the derived-to-base conversion. */ |
| conv = build_conv (ck_base, t, conv); |
| /* We will actually be binding to the base-class subobject in |
| the derived class, so we mark this conversion appropriately. |
| That way, convert_like knows not to generate a temporary. */ |
| conv->need_temporary_p = false; |
| } |
| else if (involves_qualification_conversion_p (t, conv->type)) |
| /* Represent the qualification conversion. After DR 2352 |
| #1 and #2 were indistinguishable conversion sequences: |
| |
| void f(int*); // #1 |
| void f(const int* const &); // #2 |
| void g(int* p) { f(p); } |
| |
| because the types "int *" and "const int *const" are |
| reference-related and we were binding both directly and they |
| had the same rank. To break it up, we add a ck_qual under the |
| ck_ref_bind so that conversion sequence ranking chooses #1. */ |
| conv = build_conv (ck_qual, t, conv); |
| |
| return build_conv (ck_ref_bind, type, conv); |
| } |
| |
| /* Returns the conversion path from type FROM to reference type TO for |
| purposes of reference binding. For lvalue binding, either pass a |
| reference type to FROM or an lvalue expression to EXPR. If the |
| reference will be bound to a temporary, NEED_TEMPORARY_P is set for |
| the conversion returned. If C_CAST_P is true, this |
| conversion is coming from a C-style cast. */ |
| |
| static conversion * |
| reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, |
| tsubst_flags_t complain) |
| { |
| conversion *conv = NULL; |
| tree to = TREE_TYPE (rto); |
| tree from = rfrom; |
| tree tfrom; |
| bool related_p; |
| bool compatible_p; |
| cp_lvalue_kind gl_kind; |
| bool is_lvalue; |
| |
| if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr)) |
| { |
| expr = instantiate_type (to, expr, tf_none); |
| if (expr == error_mark_node) |
| return NULL; |
| from = TREE_TYPE (expr); |
| } |
| |
| bool copy_list_init = false; |
| if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr)) |
| { |
| maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); |
| /* DR 1288: Otherwise, if the initializer list has a single element |
| of type E and ... [T's] referenced type is reference-related to E, |
| the object or reference is initialized from that element... |
| |
| ??? With P0388R4, we should bind 't' directly to U{}: |
| using U = A[2]; |
| A (&&t)[] = {U{}}; |
| 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 |
| && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr)) |
| { |
| tree elt = CONSTRUCTOR_ELT (expr, 0)->value; |
| if (error_operand_p (elt)) |
| return NULL; |
| tree etype = TREE_TYPE (elt); |
| if (reference_related_p (to, etype)) |
| { |
| expr = elt; |
| from = etype; |
| goto skip; |
| } |
| } |
| /* Otherwise, if T is a reference type, a prvalue temporary of the type |
| referenced by T is copy-list-initialized, and the reference is bound |
| to that temporary. */ |
| copy_list_init = true; |
| skip:; |
| } |
| |
| if (TYPE_REF_P (from)) |
| { |
| from = TREE_TYPE (from); |
| if (!TYPE_REF_IS_RVALUE (rfrom) |
| || TREE_CODE (from) == FUNCTION_TYPE) |
| gl_kind = clk_ordinary; |
| else |
| gl_kind = clk_rvalueref; |
| } |
| else if (expr) |
| gl_kind = lvalue_kind (expr); |
| else if (CLASS_TYPE_P (from) |
| || TREE_CODE (from) == ARRAY_TYPE) |
| gl_kind = clk_class; |
| else |
| gl_kind = clk_none; |
| |
| /* Don't allow a class prvalue when LOOKUP_NO_TEMP_BIND. */ |
| if ((flags & LOOKUP_NO_TEMP_BIND) |
| && (gl_kind & clk_class)) |
| gl_kind = clk_none; |
| |
| /* Same mask as real_lvalue_p. */ |
| is_lvalue = gl_kind && !(gl_kind & (clk_rvalueref|clk_class)); |
| |
| tfrom = from; |
| if ((gl_kind & clk_bitfield) != 0) |
| tfrom = unlowered_expr_type (expr); |
| |
| /* Figure out whether or not the types are reference-related and |
| reference compatible. We have to do this after stripping |
| references from FROM. */ |
| related_p = reference_related_p (to, tfrom); |
| /* If this is a C cast, first convert to an appropriately qualified |
| type, so that we can later do a const_cast to the desired type. */ |
| if (related_p && c_cast_p |
| && !at_least_as_qualified_p (to, tfrom)) |
| to = cp_build_qualified_type (to, cp_type_quals (tfrom)); |
| compatible_p = reference_compatible_p (to, tfrom); |
| |
| /* Directly bind reference when target expression's type is compatible with |
| the reference and expression is an lvalue. In DR391, the wording in |
| [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for |
| const and rvalue references to rvalues of compatible class type. |
| We should also do direct bindings for non-class xvalues. */ |
| if ((related_p || compatible_p) && gl_kind) |
| { |
| /* [dcl.init.ref] |
| |
| If the initializer expression |
| |
| -- is an lvalue (but not an lvalue for a bit-field), and "cv1 T1" |
| is reference-compatible with "cv2 T2," |
| |
| the reference is bound directly to the initializer expression |
| lvalue. |
| |
| [...] |
| If the initializer expression is an rvalue, with T2 a class type, |
| and "cv1 T1" is reference-compatible with "cv2 T2", the reference |
| is bound to the object represented by the rvalue or to a sub-object |
| within that object. */ |
| |
| conv = build_identity_conv (tfrom, expr); |
| conv = direct_reference_binding (rto, conv); |
| |
| if (TYPE_REF_P (rfrom)) |
| /* Handle rvalue reference to function properly. */ |
| conv->rvaluedness_matches_p |
| = (TYPE_REF_IS_RVALUE (rto) == TYPE_REF_IS_RVALUE (rfrom)); |
| else |
| conv->rvaluedness_matches_p |
| = (TYPE_REF_IS_RVALUE (rto) == !is_lvalue); |
| |
| if ((gl_kind & clk_bitfield) != 0 |
| || ((gl_kind & clk_packed) != 0 && !TYPE_PACKED (to))) |
| /* For the purposes of overload resolution, we ignore the fact |
| this expression is a bitfield or packed field. (In particular, |
| [over.ics.ref] says specifically that a function with a |
| non-const reference parameter is viable even if the |
| argument is a bitfield.) |
| |
| However, when we actually call the function we must create |
| a temporary to which to bind the reference. If the |
| reference is volatile, or isn't const, then we cannot make |
| a temporary, so we just issue an error when the conversion |
| actually occurs. */ |
| conv->need_temporary_p = true; |
| |
| /* Don't allow binding of lvalues (other than function lvalues) to |
| rvalue references. */ |
| if (is_lvalue && TYPE_REF_IS_RVALUE (rto) |
| && TREE_CODE (to) != FUNCTION_TYPE) |
| conv->bad_p = true; |
| |
| /* Nor the reverse. */ |
| if (!is_lvalue && !TYPE_REF_IS_RVALUE (rto) |
| /* Unless it's really an lvalue. */ |
| && !(cxx_dialect >= cxx20 |
| && (gl_kind & clk_implicit_rval)) |
| && (!CP_TYPE_CONST_NON_VOLATILE_P (to) |
| || (flags & LOOKUP_NO_RVAL_BIND)) |
| && TREE_CODE (to) != FUNCTION_TYPE) |
| conv->bad_p = true; |
| |
| if (!compatible_p) |
| conv->bad_p = true; |
| |
| return conv; |
| } |
| /* [class.conv.fct] A conversion function is never used to convert a |
| (possibly cv-qualified) object to the (possibly cv-qualified) same |
| object type (or a reference to it), to a (possibly cv-qualified) base |
| class of that type (or a reference to it).... */ |
| else if (CLASS_TYPE_P (from) && !related_p |
| && !(flags & LOOKUP_NO_CONVERSION)) |
| { |
| /* [dcl.init.ref] |
| |
| If the initializer expression |
| |
| -- has a class type (i.e., T2 is a class type) can be |
| implicitly converted to an lvalue of type "cv3 T3," where |
| "cv1 T1" is reference-compatible with "cv3 T3". (this |
| conversion is selected by enumerating the applicable |
| conversion functions (_over.match.ref_) and choosing the |
| best one through overload resolution. (_over.match_). |
| |
| the reference is bound to the lvalue result of the conversion |
| in the second case. */ |
| z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags, |
| complain); |
| if (cand) |
| return cand->second_conv; |
| } |
| |
| /* From this point on, we conceptually need temporaries, even if we |
| elide them. Only the cases above are "direct bindings". */ |
| if (flags & LOOKUP_NO_TEMP_BIND) |
| return NULL; |
| |
| /* [over.ics.rank] |
| |
| When a parameter of reference type is not bound directly to an |
| argument expression, the conversion sequence is the one required |
| to convert the argument expression to the underlying type of the |
| reference according to _over.best.ics_. Conceptually, this |
| conversion sequence corresponds to copy-initializing a temporary |
| of the underlying type with the argument expression. Any |
| difference in top-level cv-qualification is subsumed by the |
| initialization itself and does not constitute a conversion. */ |
| |
| /* [dcl.init.ref] |
| |
| Otherwise, the reference shall be an lvalue reference to a |
| non-volatile const type, or the reference shall be an rvalue |
| reference. |
| |
| We try below to treat this as a bad conversion to improve diagnostics, |
| but if TO is an incomplete class, we need to reject this conversion |
| now to avoid unnecessary instantiation. */ |
| if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto) |
| && !COMPLETE_TYPE_P (to)) |
| return NULL; |
| |
| /* We're generating a temporary now, but don't bind any more in the |
| conversion (specifically, don't slice the temporary returned by a |
| conversion operator). */ |
| flags |= LOOKUP_NO_TEMP_BIND; |
| |
| /* Core issue 899: When [copy-]initializing a temporary to be bound |
| to the first parameter of a copy constructor (12.8) called with |
| a single argument in the context of direct-initialization, |
| explicit conversion functions are also considered. |
| |
| So don't set LOOKUP_ONLYCONVERTING in that case. */ |
| if (!(flags & LOOKUP_COPY_PARM)) |
| flags |= LOOKUP_ONLYCONVERTING; |
| |
| if (!conv) |
| conv = implicit_conversion (to, from, expr, c_cast_p, |
| flags, complain); |
| if (!conv) |
| return NULL; |
| |
| if (conv->user_conv_p) |
| { |
| if (copy_list_init) |
| /* Remember this was copy-list-initialization. */ |
| conv->need_temporary_p = true; |
| |
| /* If initializing the temporary used a conversion function, |
| recalculate the second conversion sequence. */ |
| for (conversion *t = conv; t; t = next_conversion (t)) |
| if (t->kind == ck_user |
| && DECL_CONV_FN_P (t->cand->fn)) |
| { |
| tree ftype = TREE_TYPE (TREE_TYPE (t->cand->fn)); |
| /* A prvalue of non-class type is cv-unqualified. */ |
| if (!TYPE_REF_P (ftype) && !CLASS_TYPE_P (ftype)) |
| ftype = cv_unqualified (ftype); |
| int sflags = (flags|LOOKUP_NO_CONVERSION)&~LOOKUP_NO_TEMP_BIND; |
| conversion *new_second |
| = reference_binding (rto, ftype, NULL_TREE, c_cast_p, |
| sflags, complain); |
| if (!new_second) |
| return NULL; |
| return merge_conversion_sequences (t, new_second); |
| } |
| } |
| |
| conv = build_conv (ck_ref_bind, rto, conv); |
| /* This reference binding, unlike those above, requires the |
| creation of a temporary. */ |
| conv->need_temporary_p = true; |
| conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto); |
| |
| /* [dcl.init.ref] |
| |
| Otherwise, the reference shall be an lvalue reference to a |
| non-volatile const type, or the reference shall be an rvalue |
| reference. */ |
| if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto)) |
| conv->bad_p = true; |
| |
| /* [dcl.init.ref] |
| |
| Otherwise, a temporary of type "cv1 T1" is created and |
| initialized from the initializer expression using the rules for a |
| non-reference copy initialization. If T1 is reference-related to |
| T2, cv1 must be the same cv-qualification as, or greater |
| cv-qualification than, cv2; otherwise, the program is ill-formed. */ |
| if (related_p && !at_least_as_qualified_p (to, from)) |
| conv->bad_p = true; |
| |
| return conv; |
| } |
| |
| /* Most of the implementation of implicit_conversion, with the same |
| parameters. */ |
| |
| static conversion * |
| implicit_conversion_1 (tree to, tree from, tree expr, bool c_cast_p, |
| int flags, tsubst_flags_t complain) |
| { |
| conversion *conv; |
| |
| if (from == error_mark_node || to == error_mark_node |
| || expr == error_mark_node) |
| return NULL; |
| |
| /* Other flags only apply to the primary function in overload |
| resolution, or after we've chosen one. */ |
| flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM |
| |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE |
| |LOOKUP_NO_NARROWING|LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL); |
| |
| /* FIXME: actually we don't want warnings either, but we can't just |
| have 'complain &= ~(tf_warning|tf_error)' because it would cause |
| the regression of, eg, g++.old-deja/g++.benjamin/16077.C. |
| We really ought not to issue that warning until we've committed |
| to that conversion. */ |
| complain &= ~tf_error; |
| |
| /* Call reshape_init early to remove redundant braces. */ |
| if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr) |
| && CLASS_TYPE_P (to) |
| && COMPLETE_TYPE_P (complete_type (to)) |
| && !CLASSTYPE_NON_AGGREGATE (to)) |
| { |
| expr = reshape_init (to, expr, complain); |
| if (expr == error_mark_node) |
| return NULL; |
| from = TREE_TYPE (expr); |
| } |
| |
| if (TYPE_REF_P (to)) |
| conv = reference_binding (to, from, expr, c_cast_p, flags, complain); |
| else |
| conv = standard_conversion (to, from, expr, c_cast_p, flags, complain); |
| |
| if (conv) |
| return conv; |
| |
| if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr)) |
| { |
| if (is_std_init_list (to) && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr)) |
| return build_list_conv (to, expr, flags, complain); |
| |
| /* As an extension, allow list-initialization of _Complex. */ |
| if (TREE_CODE (to) == COMPLEX_TYPE |
| && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr)) |
| { |
| conv = build_complex_conv (to, expr, flags, complain); |
| if (conv) |
| return conv; |
| } |
| |
| /* Allow conversion from an initializer-list with one element to a |
| scalar type. */ |
| if (SCALAR_TYPE_P (to)) |
| { |
| int nelts = CONSTRUCTOR_NELTS (expr); |
| tree elt; |
| |
| if (nelts == 0) |
| elt = build_value_init (to, tf_none); |
| else if (nelts == 1 && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr)) |
| elt = CONSTRUCTOR_ELT (expr, 0)->value; |
| else |
| elt = error_mark_node; |
| |
| conv = implicit_conversion (to, TREE_TYPE (elt), elt, |
| c_cast_p, flags, complain); |
| if (conv) |
| { |
| conv->check_narrowing = true; |
| if (BRACE_ENCLOSED_INITIALIZER_P (elt)) |
| /* Too many levels of braces, i.e. '{{1}}'. */ |
| conv->bad_p = true; |
| return conv; |
| } |
| } |
| else if (TREE_CODE (to) == ARRAY_TYPE) |
| return build_array_conv (to, expr, flags, complain); |
| } |
| |
| if (expr != NULL_TREE |
| && (MAYBE_CLASS_TYPE_P (from) |
| || MAYBE_CLASS_TYPE_P (to)) |
| && (flags & LOOKUP_NO_CONVERSION) == 0) |
| { |
| struct z_candidate *cand; |
| |
| if (CLASS_TYPE_P (to) |
| && BRACE_ENCLOSED_INITIALIZER_P (expr) |
| && !CLASSTYPE_NON_AGGREGATE (complete_type (to))) |
| return build_aggr_conv (to, expr, flags, complain); |
| |
| cand = build_user_type_conversion_1 (to, expr, flags, complain); |
| if (cand) |
| { |
| 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 |
| initializer list has a single element of type cv U, where U is |
| X or a class derived from X, the implicit conversion sequence |
| has Exact Match rank if U is X, or Conversion rank if U is |
| derived from X." */ |
| tree elt = CONSTRUCTOR_ELT (expr, 0)->value; |
| tree elttype = TREE_TYPE (elt); |
| if (reference_related_p (to, elttype)) |
| return implicit_conversion (to, elttype, elt, |
| c_cast_p, flags, complain); |
| } |
| conv = cand->second_conv; |
| } |
| |
| /* We used to try to bind a reference to a temporary here, but that |
| is now handled after the recursive call to this function at the end |
| of reference_binding. */ |
| return conv; |
| } |
| |
| return NULL; |
| } |
| |
| /* Returns the implicit conversion sequence (see [over.ics]) from type |
| FROM to type TO. The optional expression EXPR may affect the |
| conversion. FLAGS are the usual overloading flags. If C_CAST_P is |
| true, this conversion is coming from a C-style cast. */ |
| |
| static conversion * |
| implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, |
| int flags, tsubst_flags_t complain) |
| { |
| conversion *conv = implicit_conversion_1 (to, from, expr, c_cast_p, |
| flags, complain); |
| if (!conv || conv->bad_p) |
| return conv; |
| if (conv_is_prvalue (conv) |
| && CLASS_TYPE_P (conv->type) |
| && CLASSTYPE_PURE_VIRTUALS (conv->type)) |
| conv->bad_p = true; |
| return conv; |
| } |
| |
| /* Like implicit_conversion, but return NULL if the conversion is bad. |
| |
| This is not static so that check_non_deducible_conversion can call it within |
| add_template_candidate_real as part of overload resolution; it should not be |
| called outside of overload resolution. */ |
| |
| conversion * |
| good_conversion (tree to, tree from, tree expr, |
| int flags, tsubst_flags_t complain) |
| { |
| conversion *c = implicit_conversion (to, from, expr, /*cast*/false, |
| flags, complain); |
| if (c && c->bad_p) |
| c = NULL; |
| return c; |
| } |
| |
| /* Add a new entry to the list of candidates. Used by the add_*_candidate |
| functions. ARGS will not be changed until a single candidate is |
| selected. */ |
| |
| static struct z_candidate * |
| add_candidate (struct z_candidate **candidates, |
| tree fn, tree first_arg, const vec<tree, va_gc> *args, |
| size_t num_convs, conversion **convs, |
| tree access_path, tree conversion_path, |
| int viable, struct rejection_reason *reason, |
| int flags) |
| { |
| struct z_candidate *cand = (struct z_candidate *) |
| conversion_obstack_alloc (sizeof (struct z_candidate)); |
| |
| cand->fn = fn; |
| cand->first_arg = first_arg; |
| cand->args = args; |
| cand->convs = convs; |
| cand->num_convs = num_convs; |
| cand->access_path = access_path; |
| cand->conversion_path = conversion_path; |
| cand->viable = viable; |
| cand->reason = reason; |
| cand->next = *candidates; |
| cand->flags = flags; |
| *candidates = cand; |
| |
| if (convs && cand->reversed ()) |
| /* Swap the conversions for comparison in joust; we'll swap them back |
| before build_over_call. */ |
| std::swap (convs[0], convs[1]); |
| |
| return cand; |
| } |
| |
| /* Return the number of remaining arguments in the parameter list |
| beginning with ARG. */ |
| |
| int |
| remaining_arguments (tree arg) |
| { |
| int n; |
| |
| for (n = 0; arg != NULL_TREE && arg != void_list_node; |
| arg = TREE_CHAIN (arg)) |
| n++; |
| |
| return n; |
| } |
| |
| /* [over.match.copy]: When initializing a temporary object (12.2) to be bound |
| to the first parameter of a constructor where the parameter is of type |
| "reference to possibly cv-qualified T" and the constructor is called with a |
| single argument in the context of direct-initialization of an object of type |
| "cv2 T", explicit conversion functions are also considered. |
| |
| So set LOOKUP_COPY_PARM to let reference_binding know that |
| it's being called in that context. */ |
| |
| int |
| conv_flags (int i, int nargs, tree fn, tree arg, int flags) |
| { |
| int lflags = flags; |
| tree t; |
| if (i == 0 && nargs == 1 && DECL_CONSTRUCTOR_P (fn) |
| && (t = FUNCTION_FIRST_USER_PARMTYPE (fn)) |
| && (same_type_ignoring_top_level_qualifiers_p |
| (non_reference (TREE_VALUE (t)), DECL_CONTEXT (fn)))) |
| { |
| if (!(flags & LOOKUP_ONLYCONVERTING)) |
| lflags |= LOOKUP_COPY_PARM; |
| if ((flags & LOOKUP_LIST_INIT_CTOR) |
| && BRACE_ENCLOSED_INITIALIZER_P (arg)) |
| lflags |= LOOKUP_NO_CONVERSION; |
| } |
| else |
| lflags |= LOOKUP_ONLYCONVERTING; |
| |
| 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. |
| |
| 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. |
| |
| 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, |
| tree fn, tree ctype, tree first_arg, |
| 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)); |
| int i, len; |
| tree parmnode; |
| tree orig_first_arg = first_arg; |
| int skip; |
| int viable = 1; |
| struct rejection_reason *reason = NULL; |
| |
| /* The `this', `in_chrg' and VTT arguments to constructors are not |
| considered in overload resolution. */ |
| if (DECL_CONSTRUCTOR_P (fn)) |
| { |
| if (ctor_omit_inherited_parms (fn)) |
| /* Bring back parameters omitted from an inherited ctor. */ |
| parmlist = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (fn)); |
| else |
| parmlist = skip_artificial_parms_for (fn, parmlist); |
| skip = num_artificial_parms_for (fn); |
| if (skip > 0 && first_arg != NULL_TREE) |
| { |
| --skip; |
| first_arg = NULL_TREE; |
| } |
| } |
| else |
| skip = 0; |
| |
| len = vec_safe_length (args) - skip + (first_arg != NULL_TREE ? 1 : 0); |
| if (!convs) |
| convs = alloc_conversions (len); |
| |
| /* 13.3.2 - Viable functions [over.match.viable] |
| First, to be a viable function, a candidate function shall have enough |
| parameters to agree in number with the arguments in the list. |
| |
| We need to check this first; otherwise, checking the ICSes might cause |
| us to produce an ill-formed template instantiation. */ |
| |
| parmnode = parmlist; |
| for (i = 0; i < len; ++i) |
| { |
| if (parmnode == NULL_TREE || parmnode == void_list_node) |
| break; |
| parmnode = TREE_CHAIN (parmnode); |
| } |
| |
| if ((i < len && parmnode) |
| || !sufficient_parms_p (parmnode)) |
| { |
| int remaining = remaining_arguments (parmnode); |
| viable = 0; |
| reason = arity_rejection (first_arg, i + remaining, len); |
| } |
| |
| /* An inherited constructor (12.6.3 [class.inhctor.init]) that has a first |
| parameter of type "reference to cv C" (including such a constructor |
| instantiated from a template) is excluded from the set of candidate |
| functions when used to construct an object of type D with an argument list |
| containing a single argument if C is reference-related to D. */ |
| if (viable && len == 1 && parmlist && DECL_CONSTRUCTOR_P (fn) |
| && flag_new_inheriting_ctors |
| && DECL_INHERITED_CTOR (fn)) |
| { |
| tree ptype = non_reference (TREE_VALUE (parmlist)); |
| tree dtype = DECL_CONTEXT (fn); |
| tree btype = DECL_INHERITED_CTOR_BASE (fn); |
| if (reference_related_p (ptype, dtype) |
| && reference_related_p (btype, ptype)) |
| { |
| viable = false; |
| reason = inherited_ctor_rejection (); |
| } |
| } |
| |
| /* Second, for a function to be viable, its constraints must be |
| satisfied. */ |
| if (flag_concepts && viable && !constraints_satisfied_p (fn)) |
| { |
| reason = constraint_failure (); |
| viable = false; |
| } |
| |
| /* When looking for a function from a subobject from an implicit |
| copy/move constructor/operator=, don't consider anything that takes (a |
| reference to) an unrelated type. See c++/44909 and core 1092. */ |
| if (viable && parmlist && (flags & LOOKUP_DEFAULTED)) |
| { |
| if (DECL_CONSTRUCTOR_P (fn)) |
| i = 1; |
| else if (DECL_ASSIGNMENT_OPERATOR_P (fn) |
| && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR)) |
| i = 2; |
| else |
| i = 0; |
| if (i && len == i) |
| { |
| parmnode = chain_index (i-1, parmlist); |
| if (!reference_related_p (non_reference (TREE_VALUE (parmnode)), |
| ctype)) |
| viable = 0; |
| } |
| |
| /* This only applies at the top level. */ |
| flags &= ~LOOKUP_DEFAULTED; |
| } |
| |
| if (! viable) |
| goto out; |
| |
| /* Third, for F to be a viable function, there shall exist for each |
| argument an implicit conversion sequence that converts that argument |
| to the corresponding parameter of F. */ |
| |
| parmnode = parmlist; |
| |
| for (i = 0; i < len; ++i) |
| { |
| tree argtype, to_type; |
| tree arg; |
| |
| if (parmnode == void_list_node) |
| break; |
| |
| if (convs[i]) |
| { |
| /* Already set during deduction. */ |
| parmnode = TREE_CHAIN (parmnode); |
| continue; |
| } |
| |
| if (i == 0 && first_arg != NULL_TREE) |
| arg = first_arg; |
| else |
| arg = CONST_CAST_TREE ( |
| (*args)[i + skip - (first_arg != NULL_TREE ? 1 : 0)]); |
| argtype = lvalue_type (arg); |
| |
| conversion *t; |
| if (parmnode) |
| { |
| tree parmtype = TREE_VALUE (parmnode); |
| 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 |
| { |
| 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 |
| { |
| t = build_identity_conv (argtype, arg); |
| t->ellipsis_p = true; |
| to_type = argtype; |
| } |
| |
| convs[i] = t; |
| if (! t) |
| { |
| viable = 0; |
| reason = arg_conversion_rejection (first_arg, i, argtype, to_type, |
| EXPR_LOCATION (arg)); |
| break; |
| } |
| |
| if (t->bad_p) |
| { |
| viable = -1; |
| reason = bad_arg_conversion_rejection (first_arg, i, arg, to_type, |
| EXPR_LOCATION (arg)); |
| if (shortcut_bad_convs) |
| break; |
| } |
| } |
| |
| out: |
| return add_candidate (candidates, fn, orig_first_arg, args, len, convs, |
| access_path, conversion_path, viable, reason, flags); |
| } |
| |
| /* Create an overload candidate for the conversion function FN which will |
| be invoked for expression OBJ, producing a pointer-to-function which |
| will in turn be called with the argument list FIRST_ARG/ARGLIST, |
| and add it to CANDIDATES. This does not change ARGLIST. FLAGS is |
| passed on to implicit_conversion. |
| |
| Actually, we don't really care about FN; we care about the type it |
| converts to. There may be multiple conversion functions that will |
| convert to that type, and we rely on build_user_type_conversion_1 to |
| choose the best one; so when we create our candidate, we record the type |
| instead of the function. */ |
| |
| static struct z_candidate * |
| add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, |
| const vec<tree, va_gc> *arglist, |
| tree access_path, tree conversion_path, |
| tsubst_flags_t complain) |
| { |
| tree totype = TREE_TYPE (TREE_TYPE (fn)); |
| int i, len, viable, flags; |
| tree parmlist, parmnode; |
| conversion **convs; |
| struct rejection_reason *reason; |
| |
| for (parmlist = totype; TREE_CODE (parmlist) != FUNCTION_TYPE; ) |
| parmlist = TREE_TYPE (parmlist); |
| parmlist = TYPE_ARG_TYPES (parmlist); |
| |
| len = vec_safe_length (arglist) + 1; |
| convs = alloc_conversions (len); |
| parmnode = parmlist; |
| viable = 1; |
| flags = LOOKUP_IMPLICIT; |
| reason = NULL; |
| |
| /* Don't bother looking up the same type twice. */ |
| if (*candidates && (*candidates)->fn == totype) |
| return NULL; |
| |
| for (i = 0; i < len; ++i) |
| { |
| tree arg, argtype, convert_type = NULL_TREE; |
| conversion *t; |
| |
| if (i == 0) |
| arg = obj; |
| else |
| arg = (*arglist)[i - 1]; |
| argtype = lvalue_type (arg); |
| |
| if (i == 0) |
| { |
| t = build_identity_conv (argtype, NULL_TREE); |
| t = build_conv (ck_user, totype, t); |
| /* Leave the 'cand' field null; we'll figure out the conversion in |
| convert_like if this candidate is chosen. */ |
| convert_type = totype; |
| } |
| else if (parmnode == void_list_node) |
| break; |
| else if (parmnode) |
| { |
| t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, |
| /*c_cast_p=*/false, flags, complain); |
| convert_type = TREE_VALUE (parmnode); |
| } |
| else |
| { |
| t = build_identity_conv (argtype, arg); |
| t->ellipsis_p = true; |
| convert_type = argtype; |
| } |
| |
| convs[i] = t; |
| if (! t) |
| break; |
| |
| if (t->bad_p) |
| { |
| viable = -1; |
| reason = bad_arg_conversion_rejection (NULL_TREE, i, arg, convert_type, |
| EXPR_LOCATION (arg)); |
| } |
| |
| if (i == 0) |
| continue; |
| |
| if (parmnode) |
| parmnode = TREE_CHAIN (parmnode); |
| } |
| |
| if (i < len |
| || ! sufficient_parms_p (parmnode)) |
| { |
| int remaining = remaining_arguments (parmnode); |
| viable = 0; |
| reason = arity_rejection (NULL_TREE, i + remaining, len); |
| } |
| |
| return add_candidate (candidates, totype, obj, arglist, len, convs, |
| access_path, conversion_path, viable, reason, flags); |
| } |
| |
| static void |
| build_builtin_candidate (struct z_candidate **candidates, tree fnname, |
| tree type1, tree type2, const vec<tree,va_gc> &args, |
| tree *argtypes, int flags, tsubst_flags_t complain) |
| { |
| conversion *t; |
| conversion **convs; |
| size_t num_convs; |
| int viable = 1; |
| tree types[2]; |
| struct rejection_reason *reason = NULL; |
| |
| types[0] = type1; |
| types[1] = type2; |
| |
| num_convs = args.length (); |
| convs = alloc_conversions (num_convs); |
| |
| /* TRUTH_*_EXPR do "contextual conversion to bool", which means explicit |
| conversion ops are allowed. We handle that here by just checking for |
| boolean_type_node because other operators don't ask for it. COND_EXPR |
| also does contextual conversion to bool for the first operand, but we |
| handle that in build_conditional_expr, and type1 here is operand 2. */ |
| if (type1 != boolean_type_node) |
| flags |= LOOKUP_ONLYCONVERTING; |
| |
| for (unsigned i = 0; i < 2 && i < num_convs; ++i) |
| { |
| t = implicit_conversion (types[i], argtypes[i], args[i], |
| /*c_cast_p=*/false, flags, complain); |
| if (! t) |
| { |
| viable = 0; |
| /* We need something for printing the candidate. */ |
| t = build_identity_conv (types[i], NULL_TREE); |
| reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i], |
| types[i], EXPR_LOCATION (args[i])); |
| } |
| else if (t->bad_p) |
| { |
| viable = 0; |
| reason = bad_arg_conversion_rejection (NULL_TREE, i, args[i], |
| types[i], |
| EXPR_LOCATION (args[i])); |
| } |
| convs[i] = t; |
| } |
| |
| /* For COND_EXPR we rearranged the arguments; undo that now. */ |
| if (num_convs == 3) |
| { |
| convs[2] = convs[1]; |
| convs[1] = convs[0]; |
| t = implicit_conversion (boolean_type_node, argtypes[2], args[2], |
| /*c_cast_p=*/false, flags, |
| complain); |
| if (t) |
| convs[0] = t; |
| else |
| { |
| viable = 0; |
| reason = arg_conversion_rejection (NULL_TREE, 0, argtypes[2], |
| boolean_type_node, |
| EXPR_LOCATION (args[2])); |
| } |
| } |
| |
| add_candidate (candidates, fnname, /*first_arg=*/NULL_TREE, /*args=*/NULL, |
| num_convs, convs, |
| /*access_path=*/NULL_TREE, |
| /*conversion_path=*/NULL_TREE, |
| viable, reason, flags); |
| } |
| |
| static bool |
| is_complete (tree t) |
| { |
| return COMPLETE_TYPE_P (complete_type (t)); |
| } |
| |
| /* Returns nonzero if TYPE is a promoted arithmetic type. */ |
| |
| static bool |
| promoted_arithmetic_type_p (tree type) |
| { |
| /* [over.built] |
| |
| In this section, the term promoted integral type is used to refer |
| to those integral types which are preserved by integral promotion |
| (including e.g. int and long but excluding e.g. char). |
| Similarly, the term promoted arithmetic type refers to promoted |
| integral types plus floating types. */ |
| return ((CP_INTEGRAL_TYPE_P (type) |
| && same_type_p (type_promotes_to (type), type)) |
| || TREE_CODE (type) == REAL_TYPE); |
| } |
| |
| /* Create any builtin operator overload candidates for the operator in |
| question given the converted operand types TYPE1 and TYPE2. The other |
| args are passed through from add_builtin_candidates to |
| build_builtin_candidate. |
| |
| TYPE1 and TYPE2 may not be permissible, and we must filter them. |
| If CODE is requires candidates operands of the same type of the kind |
| of which TYPE1 and TYPE2 are, we add both candidates |
| CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2). */ |
| |
| static void |
| add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, |
| enum tree_code code2, tree fnname, tree type1, |
| tree type2, vec<tree,va_gc> &args, tree *argtypes, |
| int flags, tsubst_flags_t complain) |
| { |
| switch (code) |
| { |
| case POSTINCREMENT_EXPR: |
| case POSTDECREMENT_EXPR: |
| args[1] = integer_zero_node; |
| type2 = integer_type_node; |
| break; |
| default: |
| break; |
| } |
| |
| switch (code) |
| { |
| |
| /* 4 For every pair (T, VQ), where T is an arithmetic type other than bool, |
| and VQ is either volatile or empty, there exist candidate operator |
| functions of the form |
| VQ T& operator++(VQ T&); |
| T operator++(VQ T&, int); |
| 5 For every pair (T, VQ), where T is an arithmetic type other than bool, |
| and VQ is either volatile or empty, there exist candidate operator |
| functions of the form |
| VQ T& operator--(VQ T&); |
| T operator--(VQ T&, int); |
| 6 For every pair (T, VQ), where T is a cv-qualified or cv-unqualified object |
| type, and VQ is either volatile or empty, there exist candidate operator |
| functions of the form |
| T*VQ& operator++(T*VQ&); |
| T*VQ& operator--(T*VQ&); |
| T* operator++(T*VQ&, int); |
| T* operator--(T*VQ&, int); */ |
| |
| case POSTDECREMENT_EXPR: |
| case PREDECREMENT_EXPR: |
| if (TREE_CODE (type1) == BOOLEAN_TYPE) |
| return; |
| /* FALLTHRU */ |
| case POSTINCREMENT_EXPR: |
| case PREINCREMENT_EXPR: |
| /* P0002R1, Remove deprecated operator++(bool) added "other than bool" |
| to p4. */ |
| if (TREE_CODE (type1) == BOOLEAN_TYPE && cxx_dialect >= cxx17) |
| return; |
| if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1)) |
| { |
| type1 = build_reference_type (type1); |
| break; |
| } |
| return; |
| |
| /* 7 For every cv-qualified or cv-unqualified object type T, there |
| exist candidate operator functions of the form |
| |
| T& operator*(T*); |
| |
| |
| 8 For every function type T that does not have cv-qualifiers or |
| a ref-qualifier, there exist candidate operator functions of the form |
| T& operator*(T*); */ |
| |
| case INDIRECT_REF: |
| if (TYPE_PTR_P (type1) |
| && (TYPE_PTROB_P (type1) |
| || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)) |
| break; |
| return; |
| |
| /* 9 For every type T, there exist candidate operator functions of the form |
| T* operator+(T*); |
| |
| 10 For every floating-point or promoted integral type T, there exist |
| candidate operator functions of the form |
| T operator+(T); |
| T operator-(T); */ |
| |
| case UNARY_PLUS_EXPR: /* unary + */ |
| if (TYPE_PTR_P (type1)) |
| break; |
| /* FALLTHRU */ |
| case NEGATE_EXPR: |
| if (ARITHMETIC_TYPE_P (type1)) |
| break; |
| return; |
| |
| /* 11 For every promoted integral type T, there exist candidate operator |
| functions of the form |
| T operator~(T); */ |
| |
| case BIT_NOT_EXPR: |
| if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1)) |
| break; |
| return; |
| |
| /* 12 For every quintuple (C1, C2, T, CV1, CV2), where C2 is a class type, C1 |
| is the same type as C2 or is a derived class of C2, and T is an object |
| type or a function type there exist candidate operator functions of the |
| form |
| CV12 T& operator->*(CV1 C1*, CV2 T C2::*); |
| where CV12 is the union of CV1 and CV2. */ |
| |
| case MEMBER_REF: |
| if (TYPE_PTR_P (type1) && TYPE_PTRMEM_P (type2)) |
| { |
| tree c1 = TREE_TYPE (type1); |
| tree c2 = TYPE_PTRMEM_CLASS_TYPE (type2); |
| |
| if (MAYBE_CLASS_TYPE_P (c1) && DERIVED_FROM_P (c2, c1) |
| && (TYPE_PTRMEMFUNC_P (type2) |
| || is_complete (TYPE_PTRMEM_POINTED_TO_TYPE (type2)))) |
| break; |
| } |
| return; |
| |
| /* 13 For every pair of types L and R, where each of L and R is a floating-point |
| or promoted integral type, there exist candidate operator functions of the |
| form |
| LR operator*(L, R); |
| LR operator/(L, R); |
| LR operator+(L, R); |
| LR operator-(L, R); |
| bool operator<(L, R); |
| bool operator>(L, R); |
| bool operator<=(L, R); |
| bool operator>=(L, R); |
| bool operator==(L, R); |
| bool operator!=(L, R); |
| where LR is the result of the usual arithmetic conversions between |
| types L and R. |
| |
| 14 For every integral type T there exists a candidate operator function of |
| the form |
| |
| std::strong_ordering operator<=>(T, T); |
| |
| 15 For every pair of floating-point types L and R, there exists a candidate |
| operator function of the form |
| |
| std::partial_ordering operator<=>(L, R); |
| |
| 16 For every cv-qualified or cv-unqualified object type T there exist |
| candidate operator functions of the form |
| T* operator+(T*, std::ptrdiff_t); |
| T& operator[](T*, std::ptrdiff_t); |
| T* operator-(T*, std::ptrdiff_t); |
| T* operator+(std::ptrdiff_t, T*); |
| T& operator[](std::ptrdiff_t, T*); |
| |
| 17 For every T, where T is a pointer to object type, there exist candidate |
| operator functions of the form |
| std::ptrdiff_t operator-(T, T); |
| |
| 18 For every T, where T is an enumeration type or a pointer type, there |
| exist candidate operator functions of the form |
| bool operator<(T, T); |
| bool operator>(T, T); |
| bool operator<=(T, T); |
| bool operator>=(T, T); |
| bool operator==(T, T); |
| bool operator!=(T, T); |
| R operator<=>(T, T); |
| |
| where R is the result type specified in [expr.spaceship]. |
| |
| 19 For every T, where T is a pointer-to-member type or std::nullptr_t, |
| there exist candidate operator functions of the form |
| bool operator==(T, T); |
| bool operator!=(T, T); */ |
| |
| case MINUS_EXPR: |
| if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2)) |
| break; |
| if (TYPE_PTROB_P (type1) |
| && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) |
| { |
| type2 = ptrdiff_type_node; |
| break; |
| } |
| /* FALLTHRU */ |
| case MULT_EXPR: |
| case TRUNC_DIV_EXPR: |
| if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) |
| break; |
| return; |
| |
| /* This isn't exactly what's specified above for operator<=>, but it's |
| close enough. In particular, we don't care about the return type |
| specified above; it doesn't participate in overload resolution and it |
| doesn't affect the semantics of the built-in operator. */ |
| case SPACESHIP_EXPR: |
| case EQ_EXPR: |
| case NE_EXPR: |
| if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2)) |
| || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))) |
| break; |
| if (NULLPTR_TYPE_P (type1) && NULLPTR_TYPE_P (type2)) |
| break; |
| if (TYPE_PTRMEM_P (type1) && null_ptr_cst_p (args[1])) |
| { |
| type2 = type1; |
| break; |
| } |
| if (TYPE_PTRMEM_P (type2) && null_ptr_cst_p (args[0])) |
| { |
| type1 = type2; |
| break; |
| } |
| /* Fall through. */ |
| case LT_EXPR: |
| case GT_EXPR: |
| case LE_EXPR: |
| case GE_EXPR: |
| case MAX_EXPR: |
| case MIN_EXPR: |
| if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) |
| break; |
| if (TYPE_PTR_P (type1) && TYPE_PTR_P (type2)) |
| break; |
| if (TREE_CODE (type1) == ENUMERAL_TYPE |
| && TREE_CODE (type2) == ENUMERAL_TYPE) |
| break; |
| if (TYPE_PTR_P (type1) |
| && null_ptr_cst_p (args[1])) |
| { |
| type2 = type1; |
| break; |
| } |
| if (null_ptr_cst_p (args[0]) |
| && TYPE_PTR_P (type2)) |
| { |
| type1 = type2; |
| break; |
| } |
| return; |
| |
| case PLUS_EXPR: |
| if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) |
| break; |
| /* FALLTHRU */ |
| case ARRAY_REF: |
| if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && TYPE_PTROB_P (type2)) |
| { |
| type1 = ptrdiff_type_node; |
| break; |
| } |
| if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) |
| { |
| type2 = ptrdiff_type_node; |
| break; |
| } |
| return; |
| |
| /* 18For every pair of promoted integral types L and R, there exist candi- |
| date operator functions of the form |
| LR operator%(L, R); |
| LR operator&(L, R); |
| LR operator^(L, R); |
| LR operator|(L, R); |
| L operator<<(L, R); |
| L operator>>(L, R); |
| where LR is the result of the usual arithmetic conversions between |
| types L and R. */ |
| |
| case TRUNC_MOD_EXPR: |
| case BIT_AND_EXPR: |
| case BIT_IOR_EXPR: |
| case BIT_XOR_EXPR: |
| case LSHIFT_EXPR: |
| case RSHIFT_EXPR: |
| if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) |
| break; |
| return; |
| |
| /* 19For every triple L, VQ, R), where L is an arithmetic or enumeration |
| type, VQ is either volatile or empty, and R is a promoted arithmetic |
| type, there exist candidate operator functions of the form |
| VQ L& operator=(VQ L&, R); |
| VQ L& operator*=(VQ L&, R); |
| VQ L& operator/=(VQ L&, R); |
| VQ L& operator+=(VQ L&, R); |
| VQ L& operator-=(VQ L&, R); |
| |
| 20For every pair T, VQ), where T is any type and VQ is either volatile |
| or empty, there exist candidate operator functions of the form |
| T*VQ& operator=(T*VQ&, T*); |
| |
| 21For every pair T, VQ), where T is a pointer to member type and VQ is |
| either volatile or empty, there exist candidate operator functions of |
| the form |
| VQ T& operator=(VQ T&, T); |
| |
| 22For every triple T, VQ, I), where T is a cv-qualified or cv- |
| unqualified complete object type, VQ is either volatile or empty, and |
| I is a promoted integral type, there exist candidate operator func- |
| tions of the form |
| T*VQ& operator+=(T*VQ&, I); |
| T*VQ& operator-=(T*VQ&, I); |
| |
| 23For every triple L, VQ, R), where L is an integral or enumeration |
| type, VQ is either volatile or empty, and R is a promoted integral |
| type, there exist candidate operator functions of the form |
| |
| VQ L& operator%=(VQ L&, R); |
| VQ L& operator<<=(VQ L&, R); |
| VQ L& operator>>=(VQ L&, R); |
| VQ L& operator&=(VQ L&, R); |
| VQ L& operator^=(VQ L&, R); |
| VQ L& operator|=(VQ L&, R); */ |
| |
| case MODIFY_EXPR: |
| switch (code2) |
| { |
| case PLUS_EXPR: |
| case MINUS_EXPR: |
| if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) |
| { |
| type2 = ptrdiff_type_node; |
| break; |
| } |
| /* FALLTHRU */ |
| case MULT_EXPR: |
| case TRUNC_DIV_EXPR: |
| if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) |
| break; |
| return; |
| |
| case TRUNC_MOD_EXPR: |
| case BIT_AND_EXPR: |
| case BIT_IOR_EXPR: |
| case BIT_XOR_EXPR: |
| case LSHIFT_EXPR: |
| case RSHIFT_EXPR: |
| if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2)) |
| break; |
| return; |
| |
| case NOP_EXPR: |
| if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) |
| break; |
| if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2)) |
| || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2)) |
| || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2)) |
| || ((TYPE_PTRMEMFUNC_P (type1) |
| || TYPE_PTR_P (type1)) |
| && null_ptr_cst_p (args[1]))) |
| { |
| type2 = type1; |
| break; |
| } |
| return; |
| |
| default: |
| gcc_unreachable (); |
| } |
| type1 = build_reference_type (type1); |
| break; |
| |
| case COND_EXPR: |
| /* [over.built] |
| |
| For every pair of promoted arithmetic types L and R, there |
| exist candidate operator functions of the form |
| |
| LR operator?(bool, L, R); |
| |
| where LR is the result of the usual arithmetic conversions |
| between types L and R. |
| |
| For every type T, where T is a pointer or pointer-to-member |
| type, there exist candidate operator functions of the form T |
| operator?(bool, T, T); */ |
| |
| if (promoted_arithmetic_type_p (type1) |
| && promoted_arithmetic_type_p (type2)) |
| /* That's OK. */ |
| break; |
| |
| /* Otherwise, the types should be pointers. */ |
| if (!TYPE_PTR_OR_PTRMEM_P (type1) || !TYPE_PTR_OR_PTRMEM_P (type2)) |
| return; |
| |
| /* We don't check that the two types are the same; the logic |
| below will actually create two candidates; one in which both |
| parameter types are TYPE1, and one in which both parameter |
| types are TYPE2. */ |
| break; |
| |
| case REALPART_EXPR: |
| case IMAGPART_EXPR: |
| if (ARITHMETIC_TYPE_P (type1)) |
| break; |
| return; |
| |
| default: |
| gcc_unreachable (); |
| } |
| |
| /* Make sure we don't create builtin candidates with dependent types. */ |
| bool u1 = uses_template_parms (type1); |
| bool u2 = type2 ? uses_template_parms (type2) : false; |
| if (u1 || u2) |
| { |
| /* Try to recover if one of the types is non-dependent. But if |
| there's only one type, there's nothing we can do. */ |
| if (!type2) |
| return; |
| /* And we lose if both are dependent. */ |
| if (u1 && u2) |
| return; |
| /* Or if they have different forms. */ |
| if (TREE_CODE (type1) != TREE_CODE (type2)) |
| return; |
| |
| if (u1 && !u2) |
| type1 = type2; |
| else if (u2 && !u1) |
| type2 = type1; |
| } |
| |
| /* If we're dealing with two pointer types or two enumeral types, |
| we need candidates for both of them. */ |
| if (type2 && !same_type_p (type1, type2) |
| && TREE_CODE (type1) == TREE_CODE (type2) |
| && (TYPE_REF_P (type1) |
| || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2)) |
| || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2)) |
| || TYPE_PTRMEMFUNC_P (type1) |
| || MAYBE_CLASS_TYPE_P (type1) |
| || TREE_CODE (type1) == ENUMERAL_TYPE)) |
| { |
| if (TYPE_PTR_OR_PTRMEM_P (type1)) |
| { |
| tree cptype = composite_pointer_type (input_location, |
| type1, type2, |
| error_mark_node, |
| error_mark_node, |
| CPO_CONVERSION, |
| tf_none); |
| if (cptype != error_mark_node) |
| { |
| build_builtin_candidate |
| (candidates, fnname, cptype, cptype, args, argtypes, |
| flags, complain); |
| return; |
| } |
| } |
| |
| build_builtin_candidate |
| (candidates, fnname, type1, type1, args, argtypes, flags, complain); |
| build_builtin_candidate |
| (candidates, fnname, type2, type2, args, argtypes, flags, complain); |
| return; |
| } |
| |
| build_builtin_candidate |
| (candidates, fnname, type1, type2, args, argtypes, flags, complain); |
| } |
| |
| tree |
| type_decays_to (tree type) |
| { |
| if (TREE_CODE (type) == ARRAY_TYPE) |
| return build_pointer_type (TREE_TYPE (type)); |
| if (TREE_CODE (type) == FUNCTION_TYPE) |
| return build_pointer_type (type); |
| return type; |
| } |
| |
| /* There are three conditions of builtin candidates: |
| |
| 1) bool-taking candidates. These are the same regardless of the input. |
| 2) pointer-pair taking candidates. These are generated for each type |
| one of the input types converts to. |
| 3) arithmetic candidates. According to the standard, we should generate |
| all of these, but I'm trying not to... |
| |
| Here we generate a superset of the possible candidates for this particular |
| case. That is a subset of the full set the standard defines, plus some |
| other cases which the standard disallows. add_builtin_candidate will |
| filter out the invalid set. */ |
| |
| static void |
| add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, |
| enum tree_code code2, tree fnname, |
| vec<tree, va_gc> *argv, |
| int flags, tsubst_flags_t complain) |
| { |
| int ref1; |
| int enum_p = 0; |
| tree type, argtypes[3], t; |
| /* TYPES[i] is the set of possible builtin-operator parameter types |
| we will consider for the Ith argument. */ |
| vec<tree, va_gc> *types[2]; |
| unsigned ix; |
| vec<tree, va_gc> &args = *argv; |
|