blob: fa18d7f8f9d121aa81a345bc4ea81766dea58333 [file] [log] [blame]
<
/* Functions related to invoking -*- C++ -*- methods and overloaded functions.
Copyright (C) 1987-2022 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);
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 (auto &e: CONSTRUCTOR_ELTS (ctor))
{
conversion *sub
= implicit_conversion (elttype, TREE_TYPE (e.value), e.value,
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);
bool bad = false;
bool user = false;
enum conversion_rank rank = cr_exact;
if (len != 2)
return NULL;
flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
for (auto &e: CONSTRUCTOR_ELTS (ctor))
{
conversion *sub
= implicit_conversion (elttype, TREE_TYPE (e.value), e.value,
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.
We strip_top_quals here which is also what standard_conversion
does. Failure to do so would confuse comp_cv_qual_signature
into thinking that in
void f(const int * const &); // #1
void f(const int *); // #2
int *x;
f(x);
#2 is a better match than #1 even though they're ambiguous (97296). */
conv = build_conv (ck_qual, strip_top_quals (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 (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