/* 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 nor ck_ambig. */
+ used only when KIND is neither ck_identity, 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 or ck_ambig. */
tree expr;
- /* The array of conversions for an initializer_list. */
+ /* 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
static conversion *reference_binding (tree, tree, tree, bool, int);
static conversion *build_conv (conversion_kind, tree, conversion *);
static conversion *build_list_conv (tree, tree, int);
+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 **);
{
/* Core issue 903 says only literal 0 is a null pointer constant. */
if (cxx_dialect < cxx0x)
- {
- t = integral_constant_value (t);
- STRIP_NOPS (t);
- }
+ t = integral_constant_value (t);
+ STRIP_NOPS (t);
if (integer_zerop (t) && !TREE_OVERFLOW (t))
return 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
+ || conv->kind == ck_identity
+ || conv->kind == ck_ambig
+ || conv->kind == ck_list)
+ return NULL;
+ return conv->u.next;
+}
+
/* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list,
is a valid aggregate initializer for array type ATYPE. */
build_user_type_conversion_1 (tree totype, tree expr, int flags)
{
struct z_candidate *candidates, *cand;
- tree fromtype = TREE_TYPE (expr);
+ tree fromtype;
tree ctors = NULL_TREE;
tree conv_fns = NULL_TREE;
conversion *conv = NULL;
bool any_viable_p;
int convflags;
+ if (!expr)
+ return NULL;
+
+ fromtype = TREE_TYPE (expr);
+
/* We represent conversion within a hierarchy using RVALUE_CONV and
BASE_CONV, as specified by [over.best.ics]; these become plain
constructor calls, as specified in [dcl.init]. */
return error_mark_node;
}
+ if (flag_tm)
+ tm_malloc_replacement (fn);
+
/* If this function was found without using argument dependent
lookup, then we want to ignore any undeclared friend
functions. */
}
/* Issue warnings if "false" is converted to a NULL pointer */
- else if (expr == boolean_false_node && TYPE_PTR_P (totype))
+ else if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
+ && TYPE_PTR_P (totype))
{
if (fn)
warning_at (input_location, OPT_Wconversion_null,
&& BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
permerror (input_location, "too many braces around initializer for %qT", totype);
- for (; t; t = t->u.next)
+ for (; t ; t = next_conversion (t))
{
if (t->kind == ck_user && t->cand->reason)
{
current_in_charge_parm, integer_zero_node),
current_vtt_parm,
vtt);
- gcc_assert (BINFO_SUBVTT_INDEX (binfo));
- sub_vtt = fold_build_pointer_plus (vtt, BINFO_SUBVTT_INDEX (binfo));
+ if (BINFO_SUBVTT_INDEX (binfo))
+ sub_vtt = fold_build_pointer_plus (vtt, BINFO_SUBVTT_INDEX (binfo));
+ else
+ sub_vtt = vtt;
if (args == NULL)
{
&& CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0)))
{
tree init_list = VEC_index (tree, *args, 0);
+ tree init = NULL_TREE;
gcc_assert (VEC_length (tree, *args) == 1
&& !(flags & LOOKUP_ONLYCONVERTING));
if (CONSTRUCTOR_NELTS (init_list) == 0
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
&& !processing_template_decl)
+ init = build_value_init (basetype, complain);
+
+ /* If BASETYPE is an aggregate, we need to do aggregate
+ initialization. */
+ else if (CP_AGGREGATE_TYPE_P (basetype))
+ init = digest_init (basetype, init_list, complain);
+
+ if (init)
{
- tree ob, init = build_value_init (basetype, complain);
+ tree ob;
if (integer_zerop (instance_ptr))
return get_target_expr_sfinae (init, complain);
ob = build_fold_indirect_ref (instance_ptr);
return init;
}
+ /* Otherwise go ahead with overload resolution. */
add_list_candidates (fns, first_mem_arg, init_list,
basetype, explicit_targs, template_only,
conversion_path, access_binfo, flags, &candidates);
if (winner)
return winner;
+ /* DR 495 moved this tiebreaker above the template ones. */
+ /* or, if not that,
+ the context is an initialization by user-defined conversion (see
+ _dcl.init_ and _over.match.user_) and the standard conversion
+ sequence from the return type of F1 to the destination type (i.e.,
+ the type of the entity being initialized) is a better conversion
+ sequence than the standard conversion sequence from the return type
+ of F2 to the destination type. */
+
+ if (cand1->second_conv)
+ {
+ winner = compare_ics (cand1->second_conv, cand2->second_conv);
+ if (winner)
+ return winner;
+ }
+
/* or, if not that,
F1 is a non-template function and F2 is a template function
specialization. */
return winner;
}
- /* or, if not that,
- the context is an initialization by user-defined conversion (see
- _dcl.init_ and _over.match.user_) and the standard conversion
- sequence from the return type of F1 to the destination type (i.e.,
- the type of the entity being initialized) is a better conversion
- sequence than the standard conversion sequence from the return type
- of F2 to the destination type. */
-
- if (cand1->second_conv)
- {
- winner = compare_ics (cand1->second_conv, cand2->second_conv);
- if (winner)
- return winner;
- }
-
/* Check whether we can discard a builtin candidate, either because we
have two identical ones or matching builtin and non-builtin candidates.
}
expr = error_mark_node;
}
- else if (processing_template_decl
- /* As a kludge, we always perform conversions between scalar
- types, as IMPLICIT_CONV_EXPR confuses c_finish_omp_for. */
- && !(SCALAR_TYPE_P (type) && SCALAR_TYPE_P (TREE_TYPE (expr))))
+ else if (processing_template_decl && conv->kind != ck_identity)
{
/* In a template, we are only concerned about determining the
type of non-dependent expressions, so we do not have to
if (TREE_CODE (expr) != TARGET_EXPR)
expr = get_target_expr (expr);
+ if (TREE_CODE (decl) == FIELD_DECL
+ && extra_warnings && !TREE_NO_WARNING (decl))
+ {
+ warning (OPT_Wextra, "a temporary bound to %qD only persists "
+ "until the constructor exits", decl);
+ TREE_NO_WARNING (decl) = true;
+ }
+
/* Recursively extend temps in this initializer. */
TARGET_EXPR_INITIAL (expr)
= extend_ref_init_temps (decl, TARGET_EXPR_INITIAL (expr), cleanups);