X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fcall.c;h=0f016ca324a6573a509ddd6bcf4fd33dbecff53e;hb=8e8ac75a13190747d6c7ce8f0fb4efe5f52cd40e;hp=a1c8682fe6c047013415428710e7e29b29bdccba;hpb=ce984e5e401accb43a1c4bfee31a4743f4004118;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a1c8682fe6c..0f016ca324a 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -639,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. */ @@ -652,24 +675,31 @@ build_aggr_conv (tree type, tree ctor, int flags) 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)) @@ -1063,7 +1093,7 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) if (!expr) return NULL; - conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true); + conversions = lookup_conversions (s); if (!conversions) return NULL; @@ -1992,6 +2022,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, case INDIRECT_REF: if (TREE_CODE (type1) == POINTER_TYPE + && is_complete (TREE_TYPE (type1)) && (TYPE_PTROB_P (type1) || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)) break; @@ -2434,8 +2465,7 @@ 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) { @@ -2998,8 +3028,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; @@ -3555,7 +3584,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)) { @@ -5260,6 +5289,10 @@ 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; + 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) { @@ -5793,15 +5826,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) access_fn = fn; if (flags & LOOKUP_SPECULATIVE) { - /* If we're checking for implicit delete, we don't want access - control errors. */ - if (!accessible_p (cand->access_path, access_fn, true)) - { - /* Unless we're under maybe_explain_implicit_delete. */ - if (flags & LOOKUP_COMPLAIN) - enforce_access (cand->access_path, access_fn, fn); - return error_mark_node; - } + 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, access_fn, fn); @@ -6025,15 +6052,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 constructor - to be defined. */ - } /* [class.copy]: the copy constructor is implicitly defined even if the implementation elided its use. */ - else if (!trivial) + if (!trivial || DECL_DELETED_FN (fn)) { mark_used (fn); already_used = true; @@ -6062,7 +6083,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) } } else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR - && trivial_fn_p (fn)) + && trivial_fn_p (fn) + && !DECL_DELETED_FN (fn)) { tree to = stabilize_reference (cp_build_indirect_ref (argarray[0], RO_NULL, complain)); @@ -6616,7 +6638,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%>",