X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Fcall.c;h=d107a71747e6a7ef2fd60a32738c117c696d7145;hp=55089edbf1d9d8fd7416a29c481459d655441367;hb=9960d752f0bd2b1e3f0c62d50deae42a1303c8ce;hpb=c2c19f68a13591b9bb6ff393319da04e2cf428d1 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 55089edbf1d..d107a71747e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -122,6 +122,11 @@ struct conversion { : (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; @@ -199,7 +204,7 @@ static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool, tree, tree, int, struct z_candidate **); static conversion *merge_conversion_sequences (conversion *, conversion *); static bool magic_varargs_p (tree); -static tree build_temp (tree, tree, int, diagnostic_t *); +static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t); /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE. NAME can take many forms... */ @@ -461,15 +466,24 @@ null_ptr_cst_p (tree t) A null pointer constant is an integral constant expression (_expr.const_) rvalue of integer type that evaluates to zero or an rvalue of type std::nullptr_t. */ - t = integral_constant_value (t); - if (t == null_node - || NULLPTR_TYPE_P (TREE_TYPE (t))) + if (NULLPTR_TYPE_P (TREE_TYPE (t))) return true; - if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t)) + if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t))) { - STRIP_NOPS (t); - if (!TREE_OVERFLOW (t)) - return true; + if (cxx_dialect >= cxx0x) + { + t = fold_non_dependent_expr (t); + t = maybe_constant_value (t); + if (TREE_CONSTANT (t) && integer_zerop (t)) + return true; + } + else + { + t = integral_constant_value (t); + STRIP_NOPS (t); + if (integer_zerop (t) && !TREE_OVERFLOW (t)) + return true; + } } return false; } @@ -625,6 +639,29 @@ build_list_conv (tree type, tree ctor, int flags) return t; } +/* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list, + is a valid aggregate initializer for array type ATYPE. */ + +static bool +can_convert_array (tree atype, tree ctor, int flags) +{ + unsigned i; + tree elttype = TREE_TYPE (atype); + for (i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i) + { + tree val = CONSTRUCTOR_ELT (ctor, i)->value; + bool ok; + if (TREE_CODE (elttype) == ARRAY_TYPE + && TREE_CODE (val) == CONSTRUCTOR) + ok = can_convert_array (elttype, val, flags); + else + ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags); + if (!ok) + return false; + } + return true; +} + /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an aggregate class, if such a conversion is possible. */ @@ -636,26 +673,33 @@ build_aggr_conv (tree type, tree ctor, int flags) tree field = next_initializable_field (TYPE_FIELDS (type)); tree empty_ctor = NULL_TREE; - for (; field; field = next_initializable_field (TREE_CHAIN (field))) + for (; field; field = next_initializable_field (DECL_CHAIN (field))) { + tree ftype = TREE_TYPE (field); + tree val; + bool ok; + if (i < CONSTRUCTOR_NELTS (ctor)) - { - constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i); - if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value), - ce->value, flags)) - return NULL; - ++i; - if (TREE_CODE (type) == UNION_TYPE) - break; - } + val = CONSTRUCTOR_ELT (ctor, i)->value; else { if (empty_ctor == NULL_TREE) empty_ctor = build_constructor (init_list_type_node, NULL); - if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (empty_ctor), - empty_ctor, flags)) - return NULL; + val = empty_ctor; } + ++i; + + if (TREE_CODE (ftype) == ARRAY_TYPE + && TREE_CODE (val) == CONSTRUCTOR) + ok = can_convert_array (ftype, val, flags); + else + ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags); + + if (!ok) + return NULL; + + if (TREE_CODE (type) == UNION_TYPE) + break; } if (i < CONSTRUCTOR_NELTS (ctor)) @@ -827,9 +871,12 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, && !TYPE_PTRMEM_P (from) && TREE_CODE (TREE_TYPE (from)) != FUNCTION_TYPE) { + tree nfrom = TREE_TYPE (from); + if (c_dialect_objc ()) + nfrom = objc_non_volatilized_type (nfrom); from = build_pointer_type - (cp_build_qualified_type (void_type_node, - cp_type_quals (TREE_TYPE (from)))); + (cp_build_qualified_type (void_type_node, + cp_type_quals (nfrom))); conv = build_conv (ck_ptr, from, conv); } else if (TYPE_PTRMEM_P (from)) @@ -895,6 +942,11 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, else if (expr && string_conv_p (to, expr, 0)) /* converting from string constant to char *. */ conv = build_conv (ck_qual, 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); @@ -994,6 +1046,9 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, 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); @@ -1035,7 +1090,10 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) struct z_candidate *cand; bool any_viable_p; - conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true); + if (!expr) + return NULL; + + conversions = lookup_conversions (s); if (!conversions) return NULL; @@ -1386,9 +1444,12 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) conversion operator). */ flags |= LOOKUP_NO_TEMP_BIND; - /* Temporaries are copy-initialized, except for this hack to allow - explicit conversion ops to the copy ctor. See also - add_function_candidate. */ + /* 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; @@ -1422,6 +1483,9 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, || expr == error_mark_node) return NULL; + if (c_dialect_objc ()) + from = objc_non_volatilized_type (from); + if (TREE_CODE (to) == REFERENCE_TYPE) conv = reference_binding (to, from, expr, c_cast_p, flags); else @@ -1443,7 +1507,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, tree elt; if (nelts == 0) - elt = integer_zero_node; + elt = build_value_init (to, tf_none); else if (nelts == 1) elt = CONSTRUCTOR_ELT (expr, 0)->value; else @@ -1585,6 +1649,30 @@ add_function_candidate (struct z_candidate **candidates, else if (!sufficient_parms_p (parmnode)) viable = 0; + /* Kludge: When looking for a function from a subobject while generating + an implicit copy/move constructor/operator=, don't consider anything + that takes (a reference to) an unrelated type. See c++/44909. */ + else if (parmlist + && ((flags & LOOKUP_SPECULATIVE) + || (current_function_decl + && DECL_DEFAULTED_FN (current_function_decl)))) + { + if (DECL_CONSTRUCTOR_P (fn)) + i = 1; + else if (DECL_ASSIGNMENT_OPERATOR_P (fn) + && DECL_OVERLOADED_OPERATOR_P (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; + } + } + if (! viable) goto out; @@ -1618,6 +1706,8 @@ add_function_candidate (struct z_candidate **candidates, tree parmtype = TREE_VALUE (parmnode); int lflags = flags; + parmnode = TREE_CHAIN (parmnode); + /* The type of the implicit object parameter ('this') for overload resolution is not always the same as for the function itself; conversion functions are considered to @@ -1634,13 +1724,25 @@ add_function_candidate (struct z_candidate **candidates, parmtype = build_pointer_type (parmtype); } - if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn) - && (len-skip == 1)) + /* 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 set LOOKUP_COPY_PARM to let reference_binding know that + it's being called in that context. We generalize the above + to handle move constructors and template constructors as well; + the standardese should soon be updated similarly. */ + if (ctype && i == 0 && (len-skip == 1) + && !(flags & LOOKUP_ONLYCONVERTING) + && DECL_CONSTRUCTOR_P (fn) + && parmtype != error_mark_node + && (same_type_ignoring_top_level_qualifiers_p + (non_reference (parmtype), ctype))) { - /* Hack: Direct-initialize copy parm (i.e. suppress - LOOKUP_ONLYCONVERTING) to make explicit conversion ops - work. See also reference_binding. */ lflags |= LOOKUP_COPY_PARM; + /* We allow user-defined conversions within init-lists, but + not for the copy constructor. */ if (flags & LOOKUP_NO_COPY_CTOR_CONVERSION) lflags |= LOOKUP_NO_CONVERSION; } @@ -1668,9 +1770,6 @@ add_function_candidate (struct z_candidate **candidates, if (t->bad_p) viable = -1; - - if (parmnode) - parmnode = TREE_CHAIN (parmnode); } out: @@ -2285,12 +2384,11 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, { int ref1, i; int enum_p = 0; - tree type, argtypes[3]; + tree type, argtypes[3], t; /* TYPES[i] is the set of possible builtin-operator parameter types - we will consider for the Ith argument. These are represented as - a TREE_LIST; the TREE_VALUE of each node is the potential - parameter type. */ - tree types[2]; + we will consider for the Ith argument. */ + VEC(tree,gc) *types[2]; + unsigned ix; for (i = 0; i < 3; ++i) { @@ -2352,7 +2450,8 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, ref1 = 0; } - types[0] = types[1] = NULL_TREE; + types[0] = make_tree_vector (); + types[1] = make_tree_vector (); for (i = 0; i < 2; ++i) { @@ -2365,17 +2464,16 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR) return; - convs = lookup_conversions (argtypes[i], - /*lookup_template_convs_p=*/false); + convs = lookup_conversions (argtypes[i]); if (code == COND_EXPR) { if (real_lvalue_p (args[i])) - types[i] = tree_cons - (NULL_TREE, build_reference_type (argtypes[i]), types[i]); + VEC_safe_push (tree, gc, types[i], + build_reference_type (argtypes[i])); - types[i] = tree_cons - (NULL_TREE, TYPE_MAIN_VARIANT (argtypes[i]), types[i]); + VEC_safe_push (tree, gc, types[i], + TYPE_MAIN_VARIANT (argtypes[i])); } else if (! convs) @@ -2391,54 +2489,60 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, continue; if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE) - types[i] = tree_cons (NULL_TREE, type, types[i]); + VEC_safe_push (tree, gc, types[i], type); type = non_reference (type); if (i != 0 || ! ref1) { type = TYPE_MAIN_VARIANT (type_decays_to (type)); if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE) - types[i] = tree_cons (NULL_TREE, type, types[i]); + VEC_safe_push (tree, gc, types[i], type); if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) type = type_promotes_to (type); } - if (! value_member (type, types[i])) - types[i] = tree_cons (NULL_TREE, type, types[i]); + if (! vec_member (type, types[i])) + VEC_safe_push (tree, gc, types[i], type); } } else { if (code == COND_EXPR && real_lvalue_p (args[i])) - types[i] = tree_cons - (NULL_TREE, build_reference_type (argtypes[i]), types[i]); + VEC_safe_push (tree, gc, types[i], + build_reference_type (argtypes[i])); type = non_reference (argtypes[i]); if (i != 0 || ! ref1) { type = TYPE_MAIN_VARIANT (type_decays_to (type)); if (enum_p && UNSCOPED_ENUM_P (type)) - types[i] = tree_cons (NULL_TREE, type, types[i]); + VEC_safe_push (tree, gc, types[i], type); if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) type = type_promotes_to (type); } - types[i] = tree_cons (NULL_TREE, type, types[i]); + VEC_safe_push (tree, gc, types[i], type); } } /* Run through the possible parameter types of both arguments, creating candidates with those parameter types. */ - for (; types[0]; types[0] = TREE_CHAIN (types[0])) + FOR_EACH_VEC_ELT_REVERSE (tree, types[0], ix, t) { - if (types[1]) - for (type = types[1]; type; type = TREE_CHAIN (type)) + unsigned jx; + tree u; + + if (!VEC_empty (tree, types[1])) + FOR_EACH_VEC_ELT_REVERSE (tree, types[1], jx, u) add_builtin_candidate - (candidates, code, code2, fnname, TREE_VALUE (types[0]), - TREE_VALUE (type), args, argtypes, flags); + (candidates, code, code2, fnname, t, + u, args, argtypes, flags); else add_builtin_candidate - (candidates, code, code2, fnname, TREE_VALUE (types[0]), + (candidates, code, code2, fnname, t, NULL_TREE, args, argtypes, flags); } + + release_tree_vector (types[0]); + release_tree_vector (types[1]); } @@ -2681,7 +2785,7 @@ build_this (tree obj) if (processing_template_decl) return build_address (obj); - return cp_build_unary_op (ADDR_EXPR, obj, 0, tf_warning_or_error); + return cp_build_addr_expr (obj, tf_warning_or_error); } /* Returns true iff functions are equivalent. Equivalent functions are @@ -2923,8 +3027,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) reference to it)... */ } else - conv_fns = lookup_conversions (fromtype, - /*lookup_template_convs_p=*/true); + conv_fns = lookup_conversions (fromtype); } candidates = 0; @@ -3099,6 +3202,76 @@ build_user_type_conversion (tree totype, tree expr, int flags) return NULL_TREE; } +/* Subroutine of convert_nontype_argument. + + EXPR is an argument for a template non-type parameter of integral or + enumeration type. Do any necessary conversions (that are permitted for + non-type arguments) to convert it to the parameter type. + + If conversion is successful, returns the converted expression; + otherwise, returns error_mark_node. */ + +tree +build_integral_nontype_arg_conv (tree type, tree expr, tsubst_flags_t complain) +{ + conversion *conv; + void *p; + tree t; + + if (error_operand_p (expr)) + return error_mark_node; + + gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type)); + + /* Get the high-water mark for the CONVERSION_OBSTACK. */ + p = conversion_obstack_alloc (0); + + conv = implicit_conversion (type, TREE_TYPE (expr), expr, + /*c_cast_p=*/false, + LOOKUP_IMPLICIT); + + /* for a non-type template-parameter of integral or + enumeration type, integral promotions (4.5) and integral + conversions (4.7) are applied. */ + /* It should be sufficient to check the outermost conversion step, since + there are no qualification conversions to integer type. */ + if (conv) + switch (conv->kind) + { + /* A conversion function is OK. If it isn't constexpr, we'll + complain later that the argument isn't constant. */ + case ck_user: + /* The lvalue-to-rvalue conversion is OK. */ + case ck_rvalue: + case ck_identity: + break; + + case ck_std: + t = conv->u.next->type; + if (INTEGRAL_OR_ENUMERATION_TYPE_P (t)) + break; + + if (complain & tf_error) + error ("conversion from %qT to %qT not considered for " + "non-type template argument", t, type); + /* and fall through. */ + + default: + conv = NULL; + break; + } + + if (conv) + expr = convert_like (conv, expr, complain); + else + expr = error_mark_node; + + /* Free all the conversions we allocated. */ + obstack_free (&conversion_obstack, p); + + return expr; +} + /* Do any initial processing on the arguments to a function call. */ static VEC(tree,gc) * @@ -3107,7 +3280,7 @@ resolve_args (VEC(tree,gc) *args) unsigned int ix; tree arg; - for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix) + FOR_EACH_VEC_ELT (tree, args, ix, arg) { if (error_operand_p (arg)) return NULL; @@ -3410,7 +3583,7 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain) LOOKUP_NORMAL, &candidates); } - convs = lookup_conversions (type, /*lookup_template_convs_p=*/true); + convs = lookup_conversions (type); for (; convs; convs = TREE_CHAIN (convs)) { @@ -3839,8 +4012,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, && same_type_p (arg2_type, arg3_type)) { result_type = arg2_type; - mark_lvalue_use (arg2); - mark_lvalue_use (arg3); + arg2 = mark_lvalue_use (arg2); + arg3 = mark_lvalue_use (arg3); goto valid_operands; } @@ -3955,6 +4128,10 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, /* In this case, there is always a common type. */ result_type = type_after_usual_arithmetic_conversions (arg2_type, arg3_type); + do_warn_double_promotion (result_type, arg2_type, arg3_type, + "implicit conversion from %qT to %qT to " + "match other result of conditional", + input_location); if (TREE_CODE (arg2_type) == ENUMERAL_TYPE && TREE_CODE (arg3_type) == ENUMERAL_TYPE) @@ -4829,7 +5006,7 @@ enforce_access (tree basetype_path, tree decl, tree diag_decl) static tree build_temp (tree expr, tree type, int flags, - diagnostic_t *diagnostic_kind) + diagnostic_t *diagnostic_kind, tsubst_flags_t complain) { int savew, savee; VEC(tree,gc) *args; @@ -4837,7 +5014,7 @@ build_temp (tree expr, tree type, int flags, savew = warningcount, savee = errorcount; args = make_tree_vector_single (expr); expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, - &args, type, flags, tf_warning_or_error); + &args, type, flags, complain); release_tree_vector (args); if (warningcount > savew) *diagnostic_kind = DK_WARNING; @@ -4996,7 +5173,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, { int nelts = CONSTRUCTOR_NELTS (expr); if (nelts == 0) - expr = integer_zero_node; + expr = build_value_init (totype, tf_warning_or_error); else if (nelts == 1) expr = CONSTRUCTOR_ELT (expr, 0)->value; else @@ -5045,7 +5222,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, 1, false, false, complain); if (sub == error_mark_node) return sub; - check_narrowing (TREE_TYPE (sub), val); + if (!BRACE_ENCLOSED_INITIALIZER_P (val)) + check_narrowing (TREE_TYPE (sub), val); CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), NULL_TREE, sub); } /* Build up the array. */ @@ -5094,7 +5272,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* We are going to bind a reference directly to a base-class subobject of EXPR. */ /* Build an expression for `*((base*) &expr)'. */ - expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain); + expr = cp_build_addr_expr (expr, complain); expr = convert_to_base (expr, build_pointer_type (totype), !c_cast_p, /*nonnull=*/true, complain); expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain); @@ -5110,7 +5288,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, conversion (i.e. the second step of copy-initialization), so don't allow any more. */ flags |= LOOKUP_NO_CONVERSION; - expr = build_temp (expr, totype, flags, &diag_kind); + if (TREE_CODE (expr) == TARGET_EXPR + && TARGET_EXPR_LIST_INIT_P (expr)) + /* Copy-list-initialization doesn't actually involve a copy. */ + return expr; + expr = build_temp (expr, totype, flags, &diag_kind, complain); if (diag_kind && fn) { if ((complain & tf_error)) @@ -5143,16 +5325,21 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, VA_ARG_EXPR and CONSTRUCTOR expressions are special cases that need temporaries, even when their types are reference compatible with the type of reference being bound, so the - upcoming call to cp_build_unary_op (ADDR_EXPR, expr, ...) - doesn't fail. */ + upcoming call to cp_build_addr_expr doesn't fail. */ if (convs->need_temporary_p || TREE_CODE (expr) == CONSTRUCTOR || TREE_CODE (expr) == VA_ARG_EXPR) { - tree type = convs->u.next->type; + /* Otherwise, a temporary of type "cv1 T1" is created and + initialized from the initializer expression using the rules + for a non-reference copy-initialization (8.5). */ + + tree type = TREE_TYPE (ref_type); cp_lvalue_kind lvalue = real_lvalue_p (expr); - if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)) + gcc_assert (same_type_ignoring_top_level_qualifiers_p + (type, convs->u.next->type)); + if (!CP_TYPE_CONST_NON_VOLATILE_P (type) && !TYPE_REF_IS_RVALUE (ref_type)) { if (complain & tf_error) @@ -5178,7 +5365,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, OK. */ if ((lvalue & clk_packed) && CLASS_TYPE_P (type) - && !TYPE_HAS_TRIVIAL_INIT_REF (type)) + && type_has_nontrivial_copy_init (type)) { if (complain & tf_error) error ("cannot bind packed field %qE to %qT", @@ -5195,7 +5382,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* Take the address of the thing to which we will bind the reference. */ - expr = cp_build_unary_op (ADDR_EXPR, expr, 1, complain); + expr = cp_build_addr_expr (expr, complain); if (expr == error_mark_node) return error_mark_node; @@ -5224,7 +5411,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, case ck_pmem: return convert_ptrmem (totype, expr, /*allow_inverse_p=*/false, - c_cast_p); + c_cast_p, complain); default: break; @@ -5247,11 +5434,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, tree convert_arg_to_ellipsis (tree arg) { + tree arg_type; + /* [expr.call] The lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed. */ arg = decay_conversion (arg); + arg_type = TREE_TYPE (arg); /* [expr.call] If the argument has integral or enumeration type that is subject @@ -5259,21 +5449,29 @@ convert_arg_to_ellipsis (tree arg) type that is subject to the floating point promotion (_conv.fpprom_), the value of the argument is converted to the promoted type before the call. */ - if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE - && (TYPE_PRECISION (TREE_TYPE (arg)) + if (TREE_CODE (arg_type) == REAL_TYPE + && (TYPE_PRECISION (arg_type) < TYPE_PRECISION (double_type_node)) - && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (arg)))) - arg = convert_to_real (double_type_node, arg); - else if (NULLPTR_TYPE_P (TREE_TYPE (arg))) + && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type))) + { + if (warn_double_promotion && !c_inhibit_evaluation_warnings) + warning (OPT_Wdouble_promotion, + "implicit conversion from %qT to %qT when passing " + "argument to function", + arg_type, double_type_node); + arg = convert_to_real (double_type_node, arg); + } + else if (NULLPTR_TYPE_P (arg_type)) arg = null_pointer_node; - else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg))) + else if (INTEGRAL_OR_ENUMERATION_TYPE_P (arg_type)) arg = perform_integral_promotions (arg); arg = require_complete_type (arg); + arg_type = TREE_TYPE (arg); if (arg != error_mark_node - && (type_has_nontrivial_copy_init (TREE_TYPE (arg)) - || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (arg)))) + && (type_has_nontrivial_copy_init (arg_type) + || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type))) { /* [expr.call] 5.2.2/7: Passing a potentially-evaluated argument of class type (Clause 9) @@ -5288,7 +5486,7 @@ convert_arg_to_ellipsis (tree arg) it is not potentially-evaluated. */ if (cp_unevaluated_operand == 0) error ("cannot pass objects of non-trivially-copyable " - "type %q#T through %<...%>", TREE_TYPE (arg)); + "type %q#T through %<...%>", arg_type); } return arg; @@ -5369,7 +5567,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) } /* Detect recursion. */ - for (i = 0; VEC_iterate (tree, default_arg_context, i, t); ++i) + FOR_EACH_VEC_ELT (tree, default_arg_context, i, t) if (t == fn) { error ("recursive evaluation of default argument for %q#D", fn); @@ -5566,7 +5764,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ++nargs; alcarray = XALLOCAVEC (tree, nargs); alcarray[0] = first_arg; - for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix) + FOR_EACH_VEC_ELT (tree, args, ix, arg) alcarray[ix + 1] = arg; argarray = alcarray; } @@ -5576,12 +5774,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (TREE_THIS_VOLATILE (fn) && cfun) current_function_returns_abnormally = 1; if (!VOID_TYPE_P (return_type)) - require_complete_type (return_type); + require_complete_type_sfinae (return_type, complain); return convert_from_reference (expr); } /* Give any warnings we noticed during overload resolution. */ - if (cand->warnings) + if (cand->warnings && (complain & tf_warning)) { struct candidate_warning *w; for (w = cand->warnings; w; w = w->next) @@ -5594,6 +5792,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (DECL_FUNCTION_MEMBER_P (fn)) { + tree access_fn; /* If FN is a template function, two cases must be considered. For example: @@ -5621,10 +5820,35 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) different access. */ if (DECL_TEMPLATE_INFO (fn) && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn))) - perform_or_defer_access_check (cand->access_path, - DECL_TI_TEMPLATE (fn), fn); + access_fn = DECL_TI_TEMPLATE (fn); + else + access_fn = fn; + if (flags & LOOKUP_SPECULATIVE) + { + if (!speculative_access_check (cand->access_path, access_fn, fn, + !!(flags & LOOKUP_COMPLAIN))) + return error_mark_node; + } else - perform_or_defer_access_check (cand->access_path, fn, fn); + perform_or_defer_access_check (cand->access_path, access_fn, fn); + } + + /* If we're checking for implicit delete, don't bother with argument + conversions. */ + if (flags & LOOKUP_SPECULATIVE) + { + if (DECL_DELETED_FN (fn)) + { + if (flags & LOOKUP_COMPLAIN) + mark_used (fn); + return error_mark_node; + } + if (cand->viable == 1) + return fn; + else if (!(flags & LOOKUP_COMPLAIN)) + /* Reject bad conversions now. */ + return error_mark_node; + /* else continue to get conversion error. */ } /* Find maximum size of vector to hold converted arguments. */ @@ -5805,6 +6029,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) tree targ; tree arg = argarray[num_artificial_parms_for (fn)]; tree fa; + bool trivial = trivial_fn_p (fn); /* Pull out the real argument, disregarding const-correctness. */ targ = arg; @@ -5826,16 +6051,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) else arg = cp_build_indirect_ref (arg, RO_NULL, complain); - if (TREE_CODE (arg) == TARGET_EXPR - && TARGET_EXPR_LIST_INIT_P (arg)) - { - /* Copy-list-initialization doesn't require the copy constructor - to be defined. */ - } /* [class.copy]: the copy constructor is implicitly defined even if the implementation elided its use. */ - else if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)) - || move_fn_p (fn)) + if (!trivial || DECL_DELETED_FN (fn)) { mark_used (fn); already_used = true; @@ -5846,20 +6064,15 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) INIT_EXPR to collapse the temp into our target. Otherwise, if the ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a temp or an INIT_EXPR otherwise. */ - fa = (cand->first_arg != NULL_TREE - ? cand->first_arg - : VEC_index (tree, args, 0)); + fa = argarray[0]; if (integer_zerop (fa)) { if (TREE_CODE (arg) == TARGET_EXPR) return arg; - else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)) - && !move_fn_p (fn)) - return build_target_expr_with_type (arg, DECL_CONTEXT (fn)); + else if (trivial) + return force_target_expr (DECL_CONTEXT (fn), arg); } - else if (TREE_CODE (arg) == TARGET_EXPR - || (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)) - && !move_fn_p (fn))) + else if (TREE_CODE (arg) == TARGET_EXPR || trivial) { tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL, complain)); @@ -5869,8 +6082,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) } } else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR - && copy_fn_p (fn) - && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn))) + && trivial_fn_p (fn) + && !DECL_DELETED_FN (fn)) { tree to = stabilize_reference (cp_build_indirect_ref (argarray[0], RO_NULL, complain)); @@ -5903,7 +6116,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) arg2 = TYPE_SIZE_UNIT (as_base); arg1 = arg; - arg0 = cp_build_unary_op (ADDR_EXPR, to, 0, complain); + arg0 = cp_build_addr_expr (to, complain); if (!can_trust_pointer_alignment ()) { @@ -5927,6 +6140,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) return val; } + /* FIXME handle trivial default constructor and destructor, too. */ if (!already_used) mark_used (fn); @@ -5975,7 +6189,8 @@ build_cxx_call (tree fn, int nargs, tree *argarray) fndecl = get_callee_fndecl (fn); if ((!fndecl || !TREE_NOTHROW (fndecl)) && at_function_scope_p () - && cfun) + && cfun + && cp_function_chain) cp_function_chain->can_throw = 1; /* Check that arguments to builtin functions match the expectations. */ @@ -6045,7 +6260,7 @@ build_java_interface_fn_ref (tree fn, tree instance) /* Determine the itable index of FN. */ i = 1; - for (method = TYPE_METHODS (iface); method; method = TREE_CHAIN (method)) + for (method = TYPE_METHODS (iface); method; method = DECL_CHAIN (method)) { if (!DECL_VIRTUAL_P (method)) continue; @@ -6118,7 +6333,7 @@ build_special_member_call (tree instance, tree name, VEC(tree,gc) **args, if (TYPE_P (binfo)) { /* Resolve the name. */ - if (!complete_type_or_else (binfo, NULL_TREE)) + if (!complete_type_or_maybe_complain (binfo, NULL_TREE, complain)) return error_mark_node; binfo = TYPE_BINFO (binfo); @@ -6177,7 +6392,7 @@ build_special_member_call (tree instance, tree name, VEC(tree,gc) **args, /* If the current function is a complete object constructor or destructor, then we fetch the VTT directly. Otherwise, we look it up using the VTT we were given. */ - vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type)); + vtt = DECL_CHAIN (CLASSTYPE_VTABLES (current_class_type)); vtt = decay_conversion (vtt); vtt = build3 (COND_EXPR, TREE_TYPE (vtt), build2 (EQ_EXPR, boolean_type_node, @@ -6422,7 +6637,7 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, { if (complain & tf_error) { - if (!COMPLETE_TYPE_P (basetype)) + if (!COMPLETE_OR_OPEN_TYPE_P (basetype)) cxx_incomplete_type_error (instance_ptr, basetype); else if (optype) error ("no matching function for call to %<%T::operator %T(%A)%#V%>", @@ -6741,22 +6956,23 @@ compare_ics (conversion *ics1, conversion *ics2) if (rank1 == cr_bad) { - /* XXX Isn't this an extension? */ - /* Both ICS are bad. We try to make a decision based on what - would have happened if they'd been good. */ - if (ics1->user_conv_p > ics2->user_conv_p - || ics1->rank > ics2->rank) + /* Both ICS are bad. We try to make a decision based on what would + have happened if they'd been good. This is not an extension, + we'll still give an error when we build up the call; this just + helps us give a more helpful error message. */ + rank1 = BAD_CONVERSION_RANK (ics1); + rank2 = BAD_CONVERSION_RANK (ics2); + + if (rank1 > rank2) return -1; - else if (ics1->user_conv_p < ics2->user_conv_p - || ics1->rank < ics2->rank) + else if (rank1 < rank2) return 1; /* We couldn't make up our minds; try to figure it out below. */ } - if (ics1->ellipsis_p || ics1->kind == ck_list) - /* Both conversions are ellipsis conversions or both are building a - std::initializer_list. */ + if (ics1->ellipsis_p) + /* Both conversions are ellipsis conversions. */ return 0; /* User-defined conversion sequence U1 is a better conversion sequence @@ -6765,16 +6981,24 @@ compare_ics (conversion *ics1, conversion *ics2) ond standard conversion sequence of U1 is better than the second standard conversion sequence of U2. */ - if (ics1->user_conv_p) + /* Handle list-conversion with the same code even though it isn't always + ranked as a user-defined conversion and it doesn't have a second + standard conversion sequence; it will still have the desired effect. + Specifically, we need to do the reference binding comparison at the + end of this function. */ + + if (ics1->user_conv_p || ics1->kind == ck_list) { conversion *t1; conversion *t2; for (t1 = ics1; t1->kind != ck_user; t1 = t1->u.next) - if (t1->kind == ck_ambig || t1->kind == ck_aggr) + if (t1->kind == ck_ambig || t1->kind == ck_aggr + || t1->kind == ck_list) break; for (t2 = ics2; t2->kind != ck_user; t2 = t2->u.next) - if (t2->kind == ck_ambig || t2->kind == ck_aggr) + if (t2->kind == ck_ambig || t2->kind == ck_aggr + || t2->kind == ck_list) break; if (t1->kind != t2->kind) @@ -7713,9 +7937,32 @@ set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp) VAR. */ if (TREE_CODE (expr) != TARGET_EXPR) expr = get_target_expr (expr); - /* Create the INIT_EXPR that will initialize the temporary - variable. */ - init = build2 (INIT_EXPR, type, var, expr); + + /* If the initializer is constant, put it in DECL_INITIAL so we get + static initialization and use in constant expressions. */ + init = maybe_constant_init (expr); + if (TREE_CONSTANT (init)) + { + if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type)) + { + /* 5.19 says that a constant expression can include an + lvalue-rvalue conversion applied to "a glvalue of literal type + that refers to a non-volatile temporary object initialized + with a constant expression". Rather than try to communicate + that this VAR_DECL is a temporary, just mark it constexpr. + + Currently this is only useful for initializer_list temporaries, + since reference vars can't appear in constant expressions. */ + DECL_DECLARED_CONSTEXPR_P (var) = true; + TREE_CONSTANT (var) = true; + } + DECL_INITIAL (var) = init; + init = NULL_TREE; + } + else + /* Create the INIT_EXPR that will initialize the temporary + variable. */ + init = build2 (INIT_EXPR, type, var, expr); if (at_function_scope_p ()) { add_decl_expr (var); @@ -7873,11 +8120,12 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup, build_pointer_type (base_conv_type), /*check_access=*/true, /*nonnull=*/true, complain); - expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr); + if (init) + expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr); } else /* Take the address of EXPR. */ - expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error); + expr = cp_build_addr_expr (expr, tf_warning_or_error); /* If a BASE_CONV was required, perform it now. */ if (base_conv_type) expr = (perform_implicit_conversion @@ -7901,6 +8149,10 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup, bool is_std_init_list (tree type) { + /* Look through typedefs. */ + if (!TYPE_P (type)) + return false; + type = TYPE_MAIN_VARIANT (type); return (CLASS_TYPE_P (type) && CP_TYPE_CONTEXT (type) == std_node && strcmp (TYPE_NAME_STRING (type), "initializer_list") == 0);